Solaris UseLogin problem

Matt Eagleson matt at rebelbase.com
Fri Mar 23 08:29:57 EST 2001


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
 	/*


More information about the openssh-unix-dev mailing list