Configuring PAM means editing its configuration files. The format of these files is fairly simple, but these files use a number of options that aren’t immediately obvious to the uninitiated. You must also know something about how the PAM configuration file works with multiple modules. These modules can also interact in unintuitive ways.
In order to implement its design goals, PAM uses one or more
configuration files: either a file called
/etc/pam.conf or files in the
/etc/pam.d directory named after the particular
systems they control. The /etc/pam.d directory
is more common in Linux; this approach enables packages to add files
to the directory for their services, without having to modify
/etc/pam.conf.
When reconfiguring PAM, you can easily render your system unable to
support logins. Thus, I recommend experimenting with one login server
at a time, leaving yourself some way to log in should you create an
inoperable system. For instance, experiment with the
login service and leave the gdm
or xdm service alone. Some distributions use the
pam_stack.so module (described shortly) to
control many login servers. With such a system, you may need to back
up its original configuration file and leave a root session running to be sure you can undo
any disastrous mistake without logging in anew.
The /etc/pam.conf file entries are similar to
the contents of files in /etc/pam.d. The
principle difference is that the /etc/pam.conf
entries begin with a service name field, which is missing from
individual service files. The overall format for the lines in
/etc/pam.d files is:
management_group control_flag module[options]
Each field has a specific meaning:
management_group
This field holds one of four keywords specifying the type of service
it defines: auth for authentication,
account for account management,
session for session management, or
password for password management. Most PAM
configuration files have at least one line of each type.
control_flag
This field describes how PAM should react to the success or failure
of a module. Possible values are requisite,
required, sufficient, and
optional. The meanings of these values are
described in the next section. A more advanced syntax involves
matching specific actions to the module’s exact
return value. This is flexible but tedious to configure (it involves
30 return codes and six possible actions), and so it
isn’t described in this book.
module
This field is a pointer to the module file itself, sometimes with its
complete path. (If the path is missing, PAM checks its modules
directory, which is usually /lib/security.)
options
You can pass parameters to the module via the
options field on the module definition
line. Some options are highly module-specific, but others are
recognized by many modules. Some of these options are described in
the Section A.3.1.
This first field in the lines of pam.conf, which
is missing from the /etc/pam.d files in most
Linux distributions, holds the name of the tool it configures, such
as login for the login service,
or gdm for the GDM GUI login tool. If your system
uses files in /etc/pam.d, the names of these
files are typically the names that appear in this first column in a
system that uses /etc/pam.conf.
In addition to configuration lines, PAM configuration files can
contain comments. These begin with a hash mark
(#). Entire lines can be comments, or comments can
come at the end of a line that serves some other purpose.
A
configuration for a single authentication tool can combine several
PAM modules. This happens in two ways. First, each of the four
management groups (auth,
account, session, and
password) requires its own configuration. Second,
with each management group, multiple modules can be called. When
multiple modules are called, the result is referred to as a module
stack. For instance, a login service might
have separate auth and account
stacks. These stacks are likely to have some modules in common (they
perform different actions depending upon the calling stack), but each
may also have some unique modules.
Individual modules in a stack deliver return values that can be classified as failures or successes. In this context, these terms don’t refer to program bugs or the lack thereof, but to failures or successes in authentication or other actions. For instance, if a user enters the wrong password, an authentication module will fail.
Modules in a stack are called in the order in which
they’re specified. This order is unimportant if all
of the modules are of the required variety, but if
you use other control flags—particularly
requisite or
sufficient—order can become important, as
described shortly.
Understanding the operation of module stacks can be tricky, because the different control flags can have confusing implications. Table A-1 summarizes the consequences of successes and failures of modules called with particular control flags.
Table A-1. Consequences of control flags
|
Control flag |
Module success result |
Module failure result |
|---|---|---|
|
|
Stack execution continues; stack may succeed or fail, depending on outcome of other modules |
Stack execution terminates immediately; stack fails |
|
|
Stack execution continues; stack may succeed or fail, depending on outcome of other modules |
Stack execution continues, but stack fails |
|
|
Stack execution terminates immediately, provided no prior
|
Stack execution continues; stack may succeed or fail, depending on outcome of other modules |
|
|
Stack execution continues; stack may succeed or fail, depending on outcome of other modules, unless other modules are missing or give inconclusive results, in which case the stack succeeds |
Stack execution continues; stack may succeed or fail, depending on outcome of other modules, unless other modules are missing or give inconclusive results, in which case the stack fails |
These rules can become quite confusing in the event of conflicting outcomes. For instance, consider the following stack:
auth required pam_unix.so try_first_pass auth sufficient pam_krb5.so try_first_pass auth required pam_env.so
For now, you need only know that the pam_unix.so
and pam_krb5.so modules authenticate users,
while pam_env.so sets environment variables but
never returns a failure code. Because this stack provides two login
modules, each with two possible outcomes, you must consider four
possibilities—both succeed, both fail,
pam_unix.so succeeds while
pam_krb5.so fails, or
pam_unix.so fails while
pam_krb5.so succeeds. In practice, this stack as
a whole succeeds if and only if pam_unix.so
succeeds; if it fails, its required status
overrides the sufficient status of
pam_krb5.so, and if it succeeds, that success
won’t be overridden by a failure of the
sufficient
pam_krb5.so. What
happens if the two authentication modules’ order is
reversed, though?
auth sufficient pam_krb5.so try_first_pass auth required pam_unix.so try_first_pass auth required pam_env.so
In this case, because the sufficient
pam_krb5.so module comes first, its success
bypasses the later required
pam_unix.so module, so this stack succeeds if
either module succeeds. A success of
pam_krb5.so, though, bypasses the
pam_env.so module, which may not be desirable.