use syslog for error messages
[unix-history] / usr / src / libexec / rshd / rshd.c
index 4046d14..2410d74 100644 (file)
@@ -1,7 +1,14 @@
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)rshd.c     4.18 (Berkeley) 84/04/11";
+static char sccsid[] = "@(#)rshd.c     4.21 (Berkeley) %G%";
 #endif
 
 #endif
 
+/*
+ * remote shell server:
+ *     remuser\0
+ *     locuser\0
+ *     command\0
+ *     data
+ */
 #include <sys/ioctl.h>
 #include <sys/param.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
 #include <sys/param.h>
 #include <sys/socket.h>
@@ -14,109 +21,38 @@ static char sccsid[] = "@(#)rshd.c 4.18 (Berkeley) 84/04/11";
 #include <pwd.h>
 #include <signal.h>
 #include <netdb.h>
 #include <pwd.h>
 #include <signal.h>
 #include <netdb.h>
+#include <syslog.h>
 
 int    errno;
 
 int    errno;
-int    reapchild();
-struct sockaddr_in sin = { AF_INET };
-struct passwd *getpwnam();
-char   *index(), *rindex(), *sprintf();
-int    options;
+char   *index(), *rindex();
 /* VARARGS 1 */
 int    error();
 /* VARARGS 1 */
 int    error();
-/*
- * remote shell server:
- *     remuser\0
- *     locuser\0
- *     command\0
- *     data
- */
+
 main(argc, argv)
        int argc;
        char **argv;
 {
 main(argc, argv)
        int argc;
        char **argv;
 {
-       int f, linger;
+       struct linger linger;
+       int on = 1, fromlen;
        struct sockaddr_in from;
        struct sockaddr_in from;
-       struct servent *sp;
-
-       sp = getservbyname("shell", "tcp");
-       if (sp == 0) {
-               fprintf(stderr, "rshd: tcp/shell: unknown service\n");
-               exit(1);
-       }
-#ifndef DEBUG
-       if (fork())
-               exit(0);
-       for (f = 0; f < 10; f++)
-               (void) close(f);
-       (void) open("/", 0);
-       (void) dup2(0, 1);
-       (void) dup2(0, 2);
-       { int t = open("/dev/tty", 2);
-         if (t >= 0) {
-               ioctl(t, TIOCNOTTY, (char *)0);
-               (void) close(t);
-         }
-       }
-#endif
-       sin.sin_port = sp->s_port;
-       argc--, argv++;
-       if (argc > 0 && !strcmp(argv[0], "-d")) {
-               options |= SO_DEBUG;
-               argc--, argv++;
-       }
-       if (argc > 0) {
-               int port = atoi(argv[0]);
 
 
-               if (port < 0) {
-                       fprintf(stderr, "%s: bad port #\n", argv[0]);
-                       exit(1);
-               }
-               sin.sin_port = htons((u_short)port);
-               argc--, argv++;
+       fromlen = sizeof (from);
+       if (getpeername(0, &from, &fromlen) < 0) {
+               fprintf(stderr, "%s: ", argv[0]);
+               perror("getpeername");
+               _exit(1);
        }
        }
-       f = socket(AF_INET, SOCK_STREAM, 0, 0);
-       if (f < 0) {
-               perror("rshd: socket");
-               exit(1);
+       if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0) {
+               openlog(argv[0], LOG_PID, 0);
+               syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
        }
        }
-       if (options & SO_DEBUG && setsockopt(f, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
-               perror("rshd: setsockopt (SO_DEBUG)");
-       if (setsockopt(f, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0)
-               perror("rshd: setsockopt (SO_KEEPALIVE)");
-       linger = 60;                    /* XXX */
-       if (setsockopt(f, SOL_SOCKET, SO_LINGER, &linger, 0) < 0)
-               perror("rshd: setsockopt (SO_LINGER)");
-       if (bind(f, (caddr_t)&sin, sizeof (sin), 0) < 0) {
-               perror("rshd: bind");
-               exit(1);
+       linger.l_onoff = 1;
+       linger.l_linger = 60;                   /* XXX */
+       if (setsockopt(0, SOL_SOCKET, SO_LINGER, &linger, sizeof (linger)) < 0) {
+               openlog(argv[0], LOG_PID, 0);
+               syslog(LOG_WARNING, "setsockopt (SO_LINGER): %m");
        }
        }
-       signal(SIGCHLD, reapchild);
-       listen(f, 10);
-       for (;;) {
-               int g, len = sizeof (from);
-
-               g = accept(f, &from, &len, 0);
-               if (g < 0) {
-                       if (errno == EINTR)
-                               continue;
-                       perror("rshd: accept");
-                       continue;
-               }
-               if (fork() == 0) {
-                       signal(SIGCHLD, SIG_IGN);
-                       close(f);
-                       doit(g, &from);
-               }
-               close(g);
-       }
-}
-
-reapchild()
-{
-       union wait status;
-
-       while (wait3(&status, WNOHANG, 0) > 0)
-               ;
+       doit(dup(0), &from);
 }
 
 char   username[20] = "USER=";
 }
 
 char   username[20] = "USER=";
@@ -154,7 +90,8 @@ doit(f, fromp)
        fromp->sin_port = ntohs((u_short)fromp->sin_port);
        if (fromp->sin_family != AF_INET ||
            fromp->sin_port >= IPPORT_RESERVED) {
        fromp->sin_port = ntohs((u_short)fromp->sin_port);
        if (fromp->sin_family != AF_INET ||
            fromp->sin_port >= IPPORT_RESERVED) {
-               fprintf(stderr, "rshd: malformed from address\n");
+               openlog("rshd", LOG_PID, 0);
+               syslog(LOG_ERR, "malformed from address\n");
                exit(1);
        }
        (void) alarm(60);
                exit(1);
        }
        (void) alarm(60);
@@ -162,7 +99,8 @@ doit(f, fromp)
        for (;;) {
                char c;
                if (read(f, &c, 1) != 1) {
        for (;;) {
                char c;
                if (read(f, &c, 1) != 1) {
-                       perror("rshd: read");
+                       openlog("rshd", LOG_PID, 0);
+                       syslog(LOG_ERR, "read: %m");
                        shutdown(f, 1+1);
                        exit(1);
                }
                        shutdown(f, 1+1);
                        exit(1);
                }
@@ -175,16 +113,19 @@ doit(f, fromp)
                int lport = IPPORT_RESERVED - 1, retryshift;
                s = rresvport(&lport);
                if (s < 0) {
                int lport = IPPORT_RESERVED - 1, retryshift;
                s = rresvport(&lport);
                if (s < 0) {
-                       perror("rshd: can't get stderr port");
+                       openlog("rshd", LOG_PID, 0);
+                       syslog(LOG_ERR, "can't get stderr port: %m");
                        exit(1);
                }
                if (port >= IPPORT_RESERVED) {
                        exit(1);
                }
                if (port >= IPPORT_RESERVED) {
-                       fprintf(stderr, "rshd: 2nd port not reserved\n");
+                       openlog("rshd", LOG_PID, 0);
+                       syslog(LOG_ERR, "2nd port not reserved\n");
                        exit(1);
                }
                fromp->sin_port = htons((u_short)port);
                if (connect(s, fromp, sizeof (*fromp), 0) < 0) {
                        exit(1);
                }
                fromp->sin_port = htons((u_short)port);
                if (connect(s, fromp, sizeof (*fromp), 0) < 0) {
-                       perror("rshd: connect");
+                       openlog("rshd", LOG_PID, 0);
+                       syslog(LOG_ERR, "connect: %m");
                        exit(1);
                }
        }
                        exit(1);
                }
        }
@@ -208,8 +149,11 @@ doit(f, fromp)
        }
        endpwent();
        if (chdir(pwd->pw_dir) < 0) {
        }
        endpwent();
        if (chdir(pwd->pw_dir) < 0) {
+               chdir("/");
+#ifdef notdef
                error("No remote directory.\n");
                exit(1);
                error("No remote directory.\n");
                exit(1);
+#endif
        }
        if (ruserok(hp->h_name, pwd->pw_uid == 0, remuser, locuser) < 0) {
                error("Permission denied.\n");
        }
        if (ruserok(hp->h_name, pwd->pw_uid == 0, remuser, locuser) < 0) {
                error("Permission denied.\n");
@@ -261,8 +205,8 @@ doit(f, fromp)
        if (*pwd->pw_shell == '\0')
                pwd->pw_shell = "/bin/sh";
        (void) close(f);
        if (*pwd->pw_shell == '\0')
                pwd->pw_shell = "/bin/sh";
        (void) close(f);
-       initgroups(pwd->pw_name, pwd->pw_gid);
        (void) setgid(pwd->pw_gid);
        (void) setgid(pwd->pw_gid);
+       initgroups(pwd->pw_name, pwd->pw_gid);
        (void) setuid(pwd->pw_uid);
        environ = envinit;
        strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
        (void) setuid(pwd->pw_uid);
        environ = envinit;
        strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);