6.4 The pam_ldap Module

Pluggable Authentication Modules (PAM) are implemented as shared libraries that distance applications from the details of account data storage, mechanisms used to authenticate users, and service authorization processes. PADL Software has developed a pam_ldap module, supported on FreeBSD, HP-UX, Linux, Mac OS 10.2, and Solaris, as part of a reference implementation for RFC 2307. This module allows you to take advantage of LDAP in PAM-aware applications and operating systems. You can download the pam_ldap source code from http://www.padl.com/OSS/pam_ldap.html. Most Linux distributions include PADL's pam_ldap and nss_ldap modules with the operating system. You should remove these packages first if you plan to build the latest version from source.

The pam_ldap and nss_ldap libraries included with Solaris as part of the operating system installation are Sun's own creation and should not be confused with the modules discussed in this chapter.

Once you have obtained and extracted the pam_ldap source code, building the module is a familiar process:

$ ./configure
$ make
$ /bin/su -c "make install"

PADL's PAM and NSS libraries can make use of the Netscape LDAP SDK and the original University of Michigan LDAP SDK, in addition to the OpenLDAP client libraries. The configure script attempts to determine which of these packages is installed on the local system. If you need to inform the configure script which LDAP client libraries you have installed and where, use the following configure options:

--with-ldap-lib=type   select ldap library [auto|netscape3|
--with-ldap-dir=DIR    base directory of ldap SDK

6.4.1 Configuring /etc/ldap.conf

The pam_ldap module (and as we will see shortly, PADL's nss_ldap module) stores its configuration settings in a text file. This file is named ldap.conf by default and is normally stored in the /etc directory. The configuration parameters you can put in this file are summarized in Table 6-1, Table 6-2, and Table 6-3; the list is fairly small and self-explanatory. We will begin customizing this file by exploring how a client locates the LDAP server and authenticates itself.

Table 6-1. ldap.conf parameters shared by pam_ldap and nss_ldap




The IP address (or hostname) of the LDAP server. The value must be resolvable without LDAP support. If a host is not specified, the nss_ldap library will attempt to locate an LDAP server by querying DNS for an SRV record for _ldap._tcp.<domain>. The current version of the pam_ldap module (v157) will not perform this auto-lookup, but support is planned for a future release. Also refer to the uri parameter.


The base DN to use in searches.


The version of LDAP to use when querying the server. Legal values are 2 and 3. Version 3 is used by default if it is supported by the client libraries.


The DN to use when binding to the LDAP server. This is an optional parameter; it is necessary when access control on directory entries prohibits anonymous searches.


The password used when binding to the LDAP server (if the binddn was defined).


The port to use when contacting the LDAP server. The default is port 389. Also refer to the uri parameter.


This parameter allows you to map the effective UID 0 (i.e., the root UID) to a DN that is used to bind to the LDAP server. If enabled, the password for this DN is read from /etc/ldap.secret. This follows the convention that the root account should be able to access all information on the system.


This parameter defines the behavior of the PAM and NSS modules for negotiating SSL when binding to the server. By default, SSL is not used. The client can be configured to use LDAPS by setting this parameter to on, or to use the StartTLS Extended command by setting this parameter to start_tls.


The scope to use when searching the LDAP tree. The possible values are sub, one, and base.


This option accepts an LDAP URI defining the host and port of the directory server.

Table 6-2. pam_ldap ldap.conf parameters




A Boolean parameter (defaults to no) that controls checking of the host attribute when authorizing a login.


A string that provides additional filter elements that are ANDed with (uid=%s) when attempting to validate a user. See the pam_login_attribute parameter for related information.


The attribute that should be matched against the user's login name. This parameter lets you use something other than a simple username for authentication?for example, an email address.


A Boolean parameter (yes or no) that tells pam_ldap whether to contact the root DSE to get the server's password policy. For use with Netscape's directory server 3.x only.


Defines the DN of a group whose membership (see the pam_member_attribute parameter) should be used to to restrict access to the local host.


Defines the group membership attribute.



These two parameters accept an integer representing the minimum and maximun uidNumber values allowed to log in. The default is to place no restrictions on logins.


This parameter defines various methods for changing passwords on LDAP servers. It supersedes the older pam_crypt, pam_nds_passwd, and pam_ad_passwd parameters. Possible values include: clear (the default; sends the clear text of the password to the server), crypt (hashes the password locally using the standard crypt( ) function before sending the change to the server), md5 (generates the MD5 hash of the password locally before sending it to the server), nds, racf (provides support for changing passwords stored in a Novell Directory Server), ad (provides support for changing passwords stored in an Active Directory server), and exop (supports the Password Modify extended operation defined in RFC 3062; implemented by OpenLDAP).

Table 6-3. nss_ldap ldap.conf parameters















These parameters allow the naming contexts for various databases in nsswitch.conf to be configured as per the recommendations from the RFC 2307 updates. The syntax is:

nss_base_XXX  base?scope?filter

The filter is combined with the default filter for the object being requested using a logical AND (&). These parameters are available only when nss_ldap has been configured to use the ?enable-rfc2307bis option at compile time.



These parameters provide a means of mapping attributes and object classes returned from the directory server to an RFC 2307-equivalent schema item. The syntax is:

nss_map_XX  rfc2307item  mapped_item

In order for the pam_ldap module to offer any help, it must be able to locate the directory server it will query for information. There are two ways that the module can locate the directory server. The sole method supported by pam_ldap is to explicitly specify the LDAP server using the host or uri parameters in ldap.conf. The alternative, utilized only by the nss_ldap library, is to omit the host parameter and create a DNS SRV record that maps the hostname _ldap._tcp.<domain> to an IP address. If no host is specified in ldap.conf, the nss_ldap library tries to look up a server with this special hostname and uses that server at that address for queries. If you have multiple servers, you can configure round-robin load sharing with either approach.

The following parameters instruct pam_ldap to contact the host ldap.plainjoe.org on the default port 389 for all LDAPv3 queries:

# Your LDAP server. Must be resolvable without using LDAP.
uri           ldap://ldap.plainjoe.org/
## Set the version number for LDAP commands. The default is to use Version 3 if
## supported by the client libraries.
ldap_version     3

Next, you must define the search parameters for pam_ldap to use when querying the directory. These options correspond to the standard ldapsearch command-line options. The following fragment of ldap.conf defines the search base, the search scope, and a maximum time limit:

## Define the search base
base          dc=plainjoe,dc=org
## Define the scope of the search [sub|base|one]. A subtree search is the default.
scope         sub
## Set a time limit in seconds to wait on a search.
timelimit     30

The DN of the user's entry must be located in order to bind to the directory on behalf of the user and thus perform the requested authentication. This search can be done either anonymously or by using a predefined binddn and bindpw. The bindpw string must be stored in ldap.conf as clear text, which always makes me nervous. Therefore, my preference is for the first option. Because anonymous searches are implied by the absence of a specified binddn, no additional ldap.conf parameters are required.

Finally, add a few parameters to fine-tune the search filter. pam_login_attribute defines which attribute should be matched to the login name entered by the user. pam_filter allows an administrator to further refine the search filter when attempting to locate a user account. In the following configuration file entries, it is specified that the user's login name should be matched against the UID attribute defined in the posixAccount object class. (Note that a UID in this schema is a login name, not a number, as in common Unix usage.)

## Define the user login name attribute (defaults to uid).
pam_login_attribute      uid
## The following filter will be used to AND with <pam_login_attribute>=%s.
pam_filter objectclass=posixAccount

With these two settings, the pam_ldap library makes the following search to verify that a user account named "carter" is in the directory:


After verifying the existence of the DN, the PAM module attempts to bind to the directory using the located DN and the password entered by the user. If this bind succeeds, pam_ldap informs the calling application that the user has been successfully authenticated.