Simple documentation about the format of PAM service configuration files.
A PAM service configuration file is a simple ASCII text file installed in /etc/pam.d/, describing the chain of modules to load and call to be able to fullfill one of four possible management facilities (account validation, authentication, password changing, and session handling). The comments, as often happens with Unix configuration files, are prefixed with a hash mark (#).
Every non-comment line of a PAM service file is composed of at least three elements: the management facility, the control directive and the parameter of this last one (always a module with the exclusion of the
include directive, that instead takes another service name) following these three elements there are optional parameters to pass to the module (they are not supported for
include ). When a single element needs to contain spaces, it can be quoted in between square parenthesis ( [ ] ), we'll see later where this is used.
The four facilities
The four management facilities are specified with a shortened version of their name:
||Verifies the validity of the account, whether it's expired, enabled, if login for that service is possible for that particular account. This is when you should check for /etc/nologin , presence in /etc/ftpusers , valid shell, and so on.||
||Handle the authentication of users: asks and checks password values, One-Time Passwords, smartcards, biometric scans, USB keys, and so on. This is probably the most critical facility as a mistake done by this chain might allow an attacker to spoof the identity of an user.||
||Takes care of changing the authentication data for the user (password, biometric data, smartcard public key, and so on).||
||Manages the session opened for the user, by setting up and destroying the environment as needed, this is the only chain that is called twice: at login and logout. Here you should call modules that handle mounting, chrooting, or changing various permissions.|
The order of each chain is related to the order in which the modules are listed in the configuration file; when you use the
include directive, the lines declaring and configuring the modules for that facility are read from the specified service file and expanded in the place of the
include line. The order of the four facilities is ignored, you can mix them.
# If this is the service file to read... auth required pam_foo1.so account required pam_foo2.so auth required pam_foo3.so account include other-service session required pam_foo4.so password required pam_foo5.so # And this is the other-service file... password required pam_bar1.so session required pam_bar2.so account required pam_bar3.so # The actual chains are equivalent to a file like this: auth required pam_foo1.so auth required pam_foo3.so account required pam_foo2.so account required pam_bar3.so password required pam_foo5.so session required pam_foo4.so
The control directives
The control directives - beside
include, that as we have seen just loads the content of the homologous chain in another file - tell PAM what to do when the module fails or succeeds. This is important because you usually want to treat failures and successes of the modules in different ways depending on the chain and on the semantic of the module. The directives for this are:
||The module success is necessary to allow the facility to complete, if this module fail, the facility will ultimately fail, but the rest of the chain is still executed.||
||Again, the module success is necessary to allow the facility to complete, but this time if the module fails, the chain is aborted immediately.||
||A success of the module will make the chain complete immediately; a failure, instead, will leave the response to the following modules. If the last module of a chain is sufficient and fails, the facility fails.||
||The result of this module is disregarded unless it's the last one to be executed, in which case the chain result will be the same as the result of the module (minus
||The result of the module will dictate the result of the whole chain: if it succeeds, it is treated like sufficient, and the chain will complete immediately, if it fails, it is treated like required, the chain will continue even if the final result will certainly be a failure.|
In addition to those, Linux-PAM also provides a more flexible way to define the behaviour of the modules, albeit quite more complex: you can decide what PAM will do in the various case (missing module, failure in loading the module, error in the call to the module's functions, failure of the implementation). To set this up, you need to pass a compless directive, quoted in square parenthesis ( [ ] ) as the second token of the line, and in it pass
condition=result couples, separated by commas, as needed. As this syntax is limited to Linux-PAM, and is usually more useful to advanced users than for default configurations, please refrain to use this syntax for the PAM service files installed by ebuilds.
Module name and parameters
The following token in the line is the module name; As modules are shared objects, they have the name pam_$something.so . A common mistake is to use the full path of the module for this token; although this works on basic setups, it is suboptimal for multilib architectures (like AMD64), where it breaks for the non-default ABI. So please always use just the base name of the library.
On AMD64, the 32-bit PAM modules come out of the
sys-libs/pampackage, and are just the default set. If your 32-bit software using PAM has a configuration that includes system-auth , the users will not be able to add extra modules to that service file. This is a drawback that needs to be tackled down soon.
After these three tokens, there are the parameters to pass to the modules. Each parameter is separated by whitespace, and as we said, if it contains spaces it should be quoted through square parenthesis ( [ ] ); this is the case for the SQL queries used together with the frontend modules for MySQL or PostgreSQL.
We would like to thank the following authors and editors for their contributions to this guide:
- Diego Pettenò