diff options
author | Ken Raeburn <raeburn@mit.edu> | 2006-04-11 19:53:48 +0000 |
---|---|---|
committer | Ken Raeburn <raeburn@mit.edu> | 2006-04-11 19:53:48 +0000 |
commit | 8bcbe9ba5c1f2384272fe121721ab72ac70d3ca1 (patch) | |
tree | 2e84e7414e5a82d1350cf8e742ef7f15bc677ed9 /src/appl/libpty | |
parent | d716f2b96aca06cd8b2fb84e9fe1f601de645c94 (diff) | |
download | krb5-8bcbe9ba5c1f2384272fe121721ab72ac70d3ca1.tar.gz krb5-8bcbe9ba5c1f2384272fe121721ab72ac70d3ca1.tar.xz krb5-8bcbe9ba5c1f2384272fe121721ab72ac70d3ca1.zip |
Move pty library from util/pty to appl/libpty; update Makefile.in and
configure.in files accordingly.
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@17887 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/appl/libpty')
-rw-r--r-- | src/appl/libpty/.Sanitize | 52 | ||||
-rw-r--r-- | src/appl/libpty/ChangeLog | 955 | ||||
-rw-r--r-- | src/appl/libpty/Makefile.in | 157 | ||||
-rw-r--r-- | src/appl/libpty/README | 108 | ||||
-rw-r--r-- | src/appl/libpty/cleanup.c | 112 | ||||
-rw-r--r-- | src/appl/libpty/configure.in | 269 | ||||
-rw-r--r-- | src/appl/libpty/dump-utmp.c | 281 | ||||
-rw-r--r-- | src/appl/libpty/getpty.c | 150 | ||||
-rw-r--r-- | src/appl/libpty/init.c | 33 | ||||
-rw-r--r-- | src/appl/libpty/init_slave.c | 100 | ||||
-rw-r--r-- | src/appl/libpty/libpty.h | 54 | ||||
-rw-r--r-- | src/appl/libpty/logwtmp.c | 112 | ||||
-rw-r--r-- | src/appl/libpty/open_ctty.c | 67 | ||||
-rw-r--r-- | src/appl/libpty/open_slave.c | 101 | ||||
-rw-r--r-- | src/appl/libpty/pty-int.h | 138 | ||||
-rw-r--r-- | src/appl/libpty/pty_err.et | 50 | ||||
-rw-r--r-- | src/appl/libpty/pty_paranoia.c | 650 | ||||
-rw-r--r-- | src/appl/libpty/sane_hostname.c | 116 | ||||
-rw-r--r-- | src/appl/libpty/update_utmp.c | 706 | ||||
-rw-r--r-- | src/appl/libpty/update_wtmp.c | 127 | ||||
-rw-r--r-- | src/appl/libpty/vhangup.c | 50 | ||||
-rw-r--r-- | src/appl/libpty/void_assoc.c | 49 |
22 files changed, 4437 insertions, 0 deletions
diff --git a/src/appl/libpty/.Sanitize b/src/appl/libpty/.Sanitize new file mode 100644 index 0000000000..d1b4efbe36 --- /dev/null +++ b/src/appl/libpty/.Sanitize @@ -0,0 +1,52 @@ +# Sanitize.in for Kerberos V5 + +# Each directory to survive it's way into a release will need a file +# like this one called "./.Sanitize". All keyword lines must exist, +# and must exist in the order specified by this file. Each directory +# in the tree will be processed, top down, in the following order. + +# Hash started lines like this one are comments and will be deleted +# before anything else is done. Blank lines will also be squashed +# out. + +# The lines between the "Do-first:" line and the "Things-to-keep:" +# line are executed as a /bin/sh shell script before anything else is +# done in this + +Do-first: + +# All files listed between the "Things-to-keep:" line and the +# "Files-to-sed:" line will be kept. All other files will be removed. +# Directories listed in this section will have their own Sanitize +# called. Directories not listed will be removed in their entirety +# with rm -rf. + +Things-to-keep: + +.cvsignore +ChangeLog +README +Makefile.in +configure.in +configure +cleanup.c +dump-utmp.c +getpty.c +init_slave.c +libpty.h +init.c +logwtmp.c +open_ctty.c +open_slave.c +pty-int.h +pty_err.et +update_utmp.c +update_wtmp.c +vhangup.c +void_assoc.c + +Things-to-lose: + +Do-last: + +# End of file. diff --git a/src/appl/libpty/ChangeLog b/src/appl/libpty/ChangeLog new file mode 100644 index 0000000000..2e42f7c993 --- /dev/null +++ b/src/appl/libpty/ChangeLog @@ -0,0 +1,955 @@ +2006-04-11 Ken Raeburn <raeburn@mit.edu> + + * Move directory from util/pty to appl/libpty. + * Makefile.in (myfulldir, RELDIR): Updated. + +2006-04-05 Tom Yu <tlyu@mit.edu> + + * configure.in: Add prerequisites for sys/ptyvar.h. + +2006-03-31 Ken Raeburn <raeburn@mit.edu> + + * configure.in: Always provide three arguments to AC_DEFINE. + +2006-03-30 Ken Raeburn <raeburn@mit.edu> + + * pty-int.h: Include autoconf.h. + +2006-03-11 Ken Raeburn <raeburn@mit.edu> + + * Makefile.in (autoconf.h): Note location change. + +2005-08-20 Ken Raeburn <raeburn@mit.edu> + + * configure.in: Use K5_AC_INIT instead of AC_INIT. + +2004-09-22 Tom Yu <tlyu@mit.edu> + + * pty-int.h: Include util.h if present. + +2004-07-30 Tom Yu <tlyu@mit.edu> + + * configure.in: Only sanity-check setutent() API if there is no + utmpx.h, since some setutent() implementations aren't sysV-derived, + e.g., NetBSD. + +2004-07-16 Ken Raeburn <raeburn@mit.edu> + + * pty-int.h: Include port-sockets.h instead of netdb.h and + netinet/in.h. + +2004-06-16 Ken Raeburn <raeburn@mit.edu> + + * Makefile.in (clean-mac): Target deleted. + +2004-06-11 Ken Raeburn <raeburn@mit.edu> + + * pty-int.h (_AIX && _THREAD_SAFE): Undefine _THREAD_SAFE. + +2004-06-04 Ken Raeburn <raeburn@mit.edu> + + * Makefile.in (LIBBASE): Renamed from LIB. + +2004-04-12 Ezra Peisach <epeisach@mit.edu> + + * configure.in: Remove tests for strsave, sys_errlist, + krb5_sigtype, setjmp, dirent, F_SETOWN. These are left over from + the split from appl/bsd. + +2004-02-18 Ken Raeburn <raeburn@mit.edu> + + * cleanup.c, init.c, init_slave.c, vhangup.c: Use ANSI style + function definitions. + +2003-03-03 Tom Yu <tlyu@mit.edu> + + * configure.in: Delete unused ADD_DEF, probably left over from + appl/bsd. + +2003-01-10 Ken Raeburn <raeburn@mit.edu> + + * configure.in: Don't explicitly invoke AC_PROG_INSTALL, + AC_PROG_ARCHIVE, AC_PROG_RANLIB. + + * Makefile.in: Add AC_SUBST_FILE marker for lib_frag and libobj_frag. + +2002-12-06 Ezra Peisach <epeisach@bu.edu> + + * configure.in: Quote the argument to AC_CHECK_HEADER. Autoconf + 2.57 was having problems. + +2002-08-29 Ken Raeburn <raeburn@mit.edu> + + * Makefile.in: Revert $(S)=>/ change, for Windows support. + + * pty_err.et: Add final "end" statement. + +2002-08-23 Ken Raeburn <raeburn@mit.edu> + + * Makefile.in: Change $(S)=>/ and $(U)=>.. globally. + +2002-07-12 Ken Raeburn <raeburn@mit.edu> + + * Makefile.in (install): Don't install libpty.h. + * configure.in: Always build static library only. + +2002-06-12 Ken Raeburn <raeburn@mit.edu> + + * cleanup.c, getpty.c, init.c, init_slave.c, logwtmp.c, + open_ctty.c, open_slave.c, pty_paranoia.c, sane_hostname.c, + update_utmp.c, update_wtmp.c, vhangup.c, void_assoc.c: Include + "com_err.h" instead of <com_err.h>. + + * pty-int.h: Don't include syslog.h. + +2002-05-24 Ken Raeburn <raeburn@mit.edu> + + * sane_hostname.c (pty_make_sane_hostname): Always initialize + "ai". + +2002-03-26 Ken Raeburn <raeburn@mit.edu> + + * sane_hostname.c: Include fake-addrinfo.h, not fake-addrinfo.c. + (FAI_PREFIX): Delete. + +2002-02-19 Ken Raeburn <raeburn@mit.edu> + + * Makefile.in (LIBMINOR): Bump due to change in internals. (Tom's + change from 1.2.x branch.) + +2001-12-03 Sam Hartman <hartmans@mit.edu> + + * README: s-pty_init_ets/pty_init/ + +2001-11-28 Tom Yu <tlyu@mit.edu> + + * update_utmp.c (PTY_GETUTXENT): Fix typo. Thanks to Shawn + Stepper. [fixes krb5-build/1020] + +2001-11-19 Tom Yu <tlyu@mit.edu> + + * update_utmp.c (pty_update_utmp): Patch from Garry Zacheiss to + kludge around cases where we need to use more than 2 characters of + LINE in order to avoid conflicts in UT_ID. + +2001-10-18 Ezra Peisach <epeisach@mit.edu> + + * sane_hostname.c (pty_make_sane_hostname): Do not declare addrbuf + twice, shadowing the first declaration. + + +2001-10-02 Ezra Peisach <epeisach@mit.edu> + + * Makefile.in (includes): Depend on + $(BUILDTOP)/include/krb5/autoconf.h. Automatic dependencies do not + work on systems in which shared libraries are build without static + ones. + +2001-09-11 Tom Yu <tlyu@mit.edu> + + * configure.in: Cosmetic fix in utmpx.ut_exit check. + +Wed Sep 5 20:08:21 2001 Ezra Peisach <epeisach@mit.edu> + + * Makefile.in ($(BUILDTOP)/include/krb5/autoconf.h): Add rules to + build include/krb5/autoconf.h - this file is wiped out during a + make clean and sane_hostname.c depends on it. + +2001-08-29 Ken Raeburn <raeburn@mit.edu> + + * sane_hostname.c: Include socket-utils.h and fake-addrinfo.c. + (FAI_PREFIX): Define to krb5int_pty. + (sockaddrlen, do_ntoa): Deleted. + (pty_make_sane_hostname): Use socklen instead of sockaddrlen. + Delete support for not having getnameinfo. Move code for do_ntoa + inline. + +2001-07-02 Tom Yu <tlyu@mit.edu> + + * update_utmp.c (pty_update_utmp): Remember to chop off leading + "/dev/" for the non-sysV case. Handle lseek() returning non-zero + yet non-negative values (it usually does... :-), so that we can + actually write somewhere not at the beginning of the utmp file if + necessary. + +2001-06-28 Ken Raeburn <raeburn@mit.edu> + + * update_utmp.c (pty_update_utmp): Don't copy host if it's a null + pointer. + + * dump-utmp.c (print_ut): Use size of ut_name field, not ut_user, + which may not exist, for width when printing ut_name field value. + Specify width when printing hostname, it may be unterminated. + (main): Move utp and utxp declarations closer to their usages, and + make both conditionalized so they're not declared if they're not + used. + +2001-06-21 Ezra Peisach <epeisach@mit.edu> + + * libpty.h: Change variable line in prototype to tty_line to + prevent shadowing. + +2001-06-11 Ezra Peisach <epeisach@mit.edu> + + * pty-int.h: Provide revoke() prototype if system headers lacking. + + * logwtmp.c: Provide logwtmp() prototype if needed. + + * configure.in: Check for system provided getutmp(), logwtmp() and + revoke() prototypes. Check for util.h, libutil.h. + + * update_wtmp.c: Provide prototype for getutmp() if needed. + +2001-05-15 Tom Yu <tlyu@mit.edu> + + * getpty.c: Make pty_getpty() into ptyint_getpty_ext(), which has + an extra argument that determines whether to call grantpt() and + unlockpt() on systems that support it. The new pty_getpty() will + simply call the extended version. This is to support some + wackiness needed by pty_paranoia.c tests. + + * pty-int.h: Add prototype for ptyint_getpty_ext(). + + * pty_paranoia.c: Add rant about ptys and quirks therein. Needs + to be updated somewhat. Add some more paranoia for the case where + we actually succeed in opening the slave of a closed master and + then succeed in opening the same master. This program will get + rewritten at some point to actually see what things result in EOFs + and under what conditions data will actually get passed between + master and slave. + +2001-05-10 Tom Yu <tlyu@mit.edu> + + * pty_paranoia.c: New file; do many paranoid checks about ctty + handling by the pty drivers. + + * Makefile.in: Add rules for pty_paranoia and check-paranoia, + which runs pty_paranoia. + + * configure.in: Define REVOKE_NEEDS_OPEN for Tru64. Add support + for program building and run flags for the sake of pty_paranoia. + + * open_slave.c: Fix somewhat; AIX doesn't like opening the ctty + twice, so only do initial open if we special-case it in + configure.in, e.g. for Tru64. + +2001-05-08 Tom Yu <tlyu@mit.edu> + + * logwtmp.c: Delete code under "#if 0". Fix reversed test for + loggingin. Don't forget to set the ut_tv or ut_time for the + entry. + + * update_utmp.c: Update rant about Tru64; remove fetching of + ut_user from old entry. The existence of the old ut_user in the + logout entry in wtmp was confusing last. + + * cleanup.c: Call update_utmp() with the correct pid to assist in + finding the old utmp entry. + + * open_ctty.c: Reformat somewhat and revise comment. + + * open_slave.c: Rework significantly. Primarily, keep a fd open + to the slave if we need to reopen the slave device following + vhangup() or revoke(), to accommodate various OS quirks. + + * update_utmp.c: Revise history section somewhat to document more + HP-UX brokenness. Search via ut_pid before searching via + ut_line. Copy stuff around because entuxent() will clobber some + things. + + * void_assoc.c: Revise comment and reformat somewhat. + +2001-05-04 Ezra Peisach <epeisach@mit.edu> + + * open_slave.c (pty_open_slave): If revoke() present on system but + VHANG_FIRST is not defined, declare local variable. + +2001-05-04 Tom Yu <tlyu@mit.edu> + + * dump-utmp.c: Fix some off-by-one errors. Handle cases where we + have utmpname() but not utmpname(). + + * pty-int.h: Fix typo; VHANG_first -> VHANG_FIRST. + + * open_slave.c (pty_open_slave): Add workaround for Tru64 v5.0, + since its revoke() will fail if the slave isn't open already. + +2001-05-03 Ezra Peisach <epeisach@rna.mit.edu> + + * sane_hostname.c (pty_make_sane_hostname): Preserve const + property of incomming parameter in casts. + +2001-05-03 Ezra Peisach <epeisach@mit.edu> + + * cleanup.c (pty_cleanup): Delcare local variable only if + VHANG_LAST defined. + + * logwtmp.c (pty_logwtmp): Only declare local variables if + logwtmp() not available on system. + + * sane_hostname.c (sockaddrlen): Only define static function if + HAVE_GETNAMEINFO defined. (pty_make_sane_hostname) Declare goto + target only if code compiled in. + +2001-05-01 Ken Raeburn <raeburn@mit.edu> + + * update_utmp.c (pty_update_utmp): Fix typo (OWRONLY -> + O_WRONLY). + +2001-05-01 Ezra Peisach <epeisach@mit.edu> + + * update_wtmp.c (ptyint_update_wtmpx): Add missing semi-colon in + code path if PTY_UTMP_E_EXIT and PTY_UTMPX_E_EXIT exist. + +2001-04-30 Tom Yu <tlyu@mit.edu> + + * configure.in: Fix some quoting of shell variables when passing + to "test". Reorder some logic in consistency checks to validate + cache variables against "yes" to account for possible empty or + nonexistent values. + + * pty-int.h: Fix conditional prototype of update_wtmp(). + + * update_wtmp.c: Fix conditional compilation of update_wtmp() to + cover the case where we have setutxent() but don't have updwtmpx() + and WTMPX_FILE, as is the case on some Linux installations. + +2001-04-27 Tom Yu <tlyu@mit.edu> + + * configure.in(K5_CHECK_UT_MEMBER): Fix typo in previous; make + sure to include the correct header when checking structure + members. + + * configure.in: Many changes to support the rewriting of the utmp + pieces of libpty. Do a large amount of checking for consistency + of various utmp and utmpx APIs as currently understood. See rant + in update_utmp.c. + + * dump-utmp.c: Rewrite; now has capability to use utmp{,x}name() + to extract entries from utmp and utmpx files. Adjusts field + widths when printing as appropriate. + + * libpty.h: Update call signature for update_utmp() and logwtmp(); + make prototypes unconditional. + + * logwtmp.c: Rewrite. Use pututline() or pututxline() API + whenever possible. + + * pty-int.h: Update call signatures for update_wtmp{,x}(); make + prototypes unconditional. + + * sane_hostname.c: Use the autoconf-correct macro names. + + * update_utmp.c: Rewrite. Basically, use functions from the + pututline() or pututxline() API whenever possible, to avoid + lossage. Inserted large rant about the conjectured history of BSD + utmp, sysV utmp, and utmpx, as well as documentation about some + known quirks. + + * update_wtmp.c: Rewrite. Add new function ptyint_logwtmpx() that + takes a utmpx rather than a utmp, so it can fail to lose data + converting to and from utmp. + +2001-01-12 Tom Yu <tlyu@mit.edu> + + * sane_hostname.c: Switch off of KRB5_USE_INET6 instead of + AF_INET6, which may be defined without a corresponding struct + sockaddr_in6. + +2000-12-06 Ken Raeburn <raeburn@mit.edu> + + * sane_hostname.c (pty_make_sane_hostname, do_ntoa): Pass address + as const sockaddr pointer. + * libpty.h (pty_make_sane_hostname): Update prototype. + + * sane_hostname.c (sockaddrlen, downcase): New function. + (do_ntoa, pty_make_sane_hostname): Reimplement using getnameinfo + and getaddrinfo if available. + * configure.in: Check for IPv6 support. + +2000-11-01 Ezra Peisach <epeisach@mit.edu> + + * configure.in: Quote macro use inside AC_CHECK_LIB. Change + AC_FUNC_CHECK to AC_CHECK_FUNC, AC_HAVE_FUNCS to AC_CHECK_FUNCS + and AC_HEADER_CHECK to AC_CHECK_HEADER.. + +2000-06-30 Ezra Peisach <epeisach@mit.edu> + + * pty-int.h: Add getutmpx() prototype if needed. + + * configure.in: If getutmpx() exists on the system, test if a + prototype is provided by the system headers. + +2000-06-28 Ezra Peisach <epeisach@mit.edu> + + * getpty.c (pty_getpty): More conditionalizing variable defintion + based on OS features. + + * cleanup.c (pty_cleanup): Add parenthesis about assignment in + conditional (gcc suggestion). + + * pty-int.h: Include pty.h if it exists (for openpty prototype + under Linux). + + * configure.in: Check for pty.h + +2000-06-26 Ezra Peisach <epeisach@mit.edu> + + * libpty.h: If SOCK_DGRAM is not defined, provide a definition for + struct sockaddr_in to satisfy prototype. (based on similar + code in k5-int.h). + + * update_wtmp.c (ptyint_update_wtmp), update_utmp.c + (pty_update_utmp), open_slave.c (pty_open_slave), getpty.c + (pty_getpty): conditionalize definition of variables based on code + paths that are included. + + + +1999-10-26 Tom Yu <tlyu@mit.edu> + + * configure.in: Check for alpha*-dec-osf* instead of + alpha-dec-osf*. + +1999-10-26 Wilfredo Sanchez <tritan@mit.edu> + + * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, + LOCAL_INCLUDES such that one can override CFLAGS from the command + line without losing CPP search patchs and defines. Some associated + Makefile cleanup. + +1999-08-03 Ken Raeburn <raeburn@mit.edu> + + * update_utmp.c (pty_update_utmp): Use "co" instead of "cons" for + console line on Solaris. Patch from Larry Schwimmer + (schwim@whatmore.Stanford.EDU). + + * Makefile.in (dump-utmp): Add a rule for building, never + automatically done. + (dump-utmp.o): Depends on dump-utmp.c. + + Updates from Cygnus KerbNet: + + * dump-utmp.c (ut_typename): Only define if + HAVE_STRUCT_UTMP_UT_TYPE is defined. + (main): Dump more info, and conditionalize it better. + + * dump-utmp.c (ctime): Declare, to prevent crashes on Alpha. + + * dump-utmp.c (UTMPX): Define if not defined but HAVE_UTMPX_H is + defined. + (ut_typename): Return shorter forms for some symbols. + (main): Require `-x' flag for [uw]tmpx file instead of guessing + from the name. Reject unknown `-' arguments. Print a message if + an error occurs while reading from utmpx file. Break up output + statements into smaller pieces. Conditionalize output of some + utmp fields on whether those fields are present. Print out exit + status fields and timestamp. + +Fri Apr 23 23:13:57 1999 Tom Yu <tlyu@mit.edu> + + * update_utmp.c (pty_update_utmp): utx.ut_pid is a pid_t, and + ent.ut_pid is sometimes a short; accordingly, use pid rather than + ent.ut_pid, which might have gotten truncated. This fixes an Irix + problem found by <rbasch@mit.edu>. + +1999-04-14 <tytso@rsts-11.mit.edu> + + * update_wtmp.c: Don't use updwtmpx() even if it exists for glibc + 2.1, since it's the same as updwtmp(), and glibc doesn't + define PATH_WTMPX. updwtmpx() is not part of the XPG + standard anyway. (Needed for RedHat 6.0.) + +Sun Mar 28 17:50:57 1999 Tom Yu <tlyu@mit.edu> + + * update_wtmp.c: Define WTMPX_FILE to be _PATH_WTMPX in case we're + on a system that cleans up the namespace that way. + +Wed Feb 17 19:47:36 1999 Tom Yu <tlyu@mit.edu> + + * sane_hostname.c (pty_make_sane_hostname): Remove unused + "char *scratch". + +Tue Feb 16 20:18:40 1999 Tom Yu <tlyu@mit.edu> + + * sane_hostname.c: Re-order so that pty-int.h precedes libpty.h to + prevent conflicting definitions of struct sockaddr_in + +Thu Feb 11 22:24:03 1999 Tom Yu <tlyu@mit.edu> + + * sane_hostname.c: Force maxlen to be 16 if it's less than 16, + since otherwise a numeric IP address won't fit. + + * Makefile.in: Add sane_hostname.{o,c}; bump minor version. + + * libpty.h: Add prototype for make_sane_hostname. + + * sane_hostname.c: New file; add function to "sanitize" hostname + for logging purposes. + +1999-01-27 Theodore Ts'o <tytso@rsts-11.mit.edu> + + * configure.in: Remove test CHECK_WAIT_TYPE since nothing is using + the results of that test (WAIT_USES_INT). + +1998-08-16 <hartmans@fundsxpress.com> + + * Makefile.in (SHLIB_EXPDEPS): Depend on lib_comerr + +1998-07-05 <hartmans@fundsxpress.com> + + * update_utmp.c (pty_update_utmp): If the ut_exit differs test + indicates the structures differ, and we don't have a special case, + do nothing rather than trying to copy the field. It's not worth + breaking the build over. + +Mon Apr 6 19:35:33 1998 Tom Yu <tlyu@voltage-multiplier.mit.edu> + + * update_utmp.c (pty_update_utmp): Don't record LOGIN_PROCESS + entries, as they confuse last on some systems. [pty/569] + +Thu Mar 12 18:09:25 1998 Tom Yu <tlyu@mit.edu> + + * update_utmp.c (pty_update_utmp): Fix bogus entry of + PTY_LOGIN_PROCESS types on BSD-ish systems. [pty/531] + +Wed Feb 18 16:33:58 1998 Tom Yu <tlyu@mit.edu> + + * Makefile.in: Remove trailing slash from thisconfigdir. Fix up + BUILDTOP for new conventions. + +Mon Feb 2 16:18:08 1998 Theodore Ts'o <tytso@rsts-11.mit.edu> + + * Makefile.in: Define BUILDTOP and thisconfigdir in the Makefile + + * configure.in, Makefile.in: Remove CopySrcHeader and CopyHeader + from configure.in and move equivalent functionality to + Makefile.in + +Sun Dec 7 00:05:28 1997 Tom Yu <tlyu@mit.edu> + + * getpty.c (pty_getpty): Fix goof in previous, which introduced + another fencepost error. + +Thu Dec 4 21:48:12 1997 Tom Yu <tlyu@mit.edu> + + * getpty.c (pty_getpty): Fix checks on string lengths to account + for terminating nul character. Some whitespace fixups. + +Wed Dec 3 17:16:44 1997 Tom Yu <tlyu@mit.edu> + + * pty_err.et: Add PTY_OPEN_SLAVE_TOOSHORT error code. + + * open_slave.c (pty_open_slave): Check to ensure that the slave + name is not NULL or zero-length. + +Tue Oct 28 13:28:54 1997 Ezra Peisach <epeisach@.mit.edu> + + * pty-int.h: Do not prototype initialize_pty_error_table as + pty-err.h does as well. + +Fri Oct 24 09:12:43 1997 Ezra Peisach <epeisach@mit.edu> + + * Makefile.in (CFILES): Add $(srcdir). + +Wed Oct 1 04:53:30 1997 Tom Yu <tlyu@mit.edu> + + * configure.in: Default to a long rather than an int for a time_t + for paranoia reasons. + +Tue Jun 3 23:05:07 1997 Theodore Y. Ts'o <tytso@mit.edu> + + * getpty.c (pty_getpty): Remove erroneous space from the HPUX open(). + +Fri Apr 25 19:14:48 1997 Theodore Y. Ts'o <tytso@mit.edu> + + * configure.in: Check for openpty() in -lutil. It's there on + FreeBSD and BSDI systems. + +Fri Feb 21 18:25:47 1997 Sam Hartman <hartmans@tertius.mit.edu> + + * pty-int.h: No longer prototype error table init function. + +Thu Jan 16 18:47:12 1997 Tom Yu <tlyu@mit.edu> + + * Makefile.in: Cause "clean" to dtrt. + + * configure.in: Punt spurious call to KRB5_LIB_PARAMS. + +Sun Dec 29 21:32:41 1996 Tom Yu <tlyu@mit.edu> + + * Makefile.in: Update to set STLIBOBJS instead of LIBSRCS; also + clean up a little bit. + +Fri Dec 27 17:09:46 1996 Tom Yu <tlyu@mit.edu> + + * Makefile.in: Fix to use OBJS.ST rather than ./OBJS.ST. + + * Makefile.in: + * configure.in: Changes to use new library build system. + +Thu Dec 5 22:43:35 1996 Theodore Y. Ts'o <tytso@mit.edu> + + * update_utmp.c (pty_update_utmp): Apply platform specific patch + so that HPUX works. (Kludge for 1.0 release) [PR#40] + +Fri Nov 22 11:52:52 1996 Sam Hartman <hartmans@mit.edu> + + * configure.in : Make sure time_t is define [203] + * update_wtmp.c (ptyint_update_wtmp): Use time_t for call to time(2). [203] + +Fri Nov 15 08:33:54 1996 Ezra Peisach <epeisach@mit.edu> + + * update_utmp.c (pty_update_utmp): Handle case where utmp uses + ut_exit.e_exit and utmpx uses ut_exit.ut_exit. + + * configure.in (UT_EXIT_STRUCTURE_DIFFER): If utmpx.h exists, and + getutmpx does not exist then test if the ut_exit part of + the utmp/utmpx structure is a structure and if their types + differ. (e_exit vs. ut_exit). + +Fri Nov 8 17:45:42 1996 Theodore Y. Ts'o <tytso@mit.edu> + + * update_utmp.c (pty_update_utmp): Add code which attempts to + compensate for systems that don't have getutmpx() + + * configure.in: Check for getutmpx(). Replace calls to + AC_FUNC_CHECK with AC_HAVE_FUNCS(). + +Thu Jun 13 22:14:24 1996 Tom Yu <tlyu@voltage-multiplier.mit.edu> + + * configure.in: remove ref to ET_RULES + + +Thu Jun 13 14:12:16 1996 Sam Hartman <hartmans@mit.edu> + + * update_wtmp.c (ptyint_update_wtmp): Only update wtmpx if we have + updwtmpx. This probably should be more general, but I'm not + really sure of HP caviats. + + * configure.in : check for updwtmpx + + * getpty.c (pty_getpty): Actually check for 256 ptys on SunOS and + other old-style systems. +Tue Apr 16 22:06:36 1996 Ken Raeburn <raeburn@cygnus.com> + + * dump-utmp.c: New file. Not automatically used by anything, but + may be useful for examining utmp/wtmp files when comparing + behavior against system software. + + Sun Mar 31 02:04:28 1996 Ken Raeburn <raeburn@cygnus.com> + + * update_utmp.c (pty_update_utmp): Always use id "cons" for + console. For HP-UX, omit "kl" prefix. Reindent for readability. + * update_wtmp.c (ptyint_update_wtmp): For HP-UX, copy ut_id and + ut_type from input utmp structure. Reindent for readability. + + Wed Mar 27 21:14:33 1996 Marc Horowitz <marc@mit.edu> + + * init_slave.c (pty_initialize_slave): Spurious signal stuff + which did nothing deleted. + +Tue Apr 16 13:43:43 1996 Sam Hartman <hartmans@mit.edu> + + * configure.in : Don't use streams on HPUX. + + * getpty.c (pty_getpty): Check /dev/ptym/clone for HPUX10, only + try /dev/ptmx if HAVE_STREAMS defined so we can bipass for HPUX9. + +Sun Apr 14 00:36:33 1996 Sam Hartman <hartmans@mit.edu> + + * pty-int.h: Don't include sys/wait.h here. + + * configure.in : Check for waitpid. + +Sat Apr 13 18:58:43 1996 Sam Hartman <hartmans@mit.edu> + + * cleanup.c (pty_cleanup): If we are doing a vhangup, then fork + and dissociate on hangup. This makes the HP happy, because there + is no way to get rid of a controlling terminal besides setsid() on + the HP. + +Sun Mar 24 19:59:14 1996 Sam Hartman <hartmans@tertius.mit.edu> + + * configure.in : Do streams handling by deciding what modules to + push for each system. + + * init_slave.c (pty_initialize_slave): Better abstraction for + dealing with what modules get pushed on what streams system. + There is a list of modules controlled on a module-by-module basis + by configure.in, and the modules included in that list are pushed. + + * void_assoc.c: Duplicate comment from open_ctty.c explaining that + it's OK to call void_association twice, and giving the caviats + about setsid. + + * open_ctty.c (pty_open_ctty): Remove test to make sure /dev/tty + worked, so we can push the streams for the HP. + + * open_slave.c (pty_open_slave): Test to see if /dev/tty works + only after calling pty_initialize_slave. + +Sat Mar 23 15:24:38 1996 Sam Hartman <hartmans@tertius.mit.edu> + + * configure.in : Remove shadow passwords check because nothing in + libpty cares about the result; remove use of libkrb5, libkrb4, + libkadm; Check for _getpty + + * getpty.c (pty_getpty): Support _getpty for Irix; Irix has + /dev/ptmx, but it doesn't work correctly at all. Also, Irix, + tends to create device nodes on the fly. + + * pty-int.h: No need to include sys/socket.h + +Sat Feb 24 21:34:58 1996 Theodore Y. Ts'o <tytso@dcl> + + * vhangup.c (ptyint_vhangup): Don't do call vhangup() if system + doesn't have it. + +Sat Jan 27 01:13:34 1996 Mark Eichin <eichin@cygnus.com> + + * void_assoc.c (ptyint_void_association): if we don't have + TIOCNOTTY (HP/UX 9 for example) don't try to use it. + +Fri Jan 26 00:26:37 1996 Sam Hartman <hartmans@tertius.mit.edu> + + * cleanup.c (pty_cleanup): Update utmp only if update_utmp is true. + +Tue Jan 16 13:52:22 1996 Sam Hartman <hartmans@tertius.mit.edu> + + * 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 <hartmans@tertius.mit.edu> + + * update_utmp.c (pty_update_utmp): Add flags field; use ttyslot + only if reasonable. + +Fri Jan 12 16:33:37 1996 Sam Hartman <hartmans@infocalypse> + + * open_slave.c (pty_open_slave): Don't use fchmod or fchown; they + don't buy much security unless /dev is world-writable and may + prevent Solaris lossage. + +Thu Dec 21 00:12:58 1995 Sam Hartman <hartmans@portnoy> + + * open_slave.c (pty_open_slave): Open with no delay. + + +Wed Jan 10 22:20:04 1996 Theodore Y. Ts'o <tytso@dcl> + + * open_slave.c (pty_open_slave): Added hack by Doug Engert to get + util/pty to work under Solaris. We should double check to + make sure this is a correct fix. + + +Sun Nov 12 12:44:33 1995 Sam Hartman <hartmans@tertius.mit.edu> + + * open_ctty.c (pty_open_ctty): Remove redundant Ultrix calls to setpgrp() + +Sun Oct 22 03:48:37 1995 Sam Hartman <hartmans@tertius.mit.edu> + + * update_wtmp.c (ptyint_update_wtmp): Add comments explaining why ifdefs are right. + +Sun Oct 22 01:20:52 1995 Sam Hartman <hartmans@infocalypse> + + * update_wtmp.c (ptyint_update_wtmp): Try utx not uts. + +Mon Oct 16 17:41:45 1995 Sam Hartman <hartmans@tertius.mit.edu> + + + + * update_wtmp.c (ptyint_update_wtmp): Update to take host name, so + we can get the full host name if it is chopped in utmp. + * update_wtmp.c (ptyint_update_wtmp): Insert fallback path for Sunos and others, return defined value. + + + + + * update_utmp.c (pty_update_utmp): Incorperate utmpx handling patch from ramus@nersc.gov to deal with support for longer hostanmes in utmpx. + + +*update_utmp.c: Add return statement and fallback path for Sunos. + +Sat Oct 14 20:49:40 1995 Sam Hartman <hartmans@tertius.mit.edu> +Fri Aug 11 17:49:36 1995 Samuel D Hartman (hartmans@vorlon) + + +Fri Sep 29 14:18:03 1995 Theodore Y. Ts'o <tytso@dcl> + * update_wtmp.c (ptyint_update_wtmp): If EMPTY not defined as a + utmp type, use DEAD_PROCESS. + + + + * configure.in: + * Makefile.in: Use the SubdirLibraryRule defined in aclocal.m4 to + create the DONE file (and to properly clean it up). + +Mon Sep 25 16:42:36 1995 Theodore Y. Ts'o <tytso@dcl> + + * Makefile.in: Removed "foo:: foo-$(WHAT)" lines from the + Makefile. + +Thu Sep 7 19:13:05 1995 Mark Eichin <eichin@cygnus.com> + + * update_utmp.c: ultimately fall back to /etc/utmp for UTMP_FILE, + if it is still missing after all previous efforts. + * update_wtmp.c: /usr/adm/wtmp for WTMP_FILE likewise. + +Thu Aug 24 18:40:48 1995 Theodore Y. Ts'o <tytso@dcl> + + * .Sanitize: Update file list + +Tue Aug 15 21:42:16 1995 <tytso@rsts-11.mit.edu> + + * update_wtmp.c (ptyint_update_wtmp): If EMPTY is not defined, + then set ut.ut_type to 0 instead. + + + +Fri Aug 11 15:49:30 1995 Sam Hartman <hartmans@tertius.mit.edu> + + * Makefile.in (CFILES): Rename initialize_slave.c to init_slave.c + so it isn't truncated in libpty.a. + +Fri Aug 11 01:12:03 1995 Sam Hartman <hartmans@infocalypse> + + * initialize_slave.c (pty_initialize_slave): You really do need to + push and pop the streams on a Sun. + +Fri Aug 11 00:49:23 1995 Sam Hartman <hartmans@dragons-lair.MIT.EDU> + + * configure.in (ac_cv_func_setsid): Pretend that Ultrix doesn't + have setsid, because if it does make the call then the pty never + becomes controlling tty. + +Thu Aug 10 09:47:07 1995 Sam Hartman <hartmans@dragons-lair.MIT.EDU> + + * open_ctty.c (pty_open_ctty): Move setpgrp() after void_assoc call + +Wed Aug 9 00:16:40 1995 Sam Hartman <hartmans@tertius.mit.edu> + + * pty-int.h (VHANG_first): Change defines so VHANG_FIRST doesn't + get defined under Ultrix because Ultrix can only establish + controlling terminal once per process and we need to get + controlling terminal again after vhangup(). + + * getpty.c (pty_getpty): Use the right test for slave buffer length. + +Tue Aug 8 22:20:33 1995 Tom Yu <tlyu@lothlorien.MIT.EDU> + + * update_utmp.c (UTMP_FILE): _PATH_UTMP under NetBSD, not + _UTMP_PATH; also fix typo (missing '&' on reference to + ent) + +Tue Aug 8 20:47:01 1995 Tom Yu <tlyu@dragons-lair.MIT.EDU> + + * update_utmp.c (pty_update_utmp): change #ifdef NO_UT_PID to + #ifndef + +Tue Aug 8 09:13:50 1995 Sam Hartman <hartmans@pao.mit.edu> + + * open_slave.c (pty_open_slave): Dissociate from controlling + terminal before calling revoke. + (pty_open_slave): Don't ask for a controlling terminal unless we need it. + +Tue Aug 8 20:32:08 1995 Tom Yu <tlyu@dragons-lair.MIT.EDU> + + * update_utmp.c: flush preprocessor directive to left margin. + * pty_err.et: Fix typo in error description. + + * cleanup.c (pty_cleanup): Don't change slave before revoking it. Also return a value all the time, not just on systems without revoke. + + + * update_utmp.c (pty_update_utmp): Move #ifdef back to column 1. + +Mon Aug 7 17:41:39 1995 Sam Hartman <hartmans@tertius.mit.edu> + + * cleanup.c (pty_cleanup): Call pty_update_utmp using new interface. + + * update_utmp.c logwtmp.c : Call ptyint_update_wtmp not pty_update_wtmp. + + * cleanup.c (pty_cleanup): We can't use pid_t because we need to + use something in libpty.h and we can't wait for pid_t to be + defined there because we may not have configure. + + * update_wtmp.c (pty_update_wtmp): Rename to ptyint_update_wtmp. + + * update_utmp.c (pty_update_utmp): Change interface so it doesn't take a struct utmp. + + * libpty.h: Remove pty_update_wtmp as it's becoming an internal interface. + +Sat Aug 5 01:00:35 1995 Ezra Peisach <epeisach@kangaroo.mit.edu> + + * open_slave.c (pty_open_slave): pty_open_ctty returns != 0 on + error, not less than. + +Fri Aug 4 13:59:11 1995 Theodore Y. Ts'o <tytso@dcl> + + * libpty.h (pty_cleanup): Fix argument type of pid to patch that + used in the C file. Include <utmpx.h> if present. Only + include <utmp.h> if it is present. + + * configure.in: Check for utmp.h and utmpx.h + +Fri Aug 4 00:59:20 1995 Tom Yu <tlyu@dragons-lair.MIT.EDU> + + * Makefile.in: use libupdate so to not get multiple copies of + object files upon rebuild. + + * vhangup.c (ptyint_vhangup): Make sure preprocessor directives + are at left margin. + + * open_slave.c (pty_open_slave): Make sure preprocessor directives + are at left margin. + + * open_ctty.c (pty_open_ctty): Make sure preprocessor directives + are at left margin. + + * cleanup.c (pty_cleanup): Add missing declarations for retval and + fd. Also, align preprocessor directives with left margin. + +Thu Aug 3 15:04:34 1995 Sam Hartman <hartmans@tertius.mit.edu> + + * configure.in: Check for vhangup and killpg. + + * cleanup.c (pty_cleanup): Kill the process group associated with + the pty if using revoke. This won't always work, but will at + least attempt to remove processes associated with the pty. + +Wed Aug 2 11:59:19 1995 Sam Hartman <hartmans@tertius.mit.edu> + + * init.c (pty_init): New file to handle initialization--currently only error tables. + + * getpty.c (pty_getpty): Reverse sense of logic tests so they work. + +Tue Aug 1 08:20:06 1995 Sam Hartman <hartmans@tertius.mit.edu> + + * cleanup.c (pty_cleanup): Allow pid to be zero (unknown). + + * pty-int.h: Define VHANG_FIRST and VHANG_LAST based on presence + of vhangup. + + * pty_err.et: Define PTY_GETPTY_SLAVE_TOOLONG + + * getpty.c (pty_getpty): Close slave side if we call openpty. + + (pty_getpty): Take length parameter; return error if it isn't big enough. + + + +Tue Aug 1 12:06:14 1995 Ezra Peisach <epeisach@kangaroo.mit.edu> + + * open_ctty.c (pty_open_ctty): Fixed typo TIOCSTTY to TIOCSCTTY. + + diff --git a/src/appl/libpty/Makefile.in b/src/appl/libpty/Makefile.in new file mode 100644 index 0000000000..3c3ca3828d --- /dev/null +++ b/src/appl/libpty/Makefile.in @@ -0,0 +1,157 @@ +thisconfigdir=. +myfulldir=appl/libpty +mydir=. +BUILDTOP=$(REL)..$(S).. +RELDIR=../appl/libpty + +SED = sed + +KRB5_RUN_ENV= @KRB5_RUN_ENV@ +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +LIBBASE=pty +LIBMAJOR=1 +LIBMINOR=2 + +STLIBOBJS= cleanup.o getpty.o init_slave.o open_ctty.o open_slave.o \ + update_utmp.o update_wtmp.o vhangup.o void_assoc.o pty_err.o \ + logwtmp.o init.o sane_hostname.o + +STOBJLISTS=OBJS.ST + +INSTALLFILE = cp + +# for pty-int.h +LOCALINCLUDES=-I. -I$(srcdir) + +FILES= Makefile cleanup.c getpty.c init_slave.c open_ctty.c open_slave.c update_utmp.c update_wtmp.c vhangup.c void_assoc.c pty_err.h pty_err.c\ +logwtmp.c init.c + +CFILES=$(srcdir)/cleanup.c $(srcdir)/getpty.c $(srcdir)/init_slave.c \ + $(srcdir)/open_ctty.c $(srcdir)/open_slave.c \ + $(srcdir)/update_utmp.c $(srcdir)/update_wtmp.c $(srcdir)/vhangup.c \ + $(srcdir)/void_assoc.c $(srcdir)/logwtmp.c \ + $(srcdir)/init.c $(srcdir)/sane_hostname.c + + +SRCS=pty_err.c $(CFILES) +SHLIB_EXPDEPS = \ + $(COM_ERR_DEPLIB) +SHLIB_EXPLIBS= -lcom_err +SHLIB_DIRS=-L$(TOPLIBD) +SHLIB_RDIRS=$(KRB5_LIBDIR) + +DEPLIBS= + +# +all-unix:: includes pty_err.h + +all-unix:: all-liblinks + +dump-utmp: dump-utmp.o + $(CC) $(LDFLAGS) -o dump-utmp dump-utmp.o +dump-utmp.o: dump-utmp.c + +pty_paranoia: pty_paranoia.o $(COM_ERR_DEPLIB) $(PTY_DEPLIB) + $(CC_LINK) -o pty_paranoia pty_paranoia.o $(PTY_LIB) $(COM_ERR_LIB) $(LIBS) + +check-paranoia: pty_paranoia + $(KRB5_RUN_ENV) ./pty_paranoia + +install-unix:: install-libs + +clean-unix:: + $(RM) libpty.a $(BUILDTOP)/include/libpty.h pty_err.c pty_err.h +clean-unix:: clean-liblinks clean-libs clean-libobjs + +depend:: pty_err.h + +#install:: libpty.h +# $(INSTALL_DATA) $(srcdir)/libpty.h $(DESTDIR)$(KRB5_INCDIR)/libpty.h + +includes:: libpty.h + if cmp $(srcdir)/libpty.h \ + $(BUILDTOP)/include/libpty.h >/dev/null 2>&1; then :; \ + else \ + (set -x; $(RM) $(BUILDTOP)/include/libpty.h; \ + $(CP) $(srcdir)/libpty.h \ + $(BUILDTOP)/include/libpty.h) ; \ + fi + +includes:: $(BUILDTOP)/include/autoconf.h + +clean-unix:: + $(RM) $(BUILDTOP)/include/libpty.h + + + +clean-unix:: clean-liblinks clean-libs clean-libobjs clean-files + +clean-files:: + rm -f *~ \#* *.bak \ + *.otl *.aux *.toc *.PS *.dvi *.x9700 *.ps \ + *.cp *.fn *.ky *.log *.pg *.tp *.vr \ + *.o profiled/?*.o libcom_err.a libcom_err_p.a \ + com_err.o compile_et \ + et.ar TAGS y.tab.c lex.yy.c error_table.c \ + et_lex.lex.c \ + test1.h test1.c test2.h test2.c test_et \ + eddep makedep *.ln + +pty_err.o: pty_err.c +pty_err.h: pty_err.et +pty_err.c: pty_err.et + +$(BUILDTOP)/include/autoconf.h: $(SRCTOP)/include/autoconf.h.in + (cd $(BUILDTOP)/include; $(MAKE) autoconf.h) + + +# @lib_frag@ +# @libobj_frag@ + +# +++ Dependency line eater +++ +# +# Makefile dependencies follow. This must be the last section in +# the Makefile.in file +# +pty_err.so pty_err.po $(OUTPRE)pty_err.$(OBJEXT): $(COM_ERR_DEPS) \ + pty_err.c +cleanup.so cleanup.po $(OUTPRE)cleanup.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h cleanup.c \ + libpty.h pty-int.h pty_err.h +getpty.so getpty.po $(OUTPRE)getpty.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h getpty.c \ + libpty.h pty-int.h pty_err.h +init_slave.so init_slave.po $(OUTPRE)init_slave.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \ + init_slave.c libpty.h pty-int.h pty_err.h +open_ctty.so open_ctty.po $(OUTPRE)open_ctty.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \ + libpty.h open_ctty.c pty-int.h pty_err.h +open_slave.so open_slave.po $(OUTPRE)open_slave.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \ + libpty.h open_slave.c pty-int.h pty_err.h +update_utmp.so update_utmp.po $(OUTPRE)update_utmp.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \ + libpty.h pty-int.h pty_err.h update_utmp.c +update_wtmp.so update_wtmp.po $(OUTPRE)update_wtmp.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \ + libpty.h pty-int.h pty_err.h update_wtmp.c +vhangup.so vhangup.po $(OUTPRE)vhangup.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h libpty.h \ + pty-int.h pty_err.h vhangup.c +void_assoc.so void_assoc.po $(OUTPRE)void_assoc.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \ + libpty.h pty-int.h pty_err.h void_assoc.c +logwtmp.so logwtmp.po $(OUTPRE)logwtmp.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h libpty.h \ + logwtmp.c pty-int.h pty_err.h +init.so init.po $(OUTPRE)init.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \ + $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h init.c \ + libpty.h pty-int.h pty_err.h +sane_hostname.so sane_hostname.po $(OUTPRE)sane_hostname.$(OBJEXT): \ + $(BUILDTOP)/include/autoconf.h $(COM_ERR_DEPS) $(SRCTOP)/include/fake-addrinfo.h \ + $(SRCTOP)/include/k5-platform.h $(SRCTOP)/include/k5-thread.h \ + $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h \ + libpty.h pty-int.h pty_err.h sane_hostname.c diff --git a/src/appl/libpty/README b/src/appl/libpty/README new file mode 100644 index 0000000000..f10dd2b371 --- /dev/null +++ b/src/appl/libpty/README @@ -0,0 +1,108 @@ + This file is to serve as documentation and usage notes on +libpty until +more formal docs are written. By that point, it will probably +describe how pty can be broken out of the Kerberos distribution. + +void pty_init(void); + + Initialize error tables. + + +long pty_getpty ( int *fd, char *slave, int slavelength); + Find and initialize a clean master pty. This should open the +pty as fd, and return the name of the slave. It should return 0 or an +error code. The slavelength parameter should include the maximum +length allocated for a slave name. The slave may not be initialized, although any + +operating-system specific initialization (for example, unlockpt and +grantpt) may be performed. + +long pty_open_slave (/*in */ char * slave, /* out*/ int *fd) + + Initialize the slave side by dissociating the current terminal +and by setting process groups, etc. In addition, it will initialize +the terminal flags (termios or old BSD) appropriately; the application +may have to do additional customization, but this should sanitize +things. In addition, the pty will be opened securely, and will become +the controlling terminal. This procedure will fail unless the process +is running as root. Ideally, pty_open_slave will be called in a child +process of the process that called pty_getpty. If an operating system +implements setsid() per the POSIX spec, but does not implement +TIOCNOTTY, this procedure will not be able to insure that the +controlling terminal is established if it is called in the parent +process. Unfortunately, the parent process must not write to the pty +until the slave side is opened. Also, the parent process should not +open the slave side through other means unless it is prepared to have +that file descriptor subjected to a vhangup() or revoke() when +pty_open_slave is called in the child. So, ideally, the parent calls +pty_getpty, forks, waits for the slave to call pty_open_slave, then +continues. Since this synchronization may be difficult to build in to +existing programs, pty_open_slave makes an effort to function if +called in the parent under operating systems where this is possible. +Currently, I haven't found any operating systems where this isn't +possible. Also note that pty_open_slave will succeed only once per process. + +long pty_open_ctty(int *fd, char *line) + + Attempt to disassociate the current process from its controlling terminal and open line as a new controlling terminal. No assumption about line being the slave side of a pty is made. + +long pty_initialize_slave (int fd) + + Perform the non-security related initializations on the slave +side of a pty. For example, push the appropriate streams, set termios +structures, etc. This is included in pty_open_slave. I am interested +in any suggestions on how to pass information on the state to which +the application wants the terminal initialized. For example, rlogind +wants a transparent channel, while other programs likely want cooked +mode. I can't take a termios structure because I may be on a +non-termios system. Currently, I push the streams, do a bit of +cleanup, but don't really modify the terminal that much. Another +possible goal for this function would be to do enough initialization +that the slave side of the pty can be treated simply as a tty instead +of a pty after this call. + + +long pty_update_utmp ( int process_type, int pid, char *user, char +*line, char *host, int flags) + + Update the utmp information or return an error.The +process_type is one of the magic types defined in libpty.h. The flags +are logical combinations of one of the following: + + PTY_TTYSLOT_USABLE: The tty pointed to by the line + parameter is the first tty that would be found by + searching stdin then stdout. In other words, + ttyslot() would return the right slot in utmp on + systems where ttyslot() is cannonically used. Note + that for inserting utmp entries for new logins, it + is not always possible to find the right place if + this flag is not given. Thus, for programs like + telnetd that set up utmp entries, it is important to + be able to set this flag on the initial utmp update. + It is expected that this flag may be cleared on + update_utmp calls to remove utmp entries. + + PTY_UTMP_USERNAME_VALID: the username field in the + utmp entry associated with this line contains the + user who (is/was) associated with the line. + Regardless of this flag, the utmp file will contain + the username specified after this call. However, if + a username is needed by the system for wtmp logout + (Solaris 2.1 for example), then the system can fetch + the user from the utmp record before doing the wtmp + update. This will only be attempted if the username + is a null pointer. + +long pty_cleanup(char *slave, pid_t pid, int update_wtmp) + + Clean up after the slave application has exited. Close down +the pty, HUPing processes associated with it. (pid is the pid of the +slave process that may have died, slave is the name of the slave +terminal.) PID is allowed to be zero if unknown; this may disable +some cleanup operations. This routine may fork on some systems. As +such, SIGCHLD may be generated and blocked for some time during the +routine. In addition, on systems without waitpid() or wait4(), wait() +may be called. + + + diff --git a/src/appl/libpty/cleanup.c b/src/appl/libpty/cleanup.c new file mode 100644 index 0000000000..57cc796ac9 --- /dev/null +++ b/src/appl/libpty/cleanup.c @@ -0,0 +1,112 @@ +/* + * pty_cleanup: Kill processes associated with pty. + * + * (C)Copyright 1995, 1996 by the Massachusetts Institute of Technology. + * + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + */ + +#include "com_err.h" +#include "libpty.h" +#include "pty-int.h" +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + +long pty_cleanup (char *slave, + /* May be zero for unknown. */ + int pid, + int update_utmp) +{ +#ifdef VHANG_LAST + int retval, fd; +#endif + + if (update_utmp) + pty_update_utmp(PTY_DEAD_PROCESS, pid, "", slave, (char *)0, PTY_UTMP_USERNAME_VALID); + + (void)chmod(slave, 0666); + (void)chown(slave, 0, 0); +#ifdef HAVE_REVOKE + revoke(slave); + /* + * Revoke isn't guaranteed to send a SIGHUP to the processes it + * dissociates from the terminal. The best solution without a Posix + * mechanism for forcing a hangup is to killpg() the process + * group of the pty. This will at least kill the shell and + * hopefully, the child processes. This is not always the case, however. + * If the shell puts each job in a process group and doesn't pass + * along SIGHUP, all processes may not die. + */ + if ( pid > 0 ) { +#ifdef HAVE_KILLPG + killpg(pid, SIGHUP); +#else + kill( -(pid), SIGHUP ); +#endif /*HAVE_KILLPG*/ + } +#else /* HAVE_REVOKE*/ +#ifdef VHANG_LAST + { + int status; +#ifdef POSIX_SIGNALS + sigset_t old, new; + sigemptyset(&new); + sigaddset(&new, SIGCHLD); + sigprocmask ( SIG_BLOCK, &new, &old); +#else /*POSIX_SIGNALS*/ + int mask = sigblock(sigmask(SIGCHLD)); +#endif /*POSIX_SIGNALS*/ + switch (retval = fork()) { + case -1: +#ifdef POSIX_SIGNALS + sigprocmask(SIG_SETMASK, &old, 0); +#else /*POSIX_SIGNALS*/ + sigsetmask(mask); +#endif /*POSIX_SIGNALS*/ + return errno; + case 0: + ptyint_void_association(); + if ((retval = pty_open_ctty(slave, &fd))) + exit(retval); + ptyint_vhangup(); + exit(0); + break; + default: +#ifdef HAVE_WAITPID + waitpid(retval, &status, 0); +#else /*HAVE_WAITPID*/ + wait(&status); +#endif +#ifdef POSIX_SIGNALS + sigprocmask(SIG_SETMASK, &old, 0); +#else /*POSIX_SIGNALS*/ + sigsetmask(mask); +#endif /*POSIX_SIGNALS*/ + + break; + } + } +#endif /*VHANG_LAST*/ +#endif /* HAVE_REVOKE*/ +#ifndef HAVE_STREAMS + slave[strlen("/dev/")] = 'p'; + (void)chmod(slave, 0666); + (void)chown(slave, 0, 0); +#endif + return 0; +} diff --git a/src/appl/libpty/configure.in b/src/appl/libpty/configure.in new file mode 100644 index 0000000000..7600b1dbd4 --- /dev/null +++ b/src/appl/libpty/configure.in @@ -0,0 +1,269 @@ +K5_AC_INIT(getpty.c) +CONFIG_RULES +AC_PROG_AWK +AC_CHECK_FUNCS(fchmod fchown revoke vhangup killpg _getpty) +dnl +LOGINLIBS= +dnl +dnl Make our operating system-specific security checks and definitions for +dnl login. +dnl In addition, the following code decides what streams modules will +dnl be pushed onto a pty.In particular, if HAVE_STREAMS is defined and +dnl HAVE_LINE_PUSH is not defined, modules may be pushed by inserting +dnl An appropriate generic ifdef for each module in init_slave.c and +dnl AC_DEFINES for the operating systems that need the modules. +dnl Each OS that supports streams has a different idea of what you want to +dnl push. +dnl +case $krb5_cv_host in +*-*-ultrix*) +echo "Disabling initial vhangup and setsid because they break under Ultrix..." +AC_DEFINE([OPEN_CTTY_ONLY_ONCE],[1],[Define on Ultrix where an initial vhangup breaks]) +ac_cv_func_setsid=no # setsid doesn't do the right thing under Ultrix even though present +;; + +*-*-aix3*) # AIX has streams include files but not streams TTY +# Moreover, strops.h trashes sys/ioctl.h +krb5_cv_has_streams=no +;; +alpha*-dec-osf*) + AC_CHECK_LIB(security,main, + AC_DEFINE(HAVE_SETLUID,1,[Define if setluid is provided by the security library]) + LOGINLIBS="$LOGINLIBS -lsecurity" + ) + AC_MSG_RESULT(will open ctty prior to revoke due to OSF/1 lossage) + AC_DEFINE(REVOKE_NEEDS_OPEN,1,[Define if ctty needs to be opened before revoke as on OSF/1]) + ;; +*-*-solaris*) + AC_DEFINE(PUSH_PTEM,1,[push ptem?]) + AC_DEFINE(PUSH_LDTERM,1,[push ldterm?]) + AC_DEFINE(PUSH_TTCOMPAT,1,[push ttcompat?]) + ;; +*-*-hpux*) + krb5_cv_has_streams=no + ;; +esac +dnl +AC_SUBST(LOGINLIBS) +dnl +AC_CHECK_LIB(util,openpty, [AC_DEFINE(HAVE_OPENPTY,1,[Define if openpty is provided in util library]) LIBS="$LIBS -lutil"]) +AC_TYPE_MODE_T +AC_CHECK_TYPE(time_t, long) +AC_CHECK_FUNCS(setreuid gettosbyname setsid ttyname line_push ptsname grantpt openpty) +AC_CHECK_HEADERS(unistd.h stdlib.h string.h libutil.h pty.h sys/filio.h sys/sockio.h sys/label.h sys/tty.h sys/wait.h ttyent.h lastlog.h sys/select.h util.h sys/stream.h) +AC_CHECK_FUNCS(waitpid) +CHECK_SIGNALS +AC_CHECK_HEADER(termios.h,[AC_CHECK_FUNC(cfsetispeed,AC_DEFINE(POSIX_TERMIOS,1,[Define for POSIX termios interface]))]) + +AC_CHECK_HEADER(sys/ptyvar.h, [], [], +[#if HAVE_SYS_STREAM_H +#include <sys/stream.h> +#endif +#if HAVE_SYS_TTY_H +#include <sys/tty.h> +#endif]) + +###################################################################### +# +# utmp related hair here. There's lots of it. +# + +AC_CHECK_HEADERS(utmp.h utmpx.h) +AC_CHECK_FUNCS(setutent setutxent updwtmp updwtmpx logwtmp getutmp getutmpx) +AC_CHECK_FUNCS(utmpname utmpxname) + +AC_DEFUN(K5_CHECK_UT_MEMBER, +[AC_MSG_CHECKING([for $2 in struct $1]) +AC_CACHE_VAL([krb5_cv_struct_$1_$2], +[AC_TRY_COMPILE([#include <sys/types.h> +#include <$1.h>], [struct $1 u; u.$2;], +eval "krb5_cv_struct_$1_$2=yes", eval "krb5_cv_struct_$1_$2=no")]) +if eval "test \"`echo '$krb5_cv_struct_'$1'_'$2`\" = yes"; then + AC_MSG_RESULT(yes) + krb5_tr_ut=HAVE_STRUCT_`echo $1'_'$2 | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + AC_DEFINE_UNQUOTED($krb5_tr_ut,1,[Define if $2 field present in $1]) +else + AC_MSG_RESULT(no) +fi]) + +if test "$ac_cv_header_utmp_h" = yes; then + AC_MSG_RESULT(checking struct utmp members) + for krb5_mem in ut_host ut_syslen ut_addr ut_id ut_pid ut_type ut_exit; do + K5_CHECK_UT_MEMBER(utmp, $krb5_mem) + done +fi + +if test "$ac_cv_header_utmpx_h" = yes; then + AC_MSG_RESULT(checking struct utmpx members) + for krb5_mem in ut_host ut_syslen ut_addr ut_id ut_pid ut_type ut_exit; do + K5_CHECK_UT_MEMBER(utmpx, $krb5_mem) + done +fi + +AC_DEFUN(K5_CHECK_UT_EXIT_MEMBER, +[AC_MSG_CHECKING([for ut_exit.$2 in struct $1]) +AC_CACHE_VAL([krb5_cv_struct_$1_ut_exit_$2], +[AC_TRY_COMPILE([#include <sys/types.h> +#include <$1.h>], [struct $1 u; u.ut_exit.$2;], +eval "krb5_cv_struct_$1_ut_exit_$2=yes", +eval "krb5_cv_struct_$1_ut_exit_$2=no")]) +if eval "test \"`echo '$krb5_cv_struct_'$1'_ut_exit_'$2`\" = yes"; then + AC_MSG_RESULT(yes) + ifelse([$3], , :, [$3]) +else + AC_MSG_RESULT(no) + ifelse([$4], , :, [$4]) +fi]) + +if test "$krb5_cv_struct_utmp_ut_exit" = yes; then + AC_MSG_RESULT(checking for working ut_exit.e_exit in struct utmp) + for krb5_mem in __e_exit ut_e_exit ut_exit e_exit; do + K5_CHECK_UT_EXIT_MEMBER(utmp, $krb5_mem, +[krb5_utmp_e_exit=$krb5_mem +krb5_utmp_e_termination=`echo $krb5_mem|sed -e 's%_exit$%_termination%'`], ) + done + if test "${krb5_utmp_e_exit+set}" = set; then + AC_MSG_RESULT([working ut_exit.e_exit in utmp is $krb5_utmp_e_exit]) + AC_DEFINE_UNQUOTED(PTY_UTMP_E_EXIT, $krb5_utmp_e_exit,[Define to utmp exit field name]) + AC_DEFINE_UNQUOTED(PTY_UTMP_E_TERMINATION, $krb5_utmp_e_termination,[Define to utmp termination field name]) + else + AC_MSG_RESULT([cannot find working ut_exit.e_exit in utmp]) + fi +fi + +if test "$krb5_cv_struct_utmpx_ut_exit" = yes; then + AC_MSG_RESULT(checking for working ut_exit.e_exit in struct utmpx) + for krb5_mem in __e_exit ut_e_exit ut_exit e_exit; do + K5_CHECK_UT_EXIT_MEMBER(utmpx, $krb5_mem, +[krb5_utmpx_e_exit=$krb5_mem +krb5_utmpx_e_termination=`echo $krb5_mem|sed -e 's%_exit$%_termination%'`], ) + done + if test "${krb5_utmpx_e_exit+set}" = set; then + AC_MSG_RESULT([working ut_exit.e_exit in utmpx is $krb5_utmpx_e_exit]) + AC_DEFINE_UNQUOTED(PTY_UTMPX_E_EXIT, $krb5_utmpx_e_exit,[Define to utmpx exit field name]) + AC_DEFINE_UNQUOTED(PTY_UTMPX_E_TERMINATION, $krb5_utmpx_e_termination,[Define to utmpx termination field name]) + else + AC_MSG_RESULT([cannot find working ut_exit.e_exit in utmpx]) + fi +fi + +if test "$ac_cv_header_utmpx_h" = yes; then + AC_MSG_CHECKING(consistency of utmpx API) + if test "$ac_cv_func_setutxent" = yes; then + if test "$krb5_cv_struct_utmpx_ut_id" = yes \ + && test "$krb5_cv_struct_utmpx_ut_type" = yes \ + && test "$krb5_cv_struct_utmpx_ut_pid" = yes; then + AC_MSG_RESULT(ok) + else + AC_MSG_RESULT(not ok) + AC_MSG_ERROR([have setutxent but no ut_id, ut_type, or ut_pid in utmpx]) + fi + else + AC_MSG_RESULT(not ok) + AC_MSG_ERROR([have utmpx.h but no setutxent]) + fi +fi + +if test "$ac_cv_func_setutent" = yes && \ + test "$ac_cv_header_utmpx_h" = no; then + AC_MSG_CHECKING(consistency of sysV-ish utmp API) + if test "$ac_cv_header_utmp_h" = yes; then + if test "$krb5_cv_struct_utmp_ut_id" = yes \ + && test "$krb5_cv_struct_utmp_ut_type" = yes \ + && test "$krb5_cv_struct_utmp_ut_pid" = yes; then + AC_MSG_RESULT(ok) + else + AC_MSG_RESULT(not ok) + AC_MSG_ERROR([have setutent but no ut_id, ut_type, or ut_pid in utmp]) + fi + else + AC_MSG_RESULT(not ok) + AC_MSG_ERROR([have setutent but no utmp.h]) + fi +fi + +# +# end of utmp-related hair +# +###################################################################### +dnl +KRB5_NEED_PROTO([#ifdef HAVE_UTMP_H +#include <utmp.h> +#endif +#ifdef HAVE_UTMPX_H +#include <utmpx.h> +#endif +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif +],getutmp) +dnl +######################################### +KRB5_NEED_PROTO([#include <sys/types.h> +#ifdef HAVE_UTMP_H +#include <utmp.h> +#endif +#ifdef HAVE_LIBUTIL_H +#include <libutil.h> +#endif +#ifdef HAVE_UTIL_H +#include <util.h> +#endif +],logwtmp) +######################################## +KRB5_NEED_PROTO([#include <unistd.h> +],revoke) +######################################## +dnl +AC_MSG_CHECKING([streams interface]) +AC_CACHE_VAL(krb5_cv_has_streams, +[AC_TRY_COMPILE( +[#include <sys/stream.h> +#include <sys/stropts.h>], [], +krb5_cv_has_streams=yes, krb5_cv_has_streams=no)]) +AC_MSG_RESULT($krb5_cv_has_streams) +if test $krb5_cv_has_streams = yes; then +AC_DEFINE(HAVE_STREAMS,1,[Define if have streams]) +fi +dnl +dnl +dnl +AC_MSG_CHECKING([arguments to getpgrp]) +AC_CACHE_VAL(krb5_cv_getpgrp_args, +[AC_TRY_COMPILE( +[#ifndef __STDC__ +#define __STDC__ 1 +#endif +#include <unistd.h> +#include <sys/types.h>], [pid_t pid = getpgrp(getpid())], +krb5_cv_getpgrp_args=pid, krb5_cv_getpgrp_args=void)]) +AC_MSG_RESULT($krb5_cv_getpgrp_args) +if test $krb5_cv_getpgrp_args = pid; then +AC_DEFINE(GETPGRP_ONEARG,1,[Define if getpgrp takes one arg]) +fi +dnl +dnl +AC_MSG_CHECKING([number of arguments to setpgrp]) +AC_CACHE_VAL(krb5_cv_setpgrp_args, +[AC_TRY_COMPILE( +[#ifndef __STDC__ +#define __STDC__ 1 +#endif +#include <unistd.h>],[setpgrp(0,0)], +krb5_cv_setpgrp_args=two, krb5_cv_setpgrp_args=void)]) +AC_MSG_RESULT($krb5_cv_setpgrp_args) +if test $krb5_cv_setpgrp_args = two; then +AC_DEFINE(SETPGRP_TWOARG,1,[Define if setpgrp takes two args]) +fi +dnl +KRB5_AC_INET6 +AC_C_CONST +dnl KRB5_BUILD_LIBRARY_WITH_DEPS +KRB5_BUILD_LIBRARY_STATIC +KRB5_BUILD_LIBOBJS +KRB5_BUILD_PROGRAM +KRB5_RUN_FLAGS +V5_AC_OUTPUT_MAKEFILE diff --git a/src/appl/libpty/dump-utmp.c b/src/appl/libpty/dump-utmp.c new file mode 100644 index 0000000000..d4c303fb3a --- /dev/null +++ b/src/appl/libpty/dump-utmp.c @@ -0,0 +1,281 @@ +/* + * Copyright 2001 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + * dump-utmp.c: dump utmp and utmpx format files for debugging purposes. + */ + +#include <sys/types.h> +#include <sys/file.h> +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +#ifndef UTMPX +#ifdef HAVE_UTMPX_H +#define UTMPX +#endif +#endif + +#if defined(HAVE_UTMPNAME) || defined(HAVE_UTMPXNAME) +#define UTN /* we can set utmp or utmpx for getut*() */ +#endif + +#ifdef UTMPX +#include <utmpx.h> +void print_utx(int, const struct utmpx *); +#endif +#include <utmp.h> + +void print_ut(int, const struct utmp *); + +void usage(const char *); + +#if defined (HAVE_STRUCT_UTMP_UT_TYPE) || defined (UTMPX) +char *ut_typename(int); + +char * +ut_typename(int t) { + switch (t) { +#define S(N) case N : return #N +#define S2(N,N2) case N : return #N2 + S(EMPTY); + S(RUN_LVL); + S(BOOT_TIME); + S(OLD_TIME); + S(NEW_TIME); + S2(INIT_PROCESS,INIT); + S2(LOGIN_PROCESS,LOGIN); + S2(USER_PROCESS,USER); + S2(DEAD_PROCESS,DEAD); + S(ACCOUNTING); + default: return "??"; + } +} +#endif + +#define S2D(x) (sizeof(x) * 2.4 + 1.5) + +void +print_ut(int all, const struct utmp *u) +{ + int lu, ll; +#ifdef HAVE_STRUCT_UTMP_UT_ID + int lid; +#endif +#ifdef HAVE_STRUCT_UTMP_UT_PID + int lpid; +#endif +#ifdef PTY_UTMP_E_EXIT + int let, lee; +#endif + +#ifdef HAVE_STRUCT_UTMP_UT_TYPE + if (!all && ((u->ut_type == EMPTY) || (u->ut_type == DEAD_PROCESS))) + return; +#endif + + lu = sizeof(u->ut_name); + ll = sizeof(u->ut_line); + printf("%-*.*s:", lu, lu, u->ut_name); + printf("%-*.*s:", ll, ll, u->ut_line); +#ifdef HAVE_STRUCT_UTMP_UT_ID + lid = sizeof(u->ut_id); + printf("%-*.*s:", lid, lid, u->ut_id); +#endif +#ifdef HAVE_STRUCT_UTMP_UT_PID + lpid = S2D(u->ut_pid); + printf("%*ld", lpid, (long)u->ut_pid); +#endif +#ifdef PTY_UTMP_E_EXIT + let = S2D(u->ut_exit.PTY_UTMP_E_TERMINATION); + lee = S2D(u->ut_exit.PTY_UTMP_E_EXIT); + printf("(%*ld,", let, (long)u->ut_exit.PTY_UTMP_E_TERMINATION); + printf("%*ld)", lee, (long)u->ut_exit.PTY_UTMP_E_EXIT); +#endif +#ifdef HAVE_STRUCT_UTMP_UT_TYPE + printf(" %-9s", ut_typename(u->ut_type)); +#endif + printf(" %s", ctime(&u->ut_time) + 4); +#ifdef HAVE_STRUCT_UTMP_UT_HOST + if (u->ut_host[0]) + printf(" %.*s\n", (int) sizeof(u->ut_host), u->ut_host); +#endif + + return; +} + +#ifdef UTMPX +void +print_utx(int all, const struct utmpx *u) +{ + int lu, ll, lid, lpid; +#ifdef PTY_UTMPX_E_EXIT + int let, lee; +#endif + + if (!all && ((u->ut_type == EMPTY) || (u->ut_type == DEAD_PROCESS))) + return; + + lu = sizeof(u->ut_user); + ll = sizeof(u->ut_line); + lid = sizeof(u->ut_id); + printf("%-*.*s:", lu, lu, u->ut_user); + printf("%-*.*s:", ll, ll, u->ut_line); + printf("%-*.*s", lid, lid, u->ut_id); + if (lu + ll + lid >= 60) + printf("\n"); + else + printf(":"); + lpid = S2D(u->ut_pid); + printf("%*ld", lpid, (long)u->ut_pid); +#ifdef PTY_UTMPX_E_EXIT + let = S2D(u->ut_exit.PTY_UTMPX_E_TERMINATION); + lee = S2D(u->ut_exit.PTY_UTMPX_E_EXIT); + printf("(%*ld,", let, (long)u->ut_exit.PTY_UTMPX_E_TERMINATION); + printf("%*ld)", lee, (long)u->ut_exit.PTY_UTMPX_E_EXIT); +#endif + printf(" %-9s", ut_typename(u->ut_type)); + printf(" %s", ctime(&u->ut_tv.tv_sec) + 4); +#ifdef HAVE_STRUCT_UTMPX_UT_HOST + if (u->ut_host[0]) + printf(" %s\n", u->ut_host); +#endif + + return; +} +#endif + +#ifdef UTMPX +#define OPTX "x" +#else +#define OPTX +#endif +#ifdef UTN +#define OPTG "g" +#else +#define OPTG +#endif +#define OPTS "a" OPTX OPTG + +void +usage(const char *prog) +{ + fprintf(stderr, "usage: %s [-" OPTS "] file\n", prog); + exit(1); +} + +int +main(int argc, char **argv) +{ + int c; + int all, is_utmpx, do_getut; + int f; + char *fn; + size_t recsize; + size_t nread; + union { + struct utmp ut; +#ifdef UTMPX + struct utmpx utx; +#endif + } u; + + all = is_utmpx = do_getut = 0; + recsize = sizeof(struct utmp); + + while ((c = getopt(argc, argv, OPTS)) != EOF) { + switch (c) { + case 'a': + all = 1; + break; +#ifdef UTMPX + case 'x': + is_utmpx = 1; + recsize = sizeof(struct utmpx); + break; +#endif +#ifdef UTN + case 'g': + do_getut = 1; + break; +#endif + default: + usage(argv[0]); + } + } + if (argc <= optind) + usage(argv[0]); + fn = argv[optind]; + if (!do_getut) { + f = open(fn, O_RDONLY); + if (f == -1) { + perror(fn); + exit(1); + } + while ((nread = read(f, &u, recsize)) > 0) { + if (nread < recsize) { + fprintf(stderr, "short read"); + close(f); + exit(1); + } + if (is_utmpx) { +#ifdef UTMPX + print_utx(all, &u.utx); +#else + abort(); +#endif + } else { + print_ut(all, &u.ut); + } + } + if (nread == -1) { + perror("read"); + exit(1); + } + close(f); + } else { + if (is_utmpx) { +#ifdef UTMPX +#ifdef HAVE_UTMPXNAME + struct utmpx *utxp; + utmpxname(fn); + setutxent(); + while ((utxp = getutxent()) != NULL) + print_utx(all, utxp); +#else + fprintf(stderr, "no utmpxname(); can't use getutxent()\n"); + exit(1); +#endif +#else + abort(); +#endif + } else { +#ifdef HAVE_UTMPNAME + struct utmp *utp; + utmpname(fn); + setutxent(); + while ((utp = getutent()) != NULL) + print_ut(all, utp); +#else + fprintf(stderr, "no utmpname(); can't use getutent()\n"); + exit(1); +#endif + } + } + exit(0); +} diff --git a/src/appl/libpty/getpty.c b/src/appl/libpty/getpty.c new file mode 100644 index 0000000000..610a471e61 --- /dev/null +++ b/src/appl/libpty/getpty.c @@ -0,0 +1,150 @@ +/* + * pty_getpty: open a PTY master. + * + * Copyright 1995, 1996 by the Massachusetts Institute of Technology. + * + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + */ + +#include "com_err.h" +#include "libpty.h" +#include "pty-int.h" + +long +ptyint_getpty_ext(int *fd, char *slave, int slavelength, int do_grantpt) +{ +#if !defined(HAVE__GETPTY) && !defined(HAVE_OPENPTY) + char *cp; + char *p; + int i,ptynum; + struct stat stb; + char slavebuf[1024]; +#endif + +#ifdef HAVE__GETPTY + char *slaveret; /*Temporary to hold pointer to slave*/ +#endif /*HAVE__GETPTY*/ + +#ifdef HAVE_OPENPTY + int slavefd; + + if(openpty(fd, &slavefd, slave, (struct termios *) 0, + (struct winsize *) 0)) return 1; + close(slavefd); + return 0; +#else /*HAVE_OPENPTY*/ +#ifdef HAVE__GETPTY + /* This code is included for Irix; as of version 5.3, Irix has /dev/ptmx, + * but it fails to work properly; even after calling unlockpt, + * root gets permission denied opening the pty. + * The code to support _getpty should be removed if Irix gets working + * streams ptys in favor of maintaining the least needed code + * paths. + */ + if ((slaveret = _getpty(fd, O_RDWR|O_NDELAY, 0600, 0)) == 0) { + *fd = -1; + return PTY_GETPTY_NOPTY; + } + if (strlen(slaveret) > slavelength - 1) { + close(*fd); + *fd = -1; + return PTY_GETPTY_SLAVE_TOOLONG; + } + else strcpy(slave, slaveret); + return 0; +#else /*HAVE__GETPTY*/ + + *fd = open("/dev/ptym/clone", O_RDWR|O_NDELAY); /* HPUX*/ +#ifdef HAVE_STREAMS + if (*fd < 0) *fd = open("/dev/ptmx",O_RDWR|O_NDELAY); /*Solaris*/ +#endif + if (*fd < 0) *fd = open("/dev/ptc", O_RDWR|O_NDELAY); /* AIX */ + if (*fd < 0) *fd = open("/dev/pty", O_RDWR|O_NDELAY); /* sysvimp */ + + if (*fd >= 0) { + +#if defined(HAVE_GRANTPT)&&defined(HAVE_STREAMS) + if (do_grantpt) + if (grantpt(*fd) || unlockpt(*fd)) return PTY_GETPTY_STREAMS; +#endif + +#ifdef HAVE_PTSNAME + p = ptsname(*fd); +#else +#ifdef HAVE_TTYNAME + p = ttyname(*fd); +#else + /* XXX If we don't have either what do we do */ +#endif +#endif + if (p) { + if (strlen(p) > slavelength - 1) { + close (*fd); + *fd = -1; + return PTY_GETPTY_SLAVE_TOOLONG; + } + strcpy(slave, p); + return 0; + } + + if (fstat(*fd, &stb) < 0) { + close(*fd); + return PTY_GETPTY_FSTAT; + } + ptynum = (int)(stb.st_rdev&0xFF); + sprintf(slavebuf, "/dev/ttyp%x", ptynum); + if (strlen(slavebuf) > slavelength - 1) { + close(*fd); + *fd = -1; + return PTY_GETPTY_SLAVE_TOOLONG; + } + strncpy(slave, slavebuf, slavelength); + return 0; + } else { + for (cp = "pqrstuvwxyzPQRST";*cp; cp++) { + sprintf(slavebuf,"/dev/ptyXX"); + slavebuf[sizeof("/dev/pty") - 1] = *cp; + slavebuf[sizeof("/dev/ptyp") - 1] = '0'; + if (stat(slavebuf, &stb) < 0) + break; + for (i = 0; i < 16; i++) { + slavebuf[sizeof("/dev/ptyp") - 1] = "0123456789abcdef"[i]; + *fd = open(slavebuf, O_RDWR); + if (*fd < 0) continue; + + /* got pty */ + slavebuf[sizeof("/dev/") - 1] = 't'; + if (strlen(slavebuf) > slavelength -1) { + close(*fd); + *fd = -1; + return PTY_GETPTY_SLAVE_TOOLONG; + } + strncpy(slave, slavebuf, slavelength); + return 0; + } + } + return PTY_GETPTY_NOPTY; + } +#endif /*HAVE__GETPTY*/ +#endif /* HAVE_OPENPTY */ +} + +long +pty_getpty(int *fd, char *slave, int slavelength) +{ + return ptyint_getpty_ext(fd, slave, slavelength, 1); +} diff --git a/src/appl/libpty/init.c b/src/appl/libpty/init.c new file mode 100644 index 0000000000..b48a1f8a79 --- /dev/null +++ b/src/appl/libpty/init.c @@ -0,0 +1,33 @@ +/* + * pty_init: Initialize internal state of pty. + * + * Currently initializes error tables. + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + */ + +#include "com_err.h" +#include "libpty.h" +#include "pty-int.h" + +long pty_init(void) +{ + initialize_pty_error_table(); + return 0; +} diff --git a/src/appl/libpty/init_slave.c b/src/appl/libpty/init_slave.c new file mode 100644 index 0000000000..ce75076454 --- /dev/null +++ b/src/appl/libpty/init_slave.c @@ -0,0 +1,100 @@ +/* + * pty_init_slave: open slave side of terminal, clearing for use. + * + * Copyright 1995, 1996 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + */ + +#include "com_err.h" +#include "libpty.h" +#include "pty-int.h" + +/* * The following is an array of modules that should be pushed on the + * stream. See configure.in for caviats and notes about when this + * array is used and not used. + */ +#if defined(HAVE_STREAMS)&&(!defined(HAVE_LINE_PUSH)) +static char *push_list[] = { +#ifdef PUSH_PTEM + "ptem", +#endif +#ifdef PUSH_LDTERM + "ldterm", +#endif +#ifdef PUSH_TTCOMPAT +"ttcompat", +#endif + 0}; +#endif /*HAVE_STREAMS but not HAVE_LINE_PUSH*/ + + + +long pty_initialize_slave (int fd) +{ +#if defined(POSIX_TERMIOS) && !defined(ultrix) + struct termios new_termio; +#else + struct sgttyb b; +#endif /* POSIX_TERMIOS */ + int pid; + +#ifdef HAVE_STREAMS +#ifdef HAVE_LINE_PUSH + while (ioctl (fd, I_POP, 0) == 0); /*Clear out any old lined's*/ + + if (line_push(fd) < 0) + { + (void) close(fd); fd = -1; + return PTY_OPEN_SLAVE_LINE_PUSHFAIL; + } +#else /*No line_push */ + { + char **module = &push_list[0]; + while (*module) + if (ioctl(fd, I_PUSH, *(module++)) < 0) + return PTY_OPEN_SLAVE_PUSH_FAIL; + } + +#endif /*LINE_PUSH*/ +#endif /*HAVE_STREAMS*/ + + /* + * Under Ultrix 3.0, the pgrp of the slave pty terminal + * needs to be set explicitly. Why rlogind works at all + * without this on 4.3BSD is a mystery. + */ +#ifdef GETPGRP_ONEARG + pid = getpgrp(getpid()); +#else + pid = getpgrp(); +#endif + +#ifdef TIOCSPGRP + ioctl(fd, TIOCSPGRP, &pid); +#endif + + +#if defined(POSIX_TERMIOS) && !defined(ultrix) + tcsetpgrp(fd, pid); + tcgetattr(fd,&new_termio); + new_termio.c_cc[VMIN] = 1; + new_termio.c_cc[VTIME] = 0; + tcsetattr(fd,TCSANOW,&new_termio); +#endif /* POSIX_TERMIOS */ + + return 0; +} diff --git a/src/appl/libpty/libpty.h b/src/appl/libpty/libpty.h new file mode 100644 index 0000000000..d95c8fe086 --- /dev/null +++ b/src/appl/libpty/libpty.h @@ -0,0 +1,54 @@ +/* + * Header file for manipulation of ptys and utmp entries. + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + */ + +#ifndef __LIBPTY_H__ + +/* Constants for pty_update_utmp */ +#define PTY_LOGIN_PROCESS 0 +#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) + +long pty_init(void); +long pty_getpty ( int *fd, char *slave, int slavelength); + +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, const char *user, + const char *tty_line, const char *host, int flags); + +long pty_logwtmp(const char *tty, const char *user, const char *host); + +long pty_cleanup(char *slave, int pid, int update_utmp); + +#ifndef SOCK_DGRAM +struct sockaddr; +#endif + +long pty_make_sane_hostname(const struct sockaddr *, int, int, int, char **); +#define __LIBPTY_H__ +#endif diff --git a/src/appl/libpty/logwtmp.c b/src/appl/libpty/logwtmp.c new file mode 100644 index 0000000000..21a35d3a90 --- /dev/null +++ b/src/appl/libpty/logwtmp.c @@ -0,0 +1,112 @@ +/* + * pty_logwtmp: Implement the logwtmp function if not present. + * + * Copyright 1995, 2001 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + */ + +#include "com_err.h" +#include "libpty.h" +#include "pty-int.h" + +#if defined(HAVE_SETUTXENT) || defined(HAVE_SETUTENT) +#ifdef HAVE_SETUTXENT +#define PTY_STRUCT_UTMPX struct utmpx +#else +#define PTY_STRUCT_UTMPX struct utmp +#endif + +#ifdef NEED_LOGWTMP_PROTO +void logwtmp(const char *, const char *, const char *); +#endif + +long +pty_logwtmp(const char *tty, const char *user, const char *host) +{ +#ifndef HAVE_LOGWTMP + PTY_STRUCT_UTMPX utx; + int loggingin; + size_t len; + const char *cp; + char utmp_id[5]; +#endif + +#ifdef HAVE_LOGWTMP + logwtmp(tty,user,host); + return 0; +#else + + loggingin = (user[0] != '\0'); + + memset(&utx, 0, sizeof(utx)); + strncpy(utx.ut_line, tty, sizeof(utx.ut_line)); + strncpy(utx.ut_user, user, sizeof(utx.ut_user)); +#if (defined(HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMPX_UT_HOST)) \ + || (!defined(HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMP_UT_HOST)) + strncpy(utx.ut_host, host, sizeof(utx.ut_host)); + utx.ut_host[sizeof(utx.ut_host) - 1] = '\0'; +#endif +#ifdef HAVE_SETUTXENT + gettimeofday(&utx.ut_tv, NULL); +#else + (void)time(&utx.ut_time); +#endif + utx.ut_pid = (loggingin ? getpid() : 0); + utx.ut_type = (loggingin ? USER_PROCESS : DEAD_PROCESS); + + len = strlen(tty); + if (len >= 2) + cp = tty + len - 2; + else + cp = tty; + sprintf(utmp_id, "kr%s", cp); + strncpy(utx.ut_id, utmp_id, sizeof(utx.ut_id)); + +#ifdef HAVE_SETUTXENT + return ptyint_update_wtmpx(&utx); +#else + return ptyint_update_wtmp(&utx); +#endif + +#endif /* !HAVE_LOGWTMP */ +} + +#else /* !(defined(HAVE_SETUTXENT) || defined(HAVE_SETUTENT)) */ + +long +pty_logwtmp(const char *tty, const char *user, const char *host) +{ + struct utmp ut; + +#ifdef HAVE_LOGWTMP + logwtmp(tty,user,host); + return 0; +#else + + memset(&ut, 0, sizeof(ut)); +#ifdef HAVE_STRUCT_UTMP_UT_HOST + strncpy(ut.ut_host, host, sizeof(ut.ut_host)); + ut.ut_host[sizeof(ut.ut_host) - 1] = '\0'; +#endif + strncpy(ut.ut_line, tty, sizeof(ut.ut_line)); + strncpy(ut.ut_name, user, sizeof(ut.ut_name)); + return ptyint_update_wtmp(&ut); + +#endif /* !HAVE_LOGWTMP */ +} + +#endif /* !(defined(HAVE_SETUTXENT) || defined(HAVE_SETUTENT)) */ diff --git a/src/appl/libpty/open_ctty.c b/src/appl/libpty/open_ctty.c new file mode 100644 index 0000000000..5a1730b31c --- /dev/null +++ b/src/appl/libpty/open_ctty.c @@ -0,0 +1,67 @@ +/* + * pty_open_ctty: Open and establish controlling terminal. + * + * Copyright 1995, 1996 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + */ + +#include "com_err.h" +#include "libpty.h" +#include "pty-int.h" + +/* + * This function will be called twice. The first time it will acquire + * a controlling terminal from which to vhangup() or revoke() (see + * comments in open_slave.c); the second time, it will be to open the + * actual slave device for use by the application. We no longer call + * ptyint_void_association(), as that will be called in + * pty_open_slave() to avoid spurious calls to setsid(), etc. + * + * It is assumed that systems where vhangup() exists and does break + * the ctty association will allow the slave to be re-acquired as the + * ctty. Also, if revoke() or vhangup() doesn't break the ctty + * association, we assume that we can successfully reopen the slave. + * + * This function doesn't check whether we actually acquired the ctty; + * we assume that the caller will check that, or that it doesn't + * matter in the particular case. + */ +long +pty_open_ctty(const char *slave, int *fd) +{ + +#ifdef ultrix + /* + * The Ultrix (and other BSD tty drivers) require the process + * group to be zero, in order to acquire the new tty as a + * controlling tty. This may actually belong in + * ptyint_void_association(). + */ + (void) setpgrp(0, 0); +#endif + *fd = open(slave, O_RDWR); + if (*fd < 0) + return PTY_OPEN_SLAVE_OPENFAIL; +#ifdef ultrix + setpgrp(0, getpid()); +#endif + +#ifdef TIOCSCTTY + ioctl(*fd, TIOCSCTTY, 0); /* Don't check return.*/ +#endif /* TIOCSTTY */ + return 0; +} diff --git a/src/appl/libpty/open_slave.c b/src/appl/libpty/open_slave.c new file mode 100644 index 0000000000..5bab6bc36c --- /dev/null +++ b/src/appl/libpty/open_slave.c @@ -0,0 +1,101 @@ +/* + * pty_open_slave: open slave side of terminal, clearing for use. + * + * Copyright 1995, 1996, 2001 by the Massachusetts Institute of + * Technology. + * + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + */ + +#include "com_err.h" +#include "libpty.h" +#include "pty-int.h" + +long +pty_open_slave(const char *slave, int *fd) +{ + int tmpfd; + long retval; + + /* Sanity check. */ + if (slave == NULL || *slave == '\0') + return PTY_OPEN_SLAVE_TOOSHORT; + + /* First, set up a new session and void old associations. */ + ptyint_void_association(); + + /* + * Make a first attempt at acquiring the ctty under certain + * condisions. This is necessary for several reasons: + * + * Under Irix, if you open a pty slave and then close it, a + * subsequent open of the slave will cause the master to read EOF. + * To prevent this, don't close the first fd until we do the real + * open following vhangup(). + * + * Under Tru64 v5.0, if there isn't a fd open on the slave, + * revoke() fails with ENOTTY, curiously enough. + * + * Anyway, sshd seems to make a practice of doing this. + */ +#if defined(VHANG_FIRST) || defined(REVOKE_NEEDS_OPEN) + retval = pty_open_ctty(slave, fd); + if (retval) + return retval; + if (*fd < 0) + return PTY_OPEN_SLAVE_OPENFAIL; +#endif + + /* chmod and chown the slave. */ + if (chmod(slave, 0)) + return PTY_OPEN_SLAVE_CHMODFAIL; + if (chown(slave, 0, 0) == -1) + return PTY_OPEN_SLAVE_CHOWNFAIL; + +#ifdef HAVE_REVOKE + if (revoke(slave) < 0) { + return PTY_OPEN_SLAVE_REVOKEFAIL; + } +#else /* !HAVE_REVOKE */ +#ifdef VHANG_FIRST + ptyint_vhangup(); +#endif +#endif /* !HAVE_REVOKE */ + + /* Open the pty for real. */ + retval = pty_open_ctty(slave, &tmpfd); +#if defined(VHANG_FIRST) || defined(REVOKE_NEEDS_OPEN) + close(*fd); +#endif + if (retval) { + *fd = -1; + return PTY_OPEN_SLAVE_OPENFAIL; + } + *fd = tmpfd; + retval = pty_initialize_slave(*fd); + if (retval) + return retval; + /* Make sure it's really our ctty. */ + tmpfd = open("/dev/tty", O_RDWR|O_NDELAY); + if (tmpfd < 0) { + close(*fd); + *fd = -1; + return PTY_OPEN_SLAVE_NOCTTY; + } + close(tmpfd); + return 0; +} diff --git a/src/appl/libpty/pty-int.h b/src/appl/libpty/pty-int.h new file mode 100644 index 0000000000..b94a65c0ea --- /dev/null +++ b/src/appl/libpty/pty-int.h @@ -0,0 +1,138 @@ +/* Includes needed by libpty*/ +#ifndef __PTY_INT_H__ +#include <pty_err.h> +#include <sys/types.h> + +#if defined(_AIX) && defined(_THREAD_SAFE) +/* On AIX 4.3.3, both utmp.h and utmpx.h will define struct utmp_data, + and they'll define them differently, if _THREAD_SAFE is defined. + + We don't actually care about this library being thread-safe, but + for various reasons we do use both versions of the interface at the + moment. + + So trick the system headers into not "helping" us in that area. + + This is an ugly hack, and shouldn't be needed. Bleah. */ +# undef _THREAD_SAFE +#endif + +#include "autoconf.h" + +#ifdef HAVE_UTMP_H +#include <utmp.h> +#endif +#ifdef HAVE_UTMPX_H +#include <utmpx.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef __SCO__ +#include <sys/unistd.h> +#endif +#ifdef HAVE_STDLIB_H +#include <stdlib.h> +#endif + +#include <stdio.h> + +#ifdef HAVE_PTY_H +#include <pty.h> +#endif +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/file.h> +#include <sys/time.h> +#include <ctype.h> +#include <fcntl.h> +#include <errno.h> +#include <pwd.h> + +#ifdef HAVE_SYS_LABEL_H +/* only SunOS 4? */ +#include <sys/label.h> +#include <sys/audit.h> +#include <pwdadj.h> +#endif + +#include <signal.h> + +#ifdef hpux +#include <sys/ptyio.h> +#endif +#ifdef sysvimp +#include <compat.h> +#endif + +#ifdef HAVE_SYS_SELECT_H +#include <sys/select.h> +#endif + +#ifdef HAVE_STREAMS +#include <sys/stream.h> +#include <sys/stropts.h> +#endif + +#if defined(POSIX_TERMIOS) && !defined(ultrix) +#include <termios.h> +#else +#include <sgtty.h> +#endif + +#include "port-sockets.h" +#include <string.h> +#include <sys/param.h> + +#ifdef HAVE_UTIL_H +#include <util.h> +#endif + +#ifdef HAVE_STREAMS +/* krlogin doesn't test sys/tty... */ +#ifdef HAVE_SYS_TTY_H +#include <sys/tty.h> +#endif + + + +#ifdef HAVE_SYS_PTYVAR_H +/* Solaris actually uses packet mode, so the real macros are needed too */ +#include <sys/ptyvar.h> +#endif +#endif + +#if defined(HAVE_VHANGUP) && !defined(OPEN_CTTY_ONLY_ONCE) \ + && !defined(HAVE_REVOKE) +/* + * Breaks under Ultrix and others where you cannot get controlling + * terminal twice. + */ +#define VHANG_FIRST +#define VHANG_LAST +#endif + +#if defined(NEED_GETUTMPX_PROTOTYPE) +extern void getutmpx (const struct utmp *, struct utmpx *); +#endif + +#if defined(NEED_REVOKE_PROTO) +extern int revoke(const char *); +#endif + +/* Internal functions */ +long ptyint_void_association(void); +long ptyint_open_ctty (char *slave, int *fd); +long ptyint_getpty_ext(int *, char *, int, int); +#ifdef HAVE_SETUTXENT +long ptyint_update_wtmpx(struct utmpx *utx); +#endif +#if !(defined(WTMPX_FILE) && defined(HAVE_UPDWTMPX)) \ + || !defined(HAVE_SETUXENT) +long ptyint_update_wtmp(struct utmp *ut); +#endif +void ptyint_vhangup(void); + +#define __PTY_INT_H__ +#endif diff --git a/src/appl/libpty/pty_err.et b/src/appl/libpty/pty_err.et new file mode 100644 index 0000000000..770cce7a90 --- /dev/null +++ b/src/appl/libpty/pty_err.et @@ -0,0 +1,50 @@ +# +# util/pty/pty_err.et +# +# Copyright 1995 by the Massachusetts Institute of Technology. +# All Rights Reserved. +# +# +# Permission to use, copy, modify, and +# distribute this software and its documentation for any purpose and +# without fee is hereby granted, provided that the above copyright +# notice appear in all copies and that both that copyright notice and +# this permission notice appear in supporting documentation, and that +# the name of M.I.T. not be used in advertising or publicity pertaining +# to distribution of the software without specific, written prior +# permission. Furthermore if you modify this software you must label +# your software as modified software and not distribute it in such a +# fashion that it might be confused with the original M.I.T. software. +# M.I.T. makes no representations about the suitability of +# this software for any purpose. It is provided "as is" without express +# or implied warranty. +# + +# libpty--pty handling error table + +error_table pty + +error_code PTY_GETPTY_STREAMS, "Failed to unlock or grant streams pty." + +error_code PTY_GETPTY_FSTAT, "fstat of master pty failed" + +error_code PTY_GETPTY_NOPTY, "All terminal ports in use" + +error_code PTY_GETPTY_SLAVE_TOOLONG, "buffer to hold slave pty name is too short" + +error_code PTY_OPEN_SLAVE_OPENFAIL, "Failed to open slave side of pty" +error_code PTY_OPEN_SLAVE_CHMODFAIL, "Failed to chmod slave side of pty" + +error_code PTY_OPEN_SLAVE_NOCTTY, "Unable to set controlling terminal" +error_code PTY_OPEN_SLAVE_CHOWNFAIL, "Failed to chown slave side of pty" +error_code PTY_OPEN_SLAVE_LINE_PUSHFAIL, "Call to line_push failed to push streams on slave pty" + +error_code PTY_OPEN_SLAVE_PUSH_FAIL, "Failed to push stream on slave side of pty" + + +error_code PTY_OPEN_SLAVE_REVOKEFAIL, "Failed to revoke slave side of pty" + +error_code PTY_UPDATE_UTMP_PROCTYPE_INVALID, "bad process type passed to pty_update_utmp" +error_code PTY_OPEN_SLAVE_TOOSHORT, "Slave pty name is zero-length" + +end diff --git a/src/appl/libpty/pty_paranoia.c b/src/appl/libpty/pty_paranoia.c new file mode 100644 index 0000000000..466a658885 --- /dev/null +++ b/src/appl/libpty/pty_paranoia.c @@ -0,0 +1,650 @@ +/* + * Copyright 2001 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + */ + +/* + * A rant on the nature of pseudo-terminals: + * ----------------------------------------- + * + * Controlling terminals and job control: + * + * First, some explanation of job control and controlling terminals is + * necessary for background. This discussion applies to hardwired + * terminals as well as ptys. On most modern systems, all processes + * belong to a process group. A process whose process group id (pgid) + * is the sames as its pid is the process group leader of its process + * group. Process groups belong to sessions. On a modern system, a + * process that is not currently a process group leader may create a + * new session by calling setsid(), which makes it a session leader as + * well as a process group leader, and also removes any existing + * controlling terminal (ctty) association. Only a session leader may + * acquire a ctty. It's not clear how systems that don't have + * setsid() handle ctty acquisition, though probably any process group + * leader that doesn't have a ctty may acquire one that way. + * + * A terminal that is a ctty has an associated foreground process + * group, which is a member of the terminal's associated session. + * This process group gets read/write access to the terminal and will + * receive terminal-generated signals (e.g. SIGINT, SIGTSTP). Process + * groups belonging to the session but not in the foreground may get + * signals that suspend them if they try to read/write from the ctty, + * depending on various terminal settings. + * + * On many systems, the controlling process (the session leader + * associated with a ctty) exiting will cause the session to lose its + * ctty, even though some processes may continue to have open file + * descriptors on the former ctty. It is possible for a process to + * have no file descriptors open on its controlling tty, but to + * reacquire such by opening /dev/tty, as long as its session still + * has a ctty. + * + * On ptys in general: + * + * Ptys have a slave side and a master side. The slave side looks + * like a hardwired serial line to the application that opens it; + * usually, telnetd or rlogind, etc. opens the slave and hands it to + * the login program as stdin/stdout/stderr. The master side usually + * gets the actual network traffic written to/from it. Roughly, the + * master and slave are two ends of a bidirectional pair of FIFOs, + * though this can get complicated by other things. + * + * The master side of a pty is theoretically a single-open device. + * This MUST be true on systems that have BSD-style ptys, since there + * is usually no way to allocate an unused pty except by attempting to + * open all the master pty nodes in the system. + * + * Often, but not always, the last close of a slave device will cause + * the master to get an EOF. Closing the master device will sometimes + * cause the foreground process group of the slave to get a SIGHUP, + * but that may depend on terminal settings. + * + * BSD ptys: + * + * On a BSD-derived system, the master nodes are named like + * /dev/ptyp0, and the slave nodes are named like /dev/ttyp0. The + * last two characters are the variable ones, and a shell-glob type + * pattern for a slave device is usually of the form + * /dev/tty[p-z][0-9a-f], though variants are known to exist. + * + * System V cloning ptys: + * + * There is a cloning master device (usually /dev/ptmx, but the name + * can vary) that gets opened. Each open of the cloning master + * results in an open file descriptor of a unique master device. The + * application calls ptsname() to find the pathname to the slave node. + * + * In theory, the slave side of the pty is locked out until the + * process opening the master calls grantpt() to adjust permissions + * and unlockpt() to unlock the slave. It turns out that Unix98 + * doesn't require that the slave actually get locked out, or that + * unlockpt() actually do anything on such systems. At least AIX + * allows the slave to be opened prior to calling unlockpt(), but most + * other SysV-ish systems seem to actually lock out the slave. + * + * Pty security: + * + * It's not guaranteed on a BSD-ish system that a slave can't be + * opened when the master isn't open. It's even possible to acquire + * the slave as a ctty (!) if the open is done as non-blocking. It's + * possible to open the master corresponding to an open slave, which + * creates some security issues: once this master is open, data + * written to the slave will actually pass to the master. + * + * On a SysV-ish system, the close of the master will invalidate any + * open file descriptors on the slave. + * + * In general, there are two functions that can be used to "clean" a + * pty slave, revoke() and vhangup(). revoke() will invalidate all + * file descriptors open on a particular pathname (often this only + * works on terminal devices), usually by invalidating the underlying + * vnode. vhangup() will send a SIGHUP to the foreground process + * group of the control terminal. On many systems, it also has + * revoke() semantics. + * + * If a process acquires a controlling terminal in order to perform a + * vhangup(), the reopen of the controlling terminal after the + * vhangup() call should be done prior to the close of the file + * descriptor used to initially acquire the controlling terminal, + * since that will likely prevent the process on the master side from + * reading a spurious EOF due to all file descriptors to the slave + * being closed. + * + * Known quirks of various OSes: + * + * AIX 4.3.3: + * + * If the environment variable XPG_SUS_ENV is not equal to "ON", then + * it's possible to open the slave prior to calling unlockpt(). + */ + +/* + * NOTE: this program will get reworked at some point to actually test + * passing of data between master and slave, and to do general cleanup. + * + * This is rather complex, so it bears some explanation. + * + * There are multiple child processes and a parent process. These + * communicate via pipes (which we assume here to be unidirectional). + * The pipes are: + * + * pp1 - parent -> any children + * + * p1p - any children -> parent + * + * p21 - only child2 -> child1 + * + * A parent process will acquire a pty master and slave via + * pty_getpty(). It will then fork a process, child1. It then does a + * waitpid() for child1, and then writes to child2 via syncpipe pp1. + * It then reads from child3 via syncpipe p1p, then closes the + * master. It writes to child3 via syncpipe pp1 to indicate that it + * has closed the master. It then reads from child3 via syncpipe p1p + * and exits with a value appropriate to what it read from child3. + * + * child1 will acquire the slave as its ctty and fork child2; child1 + * will exit once it reads from the syncpipe p21 from child2. + * + * child2 will set a signal handler for SIGHUP and then write to + * child1 via syncpipe p21 to indicate that child2 has set up the + * handler. It will then read from the syncpipe pp1 from the parent + * to confirm that the parent has seen child1 exit, and then checks to + * see if it still has a ctty. Under Unix98, and likely earlier + * System V derivatives, the exiting of the session leader associated + * with a ctty (in this case, child1) will cause the entire session to + * lose its ctty. + * + * child2 will then check to see if it can reopen the slave, and + * whether it has a ctty after reopening it. This should fail on most + * systems. + * + * child2 will then fork child3 and immediately exit. + * + * child3 will write to the syncpipe p1p and read from the syncpipe + * pp1. It will then check if it has a ctty and then attempt to + * reopen the slave. This should fail. It will then write to the + * parent via syncpipe p1p and exit. + * + * If this doesn't fail, child3 will attempt to write to the open + * slave fd. This should fail unless a prior call to revoke(), + * etc. failed due to lack of permissions, e.g. NetBSD when running as + * non-root. + */ + +#include "com_err.h" +#include "libpty.h" +#include "pty-int.h" +#include <sys/wait.h> +#include <stdlib.h> + +char *prog; +int masterfd, slavefd; +char slave[64], slave2[64]; +pid_t pid1, pid2, pid3; +int status1, status2; +int pp1[2], p1p[2], p21[2]; + +void handler(int); +void rdsync(int, int *, const char *); +void wrsync(int, int, const char *); +void testctty(const char *); +void testex(int, const char *); +void testwr(int, const char *); +void child1(void); +void child2(void); +void child3(void); + +void +handler(int sig) +{ + printf("pid %ld got signal %d\n", (long)getpid(), sig); + fflush(stdout); + return; +} + +void +rdsync(int fd, int *status, const char *caller) +{ + int n; + char c; + +#if 0 + printf("rdsync: %s: starting\n", caller); + fflush(stdout); +#endif + while ((n = read(fd, &c, 1)) < 0) { + if (errno != EINTR) { + fprintf(stderr, "rdsync: %s", caller); + perror(""); + exit(1); + } else { + printf("rdsync: %s: got EINTR; looping\n", caller); + fflush(stdout); + } + } + if (!n) { + fprintf(stderr, "rdsync: %s: unexpected EOF\n", caller); + exit(1); + } + printf("rdsync: %s: got sync byte\n", caller); + fflush(stdout); + if (status != NULL) + *status = c; +} + +void +wrsync(int fd, int status, const char *caller) +{ + int n; + char c; + + c = status; + while ((n = write(fd, &c, 1)) < 0) { + if (errno != EINTR) { + fprintf(stderr, "wrsync: %s", caller); + perror(""); + exit(1); + } else { + printf("wrsync: %s: got EINTR; looping\n", caller); + fflush(stdout); + } + } +#if 0 + printf("wrsync: %s: sent sync byte\n", caller); +#endif + fflush(stdout); +} + +void +testctty(const char *caller) +{ + int fd; + + fd = open("/dev/tty", O_RDWR|O_NONBLOCK); + if (fd < 0) { + printf("%s: no ctty\n", caller); + } else { + printf("%s: have ctty\n", caller); + } +} + +void +testex(int fd, const char *caller) +{ + fd_set rfds, xfds; + struct timeval timeout; + int n; + char c; + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + FD_ZERO(&rfds); + FD_ZERO(&xfds); + FD_SET(fd, &rfds); + FD_SET(fd, &xfds); + + n = select(fd + 1, &rfds, NULL, &xfds, &timeout); + if (n < 0) { + fprintf(stderr, "testex: %s: ", caller); + perror("select"); + } + if (n) { + if (FD_ISSET(fd, &rfds) || FD_ISSET(fd, &xfds)) { + n = read(fd, &c, 1); + if (!n) { + printf("testex: %s: got EOF\n", caller); + fflush(stdout); + return; + } else if (n == -1) { + printf("testex: %s: got errno=%ld (%s)\n", + caller, (long)errno, strerror(errno)); + } else { + printf("testex: %s: read 1 byte!?\n", caller); + } + } + } else { + printf("testex: %s: no exceptions or readable fds\n", caller); + } +} + +void +testwr(int fd, const char *caller) +{ + fd_set wfds; + struct timeval timeout; + int n; + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + FD_ZERO(&wfds); + FD_SET(fd, &wfds); + + n = select(fd + 1, NULL, &wfds, NULL, &timeout); + if (n < 0) { + fprintf(stderr, "testwr: %s: ", caller); + perror("select"); + } + if (n) { + if (FD_ISSET(fd, &wfds)) { + printf("testwr: %s: is writable\n", caller); + fflush(stdout); + } + } +} + + +void +child3(void) +{ + int n; + + ptyint_void_association(); + slavefd = open(slave, O_RDWR|O_NONBLOCK); + if (slavefd < 0) { + wrsync(p1p[1], 1, "[02] child3->parent"); + printf("child3: failed reopen of slave\n"); + fflush(stdout); + exit(1); + } +#ifdef TIOCSCTTY + ioctl(slavefd, TIOCSCTTY, 0); +#endif + + printf("child3: reopened slave\n"); + testctty("child3: after reopen of slave"); + testwr(slavefd, "child3: after reopen of slave"); + testex(slavefd, "child3: after reopen of slave"); + close(slavefd); + testctty("child3: after close of slave"); + + /* + * Sync for parent to close master. + */ + wrsync(p1p[1], 0, "[02] child3->parent"); + rdsync(pp1[0], NULL, "[03] parent->child3"); + + testctty("child3: after close of master"); + printf("child3: attempting reopen of slave\n"); + fflush(stdout); + slavefd = open(slave, O_RDWR|O_NONBLOCK); + if (slavefd < 0) { + printf("child3: failed reopen of slave after master close: " + "errno=%ld (%s)\n", (long)errno, strerror(errno)); + wrsync(p1p[1], 0, "[04] child3->parent"); + fflush(stdout); + exit(0); + } + if (fcntl(slavefd, F_SETFL, 0) == -1) { + perror("child3: fcntl"); + wrsync(p1p[1], 2, "[04] child3->parent"); + exit(1); + } +#ifdef TIOCSCTTY + ioctl(slavefd, TIOCSCTTY, 0); +#endif + printf("child3: reopened slave after master close\n"); + testctty("child3: after reopen of slave after master close"); + testwr(slavefd, "child3: after reopen of slave after master close"); + testex(slavefd, "child3: after reopen of slave after master close"); + n = write(slavefd, "foo", 4); + if (n < 0) { + printf("child3: writing to slave of closed master: errno=%ld (%s)\n", + (long)errno, strerror(errno)); + wrsync(p1p[1], 1, "[04] child3->parent"); + } else { + printf("child3: wrote %d byes to slave of closed master\n", n); + fflush(stdout); + wrsync(p1p[1], 2, "[04] child3->parent"); + } + rdsync(pp1[0], NULL, "[05] parent->child3"); + testex(slavefd, "child3: after parent reopen of master"); + testwr(slavefd, "child3: after parent reopen of master"); + fflush(stdout); + n = write(slavefd, "bar", 4); + if (n < 0) { + perror("child3: writing to slave"); + } else { + printf("child3: wrote %d bytes to slave\n", n); + fflush(stdout); + } + wrsync(p1p[1], 0, "[06] child3->parent"); + rdsync(pp1[0], NULL, "[07] parent->child3"); + wrsync(p1p[1], 0, "[08] child3->parent"); + exit(0); +} + +void +child2(void) +{ + struct sigaction sa; + + close(p21[0]); + setpgid(0, 0); + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + sa.sa_handler = handler; + if (sigaction(SIGHUP, &sa, NULL) < 0) { + wrsync(p21[1], 1, "[00] child2->child1"); + perror("child2: sigaction"); + fflush(stdout); + exit(1); + } + printf("child2: set up signal handler\n"); + testctty("child2: after start"); + testwr(slavefd, "child2: after start"); + wrsync(p21[1], 0, "[00] child2->child1"); + rdsync(pp1[0], NULL, "[01] parent->child2"); + + testctty("child2: after child1 exit"); + testex(slavefd, "child2: after child1 exit"); + testwr(slavefd, "child2: after child1 exit"); + close(slavefd); + testctty("child2: after close of slavefd"); + slavefd = open(slave, O_RDWR|O_NONBLOCK); + if (slavefd < 0) { + wrsync(p1p[1], 1, "[02] child2->parent"); + printf("child2: failed reopen of slave\n"); + fflush(stdout); + exit(1); + } +#ifdef TIOCSCTTY + ioctl(slavefd, TIOCSCTTY, 0); +#endif + printf("child2: reopened slave\n"); + testctty("child2: after reopen of slave"); + fflush(stdout); + close(slavefd); + pid3 = fork(); + if (!pid3) { + child3(); + } else if (pid3 == -1) { + wrsync(p1p[1], 1, "[02] child2->parent"); + perror("child2: fork of child3"); + exit(1); + } + printf("child2: forked child3=%ld\n", (long)pid3); + fflush(stdout); + exit(0); +} + +void +child1(void) +{ + int status; + +#if 0 + setuid(1); +#endif + close(pp1[1]); + close(p1p[0]); + close(masterfd); + ptyint_void_association(); + slavefd = open(slave, O_RDWR|O_NONBLOCK); + if (slavefd < 0) { + perror("child1: open slave"); + exit(1); + } +#ifdef TIOCSCTTY + ioctl(slavefd, TIOCSCTTY, 0); +#endif + + printf("child1: opened slave\n"); + testctty("child1: after slave open"); + + if (pipe(p21) < 0) { + perror("pipe child2->child1"); + exit(1); + } + pid2 = fork(); + if (!pid2) { + child2(); + } else if (pid2 == -1) { + perror("child1: fork child2"); + exit(1); + } + close(p21[1]); + printf("child1: forked child2=%ld\n", (long)pid2); + fflush(stdout); + rdsync(p21[0], &status, "[00] child2->child1"); + exit(status); +} + +int +main(int argc, char *argv[]) +{ + long retval; + int status; + char buf[4]; + int n; + + prog = argv[0]; + + printf("parent: pid=%ld\n", (long)getpid()); + + retval = ptyint_getpty_ext(&masterfd, slave, sizeof(slave), 0); + + if (retval) { + com_err(prog, retval, "open master"); + exit(1); + } +#if 0 + chown(slave, 1, -1); +#endif + printf("parent: master opened; slave=%s\n", slave); + fflush(stdout); + +#if defined(HAVE_GRANTPT) && defined(HAVE_STREAMS) +#ifdef O_NOCTTY + printf("parent: attempting to open slave before unlockpt\n"); + fflush(stdout); + slavefd = open(slave, O_RDWR|O_NONBLOCK|O_NOCTTY); + if (slavefd < 0) { + printf("parent: failed slave open before unlockpt errno=%ld (%s)\n", + (long)errno, strerror(errno)); + } else { + printf("parent: WARNING: " + "succeeded in opening slave before unlockpt\n"); + } + close(slavefd); +#endif + if (grantpt(masterfd) < 0) { + perror("parent: grantpt"); + exit(1); + } + if (unlockpt(masterfd) < 0) { + perror("parent: unlockpt"); + exit(1); + } +#endif /* HAVE_GRANTPT && HAVE_STREAMS */ + + if (pipe(pp1) < 0) { + perror("pipe parent->child1"); + exit(1); + } + if (pipe(p1p) < 0) { + perror("pipe child1->parent"); + exit(1); + } + + pid1 = fork(); + if (!pid1) { + child1(); + } else if (pid1 == -1) { + perror("fork of child1"); + exit(1); + } + printf("parent: forked child1=%ld\n", (long)pid1); + fflush(stdout); + if (waitpid(pid1, &status1, 0) < 0) { + perror("waitpid for child1"); + exit(1); + } + printf("parent: child1 exited, status=%d\n", status1); + if (status1) + exit(status1); + + wrsync(pp1[1], 0, "[01] parent->child2"); + rdsync(p1p[0], &status, "[02] child3->parent"); + if (status) { + fprintf(stderr, "child2 or child3 got an error\n"); + exit(1); + } + + printf("parent: closing master\n"); + fflush(stdout); + close(masterfd); + chmod(slave, 0666); + printf("parent: closed master\n"); + wrsync(pp1[1], 0, "[03] parent->child3"); + + rdsync(p1p[0], &status, "[04] child3->parent"); + switch (status) { + case 1: + break; + case 0: + exit(0); + default: + fprintf(stderr, "child3 got an error\n"); + fflush(stdout); + exit(1); + } + + retval = pty_getpty(&masterfd, slave2, sizeof(slave2)); + printf("parent: new master opened; slave=%s\n", slave2); +#if 0 +#ifdef HAVE_REVOKE + printf("parent: revoking\n"); + revoke(slave2); +#endif +#endif + fflush(stdout); + wrsync(pp1[1], 0, "[05] parent->child3"); + rdsync(p1p[0], NULL, "[06] child3->parent"); + + n = read(masterfd, buf, 4); + if (n < 0) { + perror("parent: reading from master"); + } else { + printf("parent: read %d bytes (%.*s) from master\n", n, n, buf); + fflush(stdout); + } + chmod(slave2, 0666); + close(masterfd); + wrsync(pp1[1], 0, "[07] parent->child3"); + rdsync(p1p[0], NULL, "[08] child3->parent"); + fflush(stdout); + exit(0); +} diff --git a/src/appl/libpty/sane_hostname.c b/src/appl/libpty/sane_hostname.c new file mode 100644 index 0000000000..8ef6de8754 --- /dev/null +++ b/src/appl/libpty/sane_hostname.c @@ -0,0 +1,116 @@ +/* + * pty_make_sane_hostname: Make a sane hostname from an IP address. + * This returns allocated memory! + * + * Copyright 1999, 2000, 2001 by the Massachusetts Institute of + * Technology. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + */ +#include "com_err.h" +#include "pty-int.h" +#include <sys/socket.h> +#include "libpty.h" +#include <arpa/inet.h> + +#include "socket-utils.h" +#include "fake-addrinfo.h" + +static void +downcase (char *s) +{ + for (; *s != '\0'; s++) + *s = tolower ((int) *s); +} + +long +pty_make_sane_hostname(const struct sockaddr *addr, int maxlen, + int strip_ldomain, int always_ipaddr, char **out) +{ + struct addrinfo *ai = 0; + char addrbuf[NI_MAXHOST]; +#ifdef HAVE_STRUCT_UTMP_UT_HOST + struct utmp ut; +#else + struct utmpx utx; +#endif + char *cp, *domain; + char lhost[MAXHOSTNAMELEN]; + size_t ut_host_len; + + /* Note that on some systems (e.g., AIX 4.3.3), we may get an IPv6 + address such as ::FFFF:18.18.1.71 when an IPv4 connection comes + in. That's okay; at least on AIX, getnameinfo will deal with + that properly. */ + + *out = NULL; + if (maxlen && maxlen < 16) + /* assume they meant 16, otherwise IPv4 addr won't fit */ + maxlen = 16; +#ifdef HAVE_STRUCT_UTMP_UT_HOST + ut_host_len = sizeof (ut.ut_host); +#else + ut_host_len = sizeof (utx.ut_host); +#endif + if (maxlen == 0) + maxlen = ut_host_len; + *out = malloc(ut_host_len); + if (*out == NULL) + return ENOMEM; + + if (always_ipaddr) { + use_ipaddr: + if (getnameinfo (addr, socklen (addr), addrbuf, sizeof (addrbuf), + (char *)0, 0, NI_NUMERICHOST) == 0) + strncpy(*out, addrbuf, ut_host_len); + else + strncpy(*out, "??", ut_host_len); + (*out)[ut_host_len - 1] = '\0'; + return 0; + } + + /* If we didn't want to chop off the local domain, this would be + much simpler -- just a single getnameinfo call and a strncpy. */ + if (getnameinfo(addr, socklen (addr), addrbuf, sizeof (addrbuf), + (char *) NULL, 0, NI_NAMEREQD) != 0) + goto use_ipaddr; + downcase (addrbuf); + if (strip_ldomain) { + struct addrinfo hints; + (void) gethostname(lhost, sizeof (lhost)); + memset (&hints, 0, sizeof (hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_flags = AI_CANONNAME; + if (getaddrinfo(lhost, (char *)NULL, &hints, &ai) == 0 + && ai != NULL) { + if (ai->ai_canonname != NULL) { + downcase (ai->ai_canonname); + domain = strchr (ai->ai_canonname, '.'); + if (domain != NULL) { + cp = strstr (addrbuf, domain); + if (cp != NULL) + *cp = '\0'; + } + } + freeaddrinfo (ai); + } + } + strncpy(*out, addrbuf, ut_host_len); + (*out)[ut_host_len - 1] = '\0'; + if (strlen(*out) >= maxlen) + goto use_ipaddr; + return 0; +} diff --git a/src/appl/libpty/update_utmp.c b/src/appl/libpty/update_utmp.c new file mode 100644 index 0000000000..004582650a --- /dev/null +++ b/src/appl/libpty/update_utmp.c @@ -0,0 +1,706 @@ +/* + * pty_update_utmp: Update or create a utmp entry + * + * Copyright 1995, 2001 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + */ + +/* + * Rant about the historical vagaries of utmp: + * ------------------------------------------- + * + * There exist many subtly incompatible incarnations of utmp, ranging + * from BSD to System V to Unix98 and everywhere in between. This + * rant attempts to collect in one place as much knowledge as possible + * about this portability nightmare. + * + * BSD: + * ---- + * + * The simplest (and earliest? possibly dating back to Version 7...) + * case is 4.x BSD utmp/wtmp. There are no auxiliary files. There is + * only a struct utmp, declared in utmp.h. Its contents usually + * include: + * + * char ut_line[] + * char ut_name[] + * char ut_host[] + * long ut_time + * + * The meanings of these fields follow their names reasonbly well. + * The ut_line field usually is the pathname of the tty device + * associated with the login, with the leading "/dev/" stripped off. + * + * It is believed that ut_host is nul-terminated, while the other + * strings are merely nul-padded. + * + * Generally, ut_name is an empty string for a logout record in both + * utmp and wtmp. For entries made by the window system or other + * terminal emulation stuff, ut_host is an empty string (at least + * under SunOS 4.x, it seems). The macro nonuser() is used to + * determine this if a utmp entry is made by the window system on at + * least SunOS 4.x. + * + * The native login never clears its own utmp entry or writes its own + * logout record; its parent (one of init, rlogind, telnetd, etc.) + * should handle that. In theory, getty could do that, but getty + * usually doesn't fork to exec login. + * + * Old (c. 1984) System V: + * ----------------------- + * + * This is partially conjecture, based on some reading of + * /usr/xpg2include/utmp.h on a SunOS 4.x system. There appears to + * only be a struct utmp, declared in utmp.h. It is likely used for + * both utmp and wtmp files. It is quite likely that the utmp is only + * supposed to be accessed via the getutline()/pututline() API. The + * contents of struct utmp seem to include: + * + * char ut_user[] + * char ut_id[] + * char ut_line[] + * short ut_pid + * short ut_type + * struct exit_status ut_exit + * time_t ut_time + * + * On these systems, ut_name is often #define'ed to be ut_user to be + * somewhat compatible with the BSD-style utmp. Note that there is + * not necessarily a ut_host field in this utmp structure. + * + * The ut_id field bears some explanation. The systems that use this + * style of utmp also use a sysV-ish init, which starts processes out + * of /etc/inittab rather than /etc/ttys, and has the concept of + * runlevels. The first field in each line of /etc/inittab contains a + * unique ID field. init probably gets really confused if there are + * conflicts here. Every process that init starts gets its own entry + * written to utmp. + * + * It is possible for multiple entries to have the same ut_line but + * different ut_id values, since the sysadmin will be responsible for + * assigning values to ut_id. Usually, ut_id is four characters, + * while the permissible unique ID values for entries in /etc/inittab + * are constrained to two characters, but this is not always the + * case. In the case where we are emulating the vendor's login + * program and being run out of getty, we need to account for which + * value of ut_id was used by the getty, since pututline() will search + * based on ut_id and not ut_line for some reason. + * + * The ut_pid and ut_type fields are used for bookkeeping by init. + * The ut_type field gets the value INIT_PROCESS for processes started + * by init. It gets the value LOGIN_PROCESS if it is a process that + * is prompting for a login name, and it gets the value USER_PROCESS + * for an actual valid login. When the process dies, either init + * cleans up after it and records a DEAD_PROCESS entry in utmp, or the + * process itself does so. It's not completely clear which actually + * happens, though it is quite possible that init only cleans up after + * processes that it starts itself. + * + * Other values of ut_type exist; they're largely internal bookkeeping + * for init's runlevels and such, and don't really interest this + * library at all. + * + * The ut_exit field contains the following members: + * + * short e_termination + * short e_exit + * + * It is not clear how these values are used; presumably they record + * the process termination status of dead processes. + * + * There is no uniform API for manipulating wtmp on systems that use + * this sort of utmp structure; it can be assumed that the structure + * can be directly written to the wtmp file. + * + * Unix98: + * ------- + * + * This description also likely applies to later System V derivatives + * as well as systems conforming to earlier X/Open standards such as + * XPG4. There is a new header, utmpx.h, which defines a struct utmpx + * and a new getutxline()/pututxline() API for accessing it. Some + * systems actually have a utmpx file on disk; others use the utmpx + * API to access a file named utmp, just to further confuse matters. + * + * The utmpx structure is guaranteed (by Unix98) to contain at least + * the following: + * + * char ut_user[] + * char ut_line[] + * char ut_id[] + * pid_t ut_pid + * short ut_type + * struct timeval ut_tv + * + * It is not guaranteed to contain, but often does contain, the + * following: + * + * char ut_host[] + * int ut_syslen + * int ut_session + * struct exit_status ut_exit + * + * The ut_syslen field, on systems that contain it, contains the + * number of significant characters in ut_host, including the + * terminating nul character. + * + * The main difference between this struct utmpx and the struct utmp + * used by early sysV derivatives is the change from a time_t or long + * for ut_time to a struct timeval for ut_tv. + * + * Comments in various header files imply that ut_session is used for + * window systems, but it's not clear how. Perhaps it contains the + * session ID of the session running the window system, e.g. the xdm + * or X server on an X11 system. + * + * Most of the description of the earlier sysV format probably applies + * here, with suitable changes of names. On systems that maintain + * utmpx and utmp files in parallel, it is assumed that using the + * pututxline() API is sufficient to keep them in sync. There are no + * known counterexamples to this. + * + * Nevertheless, there are, on some systems, API functions getutmp() + * and getutmpx() that appear to convert from struct utmpx to struct + * utmp and vice versa. This could be useful when there is a wtmp + * file but not a corresponding wtmpx file. + * + * Incidentally, ut_exit is sometimes present in the struct utmp but + * not the struct utmpx for a given system. Sometimes, it exists in + * both, but contains differently named members. It's probably one of + * the least portable pieces in this whole mess. + * + * Known Quirks of Specific OSes: + * ------------------------------ + * + * Solaris 2.x: + * + * Has utmpd, which will automatically clean up utmpx, utmp, wtmpx, + * wtmp after process termination, provided that pututxline() was + * used. + * + * Solaris 8 seems to have a bug in utmpname() that causes + * garbage filenames to be generated. Solaris 7 (and possibly Solaris + * 8) have a bug in utmpxname() that prevents them from looking at + * anything other than /var/adm/utmpx, it seems. For some reason, + * though, utmpname() goes and looks at the corresponding utmpx file. + * + * Solaris 7 (and may be 8 as well) has a bug in pututline() that + * interacts badly with prior invocation of getutline(): if + * getutline() finds an entry, calling pututline() without first + * calling setutent() will overwrite the record following the one that + * was intended. + * + * Also, ut_exit in utmpx contains ut_e_termination and + * ut_e_exit (otherwise it contains the expected e_termination and + * e_exit) only if _XPG4_2 is defined and __EXTENSIONS__ is not, which + * is not a compilation environment we're likely to encourage. The + * ut_exit field of utmp contains the expected fields. + * + * If _XPG4_2 is not defined or __EXTENSIONS__ is defined, the + * functions getutmp(), getutmpx(), updwtmp(), and updwtmpx() are + * available, as well as the undocumented functions makeutx() and + * modutx(). + * + * All the files utmp, utmpx, wtmp, and wtmpx exist. + * + * HP-UX 10.x: + * + * There is a curious interaction between how we allocate pty masters + * and how ttyname() works. It seems that if /dev/ptmx/clone is + * opened, a call to ptsname() on the master fd gets a filename of the + * form /dev/pty/tty[pqrs][0-9a-f], while ttyname() called on a fd + * opened with that filename returns a filename of the form + * /dev/tty[pqrs][0-9a-f] instead. These two filenames are actually + * hardlinks to the same special device node, so it shouldn't be a + * security problem. + * + * We can't call ttyname() in the parent because it would involve + * possibly acquiring a controlling terminal (which would be + * potentially problematic), so we have to resort to some trickery in + * order to ensure that the ut_line in the wtmp logout and login + * records match. If they don't match, various utilities such as last + * will get confused. Of course it's likely an OS bug that ttyname() + * and ptsname() are inconsistent in this way, but it's one that isn't + * too painful to work around. + * + * It seems that the HP-UX native telnetd has problems similar to ours + * in this area, though it manages to write the correct logout record + * to wtmp somehow. It probably does basically what we do here: + * search for a record with a matching ut_pid and grab its ut_line for + * writing into the logout record. Interestingly enough, its + * LOGIN_PROCESS record is of the form pty/tty[pqrs][0-9][a-f]. + * + * Uses four-character unique IDs for /etc/inittab, which means that + * programs not running out of init should use two-character ut_id + * fields to avoid conflict. + * + * In utmpx, ut_exit contains __e_termination and __e_exit, while + * ut_exit in utmp contains the expected fields. + * + * There is no wtmpx file, despite there being utmp and utmpx files. + * + * Irix 6.x: + * + * In utmpx, ut_exit contains __e_termination and __e_exit, which get + * #define aliases e_termination and e_exit if _NO_XOPEN4 is true. + * Curiously enough, utmp.h declares ut_exit to have __e_termination + * and __e_exit as well, but does #define e_termination + * __e_termination, etc. if another header (utmpx.h) hasn't already + * declared struct __exit_status. It seems that the default + * compilation environment has the effect of making _NO_XOPEN4 true + * though. + * + * If _NO_XOPEN4 is true, getutmp(), getutmpx(), updwtmp(), and + * updwtmpx() are available, as well as the undocumented functions + * makeutx() and modutx(). + * + * All the files utmp, utmpx, wtmp, and wtmpx exist. + * + * Tru64 Unix 4.x: + * + * In utmpx, ut_exit contains ut_termination and ut_exit, while utmp + * contains the expected fields. The files utmp and wtmp seem to + * exist, but not utmpx or wtmpx. + * + * When writing a logout entry, the presence of a non-empty username + * confuses last. + * + * AIX 4.3.x: + * + * The ut_exit field seems to exist in utmp, but not utmpx. The files + * utmp and wtmp seem to exist, but not utmpx, or wtmpx. + * + * libpty Implementation Decisions: + * -------------------------------- + * + * We choose to use the pututxline() whenever possible, falling back + * to pututline() and calling write() to write out struct utmp if + * necessary. The code to handle pututxline() and pututline() is + * rather similar, since the structure members are quite similar, and + * we make the assumption that it will never be necessary to call + * both. This allows us to avoid duplicating lots of code, by means + * of some slightly demented macros. + * + * If neither pututxline() nor pututline() are available, we assume + * BSD-style utmp files and behave accordingly, writing the structure + * out to disk ourselves. + * + * On systems where updwtmpx() or updwtmp() are available, we use + * those to update the wtmpx or wtmp file. When they're not + * available, we write the utmpx or utmp structure out to disk + * ourselves, though sometimes conversion from utmpx to utmp format is + * needed. + * + * We assume that at logout the system is ok with with having an empty + * username both in utmp and wtmp. + */ + +#include "com_err.h" +#include "libpty.h" +#include "pty-int.h" + +#if !defined(UTMP_FILE) && defined(_PATH_UTMP) +#define UTMP_FILE _PATH_UTMP +#endif + +/* if it is *still* missing, assume SunOS */ +#ifndef UTMP_FILE +#define UTMP_FILE "/etc/utmp" +#endif + +/* + * The following grossness exists to avoid duplicating lots of code + * between the cases where we have an old-style sysV utmp and where we + * have a modern (Unix98 or XPG4) utmpx. See the above history rant + * for further explanation. + */ +#if defined(HAVE_SETUTXENT) || defined(HAVE_SETUTENT) +#ifdef HAVE_SETUTXENT +#define PTY_STRUCT_UTMPX struct utmpx +#define PTY_SETUTXENT setutxent +#define PTY_GETUTXENT getutxent +#define PTY_GETUTXLINE getutxline +#define PTY_PUTUTXLINE pututxline +#define PTY_ENDUTXENT endutxent +#else +#define PTY_STRUCT_UTMPX struct utmp +#define PTY_SETUTXENT setutent +#define PTY_GETUTXENT getutent +#define PTY_GETUTXLINE getutline +#define PTY_PUTUTXLINE pututline +#define PTY_ENDUTXENT endutent +#endif + +static int better(const PTY_STRUCT_UTMPX *, const PTY_STRUCT_UTMPX *, + const PTY_STRUCT_UTMPX *); +static int match_pid(const PTY_STRUCT_UTMPX *, + const PTY_STRUCT_UTMPX *); +static PTY_STRUCT_UTMPX *best_utxent(const PTY_STRUCT_UTMPX *); + +/* + * Utility function to determine whether A is a better match for + * SEARCH than B. Should only be called by best_utxent(). + */ +static int +better(const PTY_STRUCT_UTMPX *search, + const PTY_STRUCT_UTMPX *a, const PTY_STRUCT_UTMPX *b) +{ + if (strncmp(search->ut_id, b->ut_id, sizeof(b->ut_id))) { + if (!strncmp(search->ut_id, a->ut_id, sizeof(a->ut_id))) { + return 1; + } + } + + if (strncmp(a->ut_id, b->ut_id, sizeof(b->ut_id))) { + /* Got different UT_IDs; find the right one. */ + if (!strncmp(search->ut_id, b->ut_id, sizeof(b->ut_id))) { + /* Old entry already matches; use it. */ + return 0; + } + if (a->ut_type == LOGIN_PROCESS + && b->ut_type != LOGIN_PROCESS) { + /* Prefer LOGIN_PROCESS */ + return 1; + } + if (search->ut_type == DEAD_PROCESS + && a->ut_type == USER_PROCESS + && b->ut_type != USER_PROCESS) { + /* + * Try USER_PROCESS if we're entering a DEAD_PROCESS. + */ + return 1; + } + return 0; + } else { + /* + * Bad juju. We shouldn't get two entries with identical + * ut_id fields for the same value of ut_line. pututxline() + * will probably pick the first entry, in spite of the strange + * state of utmpx, if we rewind with setutxent() first. + * + * For now, return 0, to force the earlier entry to be used. + */ + return 0; + } +} + +static int +match_pid(const PTY_STRUCT_UTMPX *search, const PTY_STRUCT_UTMPX *u) +{ + if (u->ut_type != LOGIN_PROCESS && u->ut_type != USER_PROCESS) + return 0; + if (u->ut_pid == search->ut_pid) { + /* + * One of ut_line or ut_id should match, else some nastiness + * may result. We can fall back to searching by ut_line if + * need be. This should only really break if we're login.krb5 + * running out of getty, or we're cleaning up after the vendor + * login, and either the vendor login or the getty has + * different ideas than we do of what both ut_id and ut_line + * should be. It should be rare, though. We may want to + * remove this restriction later. + */ + if (!strncmp(u->ut_line, search->ut_line, sizeof(u->ut_line))) + return 1; + if (!strncmp(u->ut_id, search->ut_id, sizeof(u->ut_id))) + return 1; + } + return 0; +} + +/* + * This expects to be called with SEARCH pointing to a struct utmpx + * with its ut_type equal to USER_PROCESS or DEAD_PROCESS, since if + * we're making a LOGIN_PROCESS entry, we presumably don't care about + * preserving existing state. At the very least, the ut_pid, ut_line, + * ut_id, and ut_type fields must be filled in by the caller. + */ +static PTY_STRUCT_UTMPX * +best_utxent(const PTY_STRUCT_UTMPX *search) +{ + PTY_STRUCT_UTMPX utxtmp, *utxp; + int i, best; + + memset(&utxtmp, 0, sizeof(utxtmp)); + + /* + * First, search based on pid, but only if non-zero. + */ + if (search->ut_pid) { + i = 0; + PTY_SETUTXENT(); + while ((utxp = PTY_GETUTXENT()) != NULL) { + if (match_pid(search, utxp)) { + return utxp; + } + i++; + } + } + /* + * Uh-oh, someone didn't enter our pid. Try valiantly to search + * by terminal line. + */ + i = 0; + best = -1; + PTY_SETUTXENT(); + while ((utxp = PTY_GETUTXLINE(search)) != NULL) { + if (better(search, utxp, &utxtmp)) { + utxtmp = *utxp; + best = i; + } + memset(utxp, 0, sizeof(*utxp)); + i++; + } + if (best == -1) + return NULL; + PTY_SETUTXENT(); + for (i = 0; i <= best; i++) { + if (utxp != NULL) + memset(utxp, 0, sizeof(*utxp)); + utxp = PTY_GETUTXLINE(search); + } + return utxp; +} + +/* + * All calls to this function for a given login session must have the + * pids be equal; various things will break if this is not the case, + * since we do some searching based on the pid. Note that if a parent + * process calls this via pty_cleanup(), it should still pass the + * child's pid rather than its own. + */ +long +pty_update_utmp(int process_type, int pid, const char *username, + const char *line, const char *host, int flags) +{ + PTY_STRUCT_UTMPX utx, *utxtmp, utx2; + const char *cp; + size_t len; + char utmp_id[5]; + + /* + * Zero things out in case there are fields we don't handle here. + * They tend to be non-portable anyway. + */ + memset(&utx, 0, sizeof(utx)); + utxtmp = NULL; + cp = line; + if (strncmp(cp, "/dev/", sizeof("/dev/") - 1) == 0) + cp += sizeof("/dev/") - 1; + strncpy(utx.ut_line, cp, sizeof(utx.ut_line)); + utx.ut_pid = pid; + switch (process_type) { + case PTY_LOGIN_PROCESS: + utx.ut_type = LOGIN_PROCESS; + break; + case PTY_USER_PROCESS: + utx.ut_type = USER_PROCESS; + break; + case PTY_DEAD_PROCESS: + utx.ut_type = DEAD_PROCESS; + break; + default: + return PTY_UPDATE_UTMP_PROCTYPE_INVALID; + } + len = strlen(line); + if (len >= 2) { + cp = line + len - 1; + if (*(cp - 1) != '/') + cp--; /* last two characters, unless it's a / */ + } else + cp = line; + /* + * HP-UX has mostly 4-character inittab ids, while most other sysV + * variants use only 2-charcter inittab ids, so to avoid + * conflicts, we pick 2-character ut_ids for our own use. We may + * want to feature-test for this, but it would be somewhat of a + * pain, and would eit cross-compiling. + */ +#ifdef __hpux + strcpy(utmp_id, cp); +#else + if (len > 2 && *(cp - 1) != '/') + sprintf(utmp_id, "k%s", cp - 1); + else + sprintf(utmp_id, "k0%s", cp); +#endif + strncpy(utx.ut_id, utmp_id, sizeof(utx.ut_id)); + /* + * Get existing utmpx entry for PID or LINE, if any, so we can + * copy some stuff from it. This is particularly important if we + * are login.krb5 and are running out of getty, since getty will + * have written the entry for the line with ut_type == + * LOGIN_PROCESS, and what it has recorded in ut_id may not be + * what we come up with, since that's up to the whim of the + * sysadmin who writes the inittab entry. + * + * Note that we may be screwed if we try to write a logout record + * for a vendor's login program, since it may construct ut_line + * and ut_id differently from us; even though we search on ut_pid, + * we validate against ut_id or ut_line to sanity-check. We may + * want to rethink whether to actually include this check, since + * it should be highly unlikely that there will be a bogus entry + * in utmpx matching our pid. + */ + if (process_type != PTY_LOGIN_PROCESS) + utxtmp = best_utxent(&utx); + +#ifdef HAVE_SETUTXENT + if (gettimeofday(&utx.ut_tv, NULL)) + return errno; +#else + (void)time(&utx.ut_time); +#endif + /* + * On what system is there not ut_host? Unix98 doesn't mandate + * this field, but we have yet to see a system that supports utmpx + * that doesn't have it. For what it's worth, some ancient utmp + * headers on svr4 systems imply that there's no ut_host in struct + * utmp... + */ +#if (defined(HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMPX_UT_HOST)) \ + || (!defined(HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMP_UT_HOST)) + if (host != NULL) { + strncpy(utx.ut_host, host, sizeof(utx.ut_host)); + /* Unlike other things in utmpx, ut_host is nul-terminated? */ + utx.ut_host[sizeof(utx.ut_host) - 1] = '\0'; + } else + utx.ut_host[0] = '\0'; +#if (defined(HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMPX_UT_SYSLEN)) \ + || (!defined (HAVE_SETUTXENT) && defined(HAVE_STRUCT_UTMP_UT_SYSLEN)) + if (host != NULL) + utx.ut_syslen = strlen(utx.ut_host) + 1; + else + utx.ut_syslen = 0; +#endif +#endif + + /* XXX deal with ut_addr? */ + + if (utxtmp != NULL) { + /* + * For entries not of type LOGIN_PROCESS, override some stuff + * with what was in the previous entry we found, if any. + */ + strncpy(utx.ut_id, utxtmp->ut_id, sizeof(utx.ut_id)); + utx.ut_pid = utxtmp->ut_pid; + } + + strncpy(utx.ut_user, username, sizeof(utx.ut_user)); + + /* + * Make a copy now and deal with copying relevant things out of + * utxtmp in case setutxline() or pututxline() clobbers utxtmp. + * (After all, the returned pointer from the getutx*() functions + * is allowed to point to static storage that may get overwritten + * by subsequent calls to related functions.) + */ + utx2 = utx; + if (process_type == PTY_DEAD_PROCESS && utxtmp != NULL) { + /* + * Use ut_line from old entry to avoid confusing last on + * HP-UX. + */ + strncpy(utx2.ut_line, utxtmp->ut_line, sizeof(utx2.ut_line)); + } + + PTY_SETUTXENT(); + PTY_PUTUTXLINE(&utx); + PTY_ENDUTXENT(); + + /* Don't record LOGIN_PROCESS entries. */ + if (process_type == PTY_LOGIN_PROCESS) + return 0; + +#ifdef HAVE_SETUTXENT + return ptyint_update_wtmpx(&utx2); +#else + return ptyint_update_wtmp(&utx2); +#endif +} + +#else /* !(HAVE_SETUTXENT || HAVE_SETUTENT) */ + +long +pty_update_utmp(int process_type, int pid, const char *username, + const char *line, const char *host, int flags) +{ + struct utmp ent, ut; + const char *cp; + int tty, lc, fd; + off_t seekpos; + ssize_t ret; + struct stat statb; + + memset(&ent, 0, sizeof(ent)); +#ifdef HAVE_STRUCT_UTMP_UT_HOST + if (host) + strncpy(ent.ut_host, host, sizeof(ent.ut_host)); +#endif + strncpy(ent.ut_name, username, sizeof(ent.ut_name)); + cp = line; + if (strncmp(cp, "/dev/", sizeof("/dev/") - 1) == 0) + cp += sizeof("/dev/") - 1; + strncpy(ent.ut_line, cp, sizeof(ent.ut_line)); + (void)time(&ent.ut_time); + + if (flags & PTY_TTYSLOT_USABLE) + tty = ttyslot(); + else { + tty = -1; + fd = open(UTMP_FILE, O_RDONLY); + if (fd == -1) + return errno; + for (lc = 0; ; lc++) { + seekpos = lseek(fd, (off_t)(lc * sizeof(struct utmp)), SEEK_SET); + if (seekpos != (off_t)(lc * sizeof(struct utmp))) + break; + 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; + break; + } + } + close(fd); + } + if (tty > 0) { + fd = open(UTMP_FILE, O_WRONLY); + if (fd == -1) + return 0; + if (fstat(fd, &statb)) { + close(fd); + return 0; + } + seekpos = lseek(fd, (off_t)(tty * sizeof(struct utmp)), SEEK_SET); + if (seekpos != (off_t)(tty * sizeof(struct utmp))) { + close(fd); + return 0; + } + ret = write(fd, (char *)&ent, sizeof(struct utmp)); + if (ret != sizeof(struct utmp)) { + ftruncate(fd, statb.st_size); + } + close(fd); + } + /* Don't record LOGIN_PROCESS entries. */ + if (process_type == PTY_LOGIN_PROCESS) + return 0; + else + return ptyint_update_wtmp(&ent); +} +#endif diff --git a/src/appl/libpty/update_wtmp.c b/src/appl/libpty/update_wtmp.c new file mode 100644 index 0000000000..988bae61ac --- /dev/null +++ b/src/appl/libpty/update_wtmp.c @@ -0,0 +1,127 @@ +/* + * ptyint_update_wtmp: Update wtmp. + * + * Copyright 1995, 2001 by the Massachusetts Institute of Technology. + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + */ + +#include "com_err.h" +#include "libpty.h" +#include "pty-int.h" + +#if !defined(WTMP_FILE) && defined(_PATH_WTMP) +#define WTMP_FILE _PATH_WTMP +#endif + +#if !defined(WTMPX_FILE) && defined(_PATH_WTMPX) +#define WTMPX_FILE _PATH_WTMPX +#endif + +/* if it is *still* missing, assume SunOS */ +#ifndef WTMP_FILE +#define WTMP_FILE "/usr/adm/wtmp" +#endif + +#ifdef HAVE_SETUTXENT + +#if defined(HAVE_GETUTMP) && defined(NEED_GETUTMP_PROTO) +extern void getutmp(const struct utmpx *, struct utmp *); +#endif + +/* + * Welcome to conditional salad. + * + * This really wants to take a (const struct utmpx *) but updutmpx() + * on Solaris at least doesn't take a const argument. *sigh* + */ +long +ptyint_update_wtmpx(struct utmpx *ent) +{ +#if !(defined(HAVE_UPDWTMPX) && defined(WTMPX_FILE)) + struct utmp ut; +#endif + +#if defined(HAVE_UPDWTMPX) && defined(WTMPX_FILE) + updwtmpx(WTMPX_FILE, ent); + return 0; +#else + +#ifdef HAVE_GETUTMP + getutmp(ent, &ut); +#else /* Emulate getutmp(). Yuck. */ + memset(&ut, 0, sizeof(ut)); + strncpy(ut.ut_name, ent->ut_user, sizeof(ut.ut_name)); + strncpy(ut.ut_line, ent->ut_line, sizeof(ut.ut_line)); + ut.ut_time = ent->ut_tv.tv_sec; +#ifdef HAVE_STRUCT_UTMP_UT_HOST + strncpy(ut.ut_host, ent->ut_host, sizeof(ut.ut_host)); + ut.ut_host[sizeof(ut.ut_host) - 1] = '\0'; +#ifdef HAVE_STRUCT_UTMP_UT_SYSLEN + ut.ut_syslen = strlen(ut.ut_host) + 1; +#endif +#endif +#ifdef HAVE_STRUCT_UTMP_UT_ID + strncpy(ut.ut_id, ent->ut_id, sizeof(ut.ut_id)); +#endif +#ifdef HAVE_STRUCT_UTMP_UT_PID + ut.ut_pid = ent->ut_pid; +#endif +#ifdef HAVE_STRUCT_UTMP_UT_TYPE + ut.ut_type = ent->ut_type; +#endif +#if defined(PTY_UTMP_E_EXIT) && defined(PTY_UTMPX_E_EXIT) + ut.ut_exit.PTY_UTMP_E_EXIT = ent->ut_exit.PTY_UTMPX_E_EXIT; + ut.ut_exit.PTY_UTMP_E_TERMINATION = + ent->ut_exit.PTY_UTMPX_E_TERMINATION; +#endif +#endif /* !HAVE_GETUTMP */ + + return ptyint_update_wtmp(&ut); +#endif /* !(defined(WTMPX_FILE) && defined(HAVE_UPDWTMPX)) */ +} + +#endif /* HAVE_SETUTXENT */ + +#if !(defined(WTMPX_FILE) && defined(HAVE_UPDWTMPX)) \ + || !defined(HAVE_SETUTXENT) + +long +ptyint_update_wtmp(struct utmp *ent) +{ +#ifndef HAVE_UPDWTMP + int fd; + struct stat statb; +#endif + +#ifdef HAVE_UPDWTMP + updwtmp(WTMP_FILE, ent); +#else + fd = open(WTMP_FILE, O_WRONLY | O_APPEND, 0); + if (fd != -1 && !fstat(fd, &statb)) { + if (write(fd, (char *)ent, sizeof(struct utmp)) + != sizeof(struct utmp)) + (void)ftruncate(fd, statb.st_size); + (void)close(fd); + } +#endif + /* + * no current failure cases; file not found is not failure! + */ + return 0; +} + +#endif diff --git a/src/appl/libpty/vhangup.c b/src/appl/libpty/vhangup.c new file mode 100644 index 0000000000..292437142e --- /dev/null +++ b/src/appl/libpty/vhangup.c @@ -0,0 +1,50 @@ +/* + * pty_open_slave: open slave side of terminal, clearing for use. + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + */ + +#include "com_err.h" +#include "libpty.h" +#include "pty-int.h" + +void ptyint_vhangup(void) +{ +#ifdef HAVE_VHANGUP +#ifdef POSIX_SIGNALS + struct sigaction sa; + /* Initialize "sa" structure. */ + (void) sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + +#endif + +#ifdef POSIX_SIGNALS + sa.sa_handler = SIG_IGN; + (void) sigaction(SIGHUP, &sa, (struct sigaction *)0); + vhangup(); + sa.sa_handler = SIG_DFL; + (void) sigaction(SIGHUP, &sa, (struct sigaction *)0); +#else + signal(SIGHUP, SIG_IGN); + vhangup(); + signal(SIGHUP, SIG_DFL); +#endif +#endif +} diff --git a/src/appl/libpty/void_assoc.c b/src/appl/libpty/void_assoc.c new file mode 100644 index 0000000000..a39c9c7236 --- /dev/null +++ b/src/appl/libpty/void_assoc.c @@ -0,0 +1,49 @@ +/* + * ptyint_void_association(): Void association with controlling terminal + * + * Copyright 1995, 1996 by the Massachusetts Institute of Technology. + * + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of + * M.I.T. not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability + * of this software for any purpose. It is provided "as is" without + * express or implied warranty. + * + */ + +#include "com_err.h" +#include "libpty.h" +#include "pty-int.h" + +/* + * This function gets called to set up the current process as a + * session leader (hence, can't be called except from a process that + * isn't already a session leader) and dissociates the controlling + * terminal (if any) from the session. + */ +long +ptyint_void_association(void) +{ + int fd; +#ifdef HAVE_SETSID + (void) setsid(); +#endif + /* Void tty association first */ +#ifdef TIOCNOTTY + fd = open("/dev/tty", O_RDWR); + if (fd >= 0) { + ioctl(fd, TIOCNOTTY, 0); + close(fd); + } +#endif + return 0; +} |