On systems that have expired passwords in /etc/shadow but don't have PAM available or on which it can't be used, OpenSSH should prompt to change the password. I have a patch which I will attach. Most of the preparation work has already been done in native OpenSSH.
Created attachment 5 [details] add suggested patch
i will work on integrating this, but i want to see if it makes sense for some more of it to be in native.
assign to stevesk
A Couple of comments on the patch: 1. I'd prefer to see the stanza in do_exec broken out into a seperate function. 2. The patch should match the behaviour of PAM expired passwords. i.e. allow password change if a pty is assigned, disconnect with an error message otherwise.
Responses to Damien: 1. I don't think it will simplify things much if it is made into a separate function, but if the person who integrates the patch would like to do it that way that's fine with me. 2. The patch already does exit with an error if there's no pty assigned, I don't understand your point.
*** Bug 116 has been marked as a duplicate of this bug. ***
hm, the patch allows tcp forwarding with expired passwds
Looks like it should also set no_port_forwarding_flag = 1
*** Bug 226 has been marked as a duplicate of this bug. ***
i'm not immediately positive if no_port_forwarding_flag=1 is sufficient. need to investigate more.
Created attachment 199 [details] Implement password change via /bin/passwd in session. openssh-passexpire10.patch: * Implementes shadow and AIX password expiry. * Adds general expire_message and login_message Buffers to replace platform-specific variables. * Implements PasswordExpireWarningDays and ForcedPasswdChange options. * Uses SIGUSR1 to reset password change flag. * Net reduction in #ifdefs. Tested on AIX, Solaris and Redhat.
I have had a quick look over the patch. It looks good, though I am unsure about the extra options (can't we always get these from shadow?). It is very tempting to ignore PAM password changing (for the non-kbdint case) and just use this method - on a PAM enabled system, passwd should be PAM enabled too.
I had seen those options in a man page for ssh-1.2.something and assumed that they would be needed. For PasswordExpireWarningDays, you're right, I missed the sp_warn field in spwd. AIX doesn't need it either, its warning messages are generated by passwdexpired(). Not sure about ForcedPasswdChange, should the admin have this option? (if you don't want password expiry then don't turn it on) The last time someone suggested PAM-chauthtok-via-passwd the objection was that passwd used the "passwd" PAM service and sshd used the "sshd" service and they might do different things (although normally they don't). Is this a PAM-purist thing? (Changed platform to "All", this bug covers a lot of them).
Created attachment 200 [details] passexpire-11: Put back shadow expiry and delete options openssh-passexpire-11: I screwed up the last merge from cvs and the shadow stuff wasn't there. This one adds it back in, uses spw->sp_warn and removes the options.
passexpire-11 is broken (doesn't correctly check for change), please ignore. I'm working on a fix.
Created attachment 201 [details] passexpire12: password expiry via /bin/passwd in session Now (correctly I hope!) checks that the password is changed successfully. Adds is_password_change_required() and privsep wrapper. This re-tests the account and resets the change flag. This is necessary because passwd sometimes does not return a failure exit code (eg AIX in the "your password has been expired too long and only the admin can change it" case). Tested on AIX 4.3.3, Solaris 8 and Redhat 8. Should work on any platform with /etc/shadow and any version of AIX 4 (unsure about previous versions). The equivalent patch against the 3.5p1 release is at http://www.zip.com.au/~dtucker/openssh/openssh-3.5p1-passexpire12.patch.
Created attachment 205 [details] passexpire13: add support for comma-in-passwd expiry This patch against the cvs tree adds support for comma-in-password-type password expiry, in addition to AIX and /etc/shadow support. This requires pw_age in struct passwd and includes a configure test for this. Also include cosmetic changes (eg "1 days left" -> "1 day left"). Tested on HP-UX 11.00 non-trusted config. It should be possible to support trusted config without PAM via getprpwnam and friends, but this has not been written yet.
Created attachment 215 [details] passexpire15: removes privsep call, HP-UX support Adds /bin/passwd-in-session password expiration support. * configure finds passwd * supports /etc/shadow & AIX platforms * uses SIGUSR1 to reset forwarding flags after successful change * warns users of impending account/password expiry * generates and stores AIX & PrintLastLog messages before privsep split (this also fixes bug #463). Changes relative to previous patch: * remove invalid privsep call * remove HP-UX password expiry * detects over-expired AIX password (this will cause passwd to bomb without setting a failure code and thus let the user login) This patch is a cleanup, I don't intend making any further changes unless a flaw is discovered. If it gets in and there's sufficient interest I'll look at re-implementing the HP-UX support (which currently can only do expiry through PAM). The equivalent patch against 3.5p1 will be available at http://www.zip.com.au/~dtucker/openssh/openssh-3.5p1-passexpire15.patch I'd like to acknowledge that these patches are originally based on patches by Pablo Sor (psor at afip gov ar) and Mark Pitt (mark.pitt at ch ibm com) and the AIX loginsuccess() changes are based on work by Kevin Cawlfield (cawlfiel at austin ibm com).
Created attachment 234 [details] passexpire16: AIX & /etc/shadow password expiry Equivalent patch against 3.5p1 at http://www.zip.com.au/~dtucker/openssh/openssh-3.5p1-passexpire16.patch. Eliminates double call of generate_login_message() when authentication is postponed.
Created attachment 240 [details] passexpire17: AIX & /etc/shadow password expiry Enabled basic PAM password expiry support. This accounts for about half the problems reported with these patches (ie people configuring this patch --with-pam, which didn't work previously). Fixed problem where forced-password changes (passwd -f) did not work when account expiry was not enabled. Re-ordered to test for forced change first. Same patch against 3.5p1 release at http://www.zip.com.au/~dtucker/openssh/openssh-3.5p1-passexpire17.patch
Created attachment 248 [details] passexpire18: AIX & /etc/shadow password expiry Fixed double-change bug when PAM was enabled. Removed resetting forwarding flags via SIGUSR1. Same patch against 3.5p1 release is available at http://www.zip.com.au/~dtucker/openssh/openssh-3.5p1-passexpire18.patch
Patch against 3.6.1p1 now available. No changes apart from diff'ing against 3.6.1p1. http://www.zip.com.au/~dtucker/openssh/openssh-3.6.1p1-passexpire18.patch
Created attachment 278 [details] passexpire19: AIX and /etc/shadow password expiry Only a small change: now takes S_MAXAGE into account when checking for over-expired passwords. Report and fix from Ravinder Sekhon. Patch against 3.6.1p2 is at http://www.zip.com.au/~dtucker/openssh/openssh-3.6.1p2-passexpire19.patch
Scott Burch found a bug in the PAM+PrivSep case which would cause password changes to fail. Binaries compiled without PAM are not affected. There's an updated patch against 3.6.1p2: http://www.zip.com.au/~dtucker/openssh/openssh-3.6.1p2-passexpire20.patch I'm not going to update the patch against -current until bug #463 is sorted out one way or another since it adds some infrastructure (Buffer loginmsg and a monitor call) that this patch needs.
Since people have asked about it, there's a patch against 3.7.1p1 here: http://www.zip.com.au/~dtucker/openssh/openssh-3.7.1p1-pwexp24.patch
Created attachment 540 [details] Hook shadow expiry into do_pwchange This is basically a simple move of the existing shadow password expiry check from auth.c into a new file auth-shadow.c, plus the hook to call it from auth-passwd.c.
Created attachment 541 [details] Hook AIX password expiry into do_pwchange This moves the AIX implementation of sys_auth_passwd to openbsd-compat/port-aix.c and adds checking for expired passwords.
Should have mentioned with earlier patches: OpenSSH -current now contains support for changing expired passwords by exec'ing /usr/bin/passwd. The previous 2 patches will apply only to recent snapshots.
Created attachment 542 [details] Hook the SSHv1 PAM password expired case into do_pwchange Call do_pwchange for expired PAM passwords when Protocol=1 and UsePrivilegeSeparation=yes.
Created attachment 543 [details] Use do_pwchange for SSHv1 password change without privsep Also replaces sshpam_new_authtok_reqd with session->force_pwchange and removes redundant functions from auth-pam.c.
Comment on attachment 543 [details] Use do_pwchange for SSHv1 password change without privsep >+ if (options.use_pam && !use_privsep && s->authctxt->force_pwchange) { >+ display_loginmsg(); > do_pam_chauthtok(); > /* XXX - signal [net] parent to enable forwardings ... >- if (s->authctxt->force_pwchange) { >+ if (s->authctxt->force_pwchange && !(options.use_pam && !use_privsep)) { > do_setusercontext(pw); > child_close_fds(); > do_pwchange(s); What about the use_pam == 1, use_privsep == 1 and authctxt->force_pwchange == 1 case?
Comment on attachment 540 [details] Hook shadow expiry into do_pwchange I'm not sure we need a while auth-shadow.h for a single function - is there anywhere else the prototype could be stashed? (even as an extern in the file where it is used) Otherwise OK.
Comment on attachment 541 [details] Hook AIX password expiry into do_pwchange looks OK to me, but you are the AIX expert.
> What about the use_pam == 1, use_privsep == 1 and authctxt->force_pwchange == 1 case? This one will catch that: + if (s->authctxt->force_pwchange && !(options.use_pam && !use_privsep)) [...] do_pwchange() = 1 && !(1 && !1) = 1 && !(0) = 1 && 1 do_pam_chauthtok() should only be called for use_pam = 1 and use_privsep = 0. The logic could possibly be clearer, though.
> I'm not sure we need a while auth-shadow.h for a single function I had thought that other shadow functions would go there too, eg auth_shadow_acctexpired(). We could put them in auth.h instead and add auth-shadow.h should it ever be worth it.
Could it be simplified by resetting authctxt->force_pwchange after do_pam_chauthtok()?
Created attachment 544 [details] Use do_pwchange for SSHv1 password change without privsep > Could it be simplified by resetting authctxt->force_pwchange after > do_pam_chauthtok()? Yeah, much neater. Tidied up the extra debugs in auth-pam too.
Comment on attachment 544 [details] Use do_pwchange for SSHv1 password change without privsep fine by me
Patches 540, 541 & 544 applied. Yeehaa....
Mass change of RESOLVED bugs to CLOSED