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 line in the file has five elements: service
name, module type, control
flag, module path, and
arguments.
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 includes four different types of modules for controlling access to
a particular service:
An auth module provides the actual
authentication (perhaps asking for and checking a password) and
sets credentials, such as group membership or Kerberos tickets.
An account module checks to
make sure that access is allowed for the user (the account has
not expired, the user is allowed to log in at this time of day,
and so on).
A password module is used to set passwords.
A session module is used after
a user has been authenticated. A
session module performs
additional tasks which are needed to allow access (for example,
mounting the user's home directory or making their mailbox
available).
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 file does not exist, that
they are not trying to log in remotely as root over an unencrypted
network connection, 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>.
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 in the
overall goal of allowing access to the service to that user.
Four types of control flags are defined by the PAM standard:
required flagged modules must be
successfully checked in order for the authentication to be
allowed. If a required module
check fails, the user is not notified until all other
modules of the same module type have been checked.
requisite flagged modules also must be
successfully checked in order for the authentication to be
successful. However, if a
requisite module check fails,
the user is notified immediately with a message reflecting the first failed
required or
requisite module.
sufficient flagged modules
checks are ignored if they fail. But, if a
sufficient flagged module is successfully
checked and no required flagged modules
above it have failed, then no other modules of this module type
are checked and this module type is considered to have
successfully been checked as a whole.
optional flagged modules are not crucial
for the overall success or failure of that module type's
authentication. The only time they play a role is when no other
modules of that module type have succeeded or failed. In this
case, the success or failure of an
optional flagged module
determines the overall PAM authentication for that module type.
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.
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 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.
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 nullok |
Line three causes the user to be asked for a password and the password
to be checked, using the information store in
/etc/passwd, and if it exists,
/etc/shadow.
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 their
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.
 | Note |
|---|
| | 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.
|