Commit | Line | Data |
---|---|---|
586c39b1 DF |
1 | /* |
2 | * Copyright (c) 1983 Regents of the University of California. | |
3 | * All rights reserved. The Berkeley software License Agreement | |
4 | * specifies the terms and conditions for redistribution. | |
5 | */ | |
6 | ||
f0bb4ca8 | 7 | #ifndef lint |
49528010 | 8 | static char sccsid[] = "@(#)rcmd.c 5.4 (Berkeley) %G%"; |
586c39b1 | 9 | #endif not lint |
f0bb4ca8 BJ |
10 | |
11 | #include <stdio.h> | |
20ac274b JB |
12 | #include <ctype.h> |
13 | #include <sys/param.h> | |
f0bb4ca8 | 14 | #include <sys/socket.h> |
40d6b022 SL |
15 | |
16 | #include <netinet/in.h> | |
17 | ||
3f5b52bc | 18 | #include <netdb.h> |
40d6b022 | 19 | #include <errno.h> |
f0bb4ca8 BJ |
20 | |
21 | extern errno; | |
22 | char *index(), *sprintf(); | |
f0bb4ca8 BJ |
23 | |
24 | rcmd(ahost, rport, locuser, remuser, cmd, fd2p) | |
25 | char **ahost; | |
26 | int rport; | |
27 | char *locuser, *remuser, *cmd; | |
28 | int *fd2p; | |
29 | { | |
40d6b022 | 30 | int s, timo = 1; |
f0bb4ca8 BJ |
31 | struct sockaddr_in sin, sin2, from; |
32 | char c; | |
40d6b022 | 33 | int lport = IPPORT_RESERVED - 1; |
3f5b52bc | 34 | struct hostent *hp; |
f0bb4ca8 | 35 | |
3f5b52bc SL |
36 | hp = gethostbyname(*ahost); |
37 | if (hp == 0) { | |
f0bb4ca8 BJ |
38 | fprintf(stderr, "%s: unknown host\n", *ahost); |
39 | return (-1); | |
40 | } | |
3f5b52bc | 41 | *ahost = hp->h_name; |
f0bb4ca8 | 42 | retry: |
c1dfbf19 | 43 | s = rresvport(&lport); |
f0bb4ca8 BJ |
44 | if (s < 0) |
45 | return (-1); | |
3f5b52bc | 46 | sin.sin_family = hp->h_addrtype; |
40d6b022 | 47 | bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); |
b567f18d | 48 | sin.sin_port = rport; |
40d6b022 | 49 | if (connect(s, (caddr_t)&sin, sizeof (sin), 0) < 0) { |
ea19968f | 50 | (void) close(s); |
40d6b022 | 51 | if (errno == EADDRINUSE) { |
40d6b022 SL |
52 | lport--; |
53 | goto retry; | |
54 | } | |
f0bb4ca8 | 55 | if (errno == ECONNREFUSED && timo <= 16) { |
f0bb4ca8 BJ |
56 | sleep(timo); |
57 | timo *= 2; | |
58 | goto retry; | |
59 | } | |
40d6b022 | 60 | perror(hp->h_name); |
f0bb4ca8 BJ |
61 | return (-1); |
62 | } | |
40d6b022 | 63 | lport--; |
f0bb4ca8 BJ |
64 | if (fd2p == 0) { |
65 | write(s, "", 1); | |
c1dfbf19 | 66 | lport = 0; |
f0bb4ca8 BJ |
67 | } else { |
68 | char num[8]; | |
c1dfbf19 | 69 | int s2 = rresvport(&lport), s3; |
ea19968f | 70 | int len = sizeof (from); |
f0bb4ca8 | 71 | |
ea19968f RC |
72 | if (s2 < 0) |
73 | goto bad; | |
40d6b022 | 74 | listen(s2, 1); |
c1dfbf19 | 75 | (void) sprintf(num, "%d", lport); |
2c510808 SL |
76 | if (write(s, num, strlen(num)+1) != strlen(num)+1) { |
77 | perror("write: setting up stderr"); | |
78 | (void) close(s2); | |
79 | goto bad; | |
80 | } | |
ea19968f RC |
81 | s3 = accept(s2, &from, &len, 0); |
82 | (void) close(s2); | |
83 | if (s3 < 0) { | |
f0bb4ca8 | 84 | perror("accept"); |
c1dfbf19 | 85 | lport = 0; |
f0bb4ca8 BJ |
86 | goto bad; |
87 | } | |
40d6b022 SL |
88 | *fd2p = s3; |
89 | from.sin_port = ntohs((u_short)from.sin_port); | |
f0bb4ca8 BJ |
90 | if (from.sin_family != AF_INET || |
91 | from.sin_port >= IPPORT_RESERVED) { | |
92 | fprintf(stderr, | |
93 | "socket: protocol failure in circuit setup.\n"); | |
40d6b022 | 94 | goto bad2; |
f0bb4ca8 | 95 | } |
f0bb4ca8 BJ |
96 | } |
97 | (void) write(s, locuser, strlen(locuser)+1); | |
98 | (void) write(s, remuser, strlen(remuser)+1); | |
99 | (void) write(s, cmd, strlen(cmd)+1); | |
100 | if (read(s, &c, 1) != 1) { | |
101 | perror(*ahost); | |
40d6b022 | 102 | goto bad2; |
f0bb4ca8 BJ |
103 | } |
104 | if (c != 0) { | |
105 | while (read(s, &c, 1) == 1) { | |
106 | (void) write(2, &c, 1); | |
107 | if (c == '\n') | |
108 | break; | |
109 | } | |
40d6b022 | 110 | goto bad2; |
f0bb4ca8 BJ |
111 | } |
112 | return (s); | |
40d6b022 | 113 | bad2: |
c1dfbf19 | 114 | if (lport) |
f0bb4ca8 | 115 | (void) close(*fd2p); |
40d6b022 | 116 | bad: |
f0bb4ca8 BJ |
117 | (void) close(s); |
118 | return (-1); | |
119 | } | |
120 | ||
c1dfbf19 SL |
121 | rresvport(alport) |
122 | int *alport; | |
f0bb4ca8 BJ |
123 | { |
124 | struct sockaddr_in sin; | |
f0bb4ca8 BJ |
125 | int s; |
126 | ||
40d6b022 | 127 | sin.sin_family = AF_INET; |
9a89481f MK |
128 | sin.sin_addr.s_addr = INADDR_ANY; |
129 | s = socket(AF_INET, SOCK_STREAM, 0); | |
40d6b022 SL |
130 | if (s < 0) |
131 | return (-1); | |
f0bb4ca8 | 132 | for (;;) { |
40d6b022 SL |
133 | sin.sin_port = htons((u_short)*alport); |
134 | if (bind(s, (caddr_t)&sin, sizeof (sin), 0) >= 0) | |
f0bb4ca8 | 135 | return (s); |
9a89481f MK |
136 | if (errno == EADDRNOTAVAIL) |
137 | return (-1); | |
138 | if (errno != EADDRINUSE) { | |
f0bb4ca8 | 139 | perror("socket"); |
ea19968f | 140 | (void) close(s); |
f0bb4ca8 BJ |
141 | return (-1); |
142 | } | |
40d6b022 SL |
143 | (*alport)--; |
144 | if (*alport == IPPORT_RESERVED/2) { | |
f0bb4ca8 | 145 | fprintf(stderr, "socket: All ports in use\n"); |
ea19968f | 146 | (void) close(s); |
f0bb4ca8 BJ |
147 | return (-1); |
148 | } | |
149 | } | |
150 | } | |
151 | ||
ff3164c8 SL |
152 | ruserok(rhost, superuser, ruser, luser) |
153 | char *rhost; | |
154 | int superuser; | |
155 | char *ruser, *luser; | |
f0bb4ca8 BJ |
156 | { |
157 | FILE *hostf; | |
20ac274b JB |
158 | char fhost[MAXHOSTNAMELEN]; |
159 | char ahost[MAXHOSTNAMELEN]; | |
f0bb4ca8 | 160 | int first = 1; |
20ac274b JB |
161 | register char *sp, *p; |
162 | int baselen = -1; | |
f0bb4ca8 | 163 | |
20ac274b JB |
164 | sp = rhost; |
165 | p = fhost; | |
166 | while (*sp) { | |
167 | if (*sp == '.') { | |
168 | if (baselen == -1) | |
169 | baselen = sp - rhost; | |
170 | *p++ = *sp++; | |
171 | } else { | |
172 | *p++ = isupper(*sp) ? tolower(*sp++) : *sp++; | |
173 | } | |
174 | } | |
175 | *p = '\0'; | |
ff3164c8 | 176 | hostf = superuser ? (FILE *)0 : fopen("/etc/hosts.equiv", "r"); |
f0bb4ca8 BJ |
177 | again: |
178 | if (hostf) { | |
179 | while (fgets(ahost, sizeof (ahost), hostf)) { | |
180 | char *user; | |
7620d83a JB |
181 | |
182 | p = ahost; | |
183 | while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') | |
20ac274b | 184 | *p++ = isupper(*p) ? tolower(*p) : *p; |
7620d83a JB |
185 | if (*p == ' ' || *p == '\t') { |
186 | *p++ = '\0'; | |
187 | while (*p == ' ' || *p == '\t') | |
188 | p++; | |
189 | user = p; | |
190 | while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') | |
191 | p++; | |
192 | } else | |
193 | user = p; | |
194 | *p = '\0'; | |
20ac274b | 195 | if (_checkhost(fhost, ahost, baselen) && |
7620d83a | 196 | !strcmp(ruser, *user ? user : luser)) { |
ff3164c8 SL |
197 | (void) fclose(hostf); |
198 | return (0); | |
199 | } | |
f0bb4ca8 BJ |
200 | } |
201 | (void) fclose(hostf); | |
202 | } | |
203 | if (first == 1) { | |
204 | first = 0; | |
205 | hostf = fopen(".rhosts", "r"); | |
206 | goto again; | |
207 | } | |
208 | return (-1); | |
f0bb4ca8 | 209 | } |
20ac274b JB |
210 | |
211 | _checkhost(rhost, lhost, len) | |
212 | char *rhost, *lhost; | |
213 | int len; | |
214 | { | |
215 | static char ldomain[MAXHOSTNAMELEN]; | |
216 | static char *domainp = NULL; | |
217 | register char *cp; | |
218 | ||
219 | if (len == -1) | |
220 | return(!strcmp(rhost, lhost)); | |
221 | if (strncmp(rhost, lhost, len)) | |
222 | return(0); | |
223 | if (!strcmp(rhost, lhost)) | |
224 | return(1); | |
225 | if (*(lhost + len) != '\0') | |
226 | return(0); | |
227 | if (!domainp) { | |
228 | if (gethostname(ldomain, sizeof(ldomain)) == -1) { | |
229 | domainp = (char *)1; | |
230 | return(0); | |
231 | } | |
232 | ldomain[MAXHOSTNAMELEN] = NULL; | |
49528010 JB |
233 | if ((domainp = index(ldomain, '.') + 1) == (char *)1) |
234 | return(0); | |
20ac274b JB |
235 | cp = domainp; |
236 | while (*cp) | |
237 | *cp++ = isupper(*cp) ? tolower(*cp) : *cp; | |
238 | } | |
239 | if (domainp == (char *)1) | |
240 | return(0); | |
241 | return(!strcmp(domainp, rhost + len +1)); | |
242 | } |