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