Annotation of 43BSDTahoe/etc/rlogind.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: char copyright[] =
        !             9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif not lint
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)rlogind.c  5.15 (Berkeley) 5/23/88";
        !            15: #endif not lint
        !            16: 
        !            17: /*
        !            18:  * remote login server:
        !            19:  *     remuser\0
        !            20:  *     locuser\0
        !            21:  *     terminal info\0
        !            22:  *     data
        !            23:  */
        !            24: 
        !            25: #include <stdio.h>
        !            26: #include <sys/types.h>
        !            27: #include <sys/stat.h>
        !            28: #include <sys/socket.h>
        !            29: #include <sys/wait.h>
        !            30: #include <sys/file.h>
        !            31: 
        !            32: #include <netinet/in.h>
        !            33: 
        !            34: #include <errno.h>
        !            35: #include <pwd.h>
        !            36: #include <signal.h>
        !            37: #include <sgtty.h>
        !            38: #include <stdio.h>
        !            39: #include <netdb.h>
        !            40: #include <syslog.h>
        !            41: #include <strings.h>
        !            42: 
        !            43: # ifndef TIOCPKT_WINDOW
        !            44: # define TIOCPKT_WINDOW 0x80
        !            45: # endif TIOCPKT_WINDOW
        !            46: 
        !            47: extern int errno;
        !            48: int    reapchild();
        !            49: struct passwd *getpwnam();
        !            50: char   *malloc();
        !            51: 
        !            52: /*ARGSUSED*/
        !            53: main(argc, argv)
        !            54:        int argc;
        !            55:        char **argv;
        !            56: {
        !            57:        int on = 1, fromlen;
        !            58:        struct sockaddr_in from;
        !            59: 
        !            60:        openlog("rlogind", LOG_PID | LOG_AUTH, LOG_AUTH);
        !            61:        fromlen = sizeof (from);
        !            62:        if (getpeername(0, &from, &fromlen) < 0) {
        !            63:                fprintf(stderr, "%s: ", argv[0]);
        !            64:                perror("getpeername");
        !            65:                _exit(1);
        !            66:        }
        !            67:        if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) {
        !            68:                syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
        !            69:        }
        !            70:        doit(0, &from);
        !            71: }
        !            72: 
        !            73: int    child;
        !            74: int    cleanup();
        !            75: int    netf;
        !            76: char   *line;
        !            77: extern char    *inet_ntoa();
        !            78: 
        !            79: struct winsize win = { 0, 0, 0, 0 };
        !            80: 
        !            81: 
        !            82: doit(f, fromp)
        !            83:        int f;
        !            84:        struct sockaddr_in *fromp;
        !            85: {
        !            86:        int i, p, t, pid, on = 1;
        !            87:        register struct hostent *hp;
        !            88:        struct hostent hostent;
        !            89:        char c;
        !            90: 
        !            91:        alarm(60);
        !            92:        read(f, &c, 1);
        !            93:        if (c != 0)
        !            94:                exit(1);
        !            95:        alarm(0);
        !            96:        fromp->sin_port = ntohs((u_short)fromp->sin_port);
        !            97:        hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr),
        !            98:                fromp->sin_family);
        !            99:        if (hp == 0) {
        !           100:                /*
        !           101:                 * Only the name is used below.
        !           102:                 */
        !           103:                hp = &hostent;
        !           104:                hp->h_name = inet_ntoa(fromp->sin_addr);
        !           105:        }
        !           106:        if (fromp->sin_family != AF_INET ||
        !           107:            fromp->sin_port >= IPPORT_RESERVED ||
        !           108:            fromp->sin_port < IPPORT_RESERVED/2)
        !           109:                fatal(f, "Permission denied");
        !           110:        write(f, "", 1);
        !           111:        for (c = 'p'; c <= 's'; c++) {
        !           112:                struct stat stb;
        !           113:                line = "/dev/ptyXX";
        !           114:                line[strlen("/dev/pty")] = c;
        !           115:                line[strlen("/dev/ptyp")] = '0';
        !           116:                if (stat(line, &stb) < 0)
        !           117:                        break;
        !           118:                for (i = 0; i < 16; i++) {
        !           119:                        line[sizeof("/dev/ptyp") - 1] = "0123456789abcdef"[i];
        !           120:                        p = open(line, O_RDWR);
        !           121:                        if (p > 0)
        !           122:                                goto gotpty;
        !           123:                }
        !           124:        }
        !           125:        fatal(f, "Out of ptys");
        !           126:        /*NOTREACHED*/
        !           127: gotpty:
        !           128:        (void) ioctl(p, TIOCSWINSZ, &win);
        !           129:        netf = f;
        !           130:        line[strlen("/dev/")] = 't';
        !           131:        t = open(line, O_RDWR);
        !           132:        if (t < 0)
        !           133:                fatalperror(f, line);
        !           134:        if (fchmod(t, 0))
        !           135:                fatalperror(f, line);
        !           136:        (void)signal(SIGHUP, SIG_IGN);
        !           137:        vhangup();
        !           138:        (void)signal(SIGHUP, SIG_DFL);
        !           139:        t = open(line, O_RDWR);
        !           140:        if (t < 0)
        !           141:                fatalperror(f, line);
        !           142:        {
        !           143:                struct sgttyb b;
        !           144: 
        !           145:                (void)ioctl(t, TIOCGETP, &b);
        !           146:                b.sg_flags = RAW|ANYP;
        !           147:                (void)ioctl(t, TIOCSETP, &b);
        !           148:        }
        !           149: #ifdef DEBUG
        !           150:        {
        !           151:                int tt = open("/dev/tty", O_RDWR);
        !           152:                if (tt > 0) {
        !           153:                        (void)ioctl(tt, TIOCNOTTY, 0);
        !           154:                        (void)close(tt);
        !           155:                }
        !           156:        }
        !           157: #endif
        !           158:        pid = fork();
        !           159:        if (pid < 0)
        !           160:                fatalperror(f, "");
        !           161:        if (pid == 0) {
        !           162:                close(f), close(p);
        !           163:                dup2(t, 0), dup2(t, 1), dup2(t, 2);
        !           164:                close(t);
        !           165:                execl("/bin/login", "login", "-r", hp->h_name, 0);
        !           166:                fatalperror(2, "/bin/login");
        !           167:                /*NOTREACHED*/
        !           168:        }
        !           169:        close(t);
        !           170:        ioctl(f, FIONBIO, &on);
        !           171:        ioctl(p, FIONBIO, &on);
        !           172:        ioctl(p, TIOCPKT, &on);
        !           173:        signal(SIGTSTP, SIG_IGN);
        !           174:        signal(SIGCHLD, cleanup);
        !           175:        setpgrp(0, 0);
        !           176:        protocol(f, p);
        !           177:        signal(SIGCHLD, SIG_IGN);
        !           178:        cleanup();
        !           179: }
        !           180: 
        !           181: char   magic[2] = { 0377, 0377 };
        !           182: char   oobdata[] = {TIOCPKT_WINDOW};
        !           183: 
        !           184: /*
        !           185:  * Handle a "control" request (signaled by magic being present)
        !           186:  * in the data stream.  For now, we are only willing to handle
        !           187:  * window size changes.
        !           188:  */
        !           189: control(pty, cp, n)
        !           190:        int pty;
        !           191:        char *cp;
        !           192:        int n;
        !           193: {
        !           194:        struct winsize w;
        !           195: 
        !           196:        if (n < 4+sizeof (w) || cp[2] != 's' || cp[3] != 's')
        !           197:                return (0);
        !           198:        oobdata[0] &= ~TIOCPKT_WINDOW;  /* we know he heard */
        !           199:        bcopy(cp+4, (char *)&w, sizeof(w));
        !           200:        w.ws_row = ntohs(w.ws_row);
        !           201:        w.ws_col = ntohs(w.ws_col);
        !           202:        w.ws_xpixel = ntohs(w.ws_xpixel);
        !           203:        w.ws_ypixel = ntohs(w.ws_ypixel);
        !           204:        (void)ioctl(pty, TIOCSWINSZ, &w);
        !           205:        return (4+sizeof (w));
        !           206: }
        !           207: 
        !           208: /*
        !           209:  * rlogin "protocol" machine.
        !           210:  */
        !           211: protocol(f, p)
        !           212:        int f, p;
        !           213: {
        !           214:        char pibuf[1024], fibuf[1024], *pbp, *fbp;
        !           215:        register pcc = 0, fcc = 0;
        !           216:        int cc;
        !           217:        char cntl;
        !           218: 
        !           219:        /*
        !           220:         * Must ignore SIGTTOU, otherwise we'll stop
        !           221:         * when we try and set slave pty's window shape
        !           222:         * (our controlling tty is the master pty).
        !           223:         */
        !           224:        (void) signal(SIGTTOU, SIG_IGN);
        !           225:        send(f, oobdata, 1, MSG_OOB);   /* indicate new rlogin */
        !           226:        for (;;) {
        !           227:                int ibits, obits, ebits;
        !           228: 
        !           229:                ibits = 0;
        !           230:                obits = 0;
        !           231:                if (fcc)
        !           232:                        obits |= (1<<p);
        !           233:                else
        !           234:                        ibits |= (1<<f);
        !           235:                if (pcc >= 0)
        !           236:                        if (pcc)
        !           237:                                obits |= (1<<f);
        !           238:                        else
        !           239:                                ibits |= (1<<p);
        !           240:                ebits = (1<<p);
        !           241:                if (select(16, &ibits, &obits, &ebits, 0) < 0) {
        !           242:                        if (errno == EINTR)
        !           243:                                continue;
        !           244:                        fatalperror(f, "select");
        !           245:                }
        !           246:                if (ibits == 0 && obits == 0 && ebits == 0) {
        !           247:                        /* shouldn't happen... */
        !           248:                        sleep(5);
        !           249:                        continue;
        !           250:                }
        !           251: #define        pkcontrol(c)    ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))
        !           252:                if (ebits & (1<<p)) {
        !           253:                        cc = read(p, &cntl, 1);
        !           254:                        if (cc == 1 && pkcontrol(cntl)) {
        !           255:                                cntl |= oobdata[0];
        !           256:                                send(f, &cntl, 1, MSG_OOB);
        !           257:                                if (cntl & TIOCPKT_FLUSHWRITE) {
        !           258:                                        pcc = 0;
        !           259:                                        ibits &= ~(1<<p);
        !           260:                                }
        !           261:                        }
        !           262:                }
        !           263:                if (ibits & (1<<f)) {
        !           264:                        fcc = read(f, fibuf, sizeof (fibuf));
        !           265:                        if (fcc < 0 && errno == EWOULDBLOCK)
        !           266:                                fcc = 0;
        !           267:                        else {
        !           268:                                register char *cp;
        !           269:                                int left, n;
        !           270: 
        !           271:                                if (fcc <= 0)
        !           272:                                        break;
        !           273:                                fbp = fibuf;
        !           274: 
        !           275:                        top:
        !           276:                                for (cp = fibuf; cp < fibuf+fcc-1; cp++)
        !           277:                                        if (cp[0] == magic[0] &&
        !           278:                                            cp[1] == magic[1]) {
        !           279:                                                left = fcc - (cp-fibuf);
        !           280:                                                n = control(p, cp, left);
        !           281:                                                if (n) {
        !           282:                                                        left -= n;
        !           283:                                                        if (left > 0)
        !           284:                                                                bcopy(cp+n, cp, left);
        !           285:                                                        fcc -= n;
        !           286:                                                        goto top; /* n^2 */
        !           287:                                                }
        !           288:                                        }
        !           289:                        }
        !           290:                }
        !           291: 
        !           292:                if ((obits & (1<<p)) && fcc > 0) {
        !           293:                        cc = write(p, fbp, fcc);
        !           294:                        if (cc > 0) {
        !           295:                                fcc -= cc;
        !           296:                                fbp += cc;
        !           297:                        }
        !           298:                }
        !           299: 
        !           300:                if (ibits & (1<<p)) {
        !           301:                        pcc = read(p, pibuf, sizeof (pibuf));
        !           302:                        pbp = pibuf;
        !           303:                        if (pcc < 0 && errno == EWOULDBLOCK)
        !           304:                                pcc = 0;
        !           305:                        else if (pcc <= 0)
        !           306:                                break;
        !           307:                        else if (pibuf[0] == 0)
        !           308:                                pbp++, pcc--;
        !           309:                        else {
        !           310:                                if (pkcontrol(pibuf[0])) {
        !           311:                                        pibuf[0] |= oobdata[0];
        !           312:                                        send(f, &pibuf[0], 1, MSG_OOB);
        !           313:                                }
        !           314:                                pcc = 0;
        !           315:                        }
        !           316:                }
        !           317:                if ((obits & (1<<f)) && pcc > 0) {
        !           318:                        cc = write(f, pbp, pcc);
        !           319:                        if (cc < 0 && errno == EWOULDBLOCK) {
        !           320:                                /* also shouldn't happen */
        !           321:                                sleep(5);
        !           322:                                continue;
        !           323:                        }
        !           324:                        if (cc > 0) {
        !           325:                                pcc -= cc;
        !           326:                                pbp += cc;
        !           327:                        }
        !           328:                }
        !           329:        }
        !           330: }
        !           331: 
        !           332: cleanup()
        !           333: {
        !           334:        rmut();
        !           335:        shutdown(netf, 2);
        !           336:        exit(1);
        !           337: }
        !           338: 
        !           339: fatal(f, msg)
        !           340:        int f;
        !           341:        char *msg;
        !           342: {
        !           343:        char buf[BUFSIZ];
        !           344: 
        !           345:        buf[0] = '\01';         /* error indicator */
        !           346:        (void) sprintf(buf + 1, "rlogind: %s.\r\n", msg);
        !           347:        (void) write(f, buf, strlen(buf));
        !           348:        exit(1);
        !           349: }
        !           350: 
        !           351: fatalperror(f, msg)
        !           352:        int f;
        !           353:        char *msg;
        !           354: {
        !           355:        char buf[BUFSIZ];
        !           356:        extern int sys_nerr;
        !           357:        extern char *sys_errlist[];
        !           358: 
        !           359:        if ((unsigned)errno < sys_nerr)
        !           360:                (void) sprintf(buf, "%s: %s", msg, sys_errlist[errno]);
        !           361:        else
        !           362:                (void) sprintf(buf, "%s: Error %d", msg, errno);
        !           363:        fatal(f, buf);
        !           364: }
        !           365: 
        !           366: #include <utmp.h>
        !           367: 
        !           368: struct utmp wtmp;
        !           369: char   wtmpf[] = "/usr/adm/wtmp";
        !           370: char   utmpf[] = "/etc/utmp";
        !           371: #define SCPYN(a, b)    strncpy(a, b, sizeof(a))
        !           372: #define SCMPN(a, b)    strncmp(a, b, sizeof(a))
        !           373: 
        !           374: rmut()
        !           375: {
        !           376:        register f;
        !           377:        int found = 0;
        !           378:        struct utmp *u, *utmp;
        !           379:        int nutmp;
        !           380:        struct stat statbf;
        !           381: 
        !           382:        f = open(utmpf, O_RDWR);
        !           383:        if (f >= 0) {
        !           384:                fstat(f, &statbf);
        !           385:                utmp = (struct utmp *)malloc(statbf.st_size);
        !           386:                if (!utmp)
        !           387:                        syslog(LOG_ERR, "utmp malloc failed");
        !           388:                if (statbf.st_size && utmp) {
        !           389:                        nutmp = read(f, utmp, statbf.st_size);
        !           390:                        nutmp /= sizeof(struct utmp);
        !           391:                
        !           392:                        for (u = utmp ; u < &utmp[nutmp] ; u++) {
        !           393:                                if (SCMPN(u->ut_line, line+5) ||
        !           394:                                    u->ut_name[0]==0)
        !           395:                                        continue;
        !           396:                                lseek(f, ((long)u)-((long)utmp), L_SET);
        !           397:                                SCPYN(u->ut_name, "");
        !           398:                                SCPYN(u->ut_host, "");
        !           399:                                time(&u->ut_time);
        !           400:                                write(f, (char *)u, sizeof(wtmp));
        !           401:                                found++;
        !           402:                        }
        !           403:                }
        !           404:                close(f);
        !           405:        }
        !           406:        if (found) {
        !           407:                f = open(wtmpf, O_WRONLY|O_APPEND);
        !           408:                if (f >= 0) {
        !           409:                        SCPYN(wtmp.ut_line, line+5);
        !           410:                        SCPYN(wtmp.ut_name, "");
        !           411:                        SCPYN(wtmp.ut_host, "");
        !           412:                        time(&wtmp.ut_time);
        !           413:                        write(f, (char *)&wtmp, sizeof(wtmp));
        !           414:                        close(f);
        !           415:                }
        !           416:        }
        !           417:        chmod(line, 0666);
        !           418:        chown(line, 0, 0);
        !           419:        line[strlen("/dev/")] = 'p';
        !           420:        chmod(line, 0666);
        !           421:        chown(line, 0, 0);
        !           422: }

unix.superglobalmegacorp.com

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