Debian Packages



PAM web site
System Administrator's Guide
Local documentation 1 
Local documentation 2 
each PAM has its own man page (e.g. man pam_unix)


Pluggable Authentication Modules. The name of the library/framework. Can also be used to refer to the modules themselves ("the PAM" (singular), or "the PAMs" (plural))
Conversation function 
A callback function that clients must supply PAM with; PAM modules can use the conversation function to acquire information from the client.
Authentication token 
Typically a password.

Overview: What is PAM

PAM is a framework that applications (services) can use to authenticate users and perform other authentication-related tasks. PAM decouples applications (services) from the concrete method of authentication that the application (service) should use.

A rough overview of how an authentication session might look when PAM is involved:

  • the user provides his credentials (usually a user name and a password) to some piece of application software
  • the application uses the API of the PAM system library to delegate checking whether the credentials are valid
  • the application identifies itself to PAM with a "service name"
  • PAM maps the service name to a configuration file in /etc/pam.d; for instance, a service named "imap" requires /etc/pam.d/imap to be present
  • PAM evaluates the configuration file to determine which authentication mechanism it should use to perform the check
  • the result of the check is reported back to the application

PAM service types

The PAM library provides different service types to its clients, each type deals with a separate type of management task. Some modules (e.g. pam_unix) can be used for all service types, while others provide only one or two service types (e.g. pam_env).

This service type provides authentication management. A module that provides this service type provides two aspects of authenticating the user: Firstly, it establishes that the user is who they claim to be, by instructing the application to prompt the user for a password or other means of identification. Secondly, the module can grant group membership or other privileges through its credential granting properties.
This service type provides non-authentication based account management. A module that provides this service type is typically used to restrict/permit access to a service based on the time of day, currently available system resources (maximum number of users) or perhaps the location of the applicant user -- 'root' login only on the console.
This service type provides password management. A module that provides this service type is required for updating the authentication token (e.g. a password) associated with the user. Typically, there is one module for each 'challenge/response' based authentication (auth) type.
This service type provides session management. A module that provides this service type is associated with doing things that need to be done for the user before/after they can be given service. Such things include the logging of information concerning the opening/closing of some data exchange with a user, mounting directories, etc.

The configuration file


A service's PAM configuration file lists the modules that will do the authentication tasks required by the service, and the appropriate behavior of the PAM-API in the event that individual modules fail.

The filename of a PAM configuration file must be in lower case. It represents the name of a service, usually a familiar application name such as login, sshd, samba or imap. A configuration file with the service name other is reserved for providing defaults.

Each line in the configuration file is a rule. A number of rules may be stacked to combine the services of a number of PAMs for a given authentication task. The format of each rule is this:

<service-type> <control> <module-path> <module-arguments>

service-type field

The service-type field refers to the service type (see chapter above) that the rule corresponds to. Possible values are:

  • account
  • auth
  • password
  • session

control field

The control field indicates the behavior of the PAM-API should the module fail to succeed in its authentication task. There are two types of syntax for this control field: the simple one has a single simple keyword; the more complicated one - which is not further explored on this page - involves a square-bracketed selection of value=action pairs. Possible keywords for control are:

  • required : failure of such a PAM will ultimately lead to the PAM-API returning failure but only after the remaining stacked modules (for this service and type) have been invoked
  • requisite : like required, however, in the case that such a module returns a failure, control is directly returned to the application. The return value is that associated with the first required or requisite module to fail. Note, this flag can be used to protect against the possibility of a user getting the opportunity to enter a password over an unsafe medium. It is conceivable that such behavior might inform an attacker of valid accounts on a system. This possibility should be weighed against the not insignificant concerns of exposing a sensitive password in a hostile environment.
  • sufficient : success of such a module is enough to satisfy the authentication requirements of the stack of modules (if a prior required module has failed the success of this one is ignored). A failure of this module is not deemed as fatal to satisfying the application that this type has succeeded. If the module succeeds the PAM framework returns success to the application immediately without trying any other modules.
  • optional : the success or failure of this module is only important if it is the only module in the stack associated with this type.
  • include : include all lines of given type from the configuration file specified as an argument to this control.
  • substack : include all lines of given type from the configuration file specified as an argument to this control. This differs from include in that evaluation of the done and die actions in a substack does not cause skipping the rest of the complete module stack, but only of the substack. Jumps in a substack also can not make evaluation jump out of it, and the whole substack is counted as one module when the jump is done in a parent stack. The reset action will reset the state of a module stack to the state it was in as of beginning of the substack evaluation.

module-path field

module-path is either the full filename of the PAM (it begins with a '/'), or a relative pathname from the default module location (/lib/security on my Debian machine)

module-arguments field

module-arguments are a space separated list of tokens that can be used to modify the specific behavior of the given PAM. Such arguments are documented for each individual module. To include spaces in an argument it must be surrounded with square brackets.

Include files

Configuration files may include other files. For instance, /etc/pam.d/other has the following content:

@include common-auth
@include common-account
@include common-password
@include common-session

A module overview

Module Services provided Description Links Comments all logdaemon style login access control based on login names, host or domain names, internet addresses or network numbers all Checks the password against dictionary words all Debug the PAM stack all Locking-out PAM module all Print text messages auth, session Set/unset environment variables all Call an external command auth Change the delay on failure per-application all Filter module auth Module for anonymous access auth Module to modify group access auth Add issue file to user prompt session Display the keyinit file session Display date of last login session Limit resources all Deny or allow services based on an arbitrary file all Require users to be listed in /etc/passwd session Record user's login uid to the process attribute auth, account Inform about available mail session Create users home directory session Display the motd file session Setup a private namespace auth, acct Prevent non-root users from login all The promiscuous module auth Grant access using .rhosts file auth Gain only root access auth Limit root login to special devices session Set the default security context auth, account Check for valid login shell all Test account characteristics auth, account Login counter (tallying) module account Time controled access session Set the file mode creation mask all Traditional password authentication auth, account Authenticate against a db database all Logs all PAM items auth, account Only permit root access to members of group wheel session Forward xauth keys between users all Authenticate against LDAP directories, and to change their passwords in the directory

Notes on specific module arguments


In the following sections, specific module arguments are discussed. The semantics of each argument is usually determined by quoting from the documentation of the pam_unix module. Hopefully, other modules retain these semantics.

Note: Usually PAMs have their own man page.


pam_unix documents the semantics of this argument like this:

The argument use_first_pass forces the module to use a previous stacked modules password and will never prompt the user - if no password is available or the password is not appropriate, the user will be denied access.

Some modules that support this argument:

  • pam_unix
  • pam_ldap


pam_unix documents the semantics of this argument like this:

Before prompting the user for their password, the module first tries the previous stacked module's password in case that satisfies this module as well.

Some modules that support this argument:

  • pam_unix
  • pam_ldap


pam_unix documents the semantics of this argument like this:

When password changing enforce the module to set the new password to the one provided by a previously stacked password module (this is used in the example of the stacking of the pam_cracklib module documented above).

Some modules that support this argument:

  • pam_unix
  • pam_ldap


pam_unix documents the semantics of this argument like this:

The default action of this module is to not permit the user access to a service if their official password is blank. The nullok argument overrides this default.

Some modules that support this argument:

  • pam_unix


This argument results from a Debian-specific patch to pam_unix which has not yet made it into upstream. The semantics of this, as explained by a post of Debian maintainer Steve Langasek, is:

The nullok_secure option was added to support passwordless pam_unix logins only from ttys listed in /etc/securetty. It was added because nullok was not considered an appropriate option to configure for all services, but there was a need to support passwordless root logins on tty2 on newly installed Debian systems when base-config has not yet been run to configure a root password.

Some modules that support this argument:

  • pam_unix

Debian specifics

Debian uses PAM by default. Various packages place their service file into /etc/pam.d. Most of them (including the other pseudo-service) include one or more of the "common" files.

There are 4 "common" include files, one for each of the 4 service types. By default, these files all use the pam_unix module which uses the regular /etc/passwd, /etc/group and /etc/shadow files.

These are the default factory rules (comments stripped away):

account    required
auth       required nullok_secure
password   required nullok obscure min=4 max=8 md5
session    required

LDAP authentication

Debian packages

Install the following Debian packages to get LDAP support for PAM:



Local documentation 1 
Local documentation 2 
man pam_ldap

Of course, the OpenLDAP page in this wiki is also relevant.


These are the questions asked by dpkg:

  • LDAP server URI = ldapi:///
  • Distinguished name of the search base = dc=herzbube,dc=ch
  • LDAP version to use = 3
  • Allow LDAP admin account to behave like local root? = No
    • Saying yes here (the default answer) will later ask for the DN of a "root" account
    • This "root" account DN will be used by pam_ldap when it is executed within a process for which geteuid() == 0
    • The idea is that the "root" DN has write access to the LDAP directory, and that pam_ldap can use this "root" DN e.g. when a password change is requested (this would work because /usr/bin/passwd has the setuid bit)
    • This is not necessary, however: the file /usr/share/doc/libpam-ldap/LDAP-Permissions.txt states that pam_ldap uses the user's DN for password changes
    • Because we have a special access rule in /etc/ldap/slapd.conf that allows the change of the userPassword attribute if the entry owning the attribute was used for authentication, the above behaviour of pam_ldap is therefore sufficient for password changes
    • Also see the notes further down for thoughts about saying "yes" to this question
  • Does the LDAP database require login? = Yes
    • We must say "yes" here because we have configured the LDAP server to disable anonymous binding
  • LDAP login user account = cn=readonly-users,ou=users,dc=herzbube,dc=ch
  • Password for LDAP login user = secret
  • Local encryption algorithm to use for passwords = clear
    • We must say "clear" here because the LDAP server stores passwords as SSHA hash
  • PAM profiles to enable
    • I don't know what to answer here, so I choose the default answer
    • The default answer enables the following profiles:
      • Unix authentication
      • LDAP Authentication
    • This DebConf question is called "libpam-runtime/profiles", i.e. the answer to the question is not stored together with the other answers

The answers are stored in


Some of the questions/answers are shared with the package libnss-ldap, so if that package has already been installed some questions may not be asked, the answers are simply taken from the DebConf database. To see a complete list of questions and answers that are stored in the DebConf database:

debconf-show libpam-ldap
# The answer to the question "PAM profiles to enable" is not stored
# under "libpam-ldap", so we need a second command to see that answer
debconf-show libpam-runtime

Notes regarding permissions:

  • The file /etc/pam_ldap.conf contains the password for the unprivileged LDAP user "auth". It is owned by root and has mode 644 (i.e. the file is world readable!!!).

Notes about the "root" DN:

  • If we say yes to the DebConf question "Allow LDAP admin account to behave like local root?", we must also specify a "root" DN
  • Usually I say "no" to the question, but I leave the following comments in this documentation if I re-decide at a later time
  • I would set the "root" DN to something like cn=libpam-ldap,ou=users,dc=herzbube,dc=ch
  • Under no circumstances would I give pam_ldap a "root" DN that actually has total super-user rights on the LDAP directory (e.g. a rootdn configuration in /etc/ldap/slapd.conf)
  • pam_ldap should only have write access to the ou=users subtree of the directory
  • The "root" DN password would be stored in /etc/pam_ldap.secret
  • The file would be owned by root and have mode 600

Directory modifications

After configuring libpam-ldap, modify the LDAP directory as follows:

  • Add an LDAP user cn=readonly-users,ou=users,dc=herzbube,dc=ch to the directory

Configure access rights in /etc/ldap/slapd.conf, then restart the LDAP daemon. The access rights can be derived from reading /usr/share/doc/libpam-ldap/LDAP-Permissions.txt:

  • Read-only access to the ou=users tree for readonly-users

User account LDAP entries must have the following structure so that pam_ldap can use them:

  • Must be located below ou=users,dc=herzbube,dc=ch (we have said so during the dpkg configuration process)
  • Must have an attribute uid whose value matches the user name provided to pam_ldap
  • Must have an attribute userPassword

Modify /etc/pam.d/common-* files

The default configuration provided by the Debian package(s) runs fine, no customization is necessary.

Obsolete PAM configuration to support LDAP

The information in this section is obsolete! The custom configuration described here might still work, but it is no longer necessary. I developed this custom configuration a long time ago when I was starting to work with LDAP. At that time I was still running Debian testing, first on some custom PC hardware and later on a MacMini. When I switched to running Debian stable (jessie) on a Dedicated Server, it turned out that the default configuration provided by the Debian package runs just fine. I'm keeping this section around for historical reasons.

Since most services include the common-* files, it makes sense to change these files to switch the entire system over to LDAP authentication in one go.

However, the matter is not resolved by simply replacing with This would require that system users (e.g. "root" and others) all need to have an LDAP entry. I don't care to maintain all these users in LDAP - for instance, if I install a Debian package and the installation process creates a new system user I would have to replicate this user in my LDAP directory. In addition, if the LDAP service ever goes down, I am completely locked out of the system because I cannot login anymore even with "root".

For these reasons, I implement the following scheme:

  • in its first attempt, PAM should try to consult the LDAP directory
  • if successful, stop here
  • if not successful (e.g. user was not found, or password did not match, or LDAP is down), fall back to traditional UNIX authentication (i.e.

This works for the following situations:

  • if a user exists in LDAP and the password matches, authentication succeeds through LDAP
  • if a user exists in LDAP and the password does not match: PAM will try traditional UNIX authentication, but I expect that the user does not exist in /etc/passwd, so both LDAP and traditional UNIX authentication fail
  • if a user does not exist in LDAP, traditional UNIX authentication rules apply


osgiliath:/etc/pam.d# cat common-account 
account [success=1 default=ignore]
account required
account required


osgiliath:/etc/pam.d# cat common-auth
# Line 1: Allow LDAP authentication to fail so that traditional UNIX
# authentication can handle system accounts (such as root) which are not
# maintained in LDAP. If LDAP authentication fails because the password did
# not match, it is expected that the user does not exist in /etc/passwd,
# so traditional UNIX authentication will fail, too.
# Line 2: use_first_pass lets pam_unix reuse the password that pam_ldap
# acquired from the user. If this option is missing, pam_unix will prompt
# the user for the password a second time.
# Line 3: This line is needed, so "success=1" in line 1 can skip over one
# module and still has a module to jump to. Without that, PAM segfaults!
auth [success=1 default=ignore]
auth required nullok_secure use_first_pass
auth required


osgiliath:/etc/pam.d# cat common-password
# Line 2: Don't specify use_first_pass or use_authtok! pam_ldap does not
# ask for a password if the user does not exist in LDAP, so pam_unix
# cannot reuse a previously entered password and will therefore always fail.
password [success=1 default=ignore]
password required nullok obscure min=4 max=8 md5
password required


osgiliath:/etc/pam.d# cat common-session 
session [success=1 default=ignore]
session required
session required