A.1 Pluggable Authentication Modules

The concept of Pluggable Authentication Modules (PAM) was first designed by Sun Microsystems' SunSoft development group and is defined in the Open Software Foundations RFC 86.0. PAM provides a framework that allows vendors and administrators to customize the services used to authenticate users on a local computer system. For example, logging onto the console of a system may require stronger authentication than logging into a host across the network via ssh. Configuring systems to use different PAM modules (e.g., smart cards or passwords) for different services (e.g., login or ssh) allows administrators to implement as much or as little security as the systems require.

In practice, administrators are exposed to this framework through shared libraries that implement various security, accounting, or account management policies. On Linux and Solaris systems, you can list the installed PAM modules by examining the contents of /lib/security. The most commonly used module for normal lookups in the system list of accounts (including /etc/shadow) is the pam_unix.so library. Linux's PAM implementation includes a drop-in replacement module named pam_pwdb.so, which relies on the generic interface to the Password Database library (http://www.kernel.org/pub/linux/libs/pam/modules.html).

PAM is a framework for authentication and authorization. Authentication is the process of proving you are who you say you are, while authorization is the process of determining what you are allowed do, given that you have established your identity. Applications can query the PAM interface to ask questions about a user or to inform a PAM module of a particular event. For example, "Does this password match with this login name?", "Is this user allowed to log onto this host at 10 p.m. on a Saturday?", "The user named smitty logged onto the local system on Thu Dec 19 21:04:27 CST 2002," or "Change this user's password to secret." In each case, the application uses a specific module to process each type of questions or event that can occur during the logon process.

A.1.1 Configuring PAM

PAM configuration files follow one of two formats. In modern Linux distributions, each application or service that possesses an individual configuration file is located in the directory /etc/pam.d/. Each file is usually named after the type of service it controls. For example, Qualcomm's Qpopper server, a POP3 daemon, uses the PAM file /etc/pam.d/pop3, and the login service is configured by the file /etc/pam.d/login. Here's a valid configuration for a PAM-enabled login service:

## /etc/pam.d/login 
## Log in using entries from /etc/[password|shadow].
auth       required   /lib/security/pam_unix.so
## Allow root logons only from a tty listed in /etc/securetty.
auth       required   /lib/security/pam_securetty.so
## Don't allow logins (except root) if /etc/nologin exists.
auth       required   /lib/security/pam_nologin.so
## Ensure that account and password are active and have not expired.
account    required   /lib/security/pam_unix.so
## Log username via syslog.
session    required   /lib/security/pam_unix.so
## Enforce good passwords.
password   required   /lib/security/pam_cracklib.so
## Change the password in /etc/[password|shadow].
password   required   /lib/security/pam_unix.so

The older type of PAM configuration file, still supported on Solaris, places information for all services in one file, /etc/pam.conf. In the absence of the /etc/pam.d/ directory, the Linux-PAM implementation will fall back to using pam.conf. This file is similar to the newer PAM configuration file, except that the first entry on each line is the name of the service being configured. In newer configuration files (such as the login file listed above), the name of the service is taken from the filename. Given these rules, you could rewrite the login configuration file into an old-style pam.conf file like this:

## /etc/pam.conf
## Previous entries and comments (for other services) deleted
login   auth       required   /lib/security/pam_unix.so
login   auth       required   /lib/security/pam_securetty.so
login   auth       required   /lib/security/pam_nologin.so
login   account    required   /lib/security/pam_unix.so
login   session    required   /lib/security/pam_unix.so
login   password   required   /lib/security/pam_cracklib.so
login   password   required   /lib/security/pam_unix.so

The general syntax of a PAM configuration file in /etc/pam.d/ is:

module-type   control-flag   module-path   arguments

A PAM module may implement any of the four defined module-types:


These modules perform authentication, including the familiar password lookups from /etc/passwd and /etc/shadow.


These modules perform certain account management functions that aren't related to authentication. For example, an account module might restrict users other than root or members of the wheel group from changing their user IDs (i.e., using /bin/su). These modules often deal with authorization, but they can perform tasks that aren't related; for example, an account module might warn a user that his password is about to expire, and should be changed.


These modules provide session management functions before or after a user can access a particular service. For example, a session module might check for new mail or mount the user's home directory.


These modules update authentication tokens for the user. There is normally one password module for each auth module defined for a service when the authentication process requires some type of credentials from the user.

Each module type can accept one of four control-flags that determine how the module interacts with other modules. These flags are:


Indicates that this module must succeed for the authentication (or authorization) to succeed. Control is not returned to the requesting application until all of the modules have been called.


Indicates that success of this module is sufficient for authentication to succeed, assuming that no previously listed required modules have failed. In this case, no other modules in the service configuration file are executed, and control returns to the calling application. If a sufficient module fails, the authentication process continues; failure of a sufficient module doesn't deny access in and of itself.


Indicates that the module's success or failure does not have any effect on the success or failure status returned to the client application. There is one exception to this rule: if no other modules return any definite success or failure status codes, the success or failure of an optional module determines whether authentication succeeds.


Indicates that the module must succeed for authentication to occur. In the event of failure, control is immediately passed back to the calling application. This is different from the required control flag, which causes all modules to be invoked before returning. This flag is not included in the original OSF-RFC 86.0.

The module-path component of a PAM configuration is the absolute path to the shared library that implements the authentication or authorization functions.

The last option listed in a PAM configuration line supplies any additional arguments that should be passed to the module upon invocation. The module must parse and process these arguments. The nature of these arguments varies from module to module; however, a few standard arguments are normally supported by all PAM modules:


Enables generation of debugging information either to standard output or via the syslogd daemon.


Disables authentication failure logging.


Instructs the module to use the password entered for the previous module and to return failure if the password does not succeed.


Instructs the module to attempt to use the password entered for the previous module. If authentication fails, the user should be prompted to enter the password for this module.

PAM administrators frequently specify stacked configurations of modules, forcing a user to be approved by multiple services. With your new understanding of module types and control flags, the previously listed /etc/pam.d/login file should make more sense. Here are the auth lines from it:

auth       required   /lib/security/pam_unix.so
auth       required   /lib/security/pam_securetty.so
auth       required   /lib/security/pam_nologin.so

Any authentication attempt must be approved by all three in order for authentication to succeed. The first PAM module performs standard user and password authentication according to entries in /etc/passwd. The second module, pam_securetty.so, causes a root login to fail unless it is on a terminal listed in /etc/securetty. The final PAM module, pam_nologin.so, results in all logins except root failing if the file /etc/nologin exists.

These modules are processed in order. You should examine for yourself what will occur in the following scenario. Assuming that the file /etc/nologin exists, what users will be able to log onto the system? The answer is that only the root account will be able to log on but only from a secure console. How would this be different if the control flag in the first line was changed from required to sufficient? (The root would be able to log in from anywhere, and the /etc/nologin file would have no affect.)