Annotation of cci/usr/src/etc/rlogind.c, revision 1.1.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.