PAM Configuration Files

The directory /etc/pam.d contains the PAM configuration files. In earlier versions of PAM, /etc/pam.conf was used. The pam.conf file is still read if no /etc/pam.d/ entry is found, but its use is deprecated.

Each application (or service, as applications designed to be used by many users are commonly known) has its own file. Each file has five different elements: service name, module type, control flag, module path, and arguments.

PAM Service Names

The service name of every PAM-enabled application is the name of its configuration file in /etc/pam.d. Each program which uses PAM defines its own service name.

For example, the login program defines the service name login, ftpd defines the service name ftp, and so on.

In general, the service name is the name of the program used to access the service, not the program used to provide the service.

PAM Modules

PAM includes four different types of modules for controlling access to a particular service:

These modules may be stacked, or placed upon one another, so that multiple modules are used. The order of a module stack is very important in the authentication process, because it makes it very easy for an administrator to require that several conditions exist before allowing user authentication to occur.

For example, rlogin normally uses at least four stacked authentication methods, as can be seen in its PAM configuration file:

auth       required     /lib/security/pam_nologin.so
auth       required     /lib/security/pam_securetty.so
auth       required     /lib/security/pam_env.so
auth       sufficient   /lib/security/pam_rhosts_auth.so
auth       required     /lib/security/pam_stack.so service=system-auth
account    required     /lib/security/pam_stack.so service=system-auth
password   required     /lib/security/pam_stack.so service=system-auth
session    required     /lib/security/pam_stack.so service=system-auth

Before someone is allowed to rlogin, PAM verifies that the /etc/nologin does not exist, that they are not trying to log in remotely as root, and that any environmental variables can be loaded. Then, a successful rhosts authentication is performed before the connection is allowed. If rhosts authentication fails, then standard password authentication is done.

New PAM modules can be added at any time, and PAM-aware applications can then be made to use them. For example, if you create a one-time-password creation method and write a PAM module to support it, PAM-aware programs can immediately use the new module and password method without being recompiled or otherwise modified in any way. As you can imagine, this is very beneficial, because it lets you mix-and-match, as well as test, authentication methods very quickly with different programs without having to recompile the programs.

Documentation on writing modules is included with the system in /usr/share/doc/pam—<version-number>.

PAM Control Flags

All PAM modules generate a success or failure result when checked. Control flags tell PAM what do with the result. Since modules can be stacked in a particular order, control flags give you the ability to set the importance of a module in respect to the modules that follow it.

Again, consider the rlogin PAM configuration file:

auth       required     /lib/security/pam_nologin.so
auth       required     /lib/security/pam_securetty.so
auth       required     /lib/security/pam_env.so
auth       sufficient   /lib/security/pam_rhosts_auth.so
auth       required     /lib/security/pam_stack.so service=system-auth
account    required     /lib/security/pam_stack.so service=system-auth
password   required     /lib/security/pam_stack.so service=system-auth
session    required     /lib/security/pam_stack.so service=system-auth

After the module type is specified, the control flags decide how important that particular module type should be considered to the overall goal of allowing access to the program to that user.

Four types of control flags are defined by the PAM standard:

A newer control flag syntax that allows for even more control is now available for PAM. Please see the PAM docs located in /usr/share/doc/pam—<version-number> for information on this new syntax.

PAM Module Paths

Module paths tell PAM where to find the pluggable module to be used with the module type specified. Usually, it is provided as the full path to the module, such as /lib/security/pam_stack.so. However, if the full path is not given (in other words, the path does not start with a /), then the module indicated is assumed to be in /lib/security, the default location for PAM modules.

PAM Arguments

PAM uses arguments to pass information to a pluggable module during authentication for a particular module type. These arguments allow the PAM configuration files for particular programs to use a common PAM module but in different ways.

For example, the pam_userdb.so module uses secrets stored in a Berkeley DB file to authenticate the user. (Berkeley DB is an open source database system designed to be embedded in many application to track particular types of information.) The module takes a db argument, specifying the Berkeley DB filename to use, which can be different for different services.

So, the pam_userdb.so line in a PAM configuration file look like this:

auth      required  /lib/security/pam_userdb.so db=path/to/file

Invalid arguments are ignored and do not otherwise affect the success or failure of the PAM module. When an invalid argument is passed, an error is usually written to /var/log/messages. However, as the reporting method is controlled by the PAM module, so it is up to the module to correctly log the error.

PAM Configuration File Samples

A sample PAM application configuration file looks like this:

#%PAM-1.0
auth      required  /lib/security/pam_securetty.so
auth      required  /lib/security/pam_unix.so shadow nullok
auth      required  /lib/security/pam_nologin.so
account   required  /lib/security/pam_unix.so
password  required  /lib/security/pam_cracklib.so
password  required  /lib/security/pam_unix.so shadow nullok use_authtok
session   required  /lib/security/pam_unix.so

The first line is a comment (any line starting with a # character is a comment). Lines two through four stack three modules to use for login authentication.

auth      required  /lib/security/pam_securetty.so

Line two makes sure that if the user is trying to log in as root, the tty on which they are logging in is listed in the /etc/securetty file, if that file exists.

auth      required  /lib/security/pam_unix.so shadow nullok

Line three causes the user to be asked for a password and the password to be checked.

auth      required  /lib/security/pam_nologin.so

Line four checks to see if the file /etc/nologin exists. If /etc/nologin exists and the user is not root, the authentication fails.

Note that all three auth modules are checked, even if the first auth module fails. This strategy prevents the user from knowing why their authentication was not allowed. Knowing why their authentication failed might allow them to break the authentication more easily on their next try. You can change this behavior by changing required to requisite. If any requisite module returns failure, PAM fails immediately without calling any other modules.

account   required  /lib/security/pam_unix.so

The fifth line causes any necessary account verification to be done. For example, if shadow passwords have been enabled, the pam_unix.so module will check to see if the account has expired or if the user has not changed his or her password within the grace period allowed.

password  required  /lib/security/pam_cracklib.so

The sixth line tests a newly changed password by seeing whether the password can easily be determined by a dictionary-based password cracking program.

password  required  /lib/security/pam_unix.so shadow nullok use_authtok

The seventh line specifies that if the login program changes the user's password, it should use the pam_unix.so module to do so. (This will happen only if an auth module has determined that the password needs to be changed — for example, if a shadow password has expired.)

session   required  /lib/security/pam_unix.so

The eighth and final line specifies that the pam_unix.so module should be used to manage the session. Currently, that module does not do anything; it could be replaced by any necessary module or supplemented by stacking.

Note that the order of the lines within each file matters. While the order in which required modules are called does not matter much, there are other control flags available. While optional is rarely used, sufficient and requisite cause order to become important.

As the next example, we will review the auth configuration for rlogin:

#%PAM-1.0
auth      required    /lib/security/pam_nologin.so
auth      required    /lib/security/pam_securetty.so
auth      required    /lib/security/pam_env.so
auth      sufficient  /lib/security/pam_rhosts_auth.so
auth      required    /lib/security/pam_stack.so service=system-auth

First, pam_nologin.so checks to see if /etc/nologin exists. If is does, no one can log in except for root.

auth      required    /lib/security/pam_securetty.so

Second, pam_securetty.so keeps root logins from occurring on insecure terminals. This effectively disallows all root rlogin attempts. If you wish to allow them (in which case you should be behind a good firewall or not be connected to the Internet), see the section called Using rlogin, rsh, and rexec with PAM.

auth      required    /lib/security/pam_env.so

Third, the pam_env.so module loads the environmental variables specified in /etc/security/pam_env.conf.

auth      sufficient  /lib/security/pam_rhosts_auth.so

Fourth, if pam_rhosts_auth.so authenticates the user using .rhosts in the user's home directory, PAM immediately authenticates the rlogin without moving on to do a normal password authentication with pam_stack.so. If pam_rhosts_auth.so fails to authenticate the user, that failed authentication is ignored.

auth      required    /lib/security/pam_stack.so service=system-auth

Fifth, if pam_rhosts_auth.so has failed to authenticate the user, the pam_stack.so module performs normal password authentication, and is passed the service=system-auth argument.

NoteNote
 

If you do not want to prompt for a password when the securetty check fails and determines that the user is trying to login as root remotely, you can change the pam_securetty.so module from required to requisite. Alternatively, if you want to allow root logins remotely (which is not a good idea), you can comment out this line.