PAM
Debian Packages
libpam-runtime libpam0g libpam-doc
References
- PAM web site
- http://www.kernel.org/pub/linux/libs/pam/
- System Administrator's Guide
- http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/Linux-PAM_SAG.html
- Local documentation 1
- /usr/share/doc/libpam-doc/Linux-PAM_SAG.txt.gz
- Local documentation 2
- each PAM has its own man page (e.g. man pam_unix)
- Wikipedia
- http://en.wikipedia.org/wiki/Pluggable_Authentication_Modules
Glossary
- PAM
- 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).
- auth
- 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.
- account
- 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.
- password
- 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.
- session
- 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
Overview
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 |
---|---|---|---|---|
pam_access.so | all | logdaemon style login access control based on login names, host or domain names, internet addresses or network numbers | kernel.org | |
pam_cracklib.so | all | Checks the password against dictionary words | kernel.org | |
pam_debug.so | all | Debug the PAM stack | kernel.org | |
pam_deny.so | all | Locking-out PAM module | kernel.org | |
pam_echo.so | all | Print text messages | kernel.org | |
pam_env.so | auth, session | Set/unset environment variables | kernel.org | |
pam_exec.so | all | Call an external command | kernel.org | |
pam_faildelay.so | auth | Change the delay on failure per-application | kernel.org | |
pam_filter.so | all | Filter module | kernel.org | |
pam_ftp.so | auth | Module for anonymous access | kernel.org | |
pam_group.so | auth | Module to modify group access | kernel.org | |
pam_issue.so | auth | Add issue file to user prompt | kernel.org | |
pam_keyinit.so | session | Display the keyinit file | kernel.org | |
pam_lastlog.so | session | Display date of last login | kernel.org | |
pam_limits.so | session | Limit resources | kernel.org | |
pam_listfile.so | all | Deny or allow services based on an arbitrary file | kernel.org | |
pam_localuser.so | all | Require users to be listed in /etc/passwd | kernel.org | |
pam_loginuid.so | session | Record user's login uid to the process attribute | kernel.org | |
pam_mail.so | auth, account | Inform about available mail | kernel.org | |
pam_mkhomedir.so | session | Create users home directory | kernel.org | |
pam_motd.so | session | Display the motd file | kernel.org | |
pam_namespace.so | session | Setup a private namespace | kernel.org | |
pam_nologin.so | auth, acct | Prevent non-root users from login | kernel.org | |
pam_permit.so | all | The promiscuous module | kernel.org | |
pam_rhosts.so | auth | Grant access using .rhosts file | kernel.org | |
pam_rootok.so | auth | Gain only root access | kernel.org | |
pam_securetty.so | auth | Limit root login to special devices | kernel.org | |
pam_selinux.so | session | Set the default security context | kernel.org | |
pam_shells.so | auth, account | Check for valid login shell | kernel.org | |
pam_succeed_if.so | all | Test account characteristics | kernel.org | |
pam_tally.so | auth, account | Login counter (tallying) module | kernel.org | |
pam_time.so | account | Time controled access | kernel.org | |
pam_umask.so | session | Set the file mode creation mask | kernel.org | |
pam_unix.so | all | Traditional password authentication | kernel.org | |
pam_userdb.so | auth, account | Authenticate against a db database | kernel.org | |
pam_warn.so | all | Logs all PAM items | kernel.org | |
pam_wheel.so | auth, account | Only permit root access to members of group wheel | kernel.org | |
pam_xauth.so | session | Forward xauth keys between users | kernel.org | |
pam_ldap.so | all | Authenticate against LDAP directories, and to change their passwords in the directory | arthurdejong.org |
Notes on specific module arguments
Overview
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.
use_first_pass
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
try_first_pass
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
use_authtok
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
nullok
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
nullok_secure
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 pam_unix.so auth required pam_unix.so nullok_secure password required pam_unix.so nullok obscure min=4 max=8 md5 session required pam_unix.so
LDAP authentication
Debian packages
Install the following Debian packages to get LDAP support for PAM:
libpam-ldapd
Note: In older Debian releases the main package was named libpam-ldap
. The modern name of that package is libpam-ldapd
. The modern package still provides a virtual package under the old name, presumably so that dependencies do not need to be changed.
References
- Local documentation 1
- /usr/share/doc/libpam-ldapd
- Local documentation 2
- man pam_ldap
- Design description
- https://arthurdejong.org/nss-pam-ldapd/design
The OpenLDAP and NSS pages in this wiki are also relevant (NSS because libpam-ldapd
shares its configuration with libnss-ldapd
).
Configuration
These are the questions that were asked by dpkg when the package was still named libpam-ldap
- it is not clear whether today the same questions would be asked for libpam-ldapd
.
- 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_ldapd can use this "root" DN e.g. when a password change is requested (this would work because /usr/bin/passwd has the setuid bit)
- outdated and potentially wrong information 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
- outdated and probably wrong information LDAP login user account = cn=readonly-users,ou=users,dc=herzbube,dc=ch
- Since nowadays the packages
libpam-ldapd
andlibnss-ldapd
access the LDAP directory via the same daemon,nslcd
, only one bind DN is needed, and currently the one fromlibnss-ldapd
is used (cn=libnss-ldap,ou=users,dc=herzbube,dc=ch
).
- Since nowadays the packages
- 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 this file:
/etc/nslcd.conf
Some of the questions/answers are shared with the package libnss-ldapd
, 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
Note: On my Debian system I run the command with the virtual (old) package name libpam-ldap
, not the name of the actual (modern) package libpam-ldapd
. This may be different on freshly installed systems. On my Debian system, which has several major OS upgrades behind it, the DebConf answers are still stored under the old package name.
Notes regarding permissions:
- The file
/etc/nslcd.conf
contains the password for the LDAP user. - The file is owned by
root:nslcd
and has mode 640. The reason for the group-readable permission is that thenslcd
daemon runs as usernslcd
.
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_ldapd 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_ldapd should only have write access to the ou=users subtree of the directory
- The "root" DN password would be stored in /etc/nslcd.conf
LDAP directory modifications
Because the packages libpam-ldapd
and libnss-ldapd
access the LDAP directory via the same daemon, nslcd
, only one bind DN is needed, and currently the one from libnss-ldapd
is used (cn=libnss-ldap,ou=users,dc=herzbube,dc=ch
).
See the NSS wiki page for details.
In the history of this wiki page information can be found about the old libnss-pam
package which was configured to use cn=readonly-users,ou=users,dc=herzbube,dc=ch
to access the LDAP directory.
potentially outdated information User account LDAP entries must have the following structure so that pam_ldapd 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.
In the history of this wiki page information can be found about a custom PAM configuration I developed when I was starting to work with LDAP. This custom configuration is no longer necessary because the default configuration provided by a modern stable Debian system runs just fine.