Annotation of 43BSDReno/domestic/src/rsh/rsh.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.