From c37e7830bd25238f680af7464837c829a89337cf Mon Sep 17 00:00:00 2001 From: Sam Hartman Date: Fri, 19 Jan 1996 01:33:08 +0000 Subject: [PATCH] Mainline utmp and login cleanups from hartmans_pty_utmp: * Fix utmp handling on Solaris for wtmpx records * Replace krlogin's SIGURG handler with a call to select squashing Solaris ctrl-c bug * Fix utmp on systems without pututline so ttyslot is only used when it works git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7338 dc483132-0cff-0310-8789-dd5450dbe970 --- src/appl/bsd/ChangeLog | 14 +++ src/appl/bsd/configure.in | 6 +- src/appl/bsd/krlogin.c | 159 ++++++----------------------- src/appl/bsd/krlogind.c | 3 +- src/appl/bsd/login.c | 2 +- src/appl/telnet/telnetd/ChangeLog | 4 + src/appl/telnet/telnetd/sys_term.c | 3 +- src/util/autoconf/configure | 3 + src/util/pty/.Sanitize | 1 + src/util/pty/ChangeLog | 19 ++++ src/util/pty/cleanup.c | 2 +- src/util/pty/libpty.h | 5 +- src/util/pty/open_ctty.c | 3 - src/util/pty/update_utmp.c | 90 ++++++++++------ src/util/pty/void_assoc.c | 4 + 15 files changed, 146 insertions(+), 172 deletions(-) diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog index 6945cedaf..4e2f94298 100644 --- a/src/appl/bsd/ChangeLog +++ b/src/appl/bsd/ChangeLog @@ -1,3 +1,17 @@ +Wed Jan 17 15:14:33 1996 Sam Hartman + + * krlogin.c ((reader): Use select to find out-of-band data, not signals. + (oob): No longer a signal handler; just a function. + (writer): get rid of copytochild setup as sigurg no longer needed + (main): Don't block SIGURG + * configure.in : Include sys/time.h check + +Mon Jan 15 16:16:07 1996 Sam Hartman + + * login.c (main): ttyslot usable here as well + + * krlogind.c (doit): update_utmp can use ttyslot. + Thu Jan 11 12:40:08 1996 Ezra Peisach (epeisach@paris) * krsh.c, krlogin.c: (main): Ultrix cc does not support automatic diff --git a/src/appl/bsd/configure.in b/src/appl/bsd/configure.in index 114d29547..7e5e2a910 100644 --- a/src/appl/bsd/configure.in +++ b/src/appl/bsd/configure.in @@ -52,9 +52,9 @@ AC_FUNC_CHECK(grantpt,AC_DEFINE(HAVE_GRANTPT)) AC_FUNC_CHECK(openpty,AC_DEFINE(HAVE_OPENPTY)) AC_FUNC_CHECK(setlogin,AC_DEFINE(HAVE_SETLOGIN)) AC_FUNC_CHECK(logwtmp,AC_DEFINE(HAVE_LOGWTMP)) -AC_CHECK_HEADERS(unistd.h stdlib.h string.h sys/filio.h sys/sockio.h) -AC_CHECK_HEADERS(sys/label.h sys/tty.h ttyent.h lastlog.h sys/select.h) -AC_CHECK_HEADERS(sys/ptyvar.h utmp.h utmpx.h stdarg.h) +AC_CHECK_HEADERS(unistd.h stdlib.h string.h sys/filio.h sys/sockio.h ) +AC_CHECK_HEADERS(sys/label.h sys/tty.h ttyent.h lastlog.h sys/select.h ) +AC_CHECK_HEADERS(sys/ptyvar.h utmp.h utmpx.h stdarg.h sys/time.h) AC_REPLACE_FUNCS(getdtablesize) DECLARE_SYS_ERRLIST KRB5_SIGTYPE diff --git a/src/appl/bsd/krlogin.c b/src/appl/bsd/krlogin.c index 3483f7940..00f3e765c 100644 --- a/src/appl/bsd/krlogin.c +++ b/src/appl/bsd/krlogin.c @@ -64,6 +64,12 @@ char copyright[] = #ifdef HAVE_STDLIB_H #include #endif +#ifdef HAVE_SYS_SELECT_H +#include +#endif +#if HAVE_SYS_TIME_H +#include +#endif #ifdef POSIX_TERMIOS #include @@ -216,7 +222,8 @@ struct winsize winsize; char *host=0; /* external, so it can be reached from confirm_death() */ -krb5_sigtype sigwinch KRB5_PROTOTYPE((int)), oob KRB5_PROTOTYPE((int)); +krb5_sigtype sigwinch KRB5_PROTOTYPE((int)); +void oob KRB5_PROTOTYPE((void)); krb5_sigtype lostpeer KRB5_PROTOTYPE((int)); #if __STDC__ int setsignal(int sig, krb5_sigtype (*act)()); @@ -544,16 +551,15 @@ main(argc, argv) (void) sigaction(SIGPIPE, &sa, (struct sigaction *)0); (void) sigemptyset(&urgmask); - (void) sigaddset(&urgmask, SIGURG); (void) sigaddset(&urgmask, SIGUSR1); oldmask = &omask; (void) sigprocmask(SIG_BLOCK, &urgmask, oldmask); #else (void) signal(SIGPIPE, lostpeer); #ifdef sgi - oldmask = sigignore(sigmask(SIGURG) | sigmask(SIGUSR1)); + oldmask = sigignore( sigmask(SIGUSR1)); #else - oldmask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1)); + oldmask = sigblock( sigmask(SIGUSR1)); #endif #endif /* POSIX_SIGNALS */ @@ -603,28 +609,6 @@ main(argc, argv) if (rem < 0) exit(1); - /* we need to do the SETOWN here so that we get the SIGURG - registered if the URG data come in early, before the reader() gets - to do this for real (otherwise, the signal is never generated - by the kernel). We block it above, so when it gets unblocked - it will get processed by the reader(). - There is a possibility that the signal will get delivered to both - writer and reader, but that is harmless, since the writer reflects - it to the reader, and the oob() processing code in the reader will - work properly even if it is called when no oob() data is present. - */ -#ifdef hpux - /* hpux invention */ - { - int pid = getpid(); - ioctl(rem, FIOSSAIOSTAT, &pid); /* trick: pid is non-zero */ - ioctl(rem, FIOSSAIOOWN, &pid); - } -#else -#ifdef HAVE_SETOWN - (void) fcntl(rem, F_SETOWN, getpid()); -#endif -#endif if (options & SO_DEBUG && setsockopt(rem, SOL_SOCKET, SO_DEBUG, (char*)&on, sizeof (on)) < 0) perror("rlogin: setsockopt (SO_DEBUG)"); @@ -682,8 +666,7 @@ int confirm_death () int child; krb5_sigtype catchild KRB5_PROTOTYPE((int)); -krb5_sigtype copytochild KRB5_PROTOTYPE((int)), - writeroob KRB5_PROTOTYPE((int)); +krb5_sigtype writeroob KRB5_PROTOTYPE((int)); int defflags, tabflag; int deflflags; @@ -810,16 +793,8 @@ doit(oldmask) exit(3); } - /* - * We may still own the socket, and may have a pending SIGURG - * (or might receive one soon) that we really want to send to - * the reader. Set a trap that simply copies such signals to - * the child. - */ #ifdef POSIX_SIGNALS /* "sa" has already been initialized above. */ - sa.sa_handler = copytochild; - (void) sigaction(SIGURG, &sa, (struct sigaction *)0); sa.sa_handler = writeroob; (void) sigaction(SIGUSR1, &sa, (struct sigaction *)0); @@ -829,7 +804,6 @@ doit(oldmask) sa.sa_handler = catchild; (void) sigaction(SIGCHLD, &sa, (struct sigaction *)0); #else - (void) signal(SIGURG, copytochild); (void) signal(SIGUSR1, writeroob); #ifndef sgi (void) sigsetmask(oldmask); @@ -921,15 +895,6 @@ done(status) -/* - * Copy SIGURGs to the child process. - */ -krb5_sigtype - copytochild(signo) -int signo; -{ - (void) kill(child, SIGURG); -} @@ -1228,15 +1193,8 @@ int rcvcnt; int rcvstate; int ppid; -#ifdef POSIX_SETJMP -sigjmp_buf rcvtop; -#else -jmp_buf rcvtop; -#endif -krb5_sigtype - oob(signo) -int signo; +void oob() { #ifndef POSIX_TERMIOS int out = FWRITE; @@ -1253,33 +1211,9 @@ int signo; struct sgttyb sb; #endif #endif + mark = 0; - while (recv(rem, &mark, 1, MSG_OOB) < 0) - switch (errno) { - - case EWOULDBLOCK: - /* - * Urgent data not here yet. - * It may not be possible to send it yet - * if we are blocked for output - * and our input buffer is full. - */ - if (rcvcnt < sizeof(rcvbuf)) { - n = read(rem, rcvbuf + rcvcnt, - sizeof(rcvbuf) - rcvcnt); - if (n <= 0) - return; - rcvd += n; - } else { - n = read(rem, waste, sizeof(waste)); - if (n <= 0) - return; - } - continue; - - default: - return; - } + recv(rem, &mark, 1, MSG_OOB); if (mark & TIOCPKT_WINDOW) { /* * Let server know about window size changes @@ -1347,38 +1281,11 @@ int signo; n = read(rem, waste, sizeof (waste)); if (n <= 0) break; +return; } - /* - * Don't want any pending data to be output, - * so clear the recv buffer. - * If we were hanging on a write when interrupted, - * don't want it to restart. If we were reading, - * restart anyway. - */ - rcvcnt = 0; -#ifdef POSIX_SETJMP - siglongjmp(rcvtop, 1); -#else - longjmp(rcvtop, 1); -#endif } - /* - * oob does not do FLUSHREAD (alas!) - */ - /* - * If we filled the receive buffer while a read was pending, - * longjmp to the top to restart appropriately. Don't abort - * a pending write, however, or we won't know how much was written. - */ -#ifdef POSIX_SETJMP - if (rcvd && rcvstate == READING) - siglongjmp(rcvtop, 1); -#else - if (rcvd && rcvstate == READING) - longjmp(rcvtop, 1); -#endif } @@ -1398,6 +1305,7 @@ reader(oldmask) #else int pid = -getpid(); #endif +fd_set readset, excset; int n, remaining; char *bufp = rcvbuf; @@ -1409,27 +1317,13 @@ reader(oldmask) sa.sa_handler = SIG_IGN; (void) sigaction(SIGTTOU, &sa, (struct sigaction *)0); -#ifdef SA_RESTART - /* Because SIGURG will be coming in during a read, - * we want to restart the syscall afterwards. */ - sa.sa_flags |= SA_RESTART; -#endif - sa.sa_handler = oob; - (void) sigaction(SIGURG, &sa, (struct sigaction *)0); #else (void) signal(SIGTTOU, SIG_IGN); - (void) signal(SIGURG, oob); #endif ppid = getppid(); -#ifdef HAVE_SETOWN - (void) fcntl(rem, F_SETOWN, pid); -#endif -#ifdef POSIX_SETJMP - (void) sigsetjmp(rcvtop, 1); -#else - (void) setjmp(rcvtop); -#endif +FD_ZERO(&readset); + FD_ZERO(&excset); #ifdef POSIX_SIGNALS sigprocmask(SIG_SETMASK, oldmask, (sigset_t*)0); #else @@ -1437,6 +1331,7 @@ reader(oldmask) (void) sigsetmask(oldmask); #endif #endif /* POSIX_SIGNALS */ + for (;;) { while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) { rcvstate = WRITING; @@ -1450,11 +1345,21 @@ reader(oldmask) } bufp = rcvbuf; rcvcnt = 0; - rcvstate = READING; - rcvcnt = des_read(rem, rcvbuf, sizeof (rcvbuf)); + rcvstate = READING; +FD_SET(rem,&readset); + FD_SET(rem,&excset); + if (select(rem+1, &readset, 0, &excset, 0) > 0 ) { +if (FD_ISSET(rem, &excset)) + oob(); +if (FD_ISSET(rem, &readset)) { + rcvcnt = des_read(rem, rcvbuf, sizeof (rcvbuf)); if (rcvcnt == 0) return (0); - if (rcvcnt < 0) { + if (rcvcnt < 0) + goto error; +} + } else + error: { if (errno == EINTR) continue; perror("read"); diff --git a/src/appl/bsd/krlogind.c b/src/appl/bsd/krlogind.c index 36dd01de7..33867b180 100644 --- a/src/appl/bsd/krlogind.c +++ b/src/appl/bsd/krlogind.c @@ -703,7 +703,8 @@ int syncpipe[2]; #ifndef NO_UT_PID { - pty_update_utmp(PTY_LOGIN_PROCESS, getpid(), "rlogin", line, ""/*host*/); + pty_update_utmp(PTY_LOGIN_PROCESS, getpid(), "rlogin", line, + ""/*host*/, PTY_TTYSLOT_USABLE); } #endif diff --git a/src/appl/bsd/login.c b/src/appl/bsd/login.c index a6c45173a..d1e98e23a 100644 --- a/src/appl/bsd/login.c +++ b/src/appl/bsd/login.c @@ -784,7 +784,7 @@ bad_login: struct utmp utmp; login_time = time(&utmp.ut_time); - if ( (retval = pty_update_utmp(PTY_USER_PROCESS, getpid(), username, ttyn, hostname)) < 0 ) + if ( (retval = pty_update_utmp(PTY_USER_PROCESS, getpid(), username, ttyn, hostname, PTY_TTYSLOT_USABLE)) < 0 ) com_err (argv[0], retval, "while updating utmp"); } diff --git a/src/appl/telnet/telnetd/ChangeLog b/src/appl/telnet/telnetd/ChangeLog index 2f38230cc..c85fe7144 100644 --- a/src/appl/telnet/telnetd/ChangeLog +++ b/src/appl/telnet/telnetd/ChangeLog @@ -1,3 +1,7 @@ +Mon Jan 15 17:35:25 1996 Sam Hartman + + * sys_term.c: Call pty_update_utmp with PTY_TTYSLOT_USABLE flag. + Mon Nov 27 15:55:50 1995 Tom Yu * state.c: use P properly so it won't break non-ansi compilers. diff --git a/src/appl/telnet/telnetd/sys_term.c b/src/appl/telnet/telnetd/sys_term.c index 8d52128ac..ccd061fb9 100644 --- a/src/appl/telnet/telnetd/sys_term.c +++ b/src/appl/telnet/telnetd/sys_term.c @@ -1137,7 +1137,8 @@ if ( read(syncpipe[0], &c, 1) == 0 ) { } else { - pty_update_utmp (PTY_LOGIN_PROCESS, getpid(), "LOGIN", line, host); + pty_update_utmp (PTY_LOGIN_PROCESS, getpid(), "LOGIN", line, + host, PTY_TTYSLOT_USABLE); getptyslave(autologin); /* Notify our parent we're ready to continue.*/ diff --git a/src/util/autoconf/configure b/src/util/autoconf/configure index a54238fad..9e419f97c 100644 --- a/src/util/autoconf/configure +++ b/src/util/autoconf/configure @@ -4,6 +4,9 @@ kadm_deplib='' kadm_lib='' +kutil_deplib='' +kutil_lib='' + kdb5_deplib='' kdb5_lib='' diff --git a/src/util/pty/.Sanitize b/src/util/pty/.Sanitize index 987e63276..013a5eb6f 100644 --- a/src/util/pty/.Sanitize +++ b/src/util/pty/.Sanitize @@ -25,6 +25,7 @@ Things-to-keep: .cvsignore ChangeLog +README Makefile.in configure.in cleanup.c diff --git a/src/util/pty/ChangeLog b/src/util/pty/ChangeLog index fca11b79f..878b08a3a 100644 --- a/src/util/pty/ChangeLog +++ b/src/util/pty/ChangeLog @@ -1,3 +1,22 @@ +Tue Jan 16 13:52:22 1996 Sam Hartman + + * void_assoc.c (ptyint_void_association): Move setsid call from open_ctty to void_association. + + * logwtmp.c (pty_logwtmp): Pass user argument to update_wtmp. + + * update_utmp.c (update_utmp): Implement PTY_UTMP_USERNAME_VALID flag + +Mon Jan 15 15:48:37 1996 Sam Hartman (hartmans@justforfun) + + * cleanup.c: Change to indiciate utmp user name is valid. + + * + +Mon Jan 15 15:21:16 1996 Sam Hartman + + * update_utmp.c (pty_update_utmp): Add flags field; use ttyslot + only if reasonable. + Fri Jan 12 16:33:37 1996 Sam Hartman * open_slave.c (pty_open_slave): Don't use fchmod or fchown; they diff --git a/src/util/pty/cleanup.c b/src/util/pty/cleanup.c index 3352fa04e..57d1258ca 100644 --- a/src/util/pty/cleanup.c +++ b/src/util/pty/cleanup.c @@ -28,7 +28,7 @@ long pty_cleanup (slave, pid, update_utmp) { int retval, fd; - pty_update_utmp(PTY_DEAD_PROCESS,0, "", slave, (char *)0); + pty_update_utmp(PTY_DEAD_PROCESS,0, "", slave, (char *)0, PTY_UTMP_USERNAME_VALID); (void)chmod(slave, 0666); (void)chown(slave, 0, 0); diff --git a/src/util/pty/libpty.h b/src/util/pty/libpty.h index c90a3300e..51d834a3b 100644 --- a/src/util/pty/libpty.h +++ b/src/util/pty/libpty.h @@ -24,6 +24,9 @@ #define PTY_USER_PROCESS 1 #define PTY_DEAD_PROCESS 2 +/* flags to update_utmp*/ +#define PTY_TTYSLOT_USABLE (0x1) +#define PTY_UTMP_USERNAME_VALID (0x2) #ifdef __STDC__ /* use prototypes */ long pty_init(void); @@ -33,7 +36,7 @@ long pty_open_slave (const char *slave, int *fd); long pty_open_ctty (const char *slave, int *fd); long pty_initialize_slave ( int fd); -long pty_update_utmp (int process_type,int pid, char *user, char *line, char *host); +long pty_update_utmp (int process_type,int pid, char *user, char *line, char *host, int flags); long pty_logwtmp (char *tty, char * user, char *host); diff --git a/src/util/pty/open_ctty.c b/src/util/pty/open_ctty.c index c54c6f106..b4b9ba97c 100644 --- a/src/util/pty/open_ctty.c +++ b/src/util/pty/open_ctty.c @@ -38,9 +38,6 @@ pty_open_ctty (slave, fd) int *fd; { int testfd, retval; -#ifdef HAVE_SETSID - (void) setsid(); -#endif /* First, dissociate from previous terminal */ if ( (retval = ptyint_void_association()) != 0 ) diff --git a/src/util/pty/update_utmp.c b/src/util/pty/update_utmp.c index 1c319ab09..fa2f5099e 100644 --- a/src/util/pty/update_utmp.c +++ b/src/util/pty/update_utmp.c @@ -29,16 +29,17 @@ #ifndef UTMP_FILE #define UTMP_FILE "/etc/utmp" #endif - -long pty_update_utmp (process_type, pid, username, line, host) +#ifndef NO_UT_PID +#define WTMP_REQUIRES_USERNAME +#endif +long pty_update_utmp (process_type, pid, username, line, host, flags) int process_type; int pid; char *username, *line, *host; + int flags; { - struct utmp ent; -#ifdef HAVE_SETUTENT - struct utmp ut; -#else + struct utmp ent, ut; +#ifndef HAVE_SETUTENT struct stat statb; int tty; #endif @@ -49,6 +50,7 @@ long pty_update_utmp (process_type, pid, username, line, host) char *tmpx; char utmp_id[5]; #endif + char userbuf[32]; int fd; strncpy(ent.ut_line, line+sizeof("/dev/")-1, sizeof(ent.ut_line)); @@ -86,37 +88,34 @@ long pty_update_utmp (process_type, pid, username, line, host) #else strncpy(ent.ut_name, username, sizeof(ent.ut_name)); #endif - + if(username[0]) + strncpy(userbuf, username, sizeof(userbuf)); + else userbuf[0] = '\0'; + #ifdef HAVE_SETUTENT utmpname(UTMP_FILE); setutent(); - pututline(&ent); - endutent(); - -#if 0 - /* XXX -- NOT NEEDED ANYMORE */ - - if (ent.ut_type == DEAD_PROCESS) { - if ((fd = open(UTMP_FILE, O_RDWR)) >= 0) { - int cnt = 0; - while(read(fd, (char *)&ut, sizeof(ut)) == sizeof(ut)) { - if (!strncmp(ut.ut_id, ent.ut_id, sizeof(ut.ut_id))) { - (void) memset(ut.ut_host, 0, sizeof(ut.ut_host)); - (void) memset(ut.ut_user, 0, sizeof(ut.ut_user)); - (void) time(&ut.ut_time); - ut.ut_exit.e_exit = ut.ut_pid = 0; - ut.ut_type = EMPTY; - (void) lseek(fd, -sizeof(ut), SEEK_CUR); - (void) write(fd, &ut, sizeof(ut)); - } - cnt++; - } - close(fd); +/* If we need to preserve the user name in the wtmp structure and + * Our flags tell us we can obtain it from the utmp and we succeed in + * obtaining it, we then save the utmp structure we obtain, write + * out the utmp structure and change the username pointer so it is used by + * update_wtmp.*/ +#ifdef WTMP_REQUIRES_USERNAME + if (( !username[0]) && (flags&PTY_UTMP_USERNAME_VALID) + &&line) + { +struct utmp *utptr; +strncpy(ut.ut_line, line, sizeof(ut.ut_line)); +utptr = getutline(&ut); +if (utptr) + strncpy(userbuf,utptr->ut_user,sizeof(ut.ut_user)); } - } #endif + pututline(&ent); + endutent(); + #ifdef HAVE_SETUTXENT setutxent(); getutmpx(&ent, &utx); @@ -128,15 +127,38 @@ if (host) #endif /* HAVE_SETUTXENT */ #else /* HAVE_SETUTENT */ - - tty = ttyslot(); - if (tty > 0 && (fd = open(UTMP_FILE, O_WRONLY, 0)) >= 0) { + if (flags&PTY_TTYSLOT_USABLE) + tty = ttyslot(); + else { + int lc; + tty = -1; + if ((fd = open(UTMP_FILE, O_RDWR)) < 0) + return errno; + for (lc = 0; + lseek(fd, (off_t)(lc * sizeof(struct utmp)), SEEK_SET) != -1; + lc++) { + if (read(fd, (char *) &ut, sizeof(struct utmp)) != sizeof(struct utmp)) + break; + if (strncmp(ut.ut_line, ent.ut_line, sizeof(ut.ut_line)) == 0) { + tty = lc; +#ifdef WTMP_REQUIRES_USERNAME + if (!username&&(flags&PTY_UTMP_USERNAME_VALID)) + strncpy(userbuf, ut.ut_user, sizeof(ut.ut_user)); +#endif + break; + } + } +close(fd); + } + + if (tty > 0 && (fd = open(UTMP_FILE, O_WRONLY, 0)) >= 0) { (void)lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); (void)write(fd, (char *)&ent, sizeof(struct utmp)); (void)close(fd); } + #endif /* HAVE_SETUTENT */ - return ptyint_update_wtmp(&ent, host, username); + return ptyint_update_wtmp(&ent, host, userbuf); } diff --git a/src/util/pty/void_assoc.c b/src/util/pty/void_assoc.c index 6735d142d..34915d5dc 100644 --- a/src/util/pty/void_assoc.c +++ b/src/util/pty/void_assoc.c @@ -24,6 +24,10 @@ long ptyint_void_association() { int con_fd; +#ifdef HAVE_SETSID + (void) setsid(); +#endif + /* Void tty association first */ if ((con_fd = open("/dev/tty", O_RDWR)) >= 0) { ioctl(con_fd, TIOCNOTTY, 0); -- 2.26.2