|
|
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.