[BACK]Return to rsh.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / rsh

Annotation of src/usr.bin/rsh/rsh.c, Revision 1.1

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