Annotation of 43BSDReno/foreign/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 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: }

unix.superglobalmegacorp.com

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