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