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