|
|
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 ! 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: #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.21 (Berkeley) 5/15/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:nwx" ! 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: case 'x': ! 136: encrypt = 1; ! 137: des_set_key(cred.session, schedule); ! 138: break; ! 139: #endif ! 140: case '?': ! 141: default: ! 142: usage(); ! 143: } ! 144: optind += argoff; ! 145: ! 146: /* if haven't gotten a host yet, do so */ ! 147: if (!host && !(host = argv[optind++])) ! 148: usage(); ! 149: ! 150: /* if no further arguments, must have been called as rlogin. */ ! 151: if (!argv[optind]) { ! 152: if (asrsh) ! 153: *argv = "rlogin"; ! 154: execv(_PATH_RLOGIN, argv); ! 155: (void)fprintf(stderr, "rsh: can't exec %s.\n", _PATH_RLOGIN); ! 156: exit(1); ! 157: } ! 158: ! 159: argc -= optind; ! 160: argv += optind; ! 161: ! 162: if (!(pw = getpwuid(uid = getuid()))) { ! 163: (void)fprintf(stderr, "rsh: unknown user id.\n"); ! 164: exit(1); ! 165: } ! 166: if (!user) ! 167: user = pw->pw_name; ! 168: ! 169: #ifdef KERBEROS ! 170: /* -x turns off -n */ ! 171: if (encrypt) ! 172: nflag = 0; ! 173: #endif ! 174: ! 175: args = copyargs(argv); ! 176: ! 177: sp = NULL; ! 178: #ifdef KERBEROS ! 179: if (use_kerberos) { ! 180: sp = getservbyname((encrypt ? "ekshell" : "kshell"), "tcp"); ! 181: if (sp == NULL) { ! 182: use_kerberos = 0; ! 183: warning("can't get entry for %s/tcp service", ! 184: encrypt ? "ekshell" : "kshell"); ! 185: } ! 186: } ! 187: #endif ! 188: if (sp == NULL) ! 189: sp = getservbyname("shell", "tcp"); ! 190: if (sp == NULL) { ! 191: (void)fprintf(stderr, "rsh: shell/tcp: unknown service.\n"); ! 192: exit(1); ! 193: } ! 194: ! 195: #ifdef KERBEROS ! 196: try_connect: ! 197: if (use_kerberos) { ! 198: rem = KSUCCESS; ! 199: errno = 0; ! 200: if (dest_realm == NULL) ! 201: dest_realm = krb_realmofhost(host); ! 202: ! 203: if (encrypt) ! 204: rem = krcmd_mutual(&host, sp->s_port, user, args, ! 205: &rfd2, dest_realm, &cred, schedule); ! 206: else ! 207: rem = krcmd(&host, sp->s_port, user, args, &rfd2, ! 208: dest_realm); ! 209: if (rem < 0) { ! 210: use_kerberos = 0; ! 211: sp = getservbyname("shell", "tcp"); ! 212: if (sp == NULL) { ! 213: (void)fprintf(stderr, ! 214: "rsh: unknown service shell/tcp.\n"); ! 215: exit(1); ! 216: } ! 217: if (errno == ECONNREFUSED) ! 218: warning("remote host doesn't support Kerberos"); ! 219: if (errno == ENOENT) ! 220: warning("can't provide Kerberos auth data"); ! 221: goto try_connect; ! 222: } ! 223: } else { ! 224: if (encrypt) { ! 225: (void)fprintf(stderr, ! 226: "rsh: the -x flag requires Kerberos authentication.\n"); ! 227: exit(1); ! 228: } ! 229: rem = rcmd(&host, sp->s_port, pw->pw_name, user, args, &rfd2); ! 230: } ! 231: #else ! 232: rem = rcmd(&host, sp->s_port, pw->pw_name, user, args, &rfd2); ! 233: #endif ! 234: ! 235: if (rem < 0) ! 236: exit(1); ! 237: ! 238: if (rfd2 < 0) { ! 239: (void)fprintf(stderr, "rsh: can't establish stderr.\n"); ! 240: exit(1); ! 241: } ! 242: if (dflag) { ! 243: if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, ! 244: sizeof(one)) < 0) ! 245: (void)fprintf(stderr, "rsh: setsockopt: %s.\n", ! 246: strerror(errno)); ! 247: if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, &one, ! 248: sizeof(one)) < 0) ! 249: (void)fprintf(stderr, "rsh: setsockopt: %s.\n", ! 250: strerror(errno)); ! 251: } ! 252: ! 253: (void)setuid(uid); ! 254: omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGTERM)); ! 255: if (signal(SIGINT, SIG_IGN) != SIG_IGN) ! 256: (void)signal(SIGINT, sendsig); ! 257: if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) ! 258: (void)signal(SIGQUIT, sendsig); ! 259: if (signal(SIGTERM, SIG_IGN) != SIG_IGN) ! 260: (void)signal(SIGTERM, sendsig); ! 261: ! 262: if (!nflag) { ! 263: pid = fork(); ! 264: if (pid < 0) { ! 265: (void)fprintf(stderr, ! 266: "rsh: fork: %s.\n", strerror(errno)); ! 267: exit(1); ! 268: } ! 269: } ! 270: ! 271: #ifdef KERBEROS ! 272: if (!encrypt) ! 273: #endif ! 274: { ! 275: (void)ioctl(rfd2, FIONBIO, &one); ! 276: (void)ioctl(rem, FIONBIO, &one); ! 277: } ! 278: ! 279: talk(nflag, omask, pid, rem); ! 280: ! 281: if (!nflag) ! 282: (void)kill(pid, SIGKILL); ! 283: exit(0); ! 284: } ! 285: ! 286: talk(nflag, omask, pid, rem) ! 287: int nflag, pid; ! 288: long omask; ! 289: register int rem; ! 290: { ! 291: register int cc, wc; ! 292: register char *bp; ! 293: int readfrom, ready, rembits; ! 294: char buf[BUFSIZ]; ! 295: ! 296: if (!nflag && pid == 0) { ! 297: (void)close(rfd2); ! 298: ! 299: reread: errno = 0; ! 300: if ((cc = read(0, buf, sizeof buf)) <= 0) ! 301: goto done; ! 302: bp = buf; ! 303: ! 304: rewrite: rembits = 1 << rem; ! 305: if (select(16, 0, &rembits, 0, 0) < 0) { ! 306: if (errno != EINTR) { ! 307: (void)fprintf(stderr, ! 308: "rsh: select: %s.\n", strerror(errno)); ! 309: exit(1); ! 310: } ! 311: goto rewrite; ! 312: } ! 313: if ((rembits & (1 << rem)) == 0) ! 314: goto rewrite; ! 315: #ifdef KERBEROS ! 316: if (encrypt) ! 317: wc = des_write(rem, bp, cc); ! 318: else ! 319: #endif ! 320: wc = write(rem, bp, cc); ! 321: if (wc < 0) { ! 322: if (errno == EWOULDBLOCK) ! 323: goto rewrite; ! 324: goto done; ! 325: } ! 326: bp += wc; ! 327: cc -= wc; ! 328: if (cc == 0) ! 329: goto reread; ! 330: goto rewrite; ! 331: done: ! 332: (void)shutdown(rem, 1); ! 333: exit(0); ! 334: } ! 335: ! 336: (void)sigsetmask(omask); ! 337: readfrom = (1 << rfd2) | (1 << rem); ! 338: do { ! 339: ready = readfrom; ! 340: if (select(16, &ready, 0, 0, 0) < 0) { ! 341: if (errno != EINTR) { ! 342: (void)fprintf(stderr, ! 343: "rsh: select: %s.\n", strerror(errno)); ! 344: exit(1); ! 345: } ! 346: continue; ! 347: } ! 348: if (ready & (1 << rfd2)) { ! 349: errno = 0; ! 350: #ifdef KERBEROS ! 351: if (encrypt) ! 352: cc = des_read(rfd2, buf, sizeof buf); ! 353: else ! 354: #endif ! 355: cc = read(rfd2, buf, sizeof buf); ! 356: if (cc <= 0) { ! 357: if (errno != EWOULDBLOCK) ! 358: readfrom &= ~(1 << rfd2); ! 359: } else ! 360: (void)write(2, buf, cc); ! 361: } ! 362: if (ready & (1 << rem)) { ! 363: errno = 0; ! 364: #ifdef KERBEROS ! 365: if (encrypt) ! 366: cc = des_read(rem, buf, sizeof buf); ! 367: else ! 368: #endif ! 369: cc = read(rem, buf, sizeof buf); ! 370: if (cc <= 0) { ! 371: if (errno != EWOULDBLOCK) ! 372: readfrom &= ~(1 << rem); ! 373: } else ! 374: (void)write(1, buf, cc); ! 375: } ! 376: } while (readfrom); ! 377: } ! 378: ! 379: void ! 380: sendsig(signo) ! 381: char signo; ! 382: { ! 383: #ifdef KERBEROS ! 384: if (encrypt) ! 385: (void)des_write(rfd2, &signo, 1); ! 386: else ! 387: #endif ! 388: (void)write(rfd2, &signo, 1); ! 389: } ! 390: ! 391: #ifdef KERBEROS ! 392: /* VARARGS */ ! 393: warning(va_alist) ! 394: va_dcl ! 395: { ! 396: va_list ap; ! 397: char *fmt; ! 398: ! 399: (void)fprintf(stderr, "rsh: warning, using standard rsh: "); ! 400: va_start(ap); ! 401: fmt = va_arg(ap, char *); ! 402: vfprintf(stderr, fmt, ap); ! 403: va_end(ap); ! 404: (void)fprintf(stderr, ".\n"); ! 405: } ! 406: #endif ! 407: ! 408: char * ! 409: copyargs(argv) ! 410: char **argv; ! 411: { ! 412: register int cc; ! 413: register char **ap, *p; ! 414: char *args, *malloc(); ! 415: ! 416: cc = 0; ! 417: for (ap = argv; *ap; ++ap) ! 418: cc += strlen(*ap) + 1; ! 419: if (!(args = malloc((u_int)cc))) { ! 420: (void)fprintf(stderr, "rsh: %s.\n", strerror(ENOMEM)); ! 421: exit(1); ! 422: } ! 423: for (p = args, ap = argv; *ap; ++ap) { ! 424: (void)strcpy(p, *ap); ! 425: for (p = strcpy(p, *ap); *p; ++p); ! 426: if (ap[1]) ! 427: *p++ = ' '; ! 428: } ! 429: return(args); ! 430: } ! 431: ! 432: usage() ! 433: { ! 434: (void)fprintf(stderr, ! 435: "usage: rsh [-ndx]%s[-l login] host [command]\n", ! 436: #ifdef KERBEROS ! 437: " [-k realm] "); ! 438: #else ! 439: " "); ! 440: #endif ! 441: exit(1); ! 442: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.