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