Darren Tucker
2003-Oct-12 14:28 UTC
[PATCH]: Call pam_chauthtok from keyboard-interactive.
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
Darren Tucker
2003-Oct-13 00:13 UTC
[PATCH]: Call pam_chauthtok from keyboard-interactive.
Darren Tucker wrote:> 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.[snip]> Still to do: add newlines to prompt messages as appropriate. Figure out > Linux last-changed problem.This version seems to fix those problems. I suspect that Redhat needed the call to pam_account_mgmt to the last-changed shadow entry ? I'm still interested in feedback about other platforms. -- 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 13 Oct 2003 00:05:25 -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); @@ -412,9 +424,9 @@ sshpam_query(void *ctx, char **name, cha case PAM_ERROR_MSG: case PAM_TEXT_INFO: /* accumulate messages */ - len = plen + strlen(msg) + 1; + len = plen + strlen(msg) + 2; **prompts = xrealloc(**prompts, len); - plen += snprintf(**prompts + plen, len, "%s", msg); + plen += snprintf(**prompts + plen, len, "%s\n", msg); xfree(msg); break; case PAM_SUCCESS: @@ -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
Andreas Girardet
2003-Oct-13 02:48 UTC
[PATCH]: Call pam_chauthtok from keyboard-interactive.
Unfortunately I tried this out on RH ES2.1 and RH 9.0 without success. The same issue still persists. I am unable to get any pw change prompt. As a sidenote. I had to apply the patch manually as the diff file did not patch cleanly on openssh-3.7.1p2. Cheers Andreas IBM Global Services - New Zealand Linux Team Linux Infrastructure project Office: +64-9-359-8761 email: girardet at nz1.ibm.com 13-17 Dundonald Street, Newton, Auckland, New Zealand
Darren J Moffat
2003-Oct-13 22:46 UTC
[PATCH]: Call pam_chauthtok from keyboard-interactive.
On Mon, 13 Oct 2003, Darren Tucker wrote:> 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.Which release of Solaris 8 and what additional patches do you have installed ? What does your pam.conf file look like ? If it has pam_unix.so entries then it is an older Solaris 8 if it has entries that look like pam_unix_auth.so and pam_authtokstore.so then it is a newer Solaris 8. -- Darren J Moffat
Darren Tucker
2003-Oct-14 03:02 UTC
[PATCH]: Call pam_chauthtok from keyboard-interactive.
Darren J Moffat wrote:> > On Mon, 13 Oct 2003, Darren Tucker wrote: > > > 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. > > Which release of Solaris 8 and what additional patches do you have installed ?2/02 with the recommended patch cluster from 5 Aug 2003.> What does your pam.conf file look like ? If it has pam_unix.so entries then > it is an older Solaris 8 if it has entries that look like pam_unix_auth.so > and pam_authtokstore.so then it is a newer Solaris 8.$ grep other /etc/pam.conf other auth requisite pam_authtok_get.so.1 other auth required pam_dhkeys.so.1 other auth required pam_unix_auth.so.1 other account requisite pam_roles.so.1 other account required pam_projects.so.1 other account required pam_unix_account.so.1 other session required pam_unix_session.so.1 other password required pam_dhkeys.so.1 other password requisite pam_authtok_get.so.1 other password requisite pam_authtok_check.so.1 other password required pam_authtok_store.so.1 -- 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.