summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMark Eichin <eichin@mit.edu>1996-11-12 04:58:46 +0000
committerMark Eichin <eichin@mit.edu>1996-11-12 04:58:46 +0000
commitb59819d1f93c744ca6267407ba2241fe4aefc7f7 (patch)
treeed8492ce6688246c430444400f409221b1a18388 /src
parent3d91ec93a95b0ce76ca64ca6f4cea76b4f37d4ca (diff)
* krshd "plumbing" fixes
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@9385 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/appl/bsd/ChangeLog21
-rw-r--r--src/appl/bsd/krshd.c157
2 files changed, 112 insertions, 66 deletions
diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog
index 4ed41d806..c8378bfe4 100644
--- a/src/appl/bsd/ChangeLog
+++ b/src/appl/bsd/ChangeLog
@@ -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
diff --git a/src/appl/bsd/krshd.c b/src/appl/bsd/krshd.c
index 156e8ffac..8859e3a9f 100644
--- a/src/appl/bsd/krshd.c
+++ b/src/appl/bsd/krshd.c
@@ -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);
}