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

unix.superglobalmegacorp.com

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