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