This patch is against netkit-rsh-0.16, or netkit-combo-0.16, and fixes a couple of reasonably important (but not security-related) bugs: without them, rlogind doesn't work, and rshd never exits and leaves zombies around. (Sigh.) Apply to netkit-rsh-0.16 by doing the following: cd netkit-rsh-0.16 patch -p1 < THIS_FILE Apply to netkit-combo-0.16 by doing the following: cd netkit-combo-0.16 patch -p0 < THIS_FILE Then recompile netkit-rsh. The resulting binaries will call themselves "netkit-rsh-0.16.1". Index: netkit-rsh/ChangeLog =================================================================== RCS file: /home/dholland/projects/netkit/CVSREPO/netkit/src/netkit-rsh/ChangeLog,v retrieving revision 1.13 retrieving revision 1.15 diff -u -r1.13 -r1.15 --- ChangeLog 1999/09/28 16:07:35 1.13 +++ ChangeLog 1999/12/17 18:36:46 1.15 @@ -1,3 +1,11 @@ +17-Dec-1999: + Fix bug in rshd (hangs forever with zombie offspring). + Also fix problems with rlogind. + To be posted as patch 1, making netkit-rsh-0.16.1. + +14-Dec-1999: + netkit-rsh-0.16 is released. + 14-Sep-1999: Close all files >= 3 before execing, in case libc has left something open. Also merge a Caldera doc fix. Index: netkit-rsh/version.h =================================================================== RCS file: /home/dholland/projects/netkit/CVSREPO/netkit/src/netkit-rsh/version.h,v retrieving revision 1.5 diff -u -r1.5 version.h --- version.h 1999/12/14 12:52:56 1.5 +++ version.h 1999/12/17 18:41:00 @@ -2,4 +2,4 @@ * String to embed in binaries to identify package */ -char pkg[]="$NetKit: netkit-rsh-0.16 $"; +char pkg[]="$NetKit: netkit-rsh-0.16.1 $"; Index: netkit-rsh/rlogind/rlogind.c =================================================================== RCS file: /home/dholland/projects/netkit/CVSREPO/netkit/src/netkit-rsh/rlogind/rlogind.c,v retrieving revision 1.33 retrieving revision 1.35 diff -u -r1.33 -r1.35 --- rlogind.c 1999/10/02 21:50:52 1.33 +++ rlogind.c 1999/12/17 18:36:25 1.35 @@ -40,7 +40,7 @@ * From: @(#)rlogind.c 5.53 (Berkeley) 4/20/91 */ char rcsid[] = - "$Id: rlogind.c,v 1.33 1999/10/02 21:50:52 dholland Exp $"; + "$Id: rlogind.c,v 1.35 1999/12/17 18:36:25 dholland Exp $"; #include "../version.h" /* @@ -298,7 +298,7 @@ chown(line, 0, 0); /* all done */ - exit(1); + exit(0); } @@ -334,21 +334,22 @@ static void child(const char *hname, const char *termtype, const char *localuser, int authenticated) { - char *termenv; + char *termenv[2]; setup_term(0, termtype); - termenv = malloc(strlen(termtype)+6); - if (termenv) { /* shouldn't ever fail, mind you */ - strcpy(termenv, "TERM="); - strcat(termenv, termtype); + termenv[0] = malloc(strlen(termtype)+6); + if (termenv[0]) { /* shouldn't ever fail, mind you */ + strcpy(termenv[0], "TERM="); + strcat(termenv[0], termtype); } + termenv[1] = NULL; if (authenticated) { auth_finish(); closeall(); execle(_PATH_LOGIN, "login", "-p", - "-h", hname, "-f", localuser, NULL, termenv, NULL); + "-h", hname, "-f", localuser, NULL, termenv); } else { if (localuser[0] == '-') { @@ -358,7 +359,7 @@ auth_finish(); closeall(); execle(_PATH_LOGIN, "login", "-p", - "-h", hname, localuser, NULL, termenv, NULL); + "-h", hname, localuser, NULL, termenv); } /* Can't exec login, croak */ fatal(STDERR_FILENO, _PATH_LOGIN, 1); Index: netkit-rsh/rshd/rshd.c =================================================================== RCS file: /home/dholland/projects/netkit/CVSREPO/netkit/src/netkit-rsh/rshd/rshd.c,v retrieving revision 1.22 retrieving revision 1.23 diff -u -r1.22 -r1.23 --- rshd.c 1999/10/02 21:45:08 1.22 +++ rshd.c 1999/12/17 14:57:09 1.23 @@ -43,7 +43,7 @@ * From: @(#)rshd.c 5.38 (Berkeley) 3/2/91 */ char rcsid[] = - "$Id: rshd.c,v 1.22 1999/10/02 21:45:08 dholland Exp $"; + "$Id: rshd.c,v 1.23 1999/12/17 14:57:09 dholland Exp $"; #include "../version.h" /* @@ -171,7 +171,7 @@ fd_set ready, readfrom; char buf[BUFSIZ], sig; int one = 1; - int nfd, cc, done=0; + int nfd, cc, guys=2; ioctl(pype, FIONBIO, (char *)&one); /* should set s nbio! */ @@ -182,24 +182,28 @@ if (pype > sock) nfd = pype+1; else nfd = sock+1; - while (!done) { + while (guys > 0) { ready = readfrom; - if (select(nfd, &ready, NULL, NULL, NULL) < 0 && errno != EINTR) { - break; + if (select(nfd, &ready, NULL, NULL, NULL) < 0) { + if (errno != EINTR) { + break; + } + continue; } - done = 1; if (FD_ISSET(sock, &ready)) { - done = 0; cc = read(sock, &sig, 1); - if (cc <= 0) FD_CLR(sock, &readfrom); + if (cc <= 0) { + FD_CLR(sock, &readfrom); + guys--; + } else killpg(pid, sig); } if (FD_ISSET(pype, &ready)) { - done = 0; cc = read(pype, buf, sizeof(buf)); if (cc <= 0) { shutdown(sock, 2); FD_CLR(pype, &readfrom); + guys--; } else write(sock, buf, cc); } @@ -209,6 +213,8 @@ /* * This does not strike me as the right place for this; this is * in a child process... what does this need to accomplish? + * + * No, it's not the child process, the code is just confusing. */ pam_close_session(pamh, 0); pam_end(pamh, PAM_SUCCESS);