turn on keep alives
[unix-history] / usr / src / libexec / rshd / rshd.c
index c734c30..f88ad8e 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)rshd.c     4.10 83/01/22";
+static char sccsid[] = "@(#)rshd.c     4.15 83/05/03";
 #endif
 
 #include <sys/ioctl.h>
 #endif
 
 #include <sys/ioctl.h>
@@ -81,10 +81,8 @@ main(argc, argv)
        }
        if (options & SO_DEBUG && setsockopt(f, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
                perror("rshd: setsockopt (SO_DEBUG)");
        }
        if (options & SO_DEBUG && setsockopt(f, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
                perror("rshd: setsockopt (SO_DEBUG)");
-#ifdef notdef
        if (setsockopt(f, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0)
                perror("rshd: setsockopt (SO_KEEPALIVE)");
        if (setsockopt(f, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0)
                perror("rshd: setsockopt (SO_KEEPALIVE)");
-#endif
        if (bind(f, (caddr_t)&sin, sizeof (sin), 0) < 0) {
                perror("rshd: bind");
                exit(1);
        if (bind(f, (caddr_t)&sin, sizeof (sin), 0) < 0) {
                perror("rshd: bind");
                exit(1);
@@ -102,6 +100,7 @@ main(argc, argv)
                        continue;
                }
                if (fork() == 0) {
                        continue;
                }
                if (fork() == 0) {
+                       signal(SIGCHLD, SIG_IGN);
                        close(f);
                        doit(g, &from);
                }
                        close(f);
                        doit(g, &from);
                }
@@ -131,7 +130,7 @@ doit(f, fromp)
        char cmdbuf[NCARGS+1], *cp;
        char locuser[16], remuser[16];
        struct passwd *pwd;
        char cmdbuf[NCARGS+1], *cp;
        char locuser[16], remuser[16];
        struct passwd *pwd;
-       int s;
+       int s, backoff;
        struct hostent *hp;
        short port;
        int pv[2], pid, ready, readfrom, cc;
        struct hostent *hp;
        short port;
        int pv[2], pid, ready, readfrom, cc;
@@ -141,7 +140,7 @@ doit(f, fromp)
        (void) signal(SIGINT, SIG_DFL);
        (void) signal(SIGQUIT, SIG_DFL);
        (void) signal(SIGTERM, SIG_DFL);
        (void) signal(SIGINT, SIG_DFL);
        (void) signal(SIGQUIT, SIG_DFL);
        (void) signal(SIGTERM, SIG_DFL);
-#ifndef DEBUG
+#ifdef DEBUG
        { int t = open("/dev/tty", 2);
          if (t >= 0) {
                ioctl(t, TIOCNOTTY, (char *)0);
        { int t = open("/dev/tty", 2);
          if (t >= 0) {
                ioctl(t, TIOCNOTTY, (char *)0);
@@ -149,37 +148,46 @@ doit(f, fromp)
          }
        }
 #endif
          }
        }
 #endif
-       dup2(f, 0);
-       dup2(f, 1);
-       dup2(f, 2);
        fromp->sin_port = ntohs((u_short)fromp->sin_port);
        if (fromp->sin_family != AF_INET ||
        fromp->sin_port = ntohs((u_short)fromp->sin_port);
        if (fromp->sin_family != AF_INET ||
-           fromp->sin_port >= IPPORT_RESERVED)
+           fromp->sin_port >= IPPORT_RESERVED) {
+               fprintf(stderr, "rshd: malformed from address\n");
                exit(1);
                exit(1);
+       }
        (void) alarm(60);
        port = 0;
        for (;;) {
                char c;
        (void) alarm(60);
        port = 0;
        for (;;) {
                char c;
-               if (read(f, &c, 1) != 1)
+               if (read(f, &c, 1) != 1) {
+                       perror("rshd: read");
+                       shutdown(f, 1+1);
                        exit(1);
                        exit(1);
+               }
                if (c == 0)
                        break;
                port = port * 10 + c - '0';
        }
        (void) alarm(0);
        if (port != 0) {
                if (c == 0)
                        break;
                port = port * 10 + c - '0';
        }
        (void) alarm(0);
        if (port != 0) {
-               int lport = IPPORT_RESERVED - 1;
+               int lport = IPPORT_RESERVED - 1, retryshift;
                s = rresvport(&lport);
                s = rresvport(&lport);
-               if (s < 0)
+               if (s < 0) {
+                       perror("rshd: can't get stderr port");
+                       exit(1);
+               }
+               if (port >= IPPORT_RESERVED) {
+                       fprintf(stderr, "rshd: 2nd port not reserved\n");
                        exit(1);
                        exit(1);
-               if (port >= IPPORT_RESERVED)
-                       goto protofail;
-               (void) alarm(60);
+               }
                fromp->sin_port = htons((u_short)port);
                fromp->sin_port = htons((u_short)port);
-               if (connect(s, fromp, sizeof (*fromp), 0) < 0)
+               if (connect(s, fromp, sizeof (*fromp), 0) < 0) {
+                       perror("rshd: connect");
                        exit(1);
                        exit(1);
-               (void) alarm(0);
+               }
        }
        }
+       dup2(f, 0);
+       dup2(f, 1);
+       dup2(f, 2);
        hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr),
                fromp->sin_family);
        if (hp == 0) {
        hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr),
                fromp->sin_family);
        if (hp == 0) {
@@ -200,7 +208,7 @@ doit(f, fromp)
                error("No remote directory.\n");
                exit(1);
        }
                error("No remote directory.\n");
                exit(1);
        }
-       if (ruserok(hp->h_name, remuser, locuser) < 0) {
+       if (ruserok(hp->h_name, pwd->pw_uid == 0, remuser, locuser) < 0) {
                error("Permission denied.\n");
                exit(1);
        }
                error("Permission denied.\n");
                exit(1);
        }
@@ -232,6 +240,7 @@ doit(f, fromp)
                                                killpg(pid, sig);
                                }
                                if (ready & (1<<pv[0])) {
                                                killpg(pid, sig);
                                }
                                if (ready & (1<<pv[0])) {
+                                       errno = 0;
                                        cc = read(pv[0], buf, sizeof (buf));
                                        if (cc <= 0) {
                                                shutdown(s, 1+1);
                                        cc = read(pv[0], buf, sizeof (buf));
                                        if (cc <= 0) {
                                                shutdown(s, 1+1);
@@ -250,8 +259,8 @@ doit(f, fromp)
                pwd->pw_shell = "/bin/sh";
        (void) close(f);
        initgroups(pwd->pw_name, pwd->pw_gid);
                pwd->pw_shell = "/bin/sh";
        (void) close(f);
        initgroups(pwd->pw_name, pwd->pw_gid);
-       (void) setuid(pwd->pw_uid);
        (void) setgid(pwd->pw_gid);
        (void) setgid(pwd->pw_gid);
+       (void) setuid(pwd->pw_uid);
        environ = envinit;
        strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
        strncat(shell, pwd->pw_shell, sizeof(shell)-7);
        environ = envinit;
        strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
        strncat(shell, pwd->pw_shell, sizeof(shell)-7);