|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #if defined(LIBC_SCCS) && !defined(lint)
21: static char sccsid[] = "@(#)rcmd.c 5.22 (Berkeley) 6/1/90";
22: #endif /* LIBC_SCCS and not lint */
23:
24: #include <stdio.h>
25: #include <ctype.h>
26: #include <pwd.h>
27: #include <sys/param.h>
28: #include <sys/file.h>
29: #include <sys/signal.h>
30: #include <sys/socket.h>
31: #include <sys/stat.h>
32:
33: #include <netinet/in.h>
34:
35: #include <netdb.h>
36: #include <errno.h>
37:
38: extern errno;
39: char *index();
40:
41: rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
42: char **ahost;
43: u_short rport;
44: char *locuser, *remuser, *cmd;
45: int *fd2p;
46: {
47: int s, timo = 1, pid;
48: long oldmask;
49: struct sockaddr_in sin, sin2, from;
50: char c;
51: int lport = IPPORT_RESERVED - 1;
52: struct hostent *hp;
53: fd_set reads;
54:
55: pid = getpid();
56: hp = gethostbyname(*ahost);
57: if (hp == 0) {
58: herror(*ahost);
59: return (-1);
60: }
61: *ahost = hp->h_name;
62: oldmask = sigblock(sigmask(SIGURG));
63: for (;;) {
64: s = rresvport(&lport);
65: if (s < 0) {
66: if (errno == EAGAIN)
67: fprintf(stderr, "socket: All ports in use\n");
68: else
69: perror("rcmd: socket");
70: sigsetmask(oldmask);
71: return (-1);
72: }
73: fcntl(s, F_SETOWN, pid);
74: sin.sin_family = hp->h_addrtype;
75: bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
76: sin.sin_port = rport;
77: if (connect(s, (caddr_t)&sin, sizeof (sin), 0) >= 0)
78: break;
79: (void) close(s);
80: if (errno == EADDRINUSE) {
81: lport--;
82: continue;
83: }
84: if (errno == ECONNREFUSED && timo <= 16) {
85: sleep(timo);
86: timo *= 2;
87: continue;
88: }
89: if (hp->h_addr_list[1] != NULL) {
90: int oerrno = errno;
91:
92: fprintf(stderr,
93: "connect to address %s: ", inet_ntoa(sin.sin_addr));
94: errno = oerrno;
95: perror(0);
96: hp->h_addr_list++;
97: bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr,
98: hp->h_length);
99: fprintf(stderr, "Trying %s...\n",
100: inet_ntoa(sin.sin_addr));
101: continue;
102: }
103: perror(hp->h_name);
104: sigsetmask(oldmask);
105: return (-1);
106: }
107: lport--;
108: if (fd2p == 0) {
109: write(s, "", 1);
110: lport = 0;
111: } else {
112: char num[8];
113: int s2 = rresvport(&lport), s3;
114: int len = sizeof (from);
115:
116: if (s2 < 0)
117: goto bad;
118: listen(s2, 1);
119: (void) sprintf(num, "%d", lport);
120: if (write(s, num, strlen(num)+1) != strlen(num)+1) {
121: perror("write: setting up stderr");
122: (void) close(s2);
123: goto bad;
124: }
125: FD_ZERO(&reads);
126: FD_SET(s, &reads);
127: FD_SET(s2, &reads);
128: errno = 0;
129: if (select(32, &reads, 0, 0, 0) < 1 ||
130: !FD_ISSET(s2, &reads)) {
131: if (errno != 0)
132: perror("select: setting up stderr");
133: else
134: fprintf(stderr,
135: "select: protocol failure in circuit setup.\n");
136: (void) close(s2);
137: goto bad;
138: }
139: s3 = accept(s2, &from, &len, 0);
140: (void) close(s2);
141: if (s3 < 0) {
142: perror("accept");
143: lport = 0;
144: goto bad;
145: }
146: *fd2p = s3;
147: from.sin_port = ntohs((u_short)from.sin_port);
148: if (from.sin_family != AF_INET ||
149: from.sin_port >= IPPORT_RESERVED ||
150: from.sin_port < IPPORT_RESERVED / 2) {
151: fprintf(stderr,
152: "socket: protocol failure in circuit setup.\n");
153: goto bad2;
154: }
155: }
156: (void) write(s, locuser, strlen(locuser)+1);
157: (void) write(s, remuser, strlen(remuser)+1);
158: (void) write(s, cmd, strlen(cmd)+1);
159: if (read(s, &c, 1) != 1) {
160: perror(*ahost);
161: goto bad2;
162: }
163: if (c != 0) {
164: while (read(s, &c, 1) == 1) {
165: (void) write(2, &c, 1);
166: if (c == '\n')
167: break;
168: }
169: goto bad2;
170: }
171: sigsetmask(oldmask);
172: return (s);
173: bad2:
174: if (lport)
175: (void) close(*fd2p);
176: bad:
177: (void) close(s);
178: sigsetmask(oldmask);
179: return (-1);
180: }
181:
182: rresvport(alport)
183: int *alport;
184: {
185: struct sockaddr_in sin;
186: int s;
187:
188: sin.sin_family = AF_INET;
189: sin.sin_addr.s_addr = INADDR_ANY;
190: s = socket(AF_INET, SOCK_STREAM, 0);
191: if (s < 0)
192: return (-1);
193: for (;;) {
194: sin.sin_port = htons((u_short)*alport);
195: if (bind(s, (caddr_t)&sin, sizeof (sin)) >= 0)
196: return (s);
197: if (errno != EADDRINUSE) {
198: (void) close(s);
199: return (-1);
200: }
201: (*alport)--;
202: if (*alport == IPPORT_RESERVED/2) {
203: (void) close(s);
204: errno = EAGAIN; /* close */
205: return (-1);
206: }
207: }
208: }
209:
210: int _check_rhosts_file = 1;
211:
212: ruserok(rhost, superuser, ruser, luser)
213: char *rhost;
214: int superuser;
215: char *ruser, *luser;
216: {
217: FILE *hostf;
218: char fhost[MAXHOSTNAMELEN];
219: int first = 1;
220: register char *sp, *p;
221: int baselen = -1;
222:
223: sp = rhost;
224: p = fhost;
225: while (*sp) {
226: if (*sp == '.') {
227: if (baselen == -1)
228: baselen = sp - rhost;
229: *p++ = *sp++;
230: } else {
231: *p++ = isupper(*sp) ? tolower(*sp++) : *sp++;
232: }
233: }
234: *p = '\0';
235: hostf = superuser ? (FILE *)0 : fopen(_PATH_HEQUIV, "r");
236: again:
237: if (hostf) {
238: if (!_validuser(hostf, fhost, luser, ruser, baselen)) {
239: (void) fclose(hostf);
240: return(0);
241: }
242: (void) fclose(hostf);
243: }
244: if (first == 1 && (_check_rhosts_file || superuser)) {
245: struct stat sbuf;
246: struct passwd *pwd;
247: char pbuf[MAXPATHLEN];
248:
249: first = 0;
250: if ((pwd = getpwnam(luser)) == NULL)
251: return(-1);
252: (void)strcpy(pbuf, pwd->pw_dir);
253: (void)strcat(pbuf, "/.rhosts");
254: if ((hostf = fopen(pbuf, "r")) == NULL)
255: return(-1);
256: /*
257: * if owned by someone other than user or root or if
258: * writeable by anyone but the owner, quit
259: */
260: if (fstat(fileno(hostf), &sbuf) ||
261: sbuf.st_uid && sbuf.st_uid != pwd->pw_uid ||
262: sbuf.st_mode&022) {
263: fclose(hostf);
264: return(-1);
265: }
266: goto again;
267: }
268: return (-1);
269: }
270:
271: /* don't make static, used by lpd(8) */
272: _validuser(hostf, rhost, luser, ruser, baselen)
273: char *rhost, *luser, *ruser;
274: FILE *hostf;
275: int baselen;
276: {
277: char *user;
278: char ahost[MAXHOSTNAMELEN];
279: register char *p;
280:
281: while (fgets(ahost, sizeof (ahost), hostf)) {
282: p = ahost;
283: while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
284: *p = isupper(*p) ? tolower(*p) : *p;
285: p++;
286: }
287: if (*p == ' ' || *p == '\t') {
288: *p++ = '\0';
289: while (*p == ' ' || *p == '\t')
290: p++;
291: user = p;
292: while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
293: p++;
294: } else
295: user = p;
296: *p = '\0';
297: if (_checkhost(rhost, ahost, baselen) &&
298: !strcmp(ruser, *user ? user : luser)) {
299: return (0);
300: }
301: }
302: return (-1);
303: }
304:
305: static
306: _checkhost(rhost, lhost, len)
307: char *rhost, *lhost;
308: int len;
309: {
310: static char ldomain[MAXHOSTNAMELEN + 1];
311: static char *domainp = NULL;
312: static int nodomain = 0;
313: register char *cp;
314:
315: if (len == -1)
316: return(!strcmp(rhost, lhost));
317: if (strncmp(rhost, lhost, len))
318: return(0);
319: if (!strcmp(rhost, lhost))
320: return(1);
321: if (*(lhost + len) != '\0')
322: return(0);
323: if (nodomain)
324: return(0);
325: if (!domainp) {
326: if (gethostname(ldomain, sizeof(ldomain)) == -1) {
327: nodomain = 1;
328: return(0);
329: }
330: ldomain[MAXHOSTNAMELEN] = NULL;
331: if ((domainp = index(ldomain, '.')) == (char *)NULL) {
332: nodomain = 1;
333: return(0);
334: }
335: for (cp = ++domainp; *cp; ++cp)
336: if (isupper(*cp))
337: *cp = tolower(*cp);
338: }
339: return(!strcmp(domainp, rhost + len +1));
340: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.