Commit | Line | Data |
---|---|---|
f0bb4ca8 | 1 | #ifndef lint |
ea19968f | 2 | static char sccsid[] = "@(#)rcmd.c 4.9 %G%"; |
f0bb4ca8 BJ |
3 | #endif |
4 | ||
5 | #include <stdio.h> | |
6 | #include <sys/types.h> | |
7 | #include <sys/socket.h> | |
40d6b022 SL |
8 | |
9 | #include <netinet/in.h> | |
10 | ||
3f5b52bc | 11 | #include <netdb.h> |
40d6b022 | 12 | #include <errno.h> |
f0bb4ca8 BJ |
13 | |
14 | extern errno; | |
15 | char *index(), *sprintf(); | |
f0bb4ca8 BJ |
16 | |
17 | rcmd(ahost, rport, locuser, remuser, cmd, fd2p) | |
18 | char **ahost; | |
19 | int rport; | |
20 | char *locuser, *remuser, *cmd; | |
21 | int *fd2p; | |
22 | { | |
40d6b022 | 23 | int s, timo = 1; |
f0bb4ca8 BJ |
24 | struct sockaddr_in sin, sin2, from; |
25 | char c; | |
40d6b022 | 26 | int lport = IPPORT_RESERVED - 1; |
3f5b52bc | 27 | struct hostent *hp; |
f0bb4ca8 | 28 | |
3f5b52bc SL |
29 | hp = gethostbyname(*ahost); |
30 | if (hp == 0) { | |
f0bb4ca8 BJ |
31 | fprintf(stderr, "%s: unknown host\n", *ahost); |
32 | return (-1); | |
33 | } | |
3f5b52bc | 34 | *ahost = hp->h_name; |
f0bb4ca8 | 35 | retry: |
c1dfbf19 | 36 | s = rresvport(&lport); |
f0bb4ca8 BJ |
37 | if (s < 0) |
38 | return (-1); | |
3f5b52bc | 39 | sin.sin_family = hp->h_addrtype; |
40d6b022 | 40 | bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); |
b567f18d | 41 | sin.sin_port = rport; |
40d6b022 | 42 | if (connect(s, (caddr_t)&sin, sizeof (sin), 0) < 0) { |
ea19968f | 43 | (void) close(s); |
40d6b022 | 44 | if (errno == EADDRINUSE) { |
40d6b022 SL |
45 | lport--; |
46 | goto retry; | |
47 | } | |
f0bb4ca8 | 48 | if (errno == ECONNREFUSED && timo <= 16) { |
f0bb4ca8 BJ |
49 | sleep(timo); |
50 | timo *= 2; | |
51 | goto retry; | |
52 | } | |
40d6b022 | 53 | perror(hp->h_name); |
f0bb4ca8 BJ |
54 | return (-1); |
55 | } | |
40d6b022 | 56 | lport--; |
f0bb4ca8 BJ |
57 | if (fd2p == 0) { |
58 | write(s, "", 1); | |
c1dfbf19 | 59 | lport = 0; |
f0bb4ca8 BJ |
60 | } else { |
61 | char num[8]; | |
c1dfbf19 | 62 | int s2 = rresvport(&lport), s3; |
ea19968f | 63 | int len = sizeof (from); |
f0bb4ca8 | 64 | |
ea19968f RC |
65 | if (s2 < 0) |
66 | goto bad; | |
40d6b022 | 67 | listen(s2, 1); |
c1dfbf19 | 68 | (void) sprintf(num, "%d", lport); |
2c510808 SL |
69 | if (write(s, num, strlen(num)+1) != strlen(num)+1) { |
70 | perror("write: setting up stderr"); | |
71 | (void) close(s2); | |
72 | goto bad; | |
73 | } | |
ea19968f RC |
74 | s3 = accept(s2, &from, &len, 0); |
75 | (void) close(s2); | |
76 | if (s3 < 0) { | |
f0bb4ca8 | 77 | perror("accept"); |
c1dfbf19 | 78 | lport = 0; |
f0bb4ca8 BJ |
79 | goto bad; |
80 | } | |
40d6b022 SL |
81 | *fd2p = s3; |
82 | from.sin_port = ntohs((u_short)from.sin_port); | |
f0bb4ca8 BJ |
83 | if (from.sin_family != AF_INET || |
84 | from.sin_port >= IPPORT_RESERVED) { | |
85 | fprintf(stderr, | |
86 | "socket: protocol failure in circuit setup.\n"); | |
40d6b022 | 87 | goto bad2; |
f0bb4ca8 | 88 | } |
f0bb4ca8 BJ |
89 | } |
90 | (void) write(s, locuser, strlen(locuser)+1); | |
91 | (void) write(s, remuser, strlen(remuser)+1); | |
92 | (void) write(s, cmd, strlen(cmd)+1); | |
93 | if (read(s, &c, 1) != 1) { | |
94 | perror(*ahost); | |
40d6b022 | 95 | goto bad2; |
f0bb4ca8 BJ |
96 | } |
97 | if (c != 0) { | |
98 | while (read(s, &c, 1) == 1) { | |
99 | (void) write(2, &c, 1); | |
100 | if (c == '\n') | |
101 | break; | |
102 | } | |
40d6b022 | 103 | goto bad2; |
f0bb4ca8 BJ |
104 | } |
105 | return (s); | |
40d6b022 | 106 | bad2: |
c1dfbf19 | 107 | if (lport) |
f0bb4ca8 | 108 | (void) close(*fd2p); |
40d6b022 | 109 | bad: |
f0bb4ca8 BJ |
110 | (void) close(s); |
111 | return (-1); | |
112 | } | |
113 | ||
c1dfbf19 SL |
114 | rresvport(alport) |
115 | int *alport; | |
f0bb4ca8 BJ |
116 | { |
117 | struct sockaddr_in sin; | |
f0bb4ca8 BJ |
118 | int s; |
119 | ||
40d6b022 SL |
120 | sin.sin_family = AF_INET; |
121 | sin.sin_addr.s_addr = 0; | |
b567f18d | 122 | s = socket(AF_INET, SOCK_STREAM, 0, 0); |
40d6b022 SL |
123 | if (s < 0) |
124 | return (-1); | |
f0bb4ca8 | 125 | for (;;) { |
40d6b022 SL |
126 | sin.sin_port = htons((u_short)*alport); |
127 | if (bind(s, (caddr_t)&sin, sizeof (sin), 0) >= 0) | |
f0bb4ca8 BJ |
128 | return (s); |
129 | if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) { | |
130 | perror("socket"); | |
ea19968f | 131 | (void) close(s); |
f0bb4ca8 BJ |
132 | return (-1); |
133 | } | |
40d6b022 SL |
134 | (*alport)--; |
135 | if (*alport == IPPORT_RESERVED/2) { | |
f0bb4ca8 | 136 | fprintf(stderr, "socket: All ports in use\n"); |
ea19968f | 137 | (void) close(s); |
f0bb4ca8 BJ |
138 | return (-1); |
139 | } | |
140 | } | |
141 | } | |
142 | ||
ff3164c8 SL |
143 | ruserok(rhost, superuser, ruser, luser) |
144 | char *rhost; | |
145 | int superuser; | |
146 | char *ruser, *luser; | |
f0bb4ca8 BJ |
147 | { |
148 | FILE *hostf; | |
149 | char ahost[32]; | |
150 | int first = 1; | |
151 | ||
ff3164c8 | 152 | hostf = superuser ? (FILE *)0 : fopen("/etc/hosts.equiv", "r"); |
f0bb4ca8 BJ |
153 | again: |
154 | if (hostf) { | |
155 | while (fgets(ahost, sizeof (ahost), hostf)) { | |
156 | char *user; | |
157 | if (index(ahost, '\n')) | |
158 | *index(ahost, '\n') = 0; | |
159 | user = index(ahost, ' '); | |
160 | if (user) | |
161 | *user++ = 0; | |
162 | if (!strcmp(rhost, ahost) && | |
ff3164c8 SL |
163 | !strcmp(ruser, user ? user : luser)) { |
164 | (void) fclose(hostf); | |
165 | return (0); | |
166 | } | |
f0bb4ca8 BJ |
167 | } |
168 | (void) fclose(hostf); | |
169 | } | |
170 | if (first == 1) { | |
171 | first = 0; | |
172 | hostf = fopen(".rhosts", "r"); | |
173 | goto again; | |
174 | } | |
175 | return (-1); | |
f0bb4ca8 | 176 | } |