Solaris UseLogin problems

Wayne Davison wayne at blorf.net
Wed Apr 4 17:25:51 EST 2001


I'm using openssh 2.5.2p2 on Solaris-x86 2.6.  I ran into a couple
problems when I set UseLogin to "yes":

The big one seems to have been reported before: login refuses to run
without a utmpx entry.  This problem appears to have been caused by
the changes in revision 1.24 of session.c.  Before this revision, the
record_login() function was always called, no matter how UseLogin was
set (FYI, the comment for revision 1.24 is "cleanup login(1)-like
jobs, no duplicate utmp entries".)

I had already created a fix for this problem by the time I finally
found this mailing list and noticed that a recent message from Matt
Eagleson had supplied a potential patch.  My version of the fix is
fairly similar to Matt's, but I put the relocated record_login() call
into its own function rather than putting it back into do_exec_pty().
The appended patch makes use of Matt's LOGIN_NEEDS_UTMPX autoconf
changes, and has the added benefit that it doesn't call record_login()
twice in the "UseLogin no" code path (which is a bug in Matt's patch).

Another problem I noticed (that I haven't seen mentioned elsewhere)
was that the terminal type failed to be passed through to "login"
unless I added an extra commandline parameter.  The solaris version of
login has an optional "terminal" arg after the "-h hostname" arg, and
without this being supplied, the value of TERM gets lost.  I have
added a define, LOGIN_NEEDS_TERM, and made configure set it if we're
running Solaris.

What I did not notice was any problems with duplicated wtmpx entries
like Matt did.

Matt:  What was the symptom you noticed that made you add the code to
loginrec.c?  Duplicated entries when running "w"?  Or something else?

..wayne..

---8<------8<------8<------8<---cut here--->8------>8------>8------>8---
Index: acconfig.h
@@ -169,6 +169,12 @@
 /* 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
+
+/* Some versions of /bin/login need the TERM supplied on the commandline */
+#undef LOGIN_NEEDS_TERM
+
 /* Define is libutil has login() function */
 #undef HAVE_LIBUTIL_LOGIN

Index: configure.in
@@ -165,6 +165,8 @@
 	LDFLAGS="$LDFLAGS -L/usr/local/lib -R/usr/local/lib"
 	need_dash_r=1
 	AC_DEFINE(PAM_SUN_CODEBASE)
+	AC_DEFINE(LOGIN_NEEDS_UTMPX)
+	AC_DEFINE(LOGIN_NEEDS_TERM)
 	# 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: session.c
@@ -126,6 +126,7 @@
 void	session_proctitle(Session *s);
 void	do_exec_pty(Session *s, const char *command, struct passwd * pw);
 void	do_exec_no_pty(Session *s, const char *command, struct passwd * pw);
+void	call_record_login(Session *s);
 void	do_login(Session *s, const char *command);
 void	do_child(Session *s, const char *command);

@@ -632,6 +633,10 @@
 		/* record login, etc. similar to login(1) */
 		if (!(options.use_login && command == NULL))
 			do_login(s, command);
+#ifdef LOGIN_NEEDS_UTMPX
+		else
+			call_record_login(s);
+#endif

 		/* Do common processing for the child, such as execing the command. */
 		do_child(s, command);
@@ -685,18 +690,11 @@
 	return remote;
 }

-/* administrative, login(1)-like work */
 void
-do_login(Session *s, const char *command)
+call_record_login(Session *s)
 {
-	FILE *f;
-	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();

@@ -714,15 +712,30 @@
 		}
 	}

+	/* 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);
+}
+
+/* administrative, login(1)-like work */
+void
+do_login(Session *s, const char *command)
+{
+	FILE *f;
+	char *time_string;
+	char buf[256];
+	char hostname[MAXHOSTNAMELEN];
+	struct stat st;
+	time_t last_login_time;
+	struct passwd * pw = s->pw;
+
+	call_record_login(s);
+
 	/* 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
 	/*
 	 * If password change is needed, do it now.
@@ -1466,6 +1479,9 @@
 			/* Launch login(1). */

 			execl(LOGIN_PROGRAM, "login", "-h", hostname,
+#ifdef LOGIN_NEEDS_TERM
+			     s->term? s->term : "unknown",
+#endif
 			     "-p", "-f", "--", pw->pw_name, NULL);

 			/* Login couldn't be executed, die. */
---8<------8<------8<------8<---cut here--->8------>8------>8------>8---




More information about the openssh-unix-dev mailing list