Hello, My initial attempt at pseudo-code of the example was incorrect, I missed the default=done bit. Next attempt: pam_unix.so if (!success) { pam_ldap.so use_first_pass if (authinfo_unavail) { pam_ccreds.so action=validate use_first_pass } else if (success) { pam_ccreds.so action=store } else { pam_ccreds.so action=update } } Now this makes more sense (action=update - delete - is only called if authentication failed). Your patch produces something a bit different: # here are the per-package modules (the "Primary" block) auth [success=4 default=ignore] pam_unix.so nullok_secure auth [success=3 default=ignore] pam_ldap.so use_first_pass auth [success=2 default=ignore] pam_ccreds.so action=validate use_first_pass auth [default=ignore] pam_ccreds.so action=update # here's the fallback if no module succeeds auth requisite pam_deny.so # prime the stack with a positive return value if there isn't one already; # this avoids us returning an error just because nothing sets a success code # since the modules above will each just jump around auth required pam_permit.so # and here are more per-package modules (the "Additional" block) auth optional pam_ccreds.so action=store auth optional pam_smbpass.so migrate # end of pam-auth-update config Which I think is more like: pam_unix.so nullok_secure if (!success) { pam_ldap.so use_first_pass } if (!success) { pam_ccreds.so action=validate use_first_pass } if (!success) { pam_ccreds.so action=update pam_deny.so } ... pam_ccreds.so action=store I guess the main difference is the example will only fall back to action=validate if pam_ldap.so returns authinfo_unavail, where as this will fall back to pam_ccreds.so if the passwords mismatch. ie. consider the case when the user's LDAP password has been changed. Maybe the old password was compromised. Obviously the old password will still be valid with the network disconnected. However, here both the old and new passwords will be valid when the system is connected to the network again, until the user enters the new password at least once. I could imagine this could be potentially confusing. Another difference is it will call action=update if the user enters the password incorrectly, and there is no network connection. If I try to log in using cached credentials, it seems to work fine, but then kicks me off again. % ssh localhost brian@localhost's password: You have been logged on using cached credentials. Connection closed by 127.0.0.1 Oh, right, this is probably because /etc/pam.d/common-account was not updated. The example config is: account [user_unknown=ignore authinfo_unavail=ignore default=done] pam_unix.so account [user_unknown=ignore authinfo_unavail=ignore default=done] pam_ldap.so account required pam_permit.so I don't know why the "user_unknown=ignore" is required, I think the important part is the "authinfo_unavail=ignore" for the pam_ldap.so line. Or in the case of the intrepid file, I added "authinfo_unavail=1" to skip the pam_deny.so For now I am going to investigate why the action=update doesn't seem to have any affect. Brian May