AIX authenticate patches

Tom Bertelson tbert at abac.com
Mon May 15 22:53:48 EST 2000


Here are some patches to re-enable support for AIX's authenticate
routines.  With them, ssh will honor locked & unlocked accounts, record
successful and unsuccessful logins, and deny accounts that are
prohibited to log in via the network.  Tested with AIX 4.3.

It also includes a fix for handling SIGCHLD that may be needed for
other platforms (HP-UX 10.20, for example).

If I get the time I'll see about rolling these changes into liblogin,
where I guess they really belong.

I didn't include the changes to configure; run "autoconf" to rebuild the
configure script.

[Is this the correct method for submitting patches, posting them to the
list?]
-- 
Tom Bertelson           "Any sufficiently advanced technology
RHI Consulting           is indistinguishable from magic."
tbert at abac.com             -- Arthur C. Clarke
-------------- next part --------------
--- acconfig.h.orig	Tue May  9 09:50:13 2000
+++ acconfig.h	Tue May  9 09:50:19 2000
@@ -9,7 +9,7 @@
 /* Define if you want to disable PAM support */
 #undef DISABLE_PAM
 
-/* Define if you want to disable AIX4's authenticate function */
+/* Define if you want to enable AIX4's authenticate function */
 #undef WITH_AIXAUTHENTICATE
 
 /* Define if you want to disable lastlog support */
--- auth.c.orig	Wed May 10 16:00:39 2000
+++ auth.c	Thu May 11 13:11:23 2000
@@ -19,6 +19,9 @@
 #include "compat.h"
 #include "channels.h"
 #include "match.h"
+#ifdef HAVE_LOGIN_H
+#include <login.h>
+#endif
 
 #include "bufaux.h"
 #include "ssh2.h"
@@ -111,8 +114,20 @@
 	}
 
 #ifdef WITH_AIXAUTHENTICATE
-	if (loginrestrictions(pw->pw_name,S_LOGIN,NULL,&loginmsg) != 0)
+	if (loginrestrictions(pw->pw_name,S_RLOGIN,NULL,&loginmsg) != 0) {
+		if (loginmsg && *loginmsg) {
+			/* Remove embedded newlines (if any) */
+			char *p;
+			for (p = loginmsg; *p; p++)
+				if (*p == '\n')
+					*p = ' ';
+			/* Remove trailing newline */
+			*--p = '\0';
+			log("Login restricted for %s: %.100s",
+					pw->pw_name, loginmsg);
+		}
 		return 0;
+	}
 #endif /* WITH_AIXAUTHENTICATE */
 
 	/* We found no reason not to let this user try to log on... */
--- auth1.c.orig	Wed May 10 15:53:51 2000
+++ auth1.c	Thu May 11 15:13:37 2000
@@ -66,9 +66,7 @@
 	    get_remote_port());
 
 #ifdef WITH_AIXAUTHENTICATE 
-		if (strncmp(get_authname(type),"password",
-		    strlen(get_authname(type))) == 0)
-			loginfailed(pw->pw_name,get_canonical_hostname(),"ssh");
+	loginfailed(user,get_canonical_hostname(),"ssh");
 #endif /* WITH_AIXAUTHENTICATE */
 
 	/* Indicate that authentication is needed. */
@@ -408,8 +406,12 @@
 			client_user = NULL;
 		}
 
-		if (attempt > AUTH_FAIL_MAX)
+		if (attempt > AUTH_FAIL_MAX) {
+#ifdef WITH_AIXAUTHENTICATE 
+			loginfailed(pw->pw_name,get_canonical_hostname(),"ssh");
+#endif /* WITH_AIXAUTHENTICATE */
 			packet_disconnect(AUTH_FAIL_MSG, pw->pw_name);
+		}
 
 		/* Send a message indicating that the authentication attempt failed. */
 		packet_start(SSH_SMSG_FAILURE);
@@ -430,7 +432,7 @@
 	unsigned int ulen;
 	char *user;
 #ifdef WITH_AIXAUTHENTICATE
-	char *loginmsg;
+	extern char *aixloginmsg;
 #endif /* WITH_AIXAUTHENTICATE */
 
 	/* Get the name of the user that we wish to log in as. */
@@ -501,7 +503,9 @@
 
 	/* The user has been authenticated and accepted. */
 #ifdef WITH_AIXAUTHENTICATE
-	loginsuccess(user,get_canonical_hostname(),"ssh",&loginmsg);
+	/* We don't have a pty yet, so just label the line as "ssh" */
+	if (loginsuccess(user,get_canonical_hostname(),"ssh",&aixloginmsg) < 0)
+		aixloginmsg = NULL;
 #endif /* WITH_AIXAUTHENTICATE */
 	packet_start(SSH_SMSG_SUCCESS);
 	packet_send();
--- auth2.c.orig	Thu May 11 14:31:01 2000
+++ auth2.c	Thu May 11 15:16:21 2000
@@ -154,9 +154,9 @@
 	int authenticated = 0;
 	char *raw, *user, *service, *method, *authmsg = NULL;
 	struct passwd *pw;
-
-	if (++attempt == AUTH_FAIL_MAX)
-		packet_disconnect("too many failed userauth_requests");
+#ifdef WITH_AIXAUTHENTICATE
+	extern char *aixloginmsg;
+#endif /* WITH_AIXAUTHENTICATE */
 
 	raw = packet_get_raw(&rlen);
 	if (plen != rlen)
@@ -164,6 +164,12 @@
 	user = packet_get_string(&len);
 	service = packet_get_string(&len);
 	method = packet_get_string(&len);
+	if (++attempt == AUTH_FAIL_MAX) {
+#ifdef WITH_AIXAUTHENTICATE 
+		loginfailed(user,get_canonical_hostname(),"ssh");
+#endif /* WITH_AIXAUTHENTICATE */
+		packet_disconnect("too many failed userauth_requests");
+	}
 	debug("userauth-request for user %s service %s method %s", user, service, method);
 
 	/* XXX we only allow the ssh-connection service */
@@ -211,6 +217,12 @@
 
 	/* XXX todo: check if multiple auth methods are needed */
 	if (authenticated == 1) {
+#ifdef WITH_AIXAUTHENTICATE
+		/* We don't have a pty yet, so just label the line as "ssh" */
+		if (loginsuccess(user,get_canonical_hostname(),"ssh",
+				&aixloginmsg) < 0)
+			aixloginmsg = NULL;
+#endif /* WITH_AIXAUTHENTICATE */
 		/* turn off userauth */
 		dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error);
 		packet_start(SSH2_MSG_USERAUTH_SUCCESS);
--- config.h.in.orig	Tue May  9 03:00:57 2000
+++ config.h.in	Wed May 10 15:26:43 2000
@@ -12,6 +12,9 @@
 /* Define if you want to disable PAM support */
 #undef DISABLE_PAM
 
+/* Define if you want to enable AIX4's authenticate function */
+#undef WITH_AIXAUTHENTICATE
+
 /* Define if you want to disable lastlog support */
 #undef DISABLE_LASTLOG
 
--- configure.in.orig	Tue May  9 09:53:53 2000
+++ configure.in	Wed May 10 11:10:59 2000
@@ -32,6 +32,7 @@
 	if test "$LD" != "gcc" -a -z "$blibpath"; then
 		blibpath="/usr/lib:/lib:/usr/local/lib"
 	fi
+	AC_CHECK_FUNC(authenticate, [AC_DEFINE(WITH_AIXAUTHENTICATE)])
 	AC_DEFINE(BROKEN_GETADDRINFO)
 	;;
 *-*-hpux10*)
--- login.c.orig	Tue May  9 13:11:36 2000
+++ login.c	Tue May  9 13:10:40 2000
@@ -53,6 +53,10 @@
 get_last_login_time(uid_t uid, const char *logname,
 		    char *buf, unsigned int bufsize)
 {
+#if defined(WITH_AIXAUTHENTICATE)
+	/* This is done in do_authentication */
+	return (unsigned long) 0;
+#else
 #if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG)
 	struct lastlog ll;
 	char *lastlog;
@@ -128,6 +132,7 @@
 
 	return t;
 #endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
+#endif /* defined(WITH_AIXAUTHENTICATE) */
 }
 
 /*
@@ -242,7 +247,8 @@
 	login(&u);
 #endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */
 
-#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG)
+#if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) && !defined(WITH_AIXAUTHENTICATE)
+	/* AIX does this in do_authentication */
 	lastlog = _PATH_LASTLOG;
 
 	/* Update lastlog unless actually recording a logout. */
@@ -272,7 +278,7 @@
 			close(fd);
 		}
 	}
-#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */
+#endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) && !defined(WITH_AIXAUTHENTICATE) */
 }
 
 /* Records that the user has logged out. */
--- serverloop.c.orig	Wed May 10 14:34:00 2000
+++ serverloop.c	Thu May 11 08:17:17 2000
@@ -85,7 +85,6 @@
 	int save_errno = errno;
 	debug("Received SIGCHLD.");
 	child_terminated = 1;
-	signal(SIGCHLD, sigchld_handler2);
 	errno = save_errno;
 }
 
@@ -640,6 +639,7 @@
 			while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
 				session_close_by_pid(pid, status);
 			child_terminated = 0;
+			signal(SIGCHLD, sigchld_handler2);
 		}
 		channel_after_select(&readset, &writeset);
 		process_input(&readset);
--- session.c.orig	Wed May 10 10:23:59 2000
+++ session.c	Wed May 10 16:16:06 2000
@@ -27,6 +27,13 @@
 #include "ssh2.h"
 #include "auth.h"
 
+#ifndef WCOREFLG
+#define WCOREFLG		0200
+#endif
+#ifndef WCOREDUMP
+#define WCOREDUMP(stat)		((stat)&WCOREFLG)
+#endif
+
 /* types */
 
 #define TTYSZ 64
@@ -83,6 +90,10 @@
 /* data */
 #define MAX_SESSIONS 10
 Session	sessions[MAX_SESSIONS];
+#ifdef WITH_AIXAUTHENTICATE
+/* AIX's lastlogin message, set in auth1.c */
+char *aixloginmsg;
+#endif /* WITH_AIXAUTHENTICATE */
 
 /* Flags set in auth-rsa from authorized_keys flags.  These are set in auth-rsa.c. */
 int no_port_forwarding_flag = 0;
@@ -631,6 +642,15 @@
 				fclose(f);
 			}
 		}
+#if defined(WITH_AIXAUTHENTICATE)
+		/*
+		 * AIX handles the lastlog info differently.  Display it here.
+		 */
+		if (command == NULL && aixloginmsg && *aixloginmsg &&
+		    !quiet_login && !options.use_login) {
+			printf("%s\n", aixloginmsg);
+		}
+#endif
 		/* Do common processing for the child, such as execing the command. */
 		do_child(command, pw, s->term, s->display, s->auth_proto, s->auth_data, s->tty);
 		/* NOTREACHED */



More information about the openssh-unix-dev mailing list