Annotation of 43BSD/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.11 (Berkeley) 5/23/86";
        !            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 errno;
        !            48: int    reapchild();
        !            49: struct passwd *getpwnam();
        !            50: char   *malloc();
        !            51: 
        !            52: main(argc, argv)
        !            53:        int argc;
        !            54:        char **argv;
        !            55: {
        !            56:        int on = 1, options = 0, fromlen;
        !            57:        struct sockaddr_in from;
        !            58: 
        !            59:        openlog("rlogind", LOG_PID | LOG_AUTH, LOG_AUTH);
        !            60:        fromlen = sizeof (from);
        !            61:        if (getpeername(0, &from, &fromlen) < 0) {
        !            62:                fprintf(stderr, "%s: ", argv[0]);
        !            63:                perror("getpeername");
        !            64:                _exit(1);
        !            65:        }
        !            66:        if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) {
        !            67:                syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
        !            68:        }
        !            69:        doit(0, &from);
        !            70: }
        !            71: 
        !            72: int    child;
        !            73: int    cleanup();
        !            74: int    netf;
        !            75: extern errno;
        !            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:                fatal(f, "Permission denied");
        !           109:        write(f, "", 1);
        !           110:        for (c = 'p'; c <= 's'; c++) {
        !           111:                struct stat stb;
        !           112:                line = "/dev/ptyXX";
        !           113:                line[strlen("/dev/pty")] = c;
        !           114:                line[strlen("/dev/ptyp")] = '0';
        !           115:                if (stat(line, &stb) < 0)
        !           116:                        break;
        !           117:                for (i = 0; i < 16; i++) {
        !           118:                        line[strlen("/dev/ptyp")] = "0123456789abcdef"[i];
        !           119:                        p = open(line, 2);
        !           120:                        if (p > 0)
        !           121:                                goto gotpty;
        !           122:                }
        !           123:        }
        !           124:        fatal(f, "Out of ptys");
        !           125:        /*NOTREACHED*/
        !           126: gotpty:
        !           127:        (void) ioctl(p, TIOCSWINSZ, &win);
        !           128:        netf = f;
        !           129:        line[strlen("/dev/")] = 't';
        !           130: #ifdef DEBUG
        !           131:        { int tt = open("/dev/tty", 2);
        !           132:          if (tt > 0) {
        !           133:                ioctl(tt, TIOCNOTTY, 0);
        !           134:                close(tt);
        !           135:          }
        !           136:        }
        !           137: #endif
        !           138:        t = open(line, 2);
        !           139:        if (t < 0)
        !           140:                fatalperror(f, line, errno);
        !           141:        { struct sgttyb b;
        !           142:          gtty(t, &b); b.sg_flags = RAW|ANYP; stty(t, &b);
        !           143:        }
        !           144:        pid = fork();
        !           145:        if (pid < 0)
        !           146:                fatalperror(f, "", errno);
        !           147:        if (pid == 0) {
        !           148:                close(f), close(p);
        !           149:                dup2(t, 0), dup2(t, 1), dup2(t, 2);
        !           150:                close(t);
        !           151:                execl("/bin/login", "login", "-r", hp->h_name, 0);
        !           152:                fatalperror(2, "/bin/login", errno);
        !           153:                /*NOTREACHED*/
        !           154:        }
        !           155:        close(t);
        !           156:        ioctl(f, FIONBIO, &on);
        !           157:        ioctl(p, FIONBIO, &on);
        !           158:        ioctl(p, TIOCPKT, &on);
        !           159:        signal(SIGTSTP, SIG_IGN);
        !           160:        signal(SIGCHLD, cleanup);
        !           161:        setpgrp(0, 0);
        !           162:        protocol(f, p);
        !           163:        cleanup();
        !           164: }
        !           165: 
        !           166: char   magic[2] = { 0377, 0377 };
        !           167: char   oobdata[] = {TIOCPKT_WINDOW};
        !           168: 
        !           169: /*
        !           170:  * Handle a "control" request (signaled by magic being present)
        !           171:  * in the data stream.  For now, we are only willing to handle
        !           172:  * window size changes.
        !           173:  */
        !           174: control(pty, cp, n)
        !           175:        int pty;
        !           176:        char *cp;
        !           177:        int n;
        !           178: {
        !           179:        struct winsize w;
        !           180: 
        !           181:        if (n < 4+sizeof (w) || cp[2] != 's' || cp[3] != 's')
        !           182:                return (0);
        !           183:        oobdata[0] &= ~TIOCPKT_WINDOW;  /* we know he heard */
        !           184:        bcopy(cp+4, (char *)&w, sizeof(w));
        !           185:        w.ws_row = ntohs(w.ws_row);
        !           186:        w.ws_col = ntohs(w.ws_col);
        !           187:        w.ws_xpixel = ntohs(w.ws_xpixel);
        !           188:        w.ws_ypixel = ntohs(w.ws_ypixel);
        !           189:        (void)ioctl(pty, TIOCSWINSZ, &w);
        !           190:        return (4+sizeof (w));
        !           191: }
        !           192: 
        !           193: /*
        !           194:  * rlogin "protocol" machine.
        !           195:  */
        !           196: protocol(f, p)
        !           197:        int f, p;
        !           198: {
        !           199:        char pibuf[1024], fibuf[1024], *pbp, *fbp;
        !           200:        register pcc = 0, fcc = 0;
        !           201:        int cc;
        !           202:        char cntl;
        !           203: 
        !           204:        /*
        !           205:         * Must ignore SIGTTOU, otherwise we'll stop
        !           206:         * when we try and set slave pty's window shape
        !           207:         * (our controlling tty is the master pty).
        !           208:         */
        !           209:        (void) signal(SIGTTOU, SIG_IGN);
        !           210:        send(f, oobdata, 1, MSG_OOB);   /* indicate new rlogin */
        !           211:        for (;;) {
        !           212:                int ibits, obits, ebits;
        !           213: 
        !           214:                ibits = 0;
        !           215:                obits = 0;
        !           216:                if (fcc)
        !           217:                        obits |= (1<<p);
        !           218:                else
        !           219:                        ibits |= (1<<f);
        !           220:                if (pcc >= 0)
        !           221:                        if (pcc)
        !           222:                                obits |= (1<<f);
        !           223:                        else
        !           224:                                ibits |= (1<<p);
        !           225:                ebits = (1<<p);
        !           226:                if (select(16, &ibits, &obits, &ebits, 0) < 0) {
        !           227:                        if (errno == EINTR)
        !           228:                                continue;
        !           229:                        fatalperror(f, "select", errno);
        !           230:                }
        !           231:                if (ibits == 0 && obits == 0 && ebits == 0) {
        !           232:                        /* shouldn't happen... */
        !           233:                        sleep(5);
        !           234:                        continue;
        !           235:                }
        !           236: #define        pkcontrol(c)    ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))
        !           237:                if (ebits & (1<<p)) {
        !           238:                        cc = read(p, &cntl, 1);
        !           239:                        if (cc == 1 && pkcontrol(cntl)) {
        !           240:                                cntl |= oobdata[0];
        !           241:                                send(f, &cntl, 1, MSG_OOB);
        !           242:                                if (cntl & TIOCPKT_FLUSHWRITE) {
        !           243:                                        pcc = 0;
        !           244:                                        ibits &= ~(1<<p);
        !           245:                                }
        !           246:                        }
        !           247:                }
        !           248:                if (ibits & (1<<f)) {
        !           249:                        fcc = read(f, fibuf, sizeof (fibuf));
        !           250:                        if (fcc < 0 && errno == EWOULDBLOCK)
        !           251:                                fcc = 0;
        !           252:                        else {
        !           253:                                register char *cp;
        !           254:                                int left, n;
        !           255: 
        !           256:                                if (fcc <= 0)
        !           257:                                        break;
        !           258:                                fbp = fibuf;
        !           259: 
        !           260:                        top:
        !           261:                                for (cp = fibuf; cp < fibuf+fcc-1; cp++)
        !           262:                                        if (cp[0] == magic[0] &&
        !           263:                                            cp[1] == magic[1]) {
        !           264:                                                left = fcc - (cp-fibuf);
        !           265:                                                n = control(p, cp, left);
        !           266:                                                if (n) {
        !           267:                                                        left -= n;
        !           268:                                                        if (left > 0)
        !           269:                                                                bcopy(cp+n, cp, left);
        !           270:                                                        fcc -= n;
        !           271:                                                        goto top; /* n^2 */
        !           272:                                                }
        !           273:                                        }
        !           274:                        }
        !           275:                }
        !           276: 
        !           277:                if ((obits & (1<<p)) && fcc > 0) {
        !           278:                        cc = write(p, fbp, fcc);
        !           279:                        if (cc > 0) {
        !           280:                                fcc -= cc;
        !           281:                                fbp += cc;
        !           282:                        }
        !           283:                }
        !           284: 
        !           285:                if (ibits & (1<<p)) {
        !           286:                        pcc = read(p, pibuf, sizeof (pibuf));
        !           287:                        pbp = pibuf;
        !           288:                        if (pcc < 0 && errno == EWOULDBLOCK)
        !           289:                                pcc = 0;
        !           290:                        else if (pcc <= 0)
        !           291:                                break;
        !           292:                        else if (pibuf[0] == 0)
        !           293:                                pbp++, pcc--;
        !           294:                        else {
        !           295:                                if (pkcontrol(pibuf[0])) {
        !           296:                                        pibuf[0] |= oobdata[0];
        !           297:                                        send(f, &pibuf[0], 1, MSG_OOB);
        !           298:                                }
        !           299:                                pcc = 0;
        !           300:                        }
        !           301:                }
        !           302:                if ((obits & (1<<f)) && pcc > 0) {
        !           303:                        cc = write(f, pbp, pcc);
        !           304:                        if (cc < 0 && errno == EWOULDBLOCK) {
        !           305:                                /* also shouldn't happen */
        !           306:                                sleep(5);
        !           307:                                continue;
        !           308:                        }
        !           309:                        if (cc > 0) {
        !           310:                                pcc -= cc;
        !           311:                                pbp += cc;
        !           312:                        }
        !           313:                }
        !           314:        }
        !           315: }
        !           316: 
        !           317: cleanup()
        !           318: {
        !           319: 
        !           320:        rmut();
        !           321:        vhangup();              /* XXX */
        !           322:        shutdown(netf, 2);
        !           323:        exit(1);
        !           324: }
        !           325: 
        !           326: fatal(f, msg)
        !           327:        int f;
        !           328:        char *msg;
        !           329: {
        !           330:        char buf[BUFSIZ];
        !           331: 
        !           332:        buf[0] = '\01';         /* error indicator */
        !           333:        (void) sprintf(buf + 1, "rlogind: %s.\r\n", msg);
        !           334:        (void) write(f, buf, strlen(buf));
        !           335:        exit(1);
        !           336: }
        !           337: 
        !           338: fatalperror(f, msg, errno)
        !           339:        int f;
        !           340:        char *msg;
        !           341:        int errno;
        !           342: {
        !           343:        char buf[BUFSIZ];
        !           344:        extern int sys_nerr;
        !           345:        extern char *sys_errlist[];
        !           346: 
        !           347:        if ((unsigned)errno < sys_nerr)
        !           348:                (void) sprintf(buf, "%s: %s", msg, sys_errlist[errno]);
        !           349:        else
        !           350:                (void) sprintf(buf, "%s: Error %d", msg, errno);
        !           351:        fatal(f, buf);
        !           352: }
        !           353: 
        !           354: #include <utmp.h>
        !           355: 
        !           356: struct utmp wtmp;
        !           357: char   wtmpf[] = "/usr/adm/wtmp";
        !           358: char   utmpf[] = "/etc/utmp";
        !           359: #define SCPYN(a, b)    strncpy(a, b, sizeof(a))
        !           360: #define SCMPN(a, b)    strncmp(a, b, sizeof(a))
        !           361: 
        !           362: rmut()
        !           363: {
        !           364:        register f;
        !           365:        int found = 0;
        !           366:        struct utmp *u, *utmp;
        !           367:        int nutmp;
        !           368:        struct stat statbf;
        !           369: 
        !           370:        f = open(utmpf, O_RDWR);
        !           371:        if (f >= 0) {
        !           372:                fstat(f, &statbf);
        !           373:                utmp = (struct utmp *)malloc(statbf.st_size);
        !           374:                if (!utmp)
        !           375:                        syslog(LOG_ERR, "utmp malloc failed");
        !           376:                if (statbf.st_size && utmp) {
        !           377:                        nutmp = read(f, utmp, statbf.st_size);
        !           378:                        nutmp /= sizeof(struct utmp);
        !           379:                
        !           380:                        for (u = utmp ; u < &utmp[nutmp] ; u++) {
        !           381:                                if (SCMPN(u->ut_line, line+5) ||
        !           382:                                    u->ut_name[0]==0)
        !           383:                                        continue;
        !           384:                                lseek(f, ((long)u)-((long)utmp), L_SET);
        !           385:                                SCPYN(u->ut_name, "");
        !           386:                                SCPYN(u->ut_host, "");
        !           387:                                time(&u->ut_time);
        !           388:                                write(f, (char *)u, sizeof(wtmp));
        !           389:                                found++;
        !           390:                        }
        !           391:                }
        !           392:                close(f);
        !           393:        }
        !           394:        if (found) {
        !           395:                f = open(wtmpf, O_WRONLY|O_APPEND);
        !           396:                if (f >= 0) {
        !           397:                        SCPYN(wtmp.ut_line, line+5);
        !           398:                        SCPYN(wtmp.ut_name, "");
        !           399:                        SCPYN(wtmp.ut_host, "");
        !           400:                        time(&wtmp.ut_time);
        !           401:                        write(f, (char *)&wtmp, sizeof(wtmp));
        !           402:                        close(f);
        !           403:                }
        !           404:        }
        !           405:        chmod(line, 0666);
        !           406:        chown(line, 0, 0);
        !           407:        line[strlen("/dev/")] = 'p';
        !           408:        chmod(line, 0666);
        !           409:        chown(line, 0, 0);
        !           410: }

unix.superglobalmegacorp.com

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