Annotation of 42BSD/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: 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.