Annotation of cci/usr/src/etc/rshd.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)rshd.c     4.17 (Berkeley) 83/07/02";
                      3: #endif
                      4: 
                      5: #include <sys/ioctl.h>
                      6: #include <sys/param.h>
                      7: #include <sys/socket.h>
                      8: #include <sys/wait.h>
                      9: 
                     10: #include <netinet/in.h>
                     11: 
                     12: #include <stdio.h>
                     13: #include <errno.h>
                     14: #include <pwd.h>
                     15: #include <signal.h>
                     16: #include <netdb.h>
                     17: 
                     18: int    errno;
                     19: int    reapchild();
                     20: struct sockaddr_in sin = { AF_INET };
                     21: struct passwd *getpwnam();
                     22: char   *index(), *rindex(), *sprintf();
                     23: int    options;
                     24: /* VARARGS 1 */
                     25: int    error();
                     26: /*
                     27:  * remote shell server:
                     28:  *     remuser\0
                     29:  *     locuser\0
                     30:  *     command\0
                     31:  *     data
                     32:  */
                     33: main(argc, argv)
                     34:        int argc;
                     35:        char **argv;
                     36: {
                     37:        int     errcnt = 0;
                     38:        int f, linger;
                     39:        struct sockaddr_in from;
                     40:        struct servent *sp;
                     41: 
                     42:        sp = getservbyname("shell", "tcp");
                     43:        if (sp == 0) {
                     44:                fprintf(stderr, "rshd: tcp/shell: unknown service\n");
                     45:                exit(1);
                     46:        }
                     47: #ifndef DEBUG
                     48:        if (fork())
                     49:                exit(0);
                     50:        close(0);
                     51:        if ( open("/dev/console", 2) <0) {
                     52:                fprintf(stderr,"rshd: cannot open /dev/console\n");
                     53:                exit(1);
                     54:        }
                     55:        (void) dup2(0, 1);
                     56:        (void) dup2(0, 2);
                     57:        for (f = 3; f < 10; f++)
                     58:                (void) close(f);
                     59:        { int t = open("/dev/tty", 2);
                     60:          if (t >= 0) {
                     61:                ioctl(t, TIOCNOTTY, (char *)0);
                     62:                (void) close(t);
                     63:          }
                     64:        }
                     65: #endif
                     66:        sin.sin_port = sp->s_port;
                     67:        argc--, argv++;
                     68:        if (argc > 0 && !strcmp(argv[0], "-d")) {
                     69:                options |= SO_DEBUG;
                     70:                argc--, argv++;
                     71:        }
                     72:        if (argc > 0) {
                     73:                int port = atoi(argv[0]);
                     74: 
                     75:                if (port < 0) {
                     76:                        fprintf(stderr, "%s: bad port #\n", argv[0]);
                     77:                        exit(1);
                     78:                }
                     79:                sin.sin_port = htons((u_short)port);
                     80:                argc--, argv++;
                     81:        }
                     82:        f = socket(AF_INET, SOCK_STREAM, 0, 0);
                     83:        if (f < 0) {
                     84:                perror("rshd: socket");
                     85:                exit(1);
                     86:        }
                     87:        if (options & SO_DEBUG && setsockopt(f, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
                     88:                perror("rshd: setsockopt (SO_DEBUG)");
                     89:        if (setsockopt(f, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0)
                     90:                perror("rshd: setsockopt (SO_KEEPALIVE)");
                     91:        linger = 60;                    /* XXX */
                     92:        if (setsockopt(f, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)) < 0)
                     93:                perror("rshd: setsockopt (SO_LINGER)");
                     94:        if (bind(f, (caddr_t)&sin, sizeof (sin), 0) < 0) {
                     95:                perror("rshd: bind");
                     96:                exit(1);
                     97:        }
                     98:        signal(SIGCHLD, reapchild);
                     99:        listen(f, 10);
                    100:        for (;errcnt < 20;) {
                    101:                int child;
                    102:                int g, len = sizeof (from);
                    103: 
                    104:                g = accept(f, &from, &len, 0);
                    105:                if (g < 0) {
                    106:                        if (errno == EINTR)
                    107:                                continue;
                    108:                        perror("rshd: accept");
                    109:                        errcnt++;
                    110:                        sleep(5);
                    111:                        continue;
                    112:                }
                    113:                child = fork();
                    114:                if (child < 0) {
                    115:                        perror("rshd: cannot fork");
                    116:                        sleep(5);
                    117:                        continue;
                    118:                }
                    119:                if (child == 0) {
                    120:                        signal(SIGCHLD, SIG_IGN);
                    121:                        close(f);
                    122:                        errcnt = 0;
                    123:                        doit(g, &from);
                    124:                }
                    125:                /* when we get here, all is okay */
                    126:                errcnt = 0;
                    127:                close(g);
                    128:        }
                    129:        fprintf(stderr,"rshd: terminated due to too many errors\n");
                    130: }
                    131: 
                    132: reapchild()
                    133: {
                    134:        union wait status;
                    135: 
                    136:        while (wait3(&status, WNOHANG, 0) > 0)
                    137:                ;
                    138: }
                    139: 
                    140: char   username[20] = "USER=";
                    141: char   homedir[64] = "HOME=";
                    142: char   shell[64] = "SHELL=";
                    143: char   *envinit[] =
                    144:            {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin", username, 0};
                    145: char   **environ;
                    146: 
                    147: doit(f, fromp)
                    148:        int f;
                    149:        struct sockaddr_in *fromp;
                    150: {
                    151:        char cmdbuf[NCARGS+1], *cp;
                    152:        char locuser[16], remuser[16];
                    153:        struct passwd *pwd;
                    154:        int s, backoff;
                    155:        struct hostent *hp;
                    156:        short port;
                    157:        int pv[2], pid, ready, readfrom, cc;
                    158:        char buf[BUFSIZ], sig;
                    159:        int one = 1;
                    160: 
                    161:        (void) signal(SIGINT, SIG_DFL);
                    162:        (void) signal(SIGQUIT, SIG_DFL);
                    163:        (void) signal(SIGTERM, SIG_DFL);
                    164: #ifdef DEBUG
                    165:        { int t = open("/dev/tty", 2);
                    166:          if (t >= 0) {
                    167:                ioctl(t, TIOCNOTTY, (char *)0);
                    168:                (void) close(t);
                    169:          }
                    170:        }
                    171: #endif
                    172:        fromp->sin_port = ntohs((u_short)fromp->sin_port);
                    173:        if (fromp->sin_family != AF_INET ||
                    174:            fromp->sin_port >= IPPORT_RESERVED) {
                    175:                fprintf(stderr, "rshd: malformed from address\n");
                    176:                exit(1);
                    177:        }
                    178:        (void) alarm(60);
                    179:        port = 0;
                    180:        for (;;) {
                    181:                char c;
                    182:                if (read(f, &c, 1) != 1) {
                    183:                        perror("rshd: read");
                    184:                        shutdown(f, 1+1);
                    185:                        exit(1);
                    186:                }
                    187:                if (c == 0)
                    188:                        break;
                    189:                port = port * 10 + c - '0';
                    190:        }
                    191:        (void) alarm(0);
                    192:        if (port != 0) {
                    193:                int lport = IPPORT_RESERVED - 1, retryshift;
                    194:                s = rresvport(&lport);
                    195:                if (s < 0) {
                    196:                        perror("rshd: can't get stderr port");
                    197:                        exit(1);
                    198:                }
                    199:                if (port >= IPPORT_RESERVED) {
                    200:                        fprintf(stderr, "rshd: 2nd port not reserved\n");
                    201:                        exit(1);
                    202:                }
                    203:                fromp->sin_port = htons((u_short)port);
                    204:                if (connect(s, fromp, sizeof (*fromp), 0) < 0) {
                    205:                        perror("rshd: connect");
                    206:                        exit(1);
                    207:                }
                    208:        }
                    209:        dup2(f, 0);
                    210:        dup2(f, 1);
                    211:        dup2(f, 2);
                    212:        hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr),
                    213:                fromp->sin_family);
                    214:        if (hp == 0) {
                    215:                error("Host name for your address unknown\n");
                    216:                exit(1);
                    217:        }
                    218:        getstr(remuser, sizeof(remuser), "remuser");
                    219:        getstr(locuser, sizeof(locuser), "locuser");
                    220:        getstr(cmdbuf, sizeof(cmdbuf), "command");
                    221:        setpwent();
                    222:        pwd = getpwnam(locuser);
                    223:        if (pwd == NULL) {
                    224:                error("Login incorrect.\n");
                    225:                exit(1);
                    226:        }
                    227:        endpwent();
                    228:        if (chdir(pwd->pw_dir) < 0) {
                    229:                error("No remote directory.\n");
                    230:                exit(1);
                    231:        }
                    232:        if (ruserok(hp->h_name, pwd->pw_uid == 0, remuser, locuser) < 0) {
                    233:                error("Permission denied.\n");
                    234:                exit(1);
                    235:        }
                    236:        (void) write(2, "\0", 1);
                    237:        if (port) {
                    238:                if (pipe(pv) < 0) {
                    239:                        error("Can't make pipe.\n");
                    240:                        exit(1);
                    241:                }
                    242:                pid = fork();
                    243:                if (pid == -1)  {
                    244:                        error("Try again.\n");
                    245:                        exit(1);
                    246:                }
                    247:                if (pid) {
                    248:                        (void) close(0); (void) close(1); (void) close(2);
                    249:                        (void) close(f); (void) close(pv[1]);
                    250:                        readfrom = (1<<s) | (1<<pv[0]);
                    251:                        ioctl(pv[1], FIONBIO, (char *)&one);
                    252:                        /* should set s nbio! */
                    253:                        do {
                    254:                                ready = readfrom;
                    255:                                if (select(16, &ready, 0, 0, 0) < 0)
                    256:                                        break;
                    257:                                if (ready & (1<<s)) {
                    258:                                        if (read(s, &sig, 1) <= 0)
                    259:                                                readfrom &= ~(1<<s);
                    260:                                        else
                    261:                                                killpg(pid, sig);
                    262:                                }
                    263:                                if (ready & (1<<pv[0])) {
                    264:                                        errno = 0;
                    265:                                        cc = read(pv[0], buf, sizeof (buf));
                    266:                                        if (cc <= 0) {
                    267:                                                shutdown(s, 1+1);
                    268:                                                readfrom &= ~(1<<pv[0]);
                    269:                                        } else
                    270:                                                (void) write(s, buf, cc);
                    271:                                }
                    272:                        } while (readfrom);
                    273:                        exit(0);
                    274:                }
                    275:                setpgrp(0, getpid());
                    276:                (void) close(s); (void) close(pv[0]);
                    277:                dup2(pv[1], 2);
                    278:        }
                    279:        if (*pwd->pw_shell == '\0')
                    280:                pwd->pw_shell = "/bin/sh";
                    281:        (void) close(f);
                    282:        initgroups(pwd->pw_name, pwd->pw_gid);
                    283:        (void) setgid(pwd->pw_gid);
                    284:        (void) setuid(pwd->pw_uid);
                    285:        environ = envinit;
                    286:        strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
                    287:        strncat(shell, pwd->pw_shell, sizeof(shell)-7);
                    288:        strncat(username, pwd->pw_name, sizeof(username)-6);
                    289:        cp = rindex(pwd->pw_shell, '/');
                    290:        if (cp)
                    291:                cp++;
                    292:        else
                    293:                cp = pwd->pw_shell;
                    294:        execl(pwd->pw_shell, cp, "-c", cmdbuf, 0);
                    295:        perror(pwd->pw_shell);
                    296:        exit(1);
                    297: protofail:
                    298:        error("rsh: protocol failure detected by remote\n");
                    299:        exit(1);
                    300: }
                    301: 
                    302: /* VARARGS 1 */
                    303: error(fmt)
                    304:        char *fmt;
                    305: {
                    306:        char buf[BUFSIZ];
                    307: 
                    308:        buf[0] = 1;
                    309:        (void) sprintf(buf+1, fmt);
                    310:        (void) write(2, buf, strlen(buf));
                    311: }
                    312: 
                    313: getstr(buf, cnt, err)
                    314:        char *buf;
                    315:        int cnt;
                    316:        char *err;
                    317: {
                    318:        char c;
                    319: 
                    320:        do {
                    321:                if (read(0, &c, 1) != 1)
                    322:                        exit(1);
                    323:                *buf++ = c;
                    324:                if (--cnt == 0) {
                    325:                        error("%s too long\n", err);
                    326:                        exit(1);
                    327:                }
                    328:        } while (c != 0);
                    329: }

unix.superglobalmegacorp.com

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