|
|
1.1 ! root 1: /*- ! 2: * Copyright (c) 1983, 1990 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: char copyright[] = ! 22: "@(#) Copyright (c) 1983, 1990 The Regents of the University of California.\n\ ! 23: All rights reserved.\n"; ! 24: #endif /* not lint */ ! 25: ! 26: #ifndef lint ! 27: static char sccsid[] = "@(#)rsh.c 5.23.1.1 (Berkeley) 10/21/90"; ! 28: #endif /* not lint */ ! 29: ! 30: /* ! 31: * $Source: mit/rsh/RCS/rsh.c,v $ ! 32: * $Header: mit/rsh/RCS/rsh.c,v 5.1 89/07/31 19:28:59 kfall Exp Locker: kfall $ ! 33: */ ! 34: ! 35: #include <sys/types.h> ! 36: #include <sys/signal.h> ! 37: #include <sys/socket.h> ! 38: #include <sys/ioctl.h> ! 39: #include <sys/file.h> ! 40: ! 41: #include <netinet/in.h> ! 42: #include <netdb.h> ! 43: ! 44: #include <pwd.h> ! 45: #include <stdio.h> ! 46: #include <errno.h> ! 47: #include <string.h> ! 48: #include <varargs.h> ! 49: #include "pathnames.h" ! 50: ! 51: #ifdef KERBEROS ! 52: #include <kerberosIV/des.h> ! 53: #include <kerberosIV/krb.h> ! 54: ! 55: CREDENTIALS cred; ! 56: Key_schedule schedule; ! 57: int use_kerberos = 1, encrypt; ! 58: char dst_realm_buf[REALM_SZ], *dest_realm; ! 59: extern char *krb_realmofhost(); ! 60: #endif ! 61: ! 62: /* ! 63: * rsh - remote shell ! 64: */ ! 65: extern int errno; ! 66: int rfd2; ! 67: ! 68: main(argc, argv) ! 69: int argc; ! 70: char **argv; ! 71: { ! 72: extern char *optarg; ! 73: extern int optind; ! 74: struct passwd *pw; ! 75: struct servent *sp; ! 76: long omask; ! 77: int argoff, asrsh, ch, dflag, nflag, one, pid, rem, uid; ! 78: register char *p; ! 79: char *args, *host, *user, *copyargs(); ! 80: void sendsig(); ! 81: ! 82: argoff = asrsh = dflag = nflag = 0; ! 83: one = 1; ! 84: host = user = NULL; ! 85: ! 86: /* if called as something other than "rsh", use it as the host name */ ! 87: if (p = rindex(argv[0], '/')) ! 88: ++p; ! 89: else ! 90: p = argv[0]; ! 91: if (strcmp(p, "rsh")) ! 92: host = p; ! 93: else ! 94: asrsh = 1; ! 95: ! 96: /* handle "rsh host flags" */ ! 97: if (!host && argc > 2 && argv[1][0] != '-') { ! 98: host = argv[1]; ! 99: argoff = 1; ! 100: } ! 101: ! 102: #ifdef KERBEROS ! 103: #define OPTIONS "8KLdek:l:nw" ! 104: #else ! 105: #define OPTIONS "8KLdel:nw" ! 106: #endif ! 107: while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != EOF) ! 108: switch(ch) { ! 109: case 'K': ! 110: #ifdef KERBEROS ! 111: use_kerberos = 0; ! 112: #endif ! 113: break; ! 114: case 'L': /* -8Lew are ignored to allow rlogin aliases */ ! 115: case 'e': ! 116: case 'w': ! 117: case '8': ! 118: break; ! 119: case 'd': ! 120: dflag = 1; ! 121: break; ! 122: case 'l': ! 123: user = optarg; ! 124: break; ! 125: #ifdef KERBEROS ! 126: case 'k': ! 127: dest_realm = dst_realm_buf; ! 128: strncpy(dest_realm, optarg, REALM_SZ); ! 129: break; ! 130: #endif ! 131: case 'n': ! 132: nflag = 1; ! 133: break; ! 134: #ifdef KERBEROS ! 135: #endif ! 136: case '?': ! 137: default: ! 138: usage(); ! 139: } ! 140: optind += argoff; ! 141: ! 142: /* if haven't gotten a host yet, do so */ ! 143: if (!host && !(host = argv[optind++])) ! 144: usage(); ! 145: ! 146: /* if no further arguments, must have been called as rlogin. */ ! 147: if (!argv[optind]) { ! 148: if (asrsh) ! 149: *argv = "rlogin"; ! 150: execv(_PATH_RLOGIN, argv); ! 151: (void)fprintf(stderr, "rsh: can't exec %s.\n", _PATH_RLOGIN); ! 152: exit(1); ! 153: } ! 154: ! 155: argc -= optind; ! 156: argv += optind; ! 157: ! 158: if (!(pw = getpwuid(uid = getuid()))) { ! 159: (void)fprintf(stderr, "rsh: unknown user id.\n"); ! 160: exit(1); ! 161: } ! 162: if (!user) ! 163: user = pw->pw_name; ! 164: ! 165: #ifdef KERBEROS ! 166: #endif ! 167: ! 168: args = copyargs(argv); ! 169: ! 170: sp = NULL; ! 171: #ifdef KERBEROS ! 172: if (use_kerberos) { ! 173: sp = getservbyname((encrypt ? "ekshell" : "kshell"), "tcp"); ! 174: if (sp == NULL) { ! 175: use_kerberos = 0; ! 176: warning("can't get entry for %s/tcp service", ! 177: encrypt ? "ekshell" : "kshell"); ! 178: } ! 179: } ! 180: #endif ! 181: if (sp == NULL) ! 182: sp = getservbyname("shell", "tcp"); ! 183: if (sp == NULL) { ! 184: (void)fprintf(stderr, "rsh: shell/tcp: unknown service.\n"); ! 185: exit(1); ! 186: } ! 187: ! 188: #ifdef KERBEROS ! 189: try_connect: ! 190: if (use_kerberos) { ! 191: rem = KSUCCESS; ! 192: errno = 0; ! 193: if (dest_realm == NULL) ! 194: dest_realm = krb_realmofhost(host); ! 195: ! 196: rem = krcmd(&host, sp->s_port, user, args, &rfd2, ! 197: dest_realm); ! 198: if (rem < 0) { ! 199: use_kerberos = 0; ! 200: sp = getservbyname("shell", "tcp"); ! 201: if (sp == NULL) { ! 202: (void)fprintf(stderr, ! 203: "rsh: unknown service shell/tcp.\n"); ! 204: exit(1); ! 205: } ! 206: if (errno == ECONNREFUSED) ! 207: warning("remote host doesn't support Kerberos"); ! 208: if (errno == ENOENT) ! 209: warning("can't provide Kerberos auth data"); ! 210: goto try_connect; ! 211: } ! 212: } else { ! 213: if (encrypt) { ! 214: (void)fprintf(stderr, ! 215: "rsh: the -x flag requires Kerberos authentication.\n"); ! 216: exit(1); ! 217: } ! 218: rem = rcmd(&host, sp->s_port, pw->pw_name, user, args, &rfd2); ! 219: } ! 220: #else ! 221: rem = rcmd(&host, sp->s_port, pw->pw_name, user, args, &rfd2); ! 222: #endif ! 223: ! 224: if (rem < 0) ! 225: exit(1); ! 226: ! 227: if (rfd2 < 0) { ! 228: (void)fprintf(stderr, "rsh: can't establish stderr.\n"); ! 229: exit(1); ! 230: } ! 231: if (dflag) { ! 232: if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, ! 233: sizeof(one)) < 0) ! 234: (void)fprintf(stderr, "rsh: setsockopt: %s.\n", ! 235: strerror(errno)); ! 236: if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, &one, ! 237: sizeof(one)) < 0) ! 238: (void)fprintf(stderr, "rsh: setsockopt: %s.\n", ! 239: strerror(errno)); ! 240: } ! 241: ! 242: (void)setuid(uid); ! 243: omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGTERM)); ! 244: if (signal(SIGINT, SIG_IGN) != SIG_IGN) ! 245: (void)signal(SIGINT, sendsig); ! 246: if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) ! 247: (void)signal(SIGQUIT, sendsig); ! 248: if (signal(SIGTERM, SIG_IGN) != SIG_IGN) ! 249: (void)signal(SIGTERM, sendsig); ! 250: ! 251: if (!nflag) { ! 252: pid = fork(); ! 253: if (pid < 0) { ! 254: (void)fprintf(stderr, ! 255: "rsh: fork: %s.\n", strerror(errno)); ! 256: exit(1); ! 257: } ! 258: } ! 259: ! 260: #ifdef KERBEROS ! 261: #endif ! 262: { ! 263: (void)ioctl(rfd2, FIONBIO, &one); ! 264: (void)ioctl(rem, FIONBIO, &one); ! 265: } ! 266: ! 267: talk(nflag, omask, pid, rem); ! 268: ! 269: if (!nflag) ! 270: (void)kill(pid, SIGKILL); ! 271: exit(0); ! 272: } ! 273: ! 274: talk(nflag, omask, pid, rem) ! 275: int nflag, pid; ! 276: long omask; ! 277: register int rem; ! 278: { ! 279: register int cc, wc; ! 280: register char *bp; ! 281: int readfrom, ready, rembits; ! 282: char buf[BUFSIZ]; ! 283: ! 284: if (!nflag && pid == 0) { ! 285: (void)close(rfd2); ! 286: ! 287: reread: errno = 0; ! 288: if ((cc = read(0, buf, sizeof buf)) <= 0) ! 289: goto done; ! 290: bp = buf; ! 291: ! 292: rewrite: rembits = 1 << rem; ! 293: if (select(16, 0, &rembits, 0, 0) < 0) { ! 294: if (errno != EINTR) { ! 295: (void)fprintf(stderr, ! 296: "rsh: select: %s.\n", strerror(errno)); ! 297: exit(1); ! 298: } ! 299: goto rewrite; ! 300: } ! 301: if ((rembits & (1 << rem)) == 0) ! 302: goto rewrite; ! 303: #ifdef KERBEROS ! 304: #endif ! 305: wc = write(rem, bp, cc); ! 306: if (wc < 0) { ! 307: if (errno == EWOULDBLOCK) ! 308: goto rewrite; ! 309: goto done; ! 310: } ! 311: bp += wc; ! 312: cc -= wc; ! 313: if (cc == 0) ! 314: goto reread; ! 315: goto rewrite; ! 316: done: ! 317: (void)shutdown(rem, 1); ! 318: exit(0); ! 319: } ! 320: ! 321: (void)sigsetmask(omask); ! 322: readfrom = (1 << rfd2) | (1 << rem); ! 323: do { ! 324: ready = readfrom; ! 325: if (select(16, &ready, 0, 0, 0) < 0) { ! 326: if (errno != EINTR) { ! 327: (void)fprintf(stderr, ! 328: "rsh: select: %s.\n", strerror(errno)); ! 329: exit(1); ! 330: } ! 331: continue; ! 332: } ! 333: if (ready & (1 << rfd2)) { ! 334: errno = 0; ! 335: #ifdef KERBEROS ! 336: #endif ! 337: cc = read(rfd2, buf, sizeof buf); ! 338: if (cc <= 0) { ! 339: if (errno != EWOULDBLOCK) ! 340: readfrom &= ~(1 << rfd2); ! 341: } else ! 342: (void)write(2, buf, cc); ! 343: } ! 344: if (ready & (1 << rem)) { ! 345: errno = 0; ! 346: #ifdef KERBEROS ! 347: #endif ! 348: cc = read(rem, buf, sizeof buf); ! 349: if (cc <= 0) { ! 350: if (errno != EWOULDBLOCK) ! 351: readfrom &= ~(1 << rem); ! 352: } else ! 353: (void)write(1, buf, cc); ! 354: } ! 355: } while (readfrom); ! 356: } ! 357: ! 358: void ! 359: sendsig(signo) ! 360: char signo; ! 361: { ! 362: #ifdef KERBEROS ! 363: #endif ! 364: (void)write(rfd2, &signo, 1); ! 365: } ! 366: ! 367: #ifdef KERBEROS ! 368: /* VARARGS */ ! 369: warning(va_alist) ! 370: va_dcl ! 371: { ! 372: va_list ap; ! 373: char *fmt; ! 374: ! 375: (void)fprintf(stderr, "rsh: warning, using standard rsh: "); ! 376: va_start(ap); ! 377: fmt = va_arg(ap, char *); ! 378: vfprintf(stderr, fmt, ap); ! 379: va_end(ap); ! 380: (void)fprintf(stderr, ".\n"); ! 381: } ! 382: #endif ! 383: ! 384: char * ! 385: copyargs(argv) ! 386: char **argv; ! 387: { ! 388: register int cc; ! 389: register char **ap, *p; ! 390: char *args, *malloc(); ! 391: ! 392: cc = 0; ! 393: for (ap = argv; *ap; ++ap) ! 394: cc += strlen(*ap) + 1; ! 395: if (!(args = malloc((u_int)cc))) { ! 396: (void)fprintf(stderr, "rsh: %s.\n", strerror(ENOMEM)); ! 397: exit(1); ! 398: } ! 399: for (p = args, ap = argv; *ap; ++ap) { ! 400: (void)strcpy(p, *ap); ! 401: for (p = strcpy(p, *ap); *p; ++p); ! 402: if (ap[1]) ! 403: *p++ = ' '; ! 404: } ! 405: return(args); ! 406: } ! 407: ! 408: usage() ! 409: { ! 410: (void)fprintf(stderr, ! 411: "usage: rsh [-nd%s]%s[-l login] host [command]\n", ! 412: #ifdef KERBEROS ! 413: "", " [-k realm] "); ! 414: #else ! 415: "", " "); ! 416: #endif ! 417: exit(1); ! 418: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.