Translation(s) : English - Français

(!) ?Discussion

Configuring LDAP Authentication

There are basically two ways to configure PAM to use an LDAP server. The first option utilizes the pam_ldap module from the libpam-ldap package to check credentials against the LDAP server. The second way uses password hashes sent from the LDAP server to the client using NSS. A traditional pam_unix module then does the authentication. In the later option, pam_ldap can still be used to change passwords. Both solutions have their pros and cons.

In both cases the users are exposed through NSS. Of note, the pam_unix option is required if using getent shadow to return password hashes when run as root.

The pure pam_ldap solution allows limiting logins by how users are stored in the directory (e.g. only allow logins for users in a certain piece of the directory, require some attribute, etc). It also requires less access rights to the LDAP directory and does not expose password hashes.

The pam_unix solution is possibly more familiar to system administrators.

PAM Setup with libpam-ldapd

libpam-ldapd is a newer alternative pam_ldap module implementation of the original PADL libpam-ldap. libpam-ldapd uses the same backend (nslcd) as libnss-ldapd, and thus also shares the same configuration file (/etc/nslcd.conf) for LDAP connection parameters. If you're already using libnss-ldapd for NSS, it may be more convenient to use libpam-ldapd's pam_ldap implementation.

As of pam 1.0.1-6 (Debian squeeze?), the /etc/pam.d/common-* files are managed by pam-auth-update (from libpam-runtime, see PAMConfigFrameworkSpec). The libpam-ldapd package includes /usr/share/pam-configs/ldap, and a dpkg-reconfigure libpam-runtime will let you configure the pam_unix/pam_ldap module(s) to use in /etc/pam.d/common-*.

Installing the libpam-ldapd package will automatically select the pam_ldap module for use in /etc/pam.d/common-*. The generated configuration is more suitable for use via @include in the various services in /etc/pam.d than the example configuration given below for libpam-ldap (e.g. login applies the auth optional after the @include common-auth).

PAM setup with libpam-ldap

In order to globally enable LDAP authentication through PAM, configure /etc/pam_ldap.conf accordingly and edit the /etc/pam.d/common-* files so that they contain something like this:


account     required
account     sufficient uid < 1000 quiet
account     [default=bad success=ok user_unknown=ignore]
account     required


auth    sufficient nullok_secure
auth    requisite uid >= 1000 quiet
auth    sufficient use_first_pass
auth    required


password    sufficient md5 obscure min=4 max=8 nullok try_first_pass
password    sufficient
password    required


session     required
session     required
session     optional

Note that there are numerous ways to configure PAM, depending on your particular situation and preference. The above only attempts to use pam_ldap if the userid is not below 1000 (i.e. normal user accounts).

PAM setup with pam_unix

(there have been reports that the following does not work as described, please correct if needed)

It is also possible to use plain old pam_unix by making sure /etc/nsswitch.conf contains something like shadow: files ldap and getent shadow shows password hashes.

If only authentication is needed, no changes to PAM configuration files should be necessary. For changing passwords, login shell and gecos install libpam-ldap, configure /etc/pam_ldap.conf and edit /etc/pam.d/common-password to contain something like this:

password   required ignore_unknown_user md5
password   optional nullok obscure min=4 max=8 md5 try_first_pass

Note the 'md5' setting. This will ensure passwords are encrypted into MD5 digests when they are changed. You may also need to add pam_password md5 to /etc/pam_ldap.conf for this to work.

Creating home directory on login

Until Bug #568577 not closed, you need to manually сreate file /usr/share/pam-configs/mkhomedir

Name: Create home directory during login
Default: yes
Priority: 900
Session-Type: Additional
        required umask=0022 skel=/etc/skel

and run command

sudo pam-auth-update

Allowing logins on a per-host basis

The pam_ldap module provides the ability to specify a list of hosts a user is allowed to log into, in the "host" attribute in LDAP. The host attribute can be specified multiple times for each user. If any of the entries match the hostname (of the machine logging in to), login is succesful. Otherwise, login is denied.

This feature is enabled by specifying pam_check_host_attr yes in /etc/pam_ldap.conf. When it is enabled, the account facility of pam_ldap will perform the checks and return an error when no proper host attribute is present.

The hostname in the "host" attribute on the user can be prefixed with "!" to deny access to that host for that user. This is mostly useful in conjunction with the special entry "*", which allows access to all hosts.

To add the "host" attribute to a user, he should have an objectClass that supports this. The "account" objectClass has the attribute, but is not compatible with the "inetOrgPerson" objectClass. To work around this, you can use the "ldapns" schema, supplied with the libpam-ldap package. This schema provides the "hostObject" objectClass, which has the proper "host" attribute.

To enable this schema, add the following line to your slapd.conf:

include         /usr/share/doc/libpam-ldap/ldapns.schema

Finally, take care that the hostname of the server is resolvable. pam_ldap will try to resolve the hostname, to find any aliasses (such as listed in /etc/hosts). If the hostname is not resolvable, access is denied.

In order to enable host based authentication with libpam-ldapd one can use nslcd with pam_authz_search option.

The pam_check_host_attr option can be emulated with this filter:


You might need something more elaborate if you want to have negation (!host) capability. E.g.:


see man nslcd.conf for more details.

Allowing logins on a per-group basis

A common task is to restrict logins to a given LDAP group. With NIS, you would do this with careful tweaking of your /etc/passwd file. With LDAP, the easiest way is to use the pam_access module that comes with libpam-modules.

Add the following line to /etc/pam.d/common-auth:

auth required

(This doesn't seem to affect logins using an SSH key unless auth is replaced by account?)

This will activate /etc/security/access.conf, to which you can tweak as follows:

# disallow all except people in the login group and root

This assumes you have a posixGroup named login in your LDAP tree with LDAP/NSS set up properly. Be careful about ensuring that you can still allow local users to login in case LDAP fails.

An alternative way for "logins on a per-group basis" is nslcd. With pam_authz_search option one can define not only primary groups as with pam_access but also check against secondary groups or even mixture of primary and secondary groups.

For example we want to allow users whose primary ldap group is admins ( gidNumber 1234 ) and also members of group developers ( secondary group ) The following filter should do the trick:

#allow only memebers of secondary group developers and users with primary group admins
pam_authz_search (|(&(objectClass=posixGroup)(cn=developers)(memberUid=$username))(&(objectClass=posixAccount)(uid=$username)(gidNumber=1234)))

Permissions on the LDAP server

To get 'chsh' and 'chfn' to work for updating LDAP, you have to have the right settings in their /etc/pam.d/ entries, and you have to setup slapd.conf to allow access for users to update their entries. If needed, add something like this to slapd.conf:

  access to attrs=loginShell
         by dn="cn=admin,dc=FOO,dc=BAR" write
         by self write
         by * read

  access to attrs=gecos
         by dn="cn=admin,dc=FOO,dc=BAR" write
         by self write
         by * read

Caching LDAP credentials for offline use (Laptops)

Disclaimer: This information was tested with Debian Lenny.

While contineous LDAP connectivity can be assumed for workstations and servers in a LAN, laptop users often do not have network connectivity. From a system administrators point of view it is tempting to create local users on the laptop but this causes trouble because you have to manage several password stores. On the other side, the situation where a user cannot login because the laptop cannot reach the LDAP server is unacceptable too.

Luckily the PAM stack has a way to cache the password information through the use of the PAM module libpam-ccreds. In short terms this module stores the password hash if a user has correctly authenticated through the PAM LDAP module. If the LDAP server is later unavailable to PAM, it uses ccred's locally cached credentials to authenticate the user.

The documentation in /usr/share/doc/libpam-ccreds/ is not using the default Debian Lenny scheme of splitted PAM config files in /etc/pam.d/ but it is easy to split the pam.conf in the examples dir into the several common-* files in /etc/pam.d/. At a minimum /etc/pam.d/common-auth has to be changed.

Unfortunately the example PAM configuration does not work out of the box with a standard Lenny installation. In some offline situations the ccred module is not used at all (you get a message in a text-mode login when libpam-ccreds is used). You can change /etc/pam.d/common-auth like this to get it working:

auth sufficient /lib/security/
auth [authinfo_unavail=ignore success=1 default=2] /lib/security/ use_first_pass
auth [default=done]     /lib/security/ action=validate use_first_pass
auth [default=done]     /lib/security/ action=store
auth [default=bad]      /lib/security/ action=update

Other alternatives:

Hint: Offline caching of LDAP credentials is only useful if LDAP information about users and groups is also available offline through NSS. This can be accomplished through the use of NSCD. See LDAP/NSS for more information.

LDAP server in Pass-through-mode

(Tested with wheezy.)

This setup example is a solution, if you have your own LDAP-server for e.g. a workgroup, but account management is done from a central LDAP server e.g. from a university. Point is: You have to be able to authenticate to 2 different LDAP servers. If server 1 accepts you, you should be logged in. If not, you should be delegated to server 2.

Solution 1 would be to configure the pam-stack with 2 entries with different config files, cf. this debian bug report. However, as mentioned there, you have to patch and build your own version of pam_ldap - at least at the moment. Furthermore, this is not the most elegant solution. Your client and server 1 both have 1 unsuccessful authentication attempt each time a user from server 2 logs in.

Solution 2 is LDAP pass-through authentication. It's an elegant solution, but it's not easy to configure:

Testing your solution

See also