I was having problems getting the UseLogin option to work on Solaris. I would recieve this error: No utmpx entry. You must exec "login" from the lowest level "shell". This led me to believe that Solaris login wants a utmpx entry in order to function. I put together a patch that calls record_login on Solaris when using the system login. I also noticed that writing a wtmpx entry was unnecessary in this situation and led to duplicate entries. I tried my best to make this patch not break other systems -- but I may have failed there. I do not claim that this patch is the correct fix, or even a working fix. I am, however, hoping that this may start some discussion that will lead to a clean and proper solution. Thanks, Matt Eagleson -------------- next part -------------- ? patch ? configure ? config.log ? config.h ? config.cache ? config.status ? Makefile ? ssh_prng_cmds ? config.h.in ? sshd_config.out ? ssh_config.out ? primes.out ? sshd ? openbsd-compat/Makefile Index: acconfig.h ==================================================================RCS file: /cvs/openssh_cvs/acconfig.h,v retrieving revision 1.108 diff -u -r1.108 acconfig.h --- acconfig.h 2001/03/17 01:15:38 1.108 +++ acconfig.h 2001/03/22 21:28:01 @@ -169,6 +169,9 @@ /* Define if you want to specify the path to your wtmpx file */ #undef CONF_WTMPX_FILE +/* Some systems need a utmpx entry for /bin/login to work */ +#undef LOGIN_NEEDS_UTMPX + /* Define is libutil has login() function */ #undef HAVE_LIBUTIL_LOGIN Index: configure.in ==================================================================RCS file: /cvs/openssh_cvs/configure.in,v retrieving revision 1.267 diff -u -r1.267 configure.in --- configure.in 2001/03/18 23:09:28 1.267 +++ configure.in 2001/03/22 21:28:01 @@ -165,6 +165,7 @@ LDFLAGS="$LDFLAGS -L/usr/local/lib -R/usr/local/lib" need_dash_r=1 AC_DEFINE(PAM_SUN_CODEBASE) + AC_DEFINE(LOGIN_NEEDS_UTMPX) # hardwire lastlog location (can't detect it on some versions) conf_lastlog_location="/var/adm/lastlog" AC_MSG_CHECKING(for obsolete utmp and wtmp in solaris2.x) Index: loginrec.c ==================================================================RCS file: /cvs/openssh_cvs/loginrec.c,v retrieving revision 1.32 diff -u -r1.32 loginrec.c --- loginrec.c 2001/02/22 21:23:21 1.32 +++ loginrec.c 2001/03/22 21:28:02 @@ -162,6 +162,7 @@ #include "loginrec.h" #include "log.h" #include "atomicio.h" +#include "servconf.h" RCSID("$Id: loginrec.c,v 1.32 2001/02/22 21:23:21 stevesk Exp $"); @@ -173,6 +174,8 @@ # include <libutil.h> #endif +extern ServerOptions options; + /** ** prototypes for helper functions in this file **/ @@ -438,7 +441,8 @@ utmpx_write_entry(li); #endif #ifdef USE_WTMPX - wtmpx_write_entry(li); + if (!options.use_login) + wtmpx_write_entry(li); #endif return 0; } Index: session.c ==================================================================RCS file: /cvs/openssh_cvs/session.c,v retrieving revision 1.100 diff -u -r1.100 session.c --- session.c 2001/03/22 02:06:57 1.100 +++ session.c 2001/03/22 21:28:04 @@ -597,6 +597,8 @@ { int fdout, ptyfd, ttyfd, ptymaster; pid_t pid; + socklen_t fromlen; + struct sockaddr_storage from; if (s == NULL) fatal("do_exec_pty: no session"); @@ -635,11 +637,35 @@ /* Close the extra descriptor for the pseudo tty. */ close(ttyfd); + + /* + * Get IP address of client. If the connection is not a socket, let + * the address be 0.0.0.0. + */ + memset(&from, 0, sizeof(from)); + if (packet_connection_is_on_socket()) { + fromlen = sizeof(from); + if (getpeername(packet_get_connection_in(), + (struct sockaddr *) & from, &fromlen) < 0) { + debug("getpeername: %.100s", strerror(errno)); + fatal_cleanup(); + } + } - /* record login, etc. similar to login(1) */ - if (!(options.use_login && command == NULL)) + /* print motd, etc. similar to login(1) */ + if (!(options.use_login && command == NULL)) { + /* Record that there was a login on that tty from the remote host. */ + record_login(getpid(), s->tty, s->pw->pw_name, s->pw->pw_uid, + get_remote_name_or_ip(), (struct sockaddr *)&from); do_login(s, command); + } +#ifdef LOGIN_NEEDS_UTMPX + /* Record that there was a login on that tty from the remote host. */ + record_login(getpid(), s->tty, s->pw->pw_name, s->pw->pw_uid, + get_remote_name_or_ip(), (struct sockaddr *)&from); +#endif + /* Do common processing for the child, such as execing the command. */ do_child(s, command); /* NOTREACHED */ @@ -700,35 +726,14 @@ char *time_string; char buf[256]; char hostname[MAXHOSTNAMELEN]; - socklen_t fromlen; - struct sockaddr_storage from; struct stat st; time_t last_login_time; struct passwd * pw = s->pw; - pid_t pid = getpid(); - /* - * Get IP address of client. If the connection is not a socket, let - * the address be 0.0.0.0. - */ - memset(&from, 0, sizeof(from)); - if (packet_connection_is_on_socket()) { - fromlen = sizeof(from); - if (getpeername(packet_get_connection_in(), - (struct sockaddr *) & from, &fromlen) < 0) { - debug("getpeername: %.100s", strerror(errno)); - fatal_cleanup(); - } - } - /* Get the time and hostname when the user last logged in. */ hostname[0] = '\0'; last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, hostname, sizeof(hostname)); - - /* Record that there was a login on that tty from the remote host. */ - record_login(pid, s->tty, pw->pw_name, pw->pw_uid, - get_remote_name_or_ip(), (struct sockaddr *)&from); #ifdef USE_PAM /*