[PATCH]: Call pam_chauthtok from keyboard-interactive.

Darren Tucker dtucker at zip.com.au
Mon Oct 13 00:28:03 EST 2003


Hi All.
	This patch calls pam_chauthtok() to change an expired password via PAM
during keyboard-interactive authentication (SSHv2 only).  It is tested on
Redhat 8 and Solaris 8.

	In theory, it should have simply been a matter of calling pam_chauthtok
with the PAM_CHANGE_EXPIRED_AUTHTOK flag, it'd only change the password is
if it's expired, right?  From the Solaris pam_chauthtok man page:

[quote]
     PAM_CHANGE_EXPIRED_AUTHTOK
           The password service should only  update  those  pass-
           words  that have aged. If this flag is not passed, all
           password services should update their passwords.
[/quote]

	Imagine my complete lack of surprise when this turns out to not be the
case.  Even with that flag, Solaris attempts to change the password
regardless of whether or not it's expired.  To work around this, I call
do_pam_account early and cache the result to prevent pam_account_mgmt
being called twice.

	It works on Redhat.  Kind of.  The prompts don't have newlines where they
should, and although the password is updated successfully, the
last-changed time isn't, so you'll have to change it at each login. 
Annoying, and I don't know why it does that.

	Still to do: add newlines to prompt messages as appropriate.  Figure out
Linux last-changed problem.

	I'm interested in how this breaks on other platforms.  Comments?

-- 
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4  37C9 C982 80C7 8FF4 FA69
    Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.
-------------- next part --------------
Index: auth-pam.c
===================================================================
RCS file: /usr/local/src/security/openssh/cvs/openssh_cvs/auth-pam.c,v
retrieving revision 1.76
diff -u -p -r1.76 auth-pam.c
--- auth-pam.c	9 Oct 2003 04:20:15 -0000	1.76
+++ auth-pam.c	12 Oct 2003 14:01:45 -0000
@@ -52,6 +52,8 @@ RCSID("$Id: auth-pam.c,v 1.76 2003/10/09
 #include "auth-options.h"
 
 extern ServerOptions options;
+extern Buffer loginmsg;
+extern int compat20;
 
 #define __unused
 
@@ -117,6 +119,7 @@ static int sshpam_authenticated = 0;
 static int sshpam_new_authtok_reqd = 0;
 static int sshpam_session_open = 0;
 static int sshpam_cred_established = 0;
+static int sshpam_account_status = -1;
 
 struct pam_ctxt {
 	sp_pthread_t	 pam_thread;
@@ -231,6 +234,15 @@ sshpam_thread(void *ctxtp)
 	sshpam_err = pam_authenticate(sshpam_handle, 0);
 	if (sshpam_err != PAM_SUCCESS)
 		goto auth_fail;
+	if (compat20) {
+		if (do_pam_account() && sshpam_new_authtok_reqd) {
+			sshpam_err = pam_chauthtok(sshpam_handle,
+			    PAM_CHANGE_EXPIRED_AUTHTOK);
+			if (sshpam_err != PAM_SUCCESS)
+				goto auth_fail;
+			sshpam_new_authtok_reqd = 0; /* XXX: reset fwd flags */
+		}
+	}
 	buffer_put_cstring(&buffer, "OK");
 	ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer);
 	buffer_free(&buffer);
@@ -532,11 +544,16 @@ finish_pam(void)
 u_int
 do_pam_account(void)
 {
+	if (sshpam_account_status != -1)
+		return (sshpam_account_status);
+
 	sshpam_err = pam_acct_mgmt(sshpam_handle, 0);
 	debug3("%s: pam_acct_mgmt = %d", __func__, sshpam_err);
 	
-	if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD)
-		return (0);
+	if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) {
+		sshpam_account_status = 0;
+		return (sshpam_account_status);
+	}
 
 	if (sshpam_err == PAM_NEW_AUTHTOK_REQD) {
 		sshpam_new_authtok_reqd = 1;
@@ -547,7 +564,8 @@ do_pam_account(void)
 		no_x11_forwarding_flag |= 2;
 	}
 
-	return (1);
+	sshpam_account_status = 1;
+	return (sshpam_account_status);
 }
 
 void


More information about the openssh-unix-dev mailing list