[PATCH] Do PAM chauthtok via keyboard-interactive.
Darren Tucker
dtucker at zip.com.au
Mon Dec 8 00:41:47 EST 2003
Hi All.
Attached is another patch that attempts to do pam_chauthtok() via SSH2
keyboard-interactive authentication. It now passes the results from the
authentication thread back to the monitor (based on a suggestion from
djm).
Because of this, it doesn't call do_pam_account twice and consequently
now works on AIX 5.2, which the previous version didn't. I haven't tested
it on any other platforms yet, but there were few other changes so it
should still work (famous last words :-)
I would be interested to know if it works with unusual PAM configurations
or platforms other than those I can test on.
--
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.84
diff -u -p -r1.84 auth-pam.c
--- auth-pam.c 21 Nov 2003 12:56:47 -0000 1.84
+++ auth-pam.c 7 Dec 2003 13:23:38 -0000
@@ -53,6 +53,7 @@ RCSID("$Id: auth-pam.c,v 1.84 2003/11/21
extern ServerOptions options;
extern Buffer loginmsg;
+extern int compat20;
#define __unused
@@ -118,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;
static char **sshpam_env = NULL;
struct pam_ctxt {
@@ -144,6 +146,21 @@ pam_getenvlist(pam_handle_t *pamh)
}
#endif
+void
+pam_password_change_required(int reqd)
+{
+ sshpam_new_authtok_reqd = reqd;
+ if (reqd) {
+ no_port_forwarding_flag |= 2;
+ no_agent_forwarding_flag |= 2;
+ no_x11_forwarding_flag |= 2;
+ } else {
+ no_port_forwarding_flag &= ~2;
+ no_agent_forwarding_flag &= ~2;
+ no_x11_forwarding_flag &= ~2;
+
+ }
+}
/* Import regular and PAM environment from subprocess */
static void
import_environments(Buffer *b)
@@ -152,6 +169,13 @@ import_environments(Buffer *b)
u_int i, num_env;
int err;
+ /* Import variables set by do_pam_account */
+ sshpam_account_status = buffer_get_int(b);
+ sshpam_new_authtok_reqd = buffer_get_int(b);
+
+ if (sshpam_new_authtok_reqd == 1)
+ pam_password_change_required(1);
+
/* Import environment from subprocess */
num_env = buffer_get_int(b);
sshpam_env = xmalloc((num_env + 1) * sizeof(*sshpam_env));
@@ -290,9 +314,28 @@ 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()) {
+ if (sshpam_new_authtok_reqd) {
+ sshpam_err = pam_chauthtok(sshpam_handle,
+ PAM_CHANGE_EXPIRED_AUTHTOK);
+ if (sshpam_err != PAM_SUCCESS)
+ goto auth_fail;
+ pam_password_change_required(0);
+ }
+ } else {
+ goto auth_fail;
+ }
+ }
+
buffer_put_cstring(&buffer, "OK");
#ifndef USE_POSIX_THREADS
+ /* Export variables set by do_pam_account */
+ buffer_put_int(&buffer, sshpam_account_status);
+ buffer_put_int(&buffer, sshpam_new_authtok_reqd);
+
/* Export any environment strings set in child */
for(i = 0; environ[i] != NULL; i++)
; /* Count */
@@ -611,22 +654,22 @@ 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_NEW_AUTHTOK_REQD) {
- sshpam_new_authtok_reqd = 1;
-
- /* Prevent forwardings until password changed */
- no_port_forwarding_flag |= 2;
- no_agent_forwarding_flag |= 2;
- no_x11_forwarding_flag |= 2;
+
+ if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) {
+ sshpam_account_status = 0;
+ return (sshpam_account_status);
}
- return (1);
+ if (sshpam_err == PAM_NEW_AUTHTOK_REQD)
+ pam_password_change_required(1);
+
+ sshpam_account_status = 1;
+ return (sshpam_account_status);
}
void
More information about the openssh-unix-dev
mailing list