6.5
User
Authentication with PAM
Traditionally, with very few exceptions, user authentication on Unix systems occurs at login time. In recent
years
, however, a new scheme has emerged that allows the authentication process to be performed and customized for a variety of system contexts. This functionality is provided by the PAM facility.
PAM stands for Pluggable Authentication Modules. PAM is a general user authentication facility available under and provided by current versions of FreeBSD, HP-UX, Linux, and Solaris. PAM's goal is to provide a flexible and administrator-configurable mechanism for authenticating users, independent of the various programs and facilities which require authentication services. In this way, programs can be developed independently of any specific user-authentication scheme instead of having one explicitly or implicitly embedded within them. When using this approach, utilities call various authentication modules at runtime to perform the actual user-validation process, and the utilities then act appropriately depending on the results the modules return to them.
There are severalcomponents to the PAM facility:
-
PAM-aware versions of traditional Unix authentication programs (for example,
login
and
passwd
). Such programs are referred to as
services
.
-
Modules to perform various specific authentication
tasks
. These are implemented as shared libraries (
.so
files), stored in
/lib/security
under Linux,
/usr/lib/security
under Solaris and HP-UX, and in
/usr/lib
under FreeBSD. Each module is responsible for just one small aspect of authentication. After executing, a module returns its result value to the PAM facility, indicating whether it will grant access or deny access to the user in question. A module may also return a neutral value, corresponding to no specific decision (
essentially
abstaining from the final decision).
-
Configuration data indicating what authentication process should be performed for each supported service, specified via one or more PAM configuration files. On Linux systems, each service has its own configuration file—with the same
name
as the service itself—in the directory
/etc/pam.d
(thus, the configuration file for the login service would be
/etc/pam.d/login
). Alternatively, the entire facility may use a single configuration file, conventionally
/etc/pam.conf
; this is how the other three systems are set up by default. If both sorts of configuration information are present (and the PAM facility has been compiled to allow multiple configuration sources), the files in
/etc/pam.d
take precedence over the contents of
/etc/pam.conf
.
-
Additional configuration settings required by some of the PAM modules. These configuration files are stored in
/etc/security
, and they have the same name as the corresponding service with the extension
.conf
appended.
The best way to understand how PAM works is with an example. Here is a simple PAM configuration file from a Linux system; this file is used by the
su
service:
auth sufficient /lib/security/pam_rootok.so
auth required /lib/security/pam_wheel.so
auth required /lib/security/pam_unix.so shadow nullok
account required /lib/security/pam_unix.so
password required /lib/security/pam_unix.so
session required /lib/security/pam_unix.so
As you can see, there are four types of entries that may appear within a PAM configuration file. Auth entries specify procedures for user authentication. Account entries are used to set user account attributes and apply account controls. Password entries are used when a password changes within the context of the current service. Session entries are
generally
used at present for login purposes to the syslog facility. The
group
of entries of a particular type are
processed
in
turn
and form a stack. In the example file, there is a stack of three auth entries and a single entry of each of the other three types.
The second field in each entry is a keyword that specifies how the results of that particular module affect the outcome of the entire authentication process. In its simplest form,
this field consists of one of four keywords:
-
sufficient
-
If this module grants access to the user, skip any remaining modules in the stack and return an authentication success value to the service).
-
requisite
-
If this module denies access, return an authentication failure value to the service and skip any remaining modules in the stack.
-
required
-
This module must grant access in order for the entire authentication process to succeed.
-
optional
-
The result of this module will be used to determine access only if no other module is deterministic.
The first two keywords are easy to understand, because they immediately either allow or deny access and terminate the authentication process at that point. The second two
indicate
whether the module is an essential, integral part of the authentication process. If no module denies or grants access before all of the modules in the stack have executed, authentication success or failure is determined by combining the results of all the required modules. If at least one of them grants access and none of them denies it, authentication is successful. Optional modules are used only when no definitive decision is reached by the required modules.
The third field in each configuration file entry is the path to the desired module (sometimes, only a filename is given, in which case the default library location is assumed). Any required and/or optional arguments used by the module follow its
path
.
Looking again at the
su
PAM configuration file, we can now decode the authentication process that it prescribes. When a user enters an
su
command, three modules are used to determine whether she is allowed to execute it. First, the
pam_rootok
module runs. This module checks whether or not the user is
root
(via the real UID). If so, success is returned, and authentication ends here because of the sufficient keyword (
root
does not need to enter any
sort
of password in order to use
su
); if the user is not
root
, authentication continues on to the
next
module. The
pam_wheel
module checks whether the user is a member of the system group allowed to
su
to
root
, returning success or failure
accordingly
(emulating a feature of BSD Unix systems), thereby limiting access to the command to that group. The authentication process then continues with the
pam_unix
module, which
requests
and verifies the appropriate password for the command being attempted (which depends on the specific user who is the target of
su
); it returns success or failure depending on whether the correct password is entered. This module is given two arguments in this instance:
shadow
indicates that a shadow password file is in use, and
nullok
says that a null password for the target account is acceptable (omitting this keyword effectively disables accounts without passwords).
The other three entries in the configuration file all call the same module,
pam_unix
. In the account context, this module establishes the status of the target user's account and password, generating an automatic password change if appropriate; the password entry is invoked when such a password change is necessary, and it handles the mechanics of that process. Finally, this session entry generates a syslog entry for this invocation of
su
.
Many PAM modules allow for quite a bit of configuration. The
pam_wheel
module, for example, allows you to specify which group
su
access is limited to (via its
group
option). It also allows you to grant access to everyone except
members
of a specific group (via the
deny
option).
Consult
the PAM documentation, usually found within the
/usr/doc
tree, for full details on the activities and options for available modules.
Here is a more complex configuration file, for the
rlogin
service, again taken from a Linux system:
auth requisite /lib/security/pam_securetty.so
auth requisite /lib/security/pam_nologin.so
auth sufficient /lib/security/pam_rhosts_auth.so
auth required /lib/security/pam_unix.so
account required /lib/security/pam_unix.so
account required /lib/security/pam_time.so
password required /lib/security/pam_cracklib.so retry=3 \
type=UNIX minlen=10 ocredit=2 \
dcredit=2
password required /lib/security/pam_unix.so \
use_authtok shadow md5
session required /lib/security/pam_unix.so
session optional /lib/security/pam_motd.so motd=/etc/pmotd
When a user attempts to connect to the system via the
rlogin
service, authentication proceeds as
follows
: the
pam_securetty
module
presents
connections to the
root
account via
rlogin
(if someone attempts to
rlogin
as
root
, the module returns failure, and authentication ends due to the
requisite
keyword).
Next, the
pam_nologin
module determines whether the file
/etc/
nologin
exists; if so, its contents are displayed to the user, and authentication fails immediately. When
/etc/nologin
is not present, the
pam_rhosts_auth
module determines whether the traditional Unix
/etc/
hosts
.equiv
mechanisms allow access to the system or not; if so, authentication succeeds immediately. In all cases, the
pam_unix
module prompts for a user password (the module uses the same arguments here as in the
preceding
example).
If authentication succeeds, the account stack comes into play. First, user account and password controls are checked via the
pam_unix
module (which makes sure that the account is not
expired
and determines whether the password needs to be changed at this time). Next, the
pam_time
module consults its configuration file to determine whether this user is allowed to log in at the current time (discussed below). In order for system access to be granted,
neither
of these modules must deny access, and at least one of them must explicitly grant it.
When a password change is required, the password stack is used. The first module,
pam_cracklib
,
performs
several different triviality checks on the new password before allowing it to be
chosen
. This module is discussed in more detail later in this section.
Finally, the first session entry generates a syslog entry each time the
rlogin
service is used. The second session entry displays a message-of-the-day at the end of the login process, displaying the contents of the file specified with the
pam_motd
's
motd
option.
6.5.1 PAM Defaults
ThePAM facility also defines an additional service called
other
, which serves as a default authentication scheme for commands and facilities not
specifically
defined as PAM services. The settings for the other service are used whenever an application requests authentication but has no individual configuration data defined. Here is a typical
other
configuration file:
auth required pam_warn.so
auth required pam_deny.so
These entries display a warning to the user that PAM has not been configured for the
requested
service, and then deny access in all cases.
6.5.2 PAM Modules Under Linux
As these examples have indicated, Linux systems provide a rich variety of PAM modules. Unfortunately, the other systems we are considering are not as well provided for by default, and you will have to build additional modules if you want them.
We will now
briefly
list the most important Linux PAM modules. Two of the most important are discussed in more detail in
subsequent
subsections of this chapter. For each module, the stacks in which it may be called are given in parentheses.
-
pam_deny (
account, auth, passwd, session
)
-
pam_permit (
account, auth, passwd, session
)
-
Deny/allow all access by always returning failure/success (respectively). These modules do not log, so stack them with
pam_warn
to log the events.
-
pam_warn (
account, auth, passwd, session
)
-
Log information about the calling user and host to syslog.
-
pam_access (
account
)
-
Specify system access based on user account and originating host/domain as in the widely used
logdaemon
facility. Its configuration file is
/etc/security/access.conf.
-
pam_unix
(
account, auth, passwd, session
)
-
pam_pwdb
(
account, auth, passwd, session
)
-
Two modules for verifying and changing user passwords. When used in the auth stack, the modules check the entered user password.
When used as an account module, they determine whether a password change is required (based on password aging settings in the shadow password file); if so, they delay access to the system until the password has been changed.
When used as a password component, the modules update the user password. In this context, the
shadow
(use the shadow password file) and
try_first_pass
options are useful; the latter forces the modules to use the password given to a previous module in the stack (rather than generating another, redundant password prompt).
In any of these modes, the
nullok
option is required if you want to allow users to have blank passwords, even as initial passwords to be changed at the first login;
otherwise
, the modules will return an authorization failure.
-
pam_cracklib
(
passwd
)
-
Password triviality checking. Needs to be
stacked
with
pam_pwdb
or
pam_unix
.
See the separate discussion below.
-
pam_pwcheck
(
passwd
)
-
Another password-checking module, checking that the proposed password conforms to the settings specified in
/etc/login.defs
(discussed previously in this chapter).
-
pam_env
(
auth
)
-
Set or unset environment
variables
with a PAM stack. It uses the configuration file
/etc/security/pam_env.conf
.
-
pam_issue
(
auth
)
-
pam_motd
(
session
)
-
Display an issue or message-of-the-day file at login. The issue file (which defaults to
/etc/issue
) is displayed before the username prompt, and the message of the day file (defaults to
/etc/motd
) is displayed at the end of a successful login process. The location of the displayed file can be changed via an argument to each module.
-
pam_krb4
(
auth, passwd, session)
-
pam_krb5
(auth, passwd, session)
-
Interface to Kerberos user authentication.
-
pam_lastlog
(
auth
)
-
Adds an entry to the
/var/log/lastlog
file, which contains data about each user login session.
-
pam_limits (
session
)
-
Sets user process resource limits (
root
is not affected), as specified in its configuration file,
/etc/security/limits.conf
(the file must be readable only by the superuser)
.
This file contains entries of the form:
name hard/soft resource limit-value
where
name
is a user or group name or an asterisk (indicating the default entry). The second field indicates whether it is a soft limit, which the user can increase if desired, or a hard limit, the upper bound that the user cannot exceed. The final two fields specify the resource in question and the limit assigned to it. The defined resources are:
-
as
-
Maximum address space
-
core
-
Maximum core file
size
-
cpu
-
CPU time, in minutes
-
data
-
Maximum size of data portion of process memory
-
fsize
-
Maximum file size
-
maxlogins
-
Maximum simultaneous login sessions
-
memlock
-
Maximum locked-in memory
-
nofile
-
Maximum number of
open
files
-
rss
-
Maximum resident set
-
stack
-
Maximum stack portion of address space
All sizes are
expressed
in kilobytes.
-
pam_listfile
(
auth
)
-
Deny/allow access based on a list of usernames in an external file. This module is best explained by example (assume this is found in the PAM configuration file for the
ftp
facility):
auth required pam_listfile.so onerr=fail sense=deny \
file=/etc/ftpusers item=user
This entry says that the file
/etc/ftpusers
(
file
argument) contains a list of usernames (
item=user
) who should be
denied
access to
ftp
(
sense=allow
). If any error occurs, access will be denied (
onerr=fail
). If you want to grant access to a list of users, use the option
sense=allow
. The
item
option indicates the kind of data present in the specified file, one of
user
,
group
,
rhost
,
ruser
,
tty
, and
shell
.
-
pam_mail
(
auth, session)
-
Displays a message indicating whether the user has mail. The default mail file location (
/var/spool/mail
) can be changed with the
dir
argument.
-
pam_mkhomedir
(
session
)
-
Creates the user's home directory if it does not already exist, copying files from the
/etc/skel
directory to the new directory (use the
skel
option to specify a different location). You can use the
umask
option specify a umask to use when the directory is created (e.g.,
umask=022
).
-
pam_nologin
(auth)
-
Prevents
non-
root
logins if the file
/etc/nologin
exists, the contents of which are displayed to the user.
-
pam_rhosts_auth
(auth)
-
Performs traditional
/etc/rhosts
and
~/.rhosts
password-free authentication for remote sessions between networked hosts (see Section 7.6).
-
pam_rootok
(auth)
-
Allows
root
access without a password.
-
pam_securetty
(auth)
-
Prevents
root
access unless the current terminal line is listed in the file
/etc/
securetty
.
-
pam_time
(account)
-
Restricts access by time of day, based on user, group, tty, and/or shell. Discussed in more detail later in this chapter.
-
pam_wheel
(auth)
-
Designed for the
su
facility, this module prevents root access by any user who is not a member of a specified group (
group=
name option), which defaults to GID 0. You can reverse the logic of the test to deny
root
access to members of a specific group by using the
deny
option along with
group
.
6.5.2.1 Checking passwords at selection time
As we've seen, the
pam_cracklib
module can be used to check a proposed user password for strength. By default, the module checks the entered new password against each word in its dictionary,
/usr/lib/cracklib_dict
. It also checks that the new password is not a trivial transformation of the current one: not a reversal,
palindrome
, character case modification, or rotation. The module also checks the password against the module's list of previous passwords for the user, stored in
/etc/security/opasswd
.
The arguments to this module specify additional criteria to be used for some of these checks. These are the most important:
-
retry
=
n
-
Number of
tries
allowed to successfully choose a new password. The default is 1.
-
type
=
string
-
Operating system name to use in prompts (defaults to Linux).
-
minlen
=
n
-
Minimum "length" value for the new password (defaults to 10). This is computed on the basis of the number of characters in the password, along with some
weighting
for different types of
characters
(specified by the various
credit
arguments). Due to the character-type credit scheme, this value should be equal to or greater than the desired password length plus one.
-
ucredit=
u
-
lcredit=
l
-
dcredit=
d
-
ocredit=
o
-
Maximum "length" credits for having uppercase letters, lowercase
letters
, digits, and other characters (respectively) in proposed passwords (all of them default to 1). If set, characters of each type will add 1 to the "length" value, up to the specified maximum number. For example,
dcredit=2
means that having two or more digits in the new password will add 2 to the number of characters in the password when comparing its "length" to
minlen
(one or zero digits will similarly add 1 or 0 to the "length").
-
difok=
n
-
The number of characters in the new password that must not be present in the old password (old passwords are stored in
/etc/security/opasswd
). The default is 10. Decrease this value when you are using long MD5 passwords.
As an example, consider our previous invocation of
pam_cracklib
:
passwordrequiredpam_cracklib.so retry=3 type=Linux \
minlen=12 ocredit=2 dcredit=2 difok=3
In this case, the user is allowed three tries to select an appropriate password (
retry=3
), and the word "Linux" will be used in the new password prompt rather than Unix (
type=Linux
). Also, the password must have a minimum length-value of 12, where each character in the password counts as 1, and up to two
numbers
(
dcredit=2
) and two nonalphanumeric characters (
ocredit=2
) can each add an additional 1 to the "length." This effectively forces passwords to be at least seven characters long, and in that case, they must contain two digits and two non-
alphanumeric
characters (7 characters + 1 alpha + 2 digits + 2 other). Passwords containing only upper- and lowercase letters will have to be at least 10 characters long. The final option specifies that three characters in the new password must not be present in the old password.
6.5.2.2 Specifying allowed times and locations for system access
The
pam_time
module uses a configuration file,
/etc/security/time.conf
, that specifies hours when users may access defined PAM services. Here's an example:
#services; ttys; users; times (Mo Tu We Th Fr Sa Su Wk Wd Al)
login;tty*;!root & !harvey & !chavez;Wd0000-2400Wk0800-2000
games;*;smithjoneswilliamswongsanchezng;!Al0700-2000
The first line is a comment indicating the contents of the various fields (note that entries are separated by semicolons). Each entry within this configuration file specifies when access to the indicated services are allowed; the entry applies when
all
of the first three fields match the current situation, and the fourth entry indicates the times when access is allowed.
In our example, the first line specifies that access to the
login
and
rlogin
services will be granted to any user except
root
,
harvey
, and
chavez
(the logical NOT is indicated by the initial !) all the time on weekends (
Wd
keyword in the fourth field) and on weekdays between 8:00 A.M. and 6:00 P.M., on any serial-line connected terminal. The second line prohibits access to any PAM-aware game by the listed users between 7:00 A.M. and 8:00 P.M. (again, regardless of tty); it does so by granting access at any time except those noted (again indicated by the initial exclamation point). Note that & and are used for logical AND and OR, respectively, and that an asterisk may be used as a wildcard (although a bare wildcard is allowed only once within the first three fields).
NOTE
As you create entries for this configuration file, keep in mind that you are creating matching rules: use the first three fields to define applicability and the final field to specify allowed or denied access periods. Note that ampersands/ANDs usually join negative (NOT-ed) items, and vertical bars/ORs usually join positive items.
Be aware that this module can provide time-based controls only for initial system access. It does nothing to enforce time limits after users have already logged in; they can stay logged in as long as they like.
6.5.2.3 MD5 passwords
Linux and some other Unix systems support much longerpasswords (up to at least 128 characters) using the MD5 encryption algorithm. Many PAM modules are also compatible with such passwords, and they provide an
md5
option that may be used to indicate they are in use and to request their usage. These include
pam_pwdb
,
pam_unix
,
pam_cracklib
, and
pam_pwcheck
.
If you decided to enable MD5 passwords, you will need to add the
md5
option to all relevant modules in the configuration files for
login
,
rlogin
,
su
,
sshd
, and
passwd
services (and perhaps others as well).
|
Not all Unix facilities are compatible with MD5 passwords. For example, some
ftp
client programs always truncate the entered password and so will not send long passwords correctly, thereby preventing
ftp
access by users with long passwords. Test your environment thoroughly before deciding to enable MD5 passwords.
|
|
6.5.3 PAM Modules Provided by Other Unix Systems
As we noted earlier, HP-UX, FreeBSD, andSolaris do not provide nearly as many PAM modules as Linux does by default. Each provides from 8 to 12 modules. All include a version of the basic password-based authentication module,
pam_unix
(named
libpam_unix
on HP-UX systems). There are also a few unique modules provided by these systems, including the following:
|
HP-UX
|
libpam_updbe
|
This module provides a method for defining
user-specific
PAM stacks (stored in the
/etc/pam_user.conf
configuration file).
|
|
Solaris
|
pam_projects
|
This module succeeds as long as the user belongs to a valid project, and fails otherwise. Solaris projects are discussed in Section 17.3.
|
|
|
pam_dial_auth
|
Perform dialup user authentication using the traditional
/etc/dialup
and
/etc/d_passwd
files (see Section 7.3).
|
|
|
pam_roles
|
Performs authentication when a user tries to assume a new role (see Section 7.5).
|
|
FreeBSD
|
pam_cleartext_pass_ok
|
Accepts authentication performed via cleartext passwords.
|
6.5.4 More Complex PAM Configuration
The latest versions of PAM introduce a new, more complex syntax for the final severity field:
return-val
=
action
[,
return-val
=
action
[,...]]
where
return-val
is one of approximately fifteen defined values that a module may return, and
action
is a keyword indicating what action should be taken if that return value is received (in other words, if that condition occurs). The available actions are
ok
(grant access),
ignore
(no opinion on access),
bad
(deny access),
die
(immediate deny access),
done
(immediate grant access), and
reset
(ignore the results of all modules processed so far and force the remaining ones in the stack to make the decision). In addition, a positive integer (
n
) may also be specified as the action, which says to skip next
n
modules in the stack, allowing simple conditional authentication schemes to be created.
Here is an example severity field using the new syntax and features:
success=ok,open_err=ignore,cred_insufficient=die,\
acct_expired=die,authtok_expired=die,default=bad
This entry says that a success return value from the module grants access; it will still need to be combined with the results of the other modules in order to determine overall authentication success or failure (as usual). A file open error causes the module to be ignored. If the module indicates that the user's credentials are insufficient for access or that his account or authentication token is expired, the entire authentication process fails immediately. The final item in the list specifies a default action to be taken when any other value is returned by the module; in this case, it is set to deny access.
These examples have shown some of the features and flexibility of the PAM facility. Now it is time for you to experiment and explore it further on your own, in the context of the needs of your particular system or site. As always, be careful as you do so, and do some preliminary testing on a noncritical system before making any changes in a production system. Using PAM effectively requires experience, and everyone locks
themselves
out in some context as they are learning to do so.
|