Linux (Ubuntu vs CentOS) LDAP Client for 389-ds - password policy

Solution 1:

I have been playing around with 389-ds on Ubuntu for a work project and came across the exact same issue.

I'm not sure about copying the config over from CentOS - I didn't have a box handy.

But when I looked and read up on PAM, it turned out to all be in the file /etc/pam.d/common-account.

pam_unix.so was above pam_ldap.so, and it also had [success=2 default=ignore], which means if it succeeds skip the next two rules, and for anything else, ignore the line.

Now since LDAP accounts are valid UNIX accounts since we added ldap to /etc/nsswitch.conf, this rule will return success and the pam_ldap.so module will never get run.

To get around this, my /etc/pam.d/common-account now looks like this:

# here are the per-package modules (the "Primary" block)
account [success=1 default=bad]  pam_succeed_if.so user ingroup auth-access quiet
account [success=reset default=bad]  pam_succeed_if.so uid <= 500 quiet
account [success=2 user_unknown=ignore default=ok]      pam_ldap.so
account [success=1 new_authtok_reqd=done default=ignore]        pam_unix.so
# here's the fallback if no module succeeds
account 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
account required                        pam_permit.so
# and here are more per-package modules (the "Additional" block)
# end of pam-auth-update config

As you can see, I've also added some rules in there to only allow users in either the LDAP group "auth-access", or system users with a UID below 500 to be seen as valid accounts.

And to explain a little:

We hit the first rule

account [success=1 default=bad]  pam_succeed_if.so user ingroup auth-access quiet

Which succeeds if the user is in that group and if so, we skip the next line as we know that'll fail (they're a valid LDAP user, so they won't have a system UID below 500) - if it doesn't succeed, return a fail (bad).

Then the next rule if it wasn't skipped

account [success=reset default=bad]  pam_succeed_if.so uid <= 500 quiet

So if this on succeeds (because the UID is below 500), reset the fail value set by the module above, because they won't be part of that LDAP group.

And the important part

account [success=2 user_unknown=ignore default=ok]      pam_ldap.so

Check the LDAP server for the account status - if it succeeds, we know an LDAP user is a valid UNIX user, so go ahead and skip the next two lines (to take us to pam_permit.so and let the user login). If the user is unknown to the LDAP server, ignore this line and move to the next one - and for all other statuses, "ok" means it's ok to pass those return codes as-is, which will pass things like password expired, etc.

And then:

account [success=1 new_authtok_reqd=done default=ignore]        pam_unix.so

We weren't a valid LDAP user if we hit this rule, so check if we're a valid system user - if succeed, skip next 1 line (takes us to pam_permit.so). Otherwise, ignore, which will take us to pam_deny.so.

Hope that helps explain a little more - the document that helped me if I wasn't very easy to understand was: http://uw714doc.sco.com/en/SEC_pam/pam-4.html

Regards, iamacarpet