Linux in a Windows World/Appendixes/Configuring PAM
(Initial conversion from Docbook)
(Initial conversion from Docbook)
Modern Linux distributions rely on the Pluggable Authentication Modules system for authentication. Part III of this book describes three network authentication tools, all of which can be used in conjunction with PAM to provide authentication for arbitrary servers and other programs that require authentication. In order to avoid duplicating content, therefore, this appendix describes PAM in detail; Part III provides a much briefer description of how PAM interacts with the relevant servers.
In order to get the most out of PAM, it helps to begin with some background—what PAM is, what it can do, why it's used, and so on. You must also understand the PAM configuration file format; PAM configuration involves editing one or more of these files. From there, knowing something about individual PAM modules, including both the standard ones and those described elsewhere in this book, will help you create an appropriate configuration. Finally, some examples of working PAM configurations will help you understand PAM and provide models you can adapt for your own use.
In Linux's early days, every server or other tool that had to authenticate users did so by reading /etc/password, the traditional Unix account file. This approach was easy to implement, but it had several problems. One of these was that the file, and hence the encrypted password, had to be readable by all users, making it vulnerable to cracking. Another problem is that changes to authentication methods, such as new password-encryption systems, required changes to all the programs that could authenticate users. This problem would result in a nightmarish tangle of upgrades should an administrator ever want to change the authentication system.
PAM is designed to solve these problems. PAM solves the problem of world readability of /etc/passwd by implementing a system known as shadow passwords, in which passwords are moved out of /etc/passwd and into a file that can be read only by root—typically /etc/shadow on Linux systems. (Shadow passwords can be implemented without PAM, but today PAM is the tool that does it on all major Linux distributions.) PAM helps minimize the pain of changing authentication systems by working as a layer between the tools that authenticate users and the account database. Instead of accessing /etc/passwd directly, programs consult PAM, which accesses /etc/passwd. Thus, if the format of data in /etc/passwd changes, individual servers don't need to be rewritten or even recompiled; only PAM must change. Indeed, PAM can be changed to support authentication systems that don't even consult /etc/passwd. It's this feature of PAM that Winbind, LDAP authentication, and some Kerberos tools use. Rather than consult /etc/passwd, PAM consults the appropriate network authentication tool.
In addition to PAM, Linux relies on another software component, the Name Service Switch, for account information. Rather than authentication information, though, NSS provides more mundane information, such as a mapping of UIDs to usernames and the account's default shell. Like PAM, NSS is designed in a modular way and sits between applications that ask for this information and the actual account databases. Although you may think in terms of authentication, which is what PAM provides, this ancillary information is just as important, so you must configure NSS to link to your authentication system. The chapters on Winbind and LDAP describe configuring NSS to work with these tools, but Kerberos provides no NSS interface, which is a limitation of Kerberos if you want a network authentication system to handle all your account information.
In practice, PAM is a modular tool: it consults libraries to handle various parts of the authentication procedure. You tell PAM which libraries to consult with the help of the PAM configuration files, which are described in the next section. Thus, the overall authentication system, and its equivalent in pre-PAM days, are depicted in Figure A-1. PAM's modular nature is manifested in this figure by the fact that PAM is shown accessing three independent authentication tools—the /etc/passwd file, an NT domain controller, and an LDAP server. A default configuration is likely to be simpler than this, but if you want to use a network authentication tool, chances are you'll leave the old-style /etc/passwd authentication intact as a backup and to provide information for accounts you might not want to define using a centralized system, such as the root account.
Figure A-1. PAM distances servers and other programs that require authentication from authentication implementations, increasing flexibility—and complexity
In practice, PAM configuration is even more complex than Figure A-1 suggests, for three reasons:
- PAM provides management features beyond those related to account authentication. In particular, it supports authentication (verifying that users are who they claim to be), account management (checking for expired accounts, the right to use a particular server, and so on), session management (login and logout housekeeping), and password changes. Each management system must be configured individually; for instance, the modules called in service of authentication may be different than those required for session management.
- A single act, such as logging in, may require multiple PAM modules. For instance, many PAM login configurations call a module called pam_deny.so, which explicitly denies access to the system if no earlier module has explicitly granted access. You can even tack on modules that aren't directly related to authentication, such as modules that display login notices.
- Each program that requires PAM's services may be configured individually. For instance, you might want to use one set of options for authenticating users for console logins and another for authenticating users to use the su command to change their effective UID numbers.
The PAM Configuration File Format
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.
PAM Configuration Files and Fields
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:
- 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.
- 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.
- 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.)
- 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|
|requisite||Stack execution continues; stack may succeed or fail, depending on outcome of other modules||Stack execution terminates immediately; stack fails|
|required||Stack execution continues; stack may succeed or fail, depending on outcome of other modules||Stack execution continues, but stack fails|
|sufficient||Stack execution terminates immediately, provided no prior required module has failed; stack succeeds (failure of a prior required module may cause stack failure, though)||Stack execution continues; stack may succeed or fail, depending on outcome of other modules|
|optional||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.
Creating or modifying a PAM configuration requires at least a basic understanding of the available PAM modules. If you check your existing PAM configuration files, you're likely to see quite a range of module calls, and modifying them to get the results you expect can be tricky if you don't understand what the existing modules do.
Some PAM modules can be called for only some management groups. Others can be called as part of a stack for any management group.
Standard PAM Modules
PAM ships with quite a few different modules. Table A-2 summarizes those that you're most likely to encounter in your existing configuration files. Note that, although some modules directly relate to password handling, others don't; they're used to display information to users, set environment variables, and so on. For these modules, PAM is simply a convenient tool for accomplishing their goals. Such modules may not affect the login process at all.
Table A-2. Common standard PAM modules
|Module filename||Management groups||Common arguments||Description|
|pam_unix.so||auth, account, session, and password||nullok, likeauth, shadow, try_first_pass, use_first_pass, use_authtok||Implements the traditional Unix (and Linux) authentication, based on /etc/passwd and /etc/shadow files.|
|pam_unix2.so||auth, account, session, and password||nullok, likeauth, shadow, try_first_pass, use_first_pass, use_authtok||A variant on pam_unix.so that implements additional features, such as an ability to authenticate against a Network Information Service (NIS) server.|
|pam_smb_auth.so||auth||use_first_pass, nolocal||This module is an alternative way to authenticate against NT domain controllers to that described in Chapter 7. It uses the /etc/pam_smb.conf configuration file.|
|pam_securetty.so||auth||-||Blocks root access to the login service unless the environment variable PAM_TTY is set to a string listed in the /etc/securetty file.|
|pam_time.so||account||-||Reads /etc/security/time.conf, which specifies time-based access restriction rules.|
|pam_nologin.so||auth and account||successok||If /etc/nologin exists, only root is permitted to log in, and all users are shown the contents of that file. If the file doesn't exist, the module has no effect, unless the successok parameter is used, in which case the login succeeds (as if the module were called with a sufficient control flag).|
|pam_homecheck.so||auth and session||abort||Prints a warning if the user's home directory or certain other files are world-writable or if they're owned by another user. If the abort option is used, the login fails under these circumstances.|
|pam_env.so||auth||conffile=filename, envfile=filename||Sets environment variables for the login session, based on the contents of the configuration file (/etc/security/pam_env.conf by default).|
|pam_mail.so||auth and session||dir=directory, empty||Checks for mail in the specified directory and notifies the user if any is present. If empty is used, also informs the user when no mail is present.|
|pam_lastlog.so||auth||nodate, noterm, nohost, silent, never||Displays information on the user's last login. The module's options tell it what information to omit from this display. It maintains last login information in the /var/log/lastlog file.|
|pam_motd.so||session||motd=filename||Displays the contents of the message of the day (MOTD) file, which is /etc/motd by default, upon a successful login.|
|pam_deny.so||auth, account, session, and password||-||Always indicates a failure; useful at the end of certain stacks or as part of a default service to eliminate the risk of an unauthorized login due to misconfiguration.|
|pam_limits.so||session||conf=filename||Places limits, described in the /etc/security/limits.conf or specified configuration file, on users' resource uses (memory, CPU time, etc.). Requires kernel support for resource limits.|
|pam_mkhomedir.so||session||skel=directory, umask=octal-umask||Creates a home directory for users if one doesn't already exist, using the specified skeleton (skel) directory to populate the home directory with default configuration files and setting the directory's permissions based on the specified umask.|
|pam_access.so||account||accessfile=filename||Uses /etc/security/access.conf or the specified access file to determine username/machine name pairs that are or aren't granted access—e.g., to deny root the right to log in from particular machines.|
|pam_pwcheck.so||password||nullok, use_first_pass, use_authtok||Performs extra checks on password changes, as defined in /etc/login.defs, to improve security on user-selected passwords.|
|pam_cracklib.so||password||use_authtok and others to set specific checks||Adds checks for various features, such as passwords that have been used in the past or passwords that are too simple, to password-change interactions. Uses the libcrack library and a system dictionary (/usr/lib/cracklib_dict).|
|pam_stack.so||auth, account, session, and password||service=name||Calls a stack for the specified service. Provides easier configuration; you need to modify only one PAM configuration file to implement PAM changes across all the services that call pam_stack.so.|
Not all the modules mentioned in Table A-2 ship with all Linux distributions. These modules are all present and used in the default installations of at least one major distribution, though, with the exception of pam_mkhomedir.so. This module ships with all the major distributions but isn't used by default. It is, however, extremely useful with NT domain and LDAP add-on PAM modules.
Some modules accept parameters that are common to other modules. These common parameters include:
- Although it's not mentioned in Table A-2, this parameter causes most modules to dump extra debugging information to your system logfiles.
- Used in auth stacks, this option causes a module to try to use a password collected by a previous module for authentication. If this password fails, the module prompts the user again. Using this option on the second and subsequent password-checking modules can eliminate multiple password requests when you try to log in.
- This parameter works much like try_first_pass, but it causes the module that uses it to not request a password if the one it's given from a prior module fails.
- Most modules that handle passwords refuse null passwords (that is, passwords of zero length). This option tells these modules that null passwords are acceptable. (For authentication, of course, the authentication database must contain a null password; this option doesn't bypass the password check.)
- This parameter causes the module to return the same value when called as a credential-setting module as an authentication module. This practice helps PAM navigate the module stack most efficiently.
- If this option is present, the module takes extra care to maintain a system with shadow passwords. In particular, it better handles password aging, expiration, and similar information.
- This option causes a module in a password stack to use the password given to a previous module in a stack.
Linux distributions vary substantially in how they build PAM stacks from these modules. If you check two distributions' files, you'll probably find they call modules using different options, and they may call different sets of modules. Even within a distribution, different services may call different modules, even when the services are similar in function. Ultimately, though, most PAM stacks call pam_unix.so or pam_unix2.so, either directly for each service or indirectly via pam_stack.so. This is the most important PAM module, especially for logins.
Additional PAM Modules
Chapters Chapter 7, Chapter 8, and Chapter 9 present information on PAM modules that can be used in addition to or instead of the standard modules. In particular, these modules can replace or supplement pam_unix.so or pam_unix2.so. If you check the Internet, you can find still more PAM modules.
As described in the relevant chapters, there's more to adding support for most network authentication modules than simply configuring PAM. These modules typically rely on external configuration files to point them to their authentication servers. Sometimes you must configure the server to accept authentication requests from your Linux system or take other special steps to get the system to work.
When you add new PAM modules for authentication, you should first decide where to add them. If your distribution uses the pam_stack.so module, you should modify the stack that it references—typically /etc/pam.d/system-auth. If your distribution doesn't use this module, however, you may need to modify the configuration files for all the services that should use the new PAM module. For login services (login, xdm, sshd, and so on), you need to add auth and account lines:
auth sufficient /lib/security/pam_winbind.so try_first_pass account sufficient /lib/security/pam_winbind.so
Of course, the name of the module you call depends on what you're adding. Add the auth line to the existing auth stack just after the line that references pam_unix.so, and add the account line just after the existing account line. This placement causes PAM to check the new service after checking the local account database. The sufficient control flag tells PAM that if this authentication succeeds, it doesn't need to perform additional authentication checks; however, if it fails, PAM falls back on the local account database. The try_first_pass option prevents PAM from prompting for a password again should this happen; it delivers the password the user entered first into the next authentication tool.
Some servers and login tools must be restarted before they'll read the new PAM configuration files, so, if you forget to restart a server, you may think your change hasn't worked, when in fact it simply hasn't yet taken effect. Try to be methodical in your tests if you run into problems. Create some test accounts and take notes on the effects.
Be sure to test the effect of incorrect logins—both nonexistent usernames and valid usernames with invalid passwords. Some PAM configurations result in successful logins even when invalid passwords, and sometimes even invalid usernames, are entered. If you run into this problem, try adding a required call to pam_deny.so and make the actual authentication modules sufficient.
For password-changing services, such as passwd, your concerns are a bit different from those for login services. Depending on your needs, you might consider doing any of several things:
- Adding a new entry to the password stack causes the passwd program to prompt for two password changes: one for the local Unix password database and again for the new service you've added.
- Adding a new entry to the password stack and using the options use_authtok or use_first_pass with the second call causes both systems to use the password you enter the first time. You may need to make both these entries sufficient rather than required.
- Replacing the existing call to pam_unix.so or pam_unix2.so causes a single prompt for a password change using the new service, leaving the local password (if it exists) untouched.
- Not changing the password stack causes only the local account to change, if it exists. Users need to use tools specific to their new authentication system, such as smbpasswd for an NT domain controller, to change their network passwords.
As if these concerns weren't enough, a further complication is root's power to change normal users' passwords. Network authentication tools typically provide strong protections against anybody but the user or the password server's administrator from changing passwords. A local root account is unlikely to have this power, so chances are you'll need to use the administrative database's tools to make these changes.
Sample PAM Configurations
The preceding presentation is fairly abstract and may be hard to digest without some examples. Here, then, are some concrete examples, taken from working Linux distributions. These include a login service, a password service, and a system that uses an authentication stack.
Typical Login Services
Login services include the login program (used by the console and the Telnet server); the X Display Manager (XDM) and its KDE and GNOME counterparts, KDM and GDM; the SSH server; POP and IMAP mail servers; and the FTP server. Other tools that are similar, but that deviate a bit more, include the su and sudo commands and password-protected screensavers.
Example A-1 shows the /etc/pam.d/login file from a Debian Linux system. (The original file has many comment lines, though, which Example A-1 has omitted for brevity.) Because this is a login configuration, the most important sections of this file—from the perspective of an administrator wanting to change the system to use a network password database—are the auth and account stacks. These stacks both contain calls to pam_unix.so, as well as a few others that can restrict access in various ways or display information.
Example A-1. Sample PAM login service configuration
auth requisite pam_securetty.so auth requisite pam_nologin.so auth required pam_env.so auth required pam_unix.so nullok account requisite pam_time.so account required pam_unix.so session required pam_unix.so session optional pam_lastlog.so session optional pam_motd.so session optional pam_mail.so standard noenv password required pam_unix.so nullok min=6 max=255 md5
To modify Example A-1 to use an LDAP server (just as an example), you would add sufficient references to the pam_ldap.so module to the auth and account stacks just before the existing pam_unix.so calls. You may also want to add a call to the pam_mkhomedir.so module to the session stack, in order to create users' home directories if they don't already exist. Example A-2 presents all of these changes, with the changed and added material shown in bold.
Example A-2. Sample PAM login service configuration with LDAP support
auth requisite pam_securetty.so auth requisite pam_nologin.so auth required pam_env.so auth sufficient pam_ldap.so auth required pam_unix.so nullok try_first_pass account requisite pam_time.so account sufficient pam_ldap.so account required pam_unix.so session required pam_unix.so session optional pam_lastlog.so session optional pam_motd.so session optional pam_mail.so standard noenv session required pam_mkhomedir.so skel=/etc/skel umask=0027 password required pam_unix.so nullok min=6 max=255 md5
Several variants on these changes are possible. For instance, instead of adding pam_ldap.so before pam_unix.so, you can add a required call to pam_ldap.so after pam_unix.so, but this requires changing the status of pam_unix.so from required to sufficient and also associating the try_first_pass option with pam_ldap.so. This order reversal can reduce network traffic if significant numbers of users have locally defined accounts. Debian's configuration doesn't call any modules in the auth or account stacks after the pam_unix.so call, but some distributions do make such calls. For them, the specification of which module is called as sufficient has implications for the conditions under which these subsequent modules are called.
Yet another option is to set the calls to both pam_unix.so and pam_ldap.so to sufficient and add calls to pam_deny.so to the ends of these stacks. This approach may be less confusing to configure because the order of modules becomes a bit less important; however, a successful login using any of the sufficient modules then bypasses all subsequent modules in the stack, which may be undesirable.
If you want modules that must be placed after the actual password-checking modules to be called in all cases, you may want to look into using the pam_stack.so module. You can then place your actual password-checking calls in a substack that returns a single value, call pam_stack.so as a required module, and have modules that appear after this call in your individual service definitions execute no matter what tool actually authenticated your users.
Unless your system uses the pam_stack.so module, you should make changes similar to these on all of the PAM modules corresponding to the login and other authentication services you use. Of course, your files aren't likely to be identical to this one unless you use Debian—and even then, other Debian PAM files aren't identical to this one. You therefore need to adjust your changes to suit your own files.
One login server requires a bit of extra attention: SSH. This server sometimes doesn't work well with PAM authentication. If you can't seem to get your SSH server to use your new authentication tool, you may need to set one of two options in the /etc/ssh/sshd_config file on the SSH server system:
UsePAM yes UsePrivilegeSeparation no
I recommend trying UsePAM yes first. If that fails, try the second option. One of the two should get SSH to play nicely with PAM.
The /etc/pam.d/passwd file on most systems controls the passwd program's interactions with PAM. Example A-3 shows a sample file from a SuSE system. This file is a bit simpler than a typical login service definition.
Example A-3. Sample PAM password service configuration
auth required pam_unix2.so nullok account required pam_unix2.so password required pam_pwcheck.so nullok password required pam_unix2.so nullok use_first_pass use_authtok session required pam_unix2.so
Suppose that you want to enable users to change passwords on their local accounts if they exist or on their LDAP accounts if they exist. PAM can be rather picky about such arrangements; the passwd command requires use of several PAM stacks to do its work, from authentication through to the actual password change. Thus, you must add references to pam_ldap.so to three stacks. Example A-4 shows the result, with changed or added parts highlighted in bold.
Example A-4. Sample PAM password service configuration with LDAP support
auth sufficient pam_ldap.so auth required pam_unix2.so nullok use_first_pass account sufficient pam_ldap.so account required pam_unix2.so password required pam_pwcheck.so nullok password optional pam_ldap.so use_first_pass use_authtok password required pam_unix2.so nullok use_first_pass use_authtok session required pam_unix2.so
This configuration enables users to change their passwords much as they ordinarily do, by typing passwd and answering the usual password-changing prompts. Making the actual password call to pam_ldap.so optional changes the LDAP password if it exists but doesn't cause the operation to fail if the LDAP password doesn't exist. Thus, this configuration works for users who are defined locally, defined on the LDAP server, or both. (The required nature of the password stack call to pam_unix2.so would seem likely to cause a failure if the account isn't defined locally, but in practice, this isn't a problem.)
This configuration does have one drawback: the root user is prompted for the LDAP password of users, if they have LDAP accounts, before being allowed to change them. As a practical matter, this means that system administrators must use LDAP tools, rather than the passwd command, to change users' forgotten passwords or to set passwords on new accounts.
Of course, you can try variants on these changes. For instance, you can require users to have LDAP accounts; however, this might be undesirable if you want to maintain some local accounts (such as root) independent of the LDAP server. Alternatively, if you make the pam_ldap.so call in the password stack sufficient, users with both LDAP and local accounts can change only their LDAP passwords.
An Authentication Stack
Some distributions, such as Red Hat, Fedora, and Gentoo, now use the pam_stack.so module to place common authentication options in a single file. This approach can greatly simplify PAM configuration because you need to change only one file. Example A-5 shows the /etc/pam.d/system-auth file from a Gentoo system. (The original includes the complete paths to the library modules; Example A-5 omits these paths to keep line lengths manageable.) In principle, this file is a combination of other PAM configuration files, defining basic features used by all of them. This file shouldn't get too specific, though; options that should apply only to a few authentication tools should go in those tools' configuration files.
Example A-5. Sample PAM stack service configuration
auth required pam_env.so auth sufficient pam_unix.so likeauth nullok auth required pam_deny.so account required pam_unix.so password required pam_cracklib.so retry=3 password sufficient pam_unix.so nullok md5 shadow use_authtok password required pam_deny.so session required pam_limits.so session required pam_unix.so
To modify Example A-5 to use LDAP in addition to the local account database, you must add references to the pam_ldap.so module in the auth and account stacks. For the latter, you may also want to change the existing call to pam_unix.so to sufficient and add a required call to pam_deny.so to prevent too-easy bypassing of account-maintenance requirements, should you implement any. You may also want to add a call to the pam_mkhomedir.so module in the session stack; however, you might prefer putting this call in the individual server PAM modules to better control home directory creation. Once all the changes are made, the result looks like Example A-6, which shows changed or added material in bold.
Example A-6. Sample PAM stack service configuration with LDAP support
auth required pam_env.so auth sufficient pam_ldap.so auth sufficient pam_unix.so likeauth nullok use_first_pass auth required pam_deny.so account sufficient pam_ldap.so account sufficient pam_unix.so account required pam_deny.so password required pam_cracklib.so retry=3 password sufficient pam_unix.so nullok md5 shadow use_authtok password required pam_deny.so session required pam_limits.so session required pam_unix.so session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
Fedora and Red Hat autogenerate their /etc/pam.d/system-auth files using a tool called authconfig or its GUI equivalent, system-config-authentication. If you make changes to the raw PAM file, they may be wiped out if you run this tool. Thus, you might want to modify the file by using the configuration tool, rather than editing it directly. This tool also enables you to set configuration options for specific network authentication tools, such as locating your NT domain controller or LDAP server.
As always, many variants on this set of changes are possible. For instance, you can make changes to the password stack analogous with those described in the earlier Section A.4.2; however, I find that implementing these changes directly in the passwd file often produces better results.
This example configuration uses sufficient calls to several modules along with pam_deny.so to block accesses that fail all of these calls. This approach works well when you have no calls subsequent to the sufficient calls in a stack. In the case of a stacked configuration like this, its calling stack can then place additional module calls after the call to pam_stack.so, no matter how the stack module exits, if the calling stack calls pam_stack.so as a required or requisite module.
Changing a stack module's configuration doesn't mean you can't change individual servers' configurations. You can make general changes to /etc/pam.d/system-auth and then add other calls to the configuration files for login, KDM, su, and other tools, as you see fit.
PAM is a powerful tool for managing authentication options in Linux. As a modular tool, PAM is easily expanded—at least, easily when compared to recompiling all of your servers and other programs that require authentication. PAM is a very flexible tool, and some of this flexibility manifests itself in a plethora of options, some of which interact in peculiar ways. Understanding at least the more common of these options will help you adapt your PAM configuration to suit your needs, including adding network authentication tools such as NT domain controllers, LDAP servers, and Kerberos realms to your system. Actually creating a working configuration is likely to take some trial and error, but the examples presented here should set you on the right path.