Annotation of 42BSD/etc/rlogind.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)rlogind.c  4.18 83/07/01";
        !             3: #endif
        !             4: 
        !             5: #include <stdio.h>
        !             6: #include <sys/types.h>
        !             7: #include <sys/stat.h>
        !             8: #include <sys/socket.h>
        !             9: #include <sys/wait.h>
        !            10: 
        !            11: #include <netinet/in.h>
        !            12: 
        !            13: #include <errno.h>
        !            14: #include <pwd.h>
        !            15: #include <signal.h>
        !            16: #include <sgtty.h>
        !            17: #include <stdio.h>
        !            18: #include <netdb.h>
        !            19: 
        !            20: extern errno;
        !            21: int    reapchild();
        !            22: struct passwd *getpwnam();
        !            23: char   *crypt(), *rindex(), *index(), *malloc(), *ntoa();
        !            24: struct sockaddr_in sin = { AF_INET };
        !            25: /*
        !            26:  * remote login server:
        !            27:  *     remuser\0
        !            28:  *     locuser\0
        !            29:  *     terminal type\0
        !            30:  *     data
        !            31:  */
        !            32: main(argc, argv)
        !            33:        int argc;
        !            34:        char **argv;
        !            35: {
        !            36:        int f, options = 0;
        !            37:        struct sockaddr_in from;
        !            38:        struct servent *sp;
        !            39: 
        !            40:        sp = getservbyname("login", "tcp");
        !            41:        if (sp == 0) {
        !            42:                fprintf(stderr, "rlogind: tcp/rlogin: unknown service\n");
        !            43:                exit(1);
        !            44:        }
        !            45: #ifndef DEBUG
        !            46:        if (fork())
        !            47:                exit(0);
        !            48:        for (f = 0; f < 10; f++)
        !            49:                (void) close(f);
        !            50:        (void) open("/", 0);
        !            51:        (void) dup2(0, 1);
        !            52:        (void) dup2(0, 2);
        !            53:        { int tt = open("/dev/tty", 2);
        !            54:          if (tt > 0) {
        !            55:                ioctl(tt, TIOCNOTTY, 0);
        !            56:                close(tt);
        !            57:          }
        !            58:        }
        !            59: #endif
        !            60:        sin.sin_port = sp->s_port;
        !            61:        argc--, argv++;
        !            62:        if (argc > 0 && !strcmp(argv[0], "-d")) {
        !            63:                options |= SO_DEBUG;
        !            64:                argc--, argv++;
        !            65:        }
        !            66:        if (argc > 0) {
        !            67:                int port = atoi(argv[0]);
        !            68: 
        !            69:                if (port < 0) {
        !            70:                        fprintf(stderr, "%s: bad port #\n", argv[0]);
        !            71:                        exit(1);
        !            72:                }
        !            73:                sin.sin_port = htons((u_short)port);
        !            74:                argv++, argc--;
        !            75:        }
        !            76:        f = socket(AF_INET, SOCK_STREAM, 0, 0);
        !            77:        if (f < 0) {
        !            78:                perror("rlogind: socket");
        !            79:                exit(1);
        !            80:        }
        !            81:        if (options & SO_DEBUG)
        !            82:                if (setsockopt(f, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
        !            83:                        perror("rlogind: setsockopt (SO_DEBUG)");
        !            84:        if (setsockopt(f, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0)
        !            85:                perror("rlogind: setsockopt (SO_KEEPALIVE)");
        !            86:        if (bind(f, &sin, sizeof (sin), 0) < 0) {
        !            87:                perror("rlogind: bind");
        !            88:                exit(1);
        !            89:        }
        !            90:        signal(SIGCHLD, reapchild);
        !            91:        listen(f, 10);
        !            92:        for (;;) {
        !            93:                int s, len = sizeof (from);
        !            94: 
        !            95:                s = accept(f, &from, &len, 0);
        !            96:                if (s < 0) {
        !            97:                        if (errno == EINTR)
        !            98:                                continue;
        !            99:                        perror("rlogind: accept");
        !           100:                        continue;
        !           101:                }
        !           102:                if (fork() == 0) {
        !           103:                        signal(SIGCHLD, SIG_IGN);
        !           104:                        close(f);
        !           105:                        doit(s, &from);
        !           106:                }
        !           107:                close(s);
        !           108:        }
        !           109: }
        !           110: 
        !           111: reapchild()
        !           112: {
        !           113:        union wait status;
        !           114: 
        !           115:        while (wait3(&status, WNOHANG, 0) > 0)
        !           116:                ;
        !           117: }
        !           118: 
        !           119: char   locuser[32], remuser[32];
        !           120: char   buf[BUFSIZ];
        !           121: int    child;
        !           122: int    cleanup();
        !           123: int    netf;
        !           124: extern errno;
        !           125: char   *line;
        !           126: 
        !           127: doit(f, fromp)
        !           128:        int f;
        !           129:        struct sockaddr_in *fromp;
        !           130: {
        !           131:        char c;
        !           132:        int i, p, cc, t, pid;
        !           133:        int stop = TIOCPKT_DOSTOP;
        !           134:        register struct hostent *hp;
        !           135: 
        !           136:        alarm(60);
        !           137:        read(f, &c, 1);
        !           138:        if (c != 0)
        !           139:                exit(1);
        !           140:        alarm(0);
        !           141:        fromp->sin_port = htons((u_short)fromp->sin_port);
        !           142:        hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr),
        !           143:                fromp->sin_family);
        !           144:        if (hp == 0) {
        !           145:                char buf[BUFSIZ], *cp = (char *)&fromp->sin_addr;
        !           146: 
        !           147:                fatal(f, sprintf(buf, "Host name for your address (%s) unknown",
        !           148:                        ntoa(fromp->sin_addr)));
        !           149:        }
        !           150:        if (fromp->sin_family != AF_INET ||
        !           151:            fromp->sin_port >= IPPORT_RESERVED ||
        !           152:            hp == 0)
        !           153:                fatal(f, "Permission denied");
        !           154:        write(f, "", 1);
        !           155:        for (c = 'p'; c <= 's'; c++) {
        !           156:                struct stat stb;
        !           157:                line = "/dev/ptyXX";
        !           158:                line[strlen("/dev/pty")] = c;
        !           159:                line[strlen("/dev/ptyp")] = '0';
        !           160:                if (stat(line, &stb) < 0)
        !           161:                        break;
        !           162:                for (i = 0; i < 16; i++) {
        !           163:                        line[strlen("/dev/ptyp")] = "0123456789abcdef"[i];
        !           164:                        p = open(line, 2);
        !           165:                        if (p > 0)
        !           166:                                goto gotpty;
        !           167:                }
        !           168:        }
        !           169:        fatal(f, "All network ports in use");
        !           170:        /*NOTREACHED*/
        !           171: gotpty:
        !           172:        dup2(f, 0);
        !           173:        line[strlen("/dev/")] = 't';
        !           174: #ifdef DEBUG
        !           175:        { int tt = open("/dev/tty", 2);
        !           176:          if (tt > 0) {
        !           177:                ioctl(tt, TIOCNOTTY, 0);
        !           178:                close(tt);
        !           179:          }
        !           180:        }
        !           181: #endif
        !           182:        t = open(line, 2);
        !           183:        if (t < 0)
        !           184:                fatalperror(f, line, errno);
        !           185:        { struct sgttyb b;
        !           186:          gtty(t, &b); b.sg_flags = RAW|ANYP; stty(t, &b);
        !           187:        }
        !           188:        pid = fork();
        !           189:        if (pid < 0)
        !           190:                fatalperror(f, "", errno);
        !           191:        if (pid) {
        !           192:                char pibuf[1024], fibuf[1024], *pbp, *fbp;
        !           193:                int pcc = 0, fcc = 0, on = 1;
        !           194: /* FILE *console = fopen("/dev/console", "w");  */
        !           195: /* setbuf(console, 0); */
        !           196: 
        !           197: /* fprintf(console, "f %d p %d\r\n", f, p); */
        !           198:                ioctl(f, FIONBIO, &on);
        !           199:                ioctl(p, FIONBIO, &on);
        !           200:                ioctl(p, TIOCPKT, &on);
        !           201:                signal(SIGTSTP, SIG_IGN);
        !           202:                signal(SIGCHLD, cleanup);
        !           203:                for (;;) {
        !           204:                        int ibits = 0, obits = 0;
        !           205: 
        !           206:                        if (fcc)
        !           207:                                obits |= (1<<p);
        !           208:                        else
        !           209:                                ibits |= (1<<f);
        !           210:                        if (pcc >= 0)
        !           211:                                if (pcc)
        !           212:                                        obits |= (1<<f);
        !           213:                                else
        !           214:                                        ibits |= (1<<p);
        !           215:                        if (fcc < 0 && pcc < 0)
        !           216:                                break;
        !           217: /* fprintf(console, "ibits from %d obits from %d\r\n", ibits, obits); */
        !           218:                        select(16, &ibits, &obits, 0, 0, 0);
        !           219: /* fprintf(console, "ibits %d obits %d\r\n", ibits, obits); */
        !           220:                        if (ibits == 0 && obits == 0) {
        !           221:                                sleep(5);
        !           222:                                continue;
        !           223:                        }
        !           224:                        if (ibits & (1<<f)) {
        !           225:                                fcc = read(f, fibuf, sizeof (fibuf));
        !           226: /* fprintf(console, "%d from f\r\n", fcc); */
        !           227:                                if (fcc < 0 && errno == EWOULDBLOCK)
        !           228:                                        fcc = 0;
        !           229:                                else {
        !           230:                                        if (fcc <= 0)
        !           231:                                                break;
        !           232:                                        fbp = fibuf;
        !           233:                                }
        !           234:                        }
        !           235:                        if (ibits & (1<<p)) {
        !           236:                                pcc = read(p, pibuf, sizeof (pibuf));
        !           237: /* fprintf(console, "%d from p, buf[0] %x, errno %d\r\n", pcc, buf[0], errno); */
        !           238:                                pbp = pibuf;
        !           239:                                if (pcc < 0 && errno == EWOULDBLOCK)
        !           240:                                        pcc = 0;
        !           241:                                else if (pcc <= 0)
        !           242:                                        pcc = -1;
        !           243:                                else if (pibuf[0] == 0)
        !           244:                                        pbp++, pcc--;
        !           245:                                else {
        !           246:                                        if (pibuf[0]&(TIOCPKT_FLUSHWRITE|
        !           247:                                                      TIOCPKT_NOSTOP|
        !           248:                                                      TIOCPKT_DOSTOP)) {
        !           249:                                                int nstop = pibuf[0] &
        !           250:                                                    (TIOCPKT_NOSTOP|
        !           251:                                                     TIOCPKT_DOSTOP);
        !           252:                                                if (nstop)
        !           253:                                                        stop = nstop;
        !           254:                                                pibuf[0] |= nstop;
        !           255:                                                send(f,&pibuf[0],1,MSG_OOB);
        !           256:                                        }
        !           257:                                        pcc = 0;
        !           258:                                }
        !           259:                        }
        !           260:                        if ((obits & (1<<f)) && pcc > 0) {
        !           261:                                cc = write(f, pbp, pcc);
        !           262: /* fprintf(console, "%d of %d to f\r\n", cc, pcc); */
        !           263:                                if (cc > 0) {
        !           264:                                        pcc -= cc;
        !           265:                                        pbp += cc;
        !           266:                                }
        !           267:                        }
        !           268:                        if ((obits & (1<<p)) && fcc > 0) {
        !           269:                                cc = write(p, fbp, fcc);
        !           270: /* fprintf(console, "%d of %d to p\r\n", cc, fcc); */
        !           271:                                if (cc > 0) {
        !           272:                                        fcc -= cc;
        !           273:                                        fbp += cc;
        !           274:                                }
        !           275:                        }
        !           276:                }
        !           277:                cleanup();
        !           278:        }
        !           279:        close(f);
        !           280:        close(p);
        !           281:        dup2(t, 0);
        !           282:        dup2(t, 1);
        !           283:        dup2(t, 2);
        !           284:        close(t);
        !           285:        execl("/bin/login", "login", "-r", hp->h_name, 0);
        !           286:        fatalperror(2, "/bin/login", errno);
        !           287:        /*NOTREACHED*/
        !           288: }
        !           289: 
        !           290: cleanup()
        !           291: {
        !           292: 
        !           293:        rmut();
        !           294:        vhangup();              /* XXX */
        !           295:        shutdown(netf, 2);
        !           296:        kill(0, SIGKILL);
        !           297:        exit(1);
        !           298: }
        !           299: 
        !           300: fatal(f, msg)
        !           301:        int f;
        !           302:        char *msg;
        !           303: {
        !           304:        char buf[BUFSIZ];
        !           305: 
        !           306:        buf[0] = '\01';         /* error indicator */
        !           307:        (void) sprintf(buf + 1, "rlogind: %s.\r\n", msg);
        !           308:        (void) write(f, buf, strlen(buf));
        !           309:        exit(1);
        !           310: }
        !           311: 
        !           312: fatalperror(f, msg, errno)
        !           313:        int f;
        !           314:        char *msg;
        !           315:        int errno;
        !           316: {
        !           317:        char buf[BUFSIZ];
        !           318:        extern char *sys_errlist[];
        !           319: 
        !           320:        (void) sprintf(buf, "%s: %s", msg, sys_errlist[errno]);
        !           321:        fatal(f, buf);
        !           322: }
        !           323: 
        !           324: #include <utmp.h>
        !           325: 
        !           326: struct utmp wtmp;
        !           327: char   wtmpf[] = "/usr/adm/wtmp";
        !           328: char   utmp[] = "/etc/utmp";
        !           329: #define SCPYN(a, b)    strncpy(a, b, sizeof(a))
        !           330: #define SCMPN(a, b)    strncmp(a, b, sizeof(a))
        !           331: 
        !           332: rmut()
        !           333: {
        !           334:        register f;
        !           335:        int found = 0;
        !           336: 
        !           337:        f = open(utmp, 2);
        !           338:        if (f >= 0) {
        !           339:                while(read(f, (char *)&wtmp, sizeof(wtmp)) == sizeof(wtmp)) {
        !           340:                        if (SCMPN(wtmp.ut_line, line+5) || wtmp.ut_name[0]==0)
        !           341:                                continue;
        !           342:                        lseek(f, -(long)sizeof(wtmp), 1);
        !           343:                        SCPYN(wtmp.ut_name, "");
        !           344:                        SCPYN(wtmp.ut_host, "");
        !           345:                        time(&wtmp.ut_time);
        !           346:                        write(f, (char *)&wtmp, sizeof(wtmp));
        !           347:                        found++;
        !           348:                }
        !           349:                close(f);
        !           350:        }
        !           351:        if (found) {
        !           352:                f = open(wtmpf, 1);
        !           353:                if (f >= 0) {
        !           354:                        SCPYN(wtmp.ut_line, line+5);
        !           355:                        SCPYN(wtmp.ut_name, "");
        !           356:                        SCPYN(wtmp.ut_host, "");
        !           357:                        time(&wtmp.ut_time);
        !           358:                        lseek(f, (long)0, 2);
        !           359:                        write(f, (char *)&wtmp, sizeof(wtmp));
        !           360:                        close(f);
        !           361:                }
        !           362:        }
        !           363:        chmod(line, 0666);
        !           364:        chown(line, 0, 0);
        !           365:        line[strlen("/dev/")] = 'p';
        !           366:        chmod(line, 0666);
        !           367:        chown(line, 0, 0);
        !           368: }
        !           369: 
        !           370: /*
        !           371:  * Convert network-format internet address
        !           372:  * to base 256 d.d.d.d representation.
        !           373:  */
        !           374: char *
        !           375: ntoa(in)
        !           376:        struct in_addr in;
        !           377: {
        !           378:        static char b[18];
        !           379:        register char *p;
        !           380: 
        !           381:        p = (char *)&in;
        !           382: #define        UC(b)   (((int)b)&0xff)
        !           383:        sprintf(b, "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
        !           384:        return (b);
        !           385: }

unix.superglobalmegacorp.com

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