User authentication has always been a problem. Build it into a program, and it's hard to change. Leave it out, and you have no security at all. Now there's an alternative: PAM, or Pluggable Authentication Modules.
PAM provides an interface that programs can use to connect to whatever authentication methods are desired. Authentication can be as trivial as the user typing "hello world", as complex as biometrics, or as prosaic as passwords.
PAM isn't the only way to do this. GSS-API, defined in RFCs 1508 and 1509, is a similar authentication interface protocol. Kerberos, SSh, and Heimdal are different, and focus on securing the authentication process itself rather than linking applications to authentication modules.
PAM is built into many Linux distributions, including Caldera 1.3, 2.2 and later; Debian 2.2 and later; Turbo Linux 3.6 and later; Red Hat 5.0 and later; and SuSE 6.2 (partial support). FreeBSD supports PAM from version 3.1.
Originally, the PAM configuration file was
/etc/pam.conf. More recent versions of PAM use a separate file for each PAM-using program, in the directory
/etc/pam.d, though some will check both
/etc/pam.d when attempting to authenticate for a program.
/etc/pam.d is recommended -- having separate files for each program prevents misconfigurations for one program from affecting others.
The default case of a PAM configuration is
/etc/pam.d/other (or the lines for the
other program in
/etc/pam.conf). For a secure installation, configure
other to use the
pam_warn.so modules to block access to unconfigured programs. If you want access rather than security, use
pam_permit.so instead of
pam_deny.so. To write to
pam_warn.so in the
other configuration file will identify programs which expect, but don't have, PAM configurations.
In each file in
/etc/pam.d, the configuration lines are:
module-type control-flag module-path arguments
account-- Non-authentication account management, such as limiting the maximum number of users or restricting root access.
auth-- User authentication, group assignment, and other authentication- and permission-related tasks.
password-- Updating the authentication token.
session-- Anything the user needs to have done to connect, such as mounting drives or logging connections.
PAM modules can be stacked -- there can be any number of modules of the same module type for a single application. The application is not told of the individual success or failure of any module, only of the success or failure of the stack. The control flags determine how each module affects the success or failure of the stack. Modules in the stack are executed in the order they are listed in the configuration file.
There are two formats for the control flag. The simpler form uses four keywords:
optional. The complex form gives a great deal more control to the system administrator, at the cost of requiring the system administrator to determine an action for each of up to 30 return values. This article covers the simple form.
required-- The module must succeed for the stack of this module type to succeed. If this module fails, all other modules in the stack are executed but the stack is considered to fail.
requisite-- The module must succeed for the stack of this module type to succeed. No later module of its type is executed: Failure is reported immediately. The return value is that of the first module in the stack to fail.
sufficient-- Success of this module is sufficient for the stack of this module type to succeed. If no previous
requiredmodule has failed, no other modules of this module type are invoked. (This overrides the
requiredexecution of all other modules.) Failure of this module does not inherently prevent the stack from succeeding.
optional-- Not critical to the success or failure of the stack. If at least one non-optional module succeeds or fails, the result of this module is ignored when calculating the success or failure of the stack.
The path name of the module.
PAM seems like an ideal solution for user authentication extensibility, but how does it fare when put to use?
Post your comments
Any arguments to the module. This is module-specific, but most modules should recognize the following arguments:
debug-- Include debugging statements in
expose_account-- Pass information about the account to the application. The default behavior is to limit account information. This argument allows the application to display information such as the user's full name.
no_warn-- Don't send warning messages to the application.
try_first_pass-- Don't prompt the user for a password, instead test the password entered for the preceding
use_first_pass-- Don't prompt the user for a password, instead use the results of the preceding
use_mapped_pass-- Take a clear text authentication token provided by a previous module and generate an encryption/decryption key to store the token. This allows a single token to be securely used by a number of modules. Note that implementing this argument risks breaching the U.S. encryption export restrictions. Check the module's documentation before relying on this argument.
# Mimics traditional Unix login without any frills.
account required /usr/lib/security/pam_unix.so
auth requisite /usr/lib/security/pam_nologin.so
auth required /usr/lib/security/pam_unix.so
session required /usr/lib/security/pam_unix.so
# Slight variations on the traditional Unix password-changer.
# The module 'pam_cracklib.so' is useful for enforcing password security.
password required /usr/lib/security/pam_unix.so nullok md5 remember=5
# Prevents the use of programs which are unconfigured.
account required /usr/lib/security/pam_deny.so
auth required /usr/lib/security/pam_deny.so
auth required /usr/lib/security/pam_warn.so
password required /usr/lib/security/pam_deny.so
password required /usr/lib/security/pam_warn.so
session required /usr/lib/security/pam_deny.so
This module provides traditional Unix authentication, password management, and user account setup. It uses standard system calls to retrieve and set password and account information, and relies on
Establishes the validity of the user's account and password and may offer advice on changing the user's password, or force a password change. The actions this module performs are controlled by the
This component of the module checks the user's password against the password databases. Configuration for this component is done in
/etc/nsswitch.conf. An additional binary,
unix_chkpwd, is used to allow the component to read protected databases without requiring the whole module to be
This component changes the user's password. The module
pam_cracklib.socan be stacked with this component to check password security.
This component logs the user name and session type to
syslog, at the start and end of the user's session. There are no arguments to this component.
audit-- A more extensive form of
bigcrypt-- Use the DEC "C2" extension to
debug-- Log information using
md5-- Use md5 encryption instead of
nis-- Use NIS (Network Information Service) passwords.
nodelay-- By default, the module requests a delay-on-failure of a second. This argument overrides the default.
not_set_pass-- Don't use the passwords from other stacked modules. Don't give the new password to other stacked modules.
nullok-- By default, if the official password is blank, the authentication fails. This argument overrides the default.
remember=n) -- Save
nrecent passwords to prevent the user from alternating passwords.
try_first_pass-- Use the password from the previous stacked
authmodule, and prompt for a new password if the retrieved password is blank or incorrect.
use_authtok-- Set the new password to the one provided by a previous module.
use_first_pass-- Use the result from the previous stacked
authmodule, never prompts the user for a password, fails if the result was a fail.
This module logs information about an authentication or password change attempt to
This module has no arguments, and only
This module blocks access to the application. As an
auth or an
account component, it prevents users from authenticating or starting their account. As a
password component, it prevents users from changing their password. As a
session component, it can be stacked with something like
pam_motd.so to display a message and prevent the user from starting a shell.
This module has no arguments, and all four components. The inverse module is
Provides standard Unix
nologin authentication. If the file
/etc/nologin exists, only root is allowed access and all users see the contents of
/etc/nologin. The module succeeds silently if
/etc/nologin is not present.
This module has no arguments, and only an
auth component. It should be included in the configurations for all login methods as a
required module, listed before any
Documentation for PAM-enabled applications should include the name of the PAM configuration file. If it doesn't, use the name of the program (or the authentication component of the program).
To test whether a program is PAM enabled, create a configuration file for that program in
/etc/pam.d, and add these lines:
auth required pam_permit.so auth required pam_warn.so
If the program is PAM enabled, these lines permit access to all users and put a warning in
syslog whenever you run the program. Run the program, try to log in, and check
syslog -- if there's a warning there, the program works with PAM.
/etc/pam.conf unless you enjoy being locked out of your system. To fix this, reboot into single user mode and restore the files.
Jennifer Vesperman is the author of Essential CVS. She writes for the O'Reilly Network, the Linux Documentation Project, and occasionally Linux.Com.
Return to the Linux DevCenter.
Copyright © 2009 O'Reilly Media, Inc.