4.Â PAM Configuration

4.1.Â PAM policy files

4.1.1.Â The
/etc/pam.conf file

The traditional PAM policy file is
/etc/pam.conf. This file contains all
the PAM policies for your system. Each line of the file
describes one step in a chain, as shown below:

login auth required pam_nologin.so no_warn

The fields are, in order: service name, facility name,
control flag, module name, and module arguments. Any
additional fields are interpreted as additional module
arguments.

A separate chain is constructed for each service /
facility pair, so while the order in which lines for the
same service and facility appear is significant, the order
in which the individual services and facilities are listed
is not. The examples in the original PAM paper grouped
configuration lines by facility, and the Solaris™ stock
pam.conf still does that, but FreeBSD's
stock configuration groups configuration lines by service.
Either way is fine; either way makes equal sense.

4.1.2.Â The
/etc/pam.d directory

OpenPAM and Linux-PAM support an alternate configuration
mechanism, which is the preferred mechanism in FreeBSD. In
this scheme, each policy is contained in a separate file
bearing the name of the service it applies to. These files
are stored in /etc/pam.d/.

These per-service policy files have only four fields
instead of pam.conf's five: the service
name field is omitted. Thus, instead of the sample
pam.conf line from the previous
section, one would have the following line in
/etc/pam.d/login:

auth required pam_nologin.so no_warn

As a consequence of this simplified syntax, it is
possible to use the same policy for multiple services by
linking each service name to a same policy file. For
instance, to use the same policy for the
su and sudo services,
one could do as follows:

#cd /etc/pam.d#ln -s su sudo

This works because the service name is determined from
the file name rather than specified in the policy file, so
the same file can be used for multiple differently-named
services.

Since each service's policy is stored in a separate
file, the pam.d mechanism also makes it
very easy to install additional policies for third-party
software packages.

4.1.3.Â The policy search
order

As we have seen above, PAM policies can be found in a
number of places. What happens if policies for the same
service exist in multiple places?

It is essential to understand that PAM's configuration
system is centered on chains.

4.2.Â Breakdown of a
configuration line

As explained in SectionÂ 4.1, “PAM policy files”, each line in
/etc/pam.conf consists of four or more
fields: the service name, the facility name, the control flag,
the module name, and zero or more module arguments.

The service name is generally (though not always) the name
of the application the statement applies to. If you are
unsure, refer to the individual application's documentation to
determine what service name it uses.

Note that if you use /etc/pam.d/
instead of /etc/pam.conf, the service
name is specified by the name of the policy file, and omitted
from the actual configuration lines, which then start with the
facility name.

Likewise, the control flag is one of the four keywords
described in SectionÂ 3.3, “Chains and
policies”,
describing how to interpret the return code from the module.
Linux-PAM supports an alternate syntax that lets you specify
the action to associate with each possible return code, but
this should be avoided as it is non-standard and closely tied
in with the way Linux-PAM dispatches service calls (which
differs greatly from the way Solaris™ and OpenPAM do it.)
Unsurprisingly, OpenPAM does not support this syntax.

4.3.Â Policies

To configure PAM correctly, it is essential to understand
how policies are interpreted.

When an application calls pam_start(3), the PAM
library loads the policy for the specified service and
constructs four module chains (one for each facility.) If one
or more of these chains are empty, the corresponding chains
from the policy for the other service are
substituted.

When the application later calls one of the six PAM
primitives, the PAM library retrieves the chain for the
corresponding facility and calls the appropriate service
function in each module listed in the chain, in the order in
which they were listed in the configuration. After each call
to a service function, the module type and the error code
returned by the service function are used to determine what
happens next. With a few exceptions, which we discuss below,
the following table applies:

TableÂ 1.Â PAM chain execution summary

Â

PAM_SUCCESS

PAM_IGNORE

other

binding

if (!fail) break;

-

fail = true;

required

-

-

fail = true;

requisite

-

-

fail = true; break;

sufficient

if (!fail) break;

-

-

optional

-

-

-

If fail is true at the end of a chain,
or when a “break” is reached, the dispatcher
returns the error code returned by the first module that
failed. Otherwise, it returns
PAM_SUCCESS.

The first exception of note is that the error code
PAM_NEW_AUTHTOK_REQD is treated like a
success, except that if no module failed, and at least one
module returned PAM_NEW_AUTHTOK_REQD, the
dispatcher will return
PAM_NEW_AUTHTOK_REQD.

The second exception is that pam_setcred(3) treats
binding and
sufficient modules as if they were
required.

The third and final exception is that
pam_chauthtok(3) runs the entire chain twice (once for
preliminary checks and once to actually set the password), and
in the preliminary phase it treats
binding and
sufficient modules as if they were
required.