* krshd "plumbing" fixes
authorMark Eichin <eichin@mit.edu>
Tue, 12 Nov 1996 04:58:46 +0000 (04:58 +0000)
committerMark Eichin <eichin@mit.edu>
Tue, 12 Nov 1996 04:58:46 +0000 (04:58 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@9385 dc483132-0cff-0310-8789-dd5450dbe970

src/appl/bsd/ChangeLog
src/appl/bsd/krshd.c

index 4ed41d806c9dc7c33c099b0b7a04cbd156a0f27c..c8378bfe4478cc7d8abbb567be2194aff9abd792 100644 (file)
@@ -1,3 +1,24 @@
+Mon Nov 11 23:38:05 1996  Mark Eichin  <eichin@cygnus.com>
+
+       * krshd "plumbing" fixes
+
+       Tue Jun 25 19:51:07 1996  Mark Eichin  <eichin@cygnus.com>
+
+       * krshd.c (doit): ignore SIGPIPE in the child, check the return
+       status of write instead.
+       Added comments labelling the various file descriptors.
+       Cleaned up formatting somewhat.
+       Check for failure of write to child stdin pipe, and stop reading.
+       Check for output from child before checking for input from net, to
+       reduce potential for missed output.
+       (cleanup): moved before doit, to eliminate need for declaration.
+       Added an argument, to allow reporting of what signal kshd died
+       on, and report that the daemon terminated, not the shell.
+
+       Thu Jun 20 18:54:04 1996  Mark Eichin  <eichin@cygnus.com>
+
+       * krshd.c: fix global-change typo in !KERBEROS branch.
+
 Mon Nov 11 15:00:25 1996  Mark Eichin  <eichin@cygnus.com>
 
        * Makefile.in, configure.in, krshd.c, v4rcp.M, v4rcp.c: added
index 156e8ffac9e2938785a3ceeb7736d7a0e4b11829..8859e3a9f28e7b6d475bf46306744450e7eb1477 100644 (file)
@@ -180,8 +180,8 @@ int netf;
 #else /* !KERBEROS */
 
 #define ARGSTR "RD:?"
-#define (*des_read)  read
-#define (*des_write) write
+int (*des_read)() = read;
+int (*des_write)() = write;
      
 #endif /* KERBEROS */
      
@@ -504,6 +504,42 @@ int auth_sys = 0;  /* Which version of Kerberos used to authenticate */
 #define KRB5_RECVAUTH_V4       4
 #define KRB5_RECVAUTH_V5       5
 
+krb5_sigtype
+cleanup(signumber)
+     int signumber;
+{
+#ifdef POSIX_SIGNALS
+    struct sigaction sa;
+
+    (void)sigemptyset(&sa.sa_mask);
+    sa.sa_flags = 0;
+    sa.sa_handler = SIG_IGN;
+    (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
+    (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
+    (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
+    (void)sigaction(SIGPIPE, &sa, (struct sigaction *)0);
+    (void)sigaction(SIGHUP, &sa, (struct sigaction *)0);
+
+    (void)kill(-pid, SIGTERM);
+#else
+    signal(SIGINT, SIG_IGN);
+    signal(SIGQUIT, SIG_IGN);
+    signal(SIGTERM, SIG_IGN);
+    signal(SIGPIPE, SIG_IGN);
+    signal(SIGHUP, SIG_IGN);
+    
+    killpg(pid, SIGTERM);
+#endif
+    wait(0);
+    
+    pty_logwtmp(ttyn,"","");
+    syslog(LOG_INFO ,"Daemon terminated via signal %d.", signumber);
+    if (ccache)
+       krb5_cc_destroy(bsd_context, ccache);
+    exit(0);
+}
+
+
 void doit(f, fromp)
      int f;
      struct sockaddr_in *fromp;
@@ -544,7 +580,6 @@ void doit(f, fromp)
     int pv[2], pw[2], px[2], cc;
     fd_set ready, readfrom;
     char buf[RSHD_BUFSIZ], sig;
-    krb5_sigtype     cleanup();
     struct sockaddr_in fromaddr;
     struct sockaddr_in localaddr;
     int non_privileged = 0;
@@ -1111,17 +1146,21 @@ void doit(f, fromp)
            (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
            (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
            (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
-           (void)sigaction(SIGPIPE, &sa, (struct sigaction *)0);
            (void)sigaction(SIGHUP, &sa, (struct sigaction *)0);
 
            sa.sa_handler = SIG_IGN;
+           /* SIGPIPE is a crutch that we don't need if we check 
+              the exit status of write. */
+           (void)sigaction(SIGPIPE, &sa, (struct sigaction *)0);
            (void)sigaction(SIGCHLD, &sa, (struct sigaction *)0);
 #else
            signal(SIGINT, cleanup);
            signal(SIGQUIT, cleanup);
            signal(SIGTERM, cleanup);
-           signal(SIGPIPE, cleanup);
            signal(SIGHUP, cleanup);
+           /* SIGPIPE is a crutch that we don't need if we check 
+              the exit status of write. */
+           signal(SIGPIPE, SIG_IGN);
            signal(SIGCHLD,SIG_IGN);
 #endif
            
@@ -1141,19 +1180,49 @@ if(port)
     FD_SET(pv[0], &readfrom);
            FD_SET(pw[0], &readfrom);
            
+           /* read from f, write to px[1] -- child stdin */
+           /* read from s, signal child */
+           /* read from pv[0], write to s -- child stderr */
+           /* read from pw[0], write to f -- child stdout */
+
            do {
                ready = readfrom;
                if (select(8*sizeof(ready), &ready, (fd_set *)0,
                           (fd_set *)0, (struct timeval *)0) < 0) {
-                   if (errno == EINTR)
+                   if (errno == EINTR) {
                        continue;
-                   else
+                   } else {
                        break;
                }
+               }
+
+               if (port&&FD_ISSET(pv[0], &ready)) {
+                   /* read from the child stderr, write to the net */
+                   errno = 0;
+                   cc = read(pv[0], buf, sizeof (buf));
+                   if (cc <= 0) {
+                       shutdown(s, 1+1);
+                       FD_CLR(pv[0], &readfrom);
+                   } else {
+                       (void) (*des_write)(s, buf, cc);
+                   }
+               }
+               if (FD_ISSET(pw[0], &ready)) {
+                   /* read from the child stdout, write to the net */
+                   errno = 0;
+                   cc = read(pw[0], buf, sizeof (buf));
+                   if (cc <= 0) {
+                       shutdown(f, 1+1);
+                       FD_CLR(pw[0], &readfrom);
+                   } else {
+                       (void) (*des_write)(f, buf, cc);
+                   }
+               }
                if (port&&FD_ISSET(s, &ready)) {
-                   if ((*des_read)(s, &sig, 1) <= 0)
+                   /* read from the alternate channel, signal the child */
+                   if ((*des_read)(s, &sig, 1) <= 0) {
                        FD_CLR(s, &readfrom);
-                   else {
+                   else {
 #ifdef POSIX_SIGNALS
                        sa.sa_handler = cleanup;
                        (void)sigaction(sig, &sa, (struct sigaction *)0);
@@ -1165,31 +1234,25 @@ if(port)
                    }
                }
                if (FD_ISSET(f, &ready)) {
+                   /* read from the net, write to child stdin */
                    errno = 0;
                    cc = (*des_read)(f, buf, sizeof(buf));
                    if (cc <= 0) {
                        (void) close(px[1]);
                        FD_CLR(f, &readfrom);
-                   } else
-                       (void) write(px[1], buf, cc);
+                   } else {
+                       int wcc;
+                       wcc = write(px[1], buf, cc);
+                       if (wcc == -1) {
+                         /* pipe closed, don't read any more */
+                         /* might check for EPIPE */
+                         (void) close(px[1]);
+                         FD_CLR(f, &readfrom);
+                       } else if (wcc != cc) {
+                         syslog(LOG_INFO, "only wrote %d/%d to child", 
+                                wcc, cc);
                }
-               if (port&&FD_ISSET(pv[0], &ready)) {
-                   errno = 0;
-                   cc = read(pv[0], buf, sizeof (buf));
-                   if (cc <= 0) {
-                       shutdown(s, 1+1);
-                       FD_CLR(pv[0], &readfrom);
-                   } else
-                       (void) (*des_write)(s, buf, cc);
                }
-               if (FD_ISSET(pw[0], &ready)) {
-                   errno = 0;
-                   cc = read(pw[0], buf, sizeof (buf));
-                   if (cc <= 0) {
-                       shutdown(f, 1+1);
-                       FD_CLR(pw[0], &readfrom);
-                   } else
-                       (void) (*des_write)(f, buf, cc);
                }
            } while ((port&&FD_ISSET(s, &readfrom)) ||
                     FD_ISSET(f, &readfrom) ||
@@ -1422,44 +1485,6 @@ void getstr(fd, buf, cnt, err)
     } while (c != 0);
 }
 
-
-
-krb5_sigtype 
-  cleanup()
-{
-#ifdef POSIX_SIGNALS
-    struct sigaction sa;
-
-    (void)sigemptyset(&sa.sa_mask);
-    sa.sa_flags = 0;
-    sa.sa_handler = SIG_IGN;
-    (void)sigaction(SIGINT, &sa, (struct sigaction *)0);
-    (void)sigaction(SIGQUIT, &sa, (struct sigaction *)0);
-    (void)sigaction(SIGTERM, &sa, (struct sigaction *)0);
-    (void)sigaction(SIGPIPE, &sa, (struct sigaction *)0);
-    (void)sigaction(SIGHUP, &sa, (struct sigaction *)0);
-
-    (void)kill(-pid, SIGTERM);
-#else
-    signal(SIGINT, SIG_IGN);
-    signal(SIGQUIT, SIG_IGN);
-    signal(SIGTERM, SIG_IGN);
-    signal(SIGPIPE, SIG_IGN);
-    signal(SIGHUP, SIG_IGN);
-    
-    killpg(pid, SIGTERM);
-#endif
-    wait(0);
-    
-    pty_logwtmp(ttyn,"","");
-    syslog(LOG_INFO ,"Shell process completed.");
-    if (ccache)
-       krb5_cc_destroy(bsd_context, ccache);
-    exit(0);
-}
-
-
-
 #ifdef CRAY
 char *makejtmp(uid, gid, jid)
      register int uid, gid, jid;
@@ -2018,7 +2043,7 @@ void fatal(f, msg)
 #else
         (void) ioctl(f, TIOCFLUSH, (char *)&out);
 #endif
-        cleanup();
+        cleanup(-1);
     }
     exit(1);
 }