Exploring LDAP — Part II (Directories)

This month, we continue our exploration of LDAP: the Lightweight Directory Access Protocol. If you followed along last month, you should now have a working LDAP server. Now we'll look at two ways of using it -- for a company directory and for user authentication. But first, let's take a look at LDAP schema.

This month, we continue our exploration of LDAP: the Lightweight Directory Access Protocol. If you followed along last month, you should now have a working LDAP server. Now we’ll look at two ways of using it — for a company directory and for user authentication. But first, let’s take a look at LDAP schema.

About Schema

A schema is a collection of object and attribute definitions that defines the structure of the entries in a database, and LDAP has its own schema definitions. LDAP objects are standardized in order to provide interoperability with a variety of directory services servers. On Linux systems, schema definitions are stored in files located in the /etc/ openldap/schema/ subdirectory. Specify the files that are in use via entries in the OpenLDAP configuration file, /etc/openldap/slapd.conf, as in the examples in Listing One.

Listing One: Configuration Entries

include /etc/openldap/schema/core.schema
include /etc/openldap/schema/misc.schema

Object definitions in the schema files are fairly easy to understand; take a look at Listing Two. This is the definition of the person object class. The first line specifies the unique Object Identifier (, followed by the class name (‘person’), a notation that the parent class is the top pseudo-object indicating the top of the hierarchy, and that this is a STRUCTURAL object. The remaining lines specify required and optional attributes for the object, with the use of the $ as a delimiter. The syntax is defined in the LDAP RFC (ftp://ftp.isi.edu/in-notes/rfc2251.txt).

Listing Two: person Object Class Definition

objectclass ( NAME ‘person’ SUP top STRUCTURAL
MUST( sn $ cn )
MAY( userPassword $ telephoneNumber $ seeAlso $ description ) )

Attributes are defined in separate entries having an even more obscure format. For example, Listing Three shows the definition of the sn (surname) attribute. The sn attribute draws its definition from its parent, the name attribute. Its definition specifies its syntax and how equality and substring comparisons are to be performed.

Listing Three: sn Attribute Definition

attributetype ( NAME ( ‘sn’ ‘surname’ ) SUP name )

attributetype ( NAME ‘name’
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMat
SYNTAX{32768} )

In general, you can figure out what’s going on with most objects by examining the relevant schema files. The Web site http://ldap.hklc.com provides a very convenient interface for exploring standard LDAP schema objects.

Creating a Company Directory

It is common to use LDAP to build a directory containing public information about everyone who works in, or belongs to, an organization. In order to create it, you’ll need to decide on the objects you’ll be using to store the information and how you want to organize them within the directory hierarchy. Then, you’ll need to get the data into the directory.

If possible, you should use standard objects for your data. Changing the standard schema will eliminate a lot of interoperability and is seldom necessary. Figure One illustrates a prototypical company directory entry.

Guru (LDAP Entry)
Figure One: Sample entry from a company directory.

This sample uses three object classes: person, organizationalPerson, and inetOrgPerson. The attributes are color-coded to match their originating object class, and there are more attributes available in these objects than there is room to include here. The first two object classes are included in the core.schema file, and the third can be found in the inetorgperson.schema file.

This sample entry illustrates an organization scheme based on the ou attribute. When searching for a person in the directory, providing the ou value among the search criteria will speed up the search in large directories.

Once data is entered or imported into the directory, users will be able to look up information through any client program, such as gq, kldap, web2ldap, or even Netscape.

It may seem a bit odd that there is a userPassword included in the attributes of an organizationalPerson since this is not, say, a user account object. This attribute is present in many objects and specifies that modification of the entry is limited to the person that it belongs to. We’ll consider how this is accomplished later in the column.

Using OpenLDAP for User Authentication

Enterprise-level user authentication is another appropriate and desirable application for an OpenLDAP-based directory service. This extends (but does not necessarily replace) the existing local authentication. Setting up such functionality is not difficult, but the process does require several steps.

1. Select an appropriate schema.

You’ll need to incorporate user account and related configuration information conventionally stored in files (or in the NIS facility) into the directory service. Fortunately, there are standard objects for this purpose. The ones to use are posixAccount and shadowAccount (both defined in the nis.schema file). In addition, if you wish to place users into an organizational unit (which is the standard practice, as we’ll see), then the account object is also used (defined in cosine.schema).

Accordingly, we’ll add these lines to slapd.conf:

include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/nis.schema

index cn,uid eq
index uidNumber eq
index gidNumber eq

The final three lines create indexes on the specified fields to speed up searches. While you are performing this process, you may also want to enable slapd logging via this configuration file entry:

# log connection setup, searches and
# various stats (8+32+256)
loglevel 296

The parameter specifies the desired items to be logged; it is a mask which ORs bits for the available items (see the OpenLDAP Administrator’s Guide for a list). Specify a log level of 0 to disable logging. Log messages are sent to the syslog local4.debug facility.

Don’t forget to restart slapd after editing its configuration file.

2. Convert existing user account data.

The next step is to transfer the user account data to the directory. The easiest way to do so is to use the open source migration tools provided by PADL software (http://www.padl.org). These are a series of Perl scripts that extract the required data from its current location and create corresponding directory entries.

To use them, first install the scripts to a convenient location. Then, edit the migrate_common.ph file. You will have to modify at least the following entries: $DEFAULT_BASE, $DEFAULT_MAIL_ DOMAIN, and $DEFAULT_MAIL_HOST. These are preset to padl.com addresses; read the inline documentation to determine which others (like those related to Sendmail recipients) you might want to change.

You should also set $EXTENDED_ SCHEMA = 1 if you would like the scripts to create user account entries as person, organizationalPerson, and inetOrgPerson objects in addition to the account-related objects.

There are two ways to proceed with the migration. First, you can run a script which automatically transfers all of the information to the directory; migrate_all_online.pl is used if slapd is running, and migrate_ all_offline.pl is used otherwise.

If you want to be even more cautious, you can use a third script to examine the resulting data step by step before importing. The following command converts the normal and shadow password files to LDIF format. The desired output file is specified as the second parameter:

# migrate_passwd.pl /etc/passwd passwd.ldif

Figure Two contains an example of the data it will generate. If you decide to go this route, you’ll also need to run the migrate_base.pl script to create the top-level directory entries that correspond to the ou‘s (e.g., People) the scripts place the accounts (and other entities) into. Another advantage of this method is you can change the ou name, subdivide it, and so forth before importing.

Figure Two: Running migrate_passwd.pl

Given the following entries from /etc/passwd and /etc/shadow:

/etc/passwd:aefrisch:x:371:100:AEleen Frisch:/home/aefrisch:/bin/tcsh

The output from migrate_passwd.pl would look like:

dn: uid=aefrisch,ou=People,dc=ahania,dc=com
uid: aefrisch
cn: AEleen Frisch
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
uidNumber: 371
gidNumber: 100
gecos: AEleen Frisch
homeDirectory: /home/aefrisch
loginShell: /bin/tcsh
userPassword: {crypt}cPv/oXHDE9hJg
shadowLastChange: 11457
shadowMax: 99999
shadowWarning: 7

There are also several PAM-related entries that may be included in ldap. conf, but for the basic functionality, the defaults usually work fine. See Figure Three for some optional pam_ ldap features.

Figure Three: Limiting Access by Host and/or Group with pam_ldap

The following ldap.conf entry tells LDAP to limit users’ access to the systems specified based on the host attribute(s) in their account entry:

# Allow user access to hosts if the user has the appropriate
# host attribute set in the directory
pam_check_host_attr yes

The following sample entry in the company directory could then be used to specify allowed access. Note that the host attribute is predefined as part of the account objectClass in the schema, and pam_ldap specifically looks for this attribute when pam_check_host_attr is activated in ldap.conf.

# List of allowed hosts
dn: uid=aefrisch,ou=People,dc=ahania,dc=com
uid: aefrisch
cn: AEleen Frisch
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
host: milton.ahania.com
host: shelley.ahania.com
host: yeats.ahania.com
uidNumber: 371
gidNumber: 100
gecos: AEleen Frisch
homeDirectory: /home/aefrisch
loginShell: /bin/tcsh
userPassword: {crypt}cPv/oXHDE9hJg
shadowLastChange: 11457
shadowMax: 99999
shadowWarning: 7

Using this entry, user aefrisch would have access only to hosts milton, shelley, and yeats. You can also set up ldap.conf to permit access to a specific host only to specified users.

# Only uniquemembers of this group can access this host
pam_groupdn cn=dalton.ahania.com,ou=People,dc=ahania,dc=com
pam_member_attribute uniquemember

And the corresponding entry for the host in the directory would be:

# List of allowed users on the local host
dn: cn=dalton.ahania.com,dc=ahania,dc=com
objectClass: ipHost
objectClass: device
objectClass: groupOfUniqueNames
cn: dalton
cn: dalton.ahania.com
uniqueMember: uid=chavez,ou=People,dc=ahania,dc=com
uniqueMember: uid=carter,ou=People,dc=ahania,dc=com

Using these entries, user aefrisch would not be able to login to host dalton, but the users chavez and carter would.

5. Configure directory access control.

The final steps for setting things up involve directory access control. The database files themselves are protected against all non-root access, so permissions are enforced by the server. Access control information is specified in slapd.conf, the server’s configuration file.

Here are some example entries:

# simple access control: read-only except passwords
access to dn=”.*,dc=ahania,dc=com” attr=userPassword
by self write
by dn=root,ou=People,dc=ahania,dc=com write
by * auth

access to dn=”.*,dc=ahania,dc=com”
by self write
by * read

The access control entry specifies a pattern that the dn must match in order for the entry to apply. In the case of multiple entries, the first matching entry is used and all other entries are ignored. The first access to entry applies to the userPassword attri-bute of any entry: any dn in dc=ahania,dc=com. The owner can modify the entry, where the owner is defined as someone binding to the server using that dn and its associated password. Everyone else can access it only for authentication/binding purposes, but they cannot view it.

The second entry serves as a default for the remainder of the database. Again, the owner can modify an entry, and everyone else can read it. This provides an access level that allows both searching and displaying. These permissions are often appropriate for a company directory but are too lax for user account data.

And Next Time…

We’ll present a lot of detailed information about LDAP authentication and security mechanisms in the third part of this series, including how to address the different security levels necessary for user authentication, as opposed to those necessary for company directory listings.

amp;AElig;leen Frisch is the author of O’Reilly amp;amp; Associates’ Essential System Administration. She can be reached at aefrisch@lorentzian.com.

Comments are closed.