Why is pam_unix.so set "required" even when LDAP is enabled?

On my Rocky Linux 9.3 machine, LDAP authentication is enabled by authselect and is working fine. I can ssh into this machine by both local accounts and LDAP-only accounts. However, my /etc/pam.d/password-auth, which is included by /etc/pam.d/sshd , seems to contradict the current behavior. It contains:

account     required                                     pam_unix.so
account     sufficient                                   pam_localuser.so
account     sufficient                                   pam_usertype.so issystem
account     [default=bad success=ok user_unknown=ignore] pam_sss.so
account     required                                     pam_permit.so

LDAP-only accounts fail in pam_unix.so (don’t they?). Because pam_unix.so is required, it appears to me that LDAP-only accounts would fail the whole account test (even if pam_sss.so succeeds). However, LDAP-only accounts do work in reality. Why?

man pam.conf says:

required: failure of such a PAM will ultimately lead to the PAM-API returning failure

sufficient: if such a module succeeds and no prior required module has failed the PAM framework returns success to the application

ok: this tells PAM that the administrator thinks this return code should contribute directly to the return code of the full stack of modules. In other words, if the former state of the stack would lead to a return of PAM_SUCCESS, the module’s return code will override this value. Note, if the former state of the stack holds some value that is indicative of a modules failure, this ‘ok’ value will not be used to override that value.
(emphasis by me)

Also in another question, required pam_unix.so caused a problem (as I expect).

Why is my system working?

Asked By: biochem_fan


Note that this for account, not auth. For the account component, man pam_unix says:

The account component performs the task of establishing the status of the user's account
and password based on the following shadow elements: expire, last_change, max_change,
min_change, warn_change. In the case of the latter, it may offer advice to the user on
changing their password or, through the PAM_AUTHTOKEN_REQD return, delay giving service to
the user until they have established a new password. The entries listed above are
documented in the shadow(5) manual page. Should the user's record not contain one or more
of these entries, the corresponding shadow check is not performed.

It won’t prevent you from logging in unless your (local) password is expired.

Also in another question, required pam_unix.so caused a problem (as I expect).

Actually, not as you expected. Check the accepted answer, which is from the OP of that question:

[The] problem on this was that since the pam authentication works in cascade, there is no reason to go ahead in the account service if you already have a local account. So the first line (pam_unix.so) is enough for an authentication. Previously the stack kept check also the pam_ldap.so because all three lines were required to login, and if the ldap service is down or unreachable, the authentication stack breaks.

Their problem wasn’t that pam_unix.so being required caused problems. It was that pam_ldap further down the stack caused problems when their LDAP service went down. Using sufficient instead of required allowed them to skip pam_ldap if pam_unix was successful. As verified by the OP of this question in the comments, pam_unix does return PAM_SUCCESS for non-local users, so the OP of the Stack Overflow question seems to have set a configuration which always (meaninglessly) succeeds for non-local users. The correct way seems to be to use pam_localuser instead like in this question.

Answered By: muru
Categories: Answers Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.