Exploring LDAP — Part I (Basics)

For years now, every time anyone put together a list of hot system administration topics, LDAP was sure to be near the top. This is the first article in a three-part series about LDAP and, specifically, OpenLDAP on Linux systems. In this first part, we will explore some basic LDAP concepts and show a few example queries and configuration options. In the second part, we'll look at how to integrate LDAP into normal system functions like user authentication. In part three, we will close the series by considering some advanced LDAP topics, including authentication, security, and data replication among multiple servers.

For years now, every time anyone put together a list of hot system administration topics, LDAP was sure to be near the top. This is the first article in a three-part series about LDAP and, specifically, OpenLDAP on Linux systems. In this first part, we will explore some basic LDAP concepts and show a few example queries and configuration options. In the second part, we’ll look at how to integrate LDAP into normal system functions like user authentication. In part three, we will close the series by considering some advanced LDAP topics, including authentication, security, and data replication among multiple servers.

About LDAP and OpenLDAP

As its name implies, LDAP (which stands for Lightweight Directory Access Protocol) is a protocol for accessing a directory, which is a database that’s been optimized for frequent reading and fast searching.

The best real-life analogy for a directory service is the phone company’s directory assistance. It’s a mechanism for customers to quickly find information they need by delegating the search to someone faster and more knowledgeable. Traditionally, human operators provided the (hopefully friendly) interface between the user (customer) and the database (the list of phone numbers). A computer-based directory service provides similar functionality.

Compared to a database made for transaction processing, an LDAP directory service differs in that:

  • It’s optimized for reading. This means, therefore, writing may be expensive.
  • It provides several advanced searching features.
  • Its fundamental data structures –collectively known as the schema — can be extended according to local needs.
  • It adheres to published standards to ensure interoperability among vendor implementations (specifically, a boatload of RFCs).
  • It takes advantage of distributed storage and data replication techniques.

LDAP was first implemented at the University of Michigan in the early 1990s. OpenLDAP is an open source implementation of LDAP based on that work.

There are interfaces to OpenLDAP in most of the common programming languages (C/C++, Java, Perl, Python, and so on). The OpenLDAP package includes daemons, configuration files, startup scripts, libraries, and utilities. (See Table One.)

Table One: OpenLDAP Daemons and Utilities

slapd OpenLDAP daemon
slurpd Data replication daemon
ldapd LDAP to X.500 gateway daemon
ldapadd, slapadd Add directory entries
ldapmodify Modify directory entries
ldapmodrdn Change an entry’s rdn
ldapdelete Delete directory entries
ldapsearch Search directory for entries matching specified criteria
ldappasswd Change entry password
slappasswd Generate encoded passwords
slapcat Display directory entries in LDIF format ( slapd not running)
slapindex Regenerate/update directory indexes (slapd not running)

LDAP directories are tree structured, and their “root” node typically corresponds to the site’s domain name. For example, ahania.com would be expressed as dc=ahania,dc=com.

Each component of the domain name becomes the value for a dc (domain component) attribute, and all of them are collected into a comma-separated list. This is known as the directory’s base.

As you would expect, domain names with more than two components would have additional dc attributes in the list (for example, dc=research, dc=ahania,dc=com represents research.ahania.com).

Such a list of attribute value pairs is the key to uniquely identifying any entry within the directory. (Spaces are not significant between items.) Let’s now turn to a sample record from a directory service database:

dn: cn=Jerry Carter, ou=MyList,
dc=ahania, dc=com
objectClass: person
cn: Jerry Carter
sn: Carter
description: Samba and LDAP
telephoneNumber: 22

This data format is known as LDIF (LDAP Data Interchange Format). It is organized as a series of colon-separated key:value pairs.

The first line in the above example is special. It specifies the entry’s distinguished name (dn), which functions as its unique key within the database. (I like to think of it as a Borg designation.) As expected, it is constructed as a comma-separated list of attribute= value pairs. In this case, the entry is for common name (cn) “Jerry Carter,” organizational unit (ou) “MyList” in the example directory for ahania.com.

The objectClass attribute specifies the type of record being defined (a person), and every entry must have at least one objectClass attribute. Valid record types are defined in the directory’s schema, and there are a variety of standard record types that have been defined. The other attributes specify the person‘s surname (sn), description, and phone number.

The first component of the dn is known as the entry’s relative distinguished name (rdn). In our example, this would be cn=Jerry Carter. It corresponds to the location within the ou=MyList,dc=ahania,dc=com subtree where this entry resides. An rdn must be unique within its subtree just as the dn attribute is unique within the entire directory.

Listing One shows a simple representation of the directory tree in which successive (deeper) levels are indicated by indentation. Notice that we have defined an additional organizational unit, which is called “PyTest.”

Listing One: Directory Tree with Indentation

cn=Jerry Carter,ou=MyList,dc=ahania,dc=com
cn=Aeleen Frisch,ou=MyList,dc=ahania,dc=com
more people …
different people …

Now that some of the theory has been covered, it’s time to start familiarizing yourself with the software.

Installing and Configuring OpenLDAP: An Overview

Installing OpenLDAP is not difficult but it can be time consuming. The first step is to obtain all of the needed software. This includes not only OpenLDAP itself, but also its prerequisites:

Guru (ldap SuSE Install)
Figure One: Installing the Open LDAP RPM under SuSE Linux.

On normal RPM-based systems, you can check for the presence of these requirements by simply submitting the following command:

# rpm -qa | egrep -i

If any of the prerequisites are missing from your system, you must make sure that you install them before building and installing OpenLDAP. Fortunately, some Red Hat and SuSE distributions provide an RPM containing the already-built software. Figure One illustrates the process of installing OpenLDAP on a SuSE system using yast2.

Once the prerequisite software is installed, the next step is to create a configuration file for the slapd daemon. We’ll assume that we’re running on a SuSE distribution, so we’ll edit the file /etc/openldap/slapd.conf. See Listing Two for a simple example of how this is done.

Listing Two: /etc/openldap/slapd.conf

# /etc/openldap/slapd.conf
include /etc/openldap/schema/core.schema
pidfile /var/run/slapd.pid
argsfile /var/run/slapd.args

database ldbm
suffix “dc=ahania, dc=com”
rootdn “cn=Manager, dc=ahania, dc=com”

# encode rootpw with `slappasswd -h ‘{MD5}’ -s secret -v -u`
rootpw {MD5}Xr4ilOzQ4PCOq3aQ0qbuaQ==
directory /var/lib/ldap

Change any paths that are not correct for your system and set the correct dc components in the suffix (base) and rootdn (database owner) entries. “Manager” is the traditional common name to use for this purpose. Also, you should be sure to set a password for the root dn in the rootpw entry. You can do this either in plain text, or you can use the slappasswd utility to encrypt it.

Finally, make sure that the specified database directory /var/lib/ldap exists, is owned by root, and is mode 700. The configuration file itself should also be readable only by root.

Once the configuration file is prepared, you can start slapd manually. On SuSE systems, you can use the provided boot script:

# /etc/rc.d/ldap start

If you want the LDAP daemons to be started at boot time, set the value of the START_LDAP entry in /etc/rc.config, as shown below:


Next, you will have to create the first directory entries. This will require you to manually write them into a text file in LDIF format. You can begin this by making a file called /tmp/entry0 and let it contain the following:

# Domain entry
dn: dc=ahania,dc=com
objectclass: dcObject
objectclass: organization
o: Exponential Consulting
dc: ahania.com

# Manager entry
dn: cn=Manager,dc=ahania,dc=com
objectclass: organizationalRole
cn: Manager

Use a command like the one in the following example to add these entries from the file you just created to an LDAP directory:

# ldapadd -x \
-D “cn=Manager,dc=ahania,
dc=com” \
-W -f /tmp/entry0

Enter LDAP Password:
adding new entry “dc=ahania,
adding new entry “cn=Manager,

The -f option to ldapadd specifies the location of the prepared LDIF file, and -D specifies the dn with which to connect to the server. This process is known as “binding.” Finally, -x and -W say to use simple authentication and to prompt for the password (respectively).

You can verify that everything is working by running the command shown in Listing Three to query the directory for all its entries. This command displays the directory’s base-level (or topmost) entry. We’ll discuss the general syntax of ldapsearch in a bit.

Listing Three: A Basic ldapsearch Search

# ldapsearch -x -b ‘dc=ahania,dc=com’ ‘(objectclass=*)’

version: 2

# ahania,dc=com
dn: dc=ahania,dc=com
objectClass: dcObject
objectClass: organization
o: Exponential Consulting
dc: ahania.com

If this command does not complete successfully, check to make sure that the slapd daemon is running; if not, look in /var/log/messages for error messages. If it is running, but you are denied access to the server, add the following options to the ldapsearch command:

-D ‘cn=Manager,dc=ahania,
dc=com’ -W

At this point, the server is ready to go to work. The next step is to learn how to construct some more interesting queries.

LDAP in Action

The full syntax of the ldapsearch command is:

ldapsearch [options] search-
criteria [attributes]

where options controls the command’s behavior, search-criteria specifies which entries to retrieve, and attributes specifies which attributes of the retrieved entries to display (the default is all of them). Search criteria are written according to the rather arcane LDAP rules. The basic format is attribute=pattern, and the pattern can be a literal value (which must be matched exactly) or a string containing wildcards. In Listing Three, the criteria (objectclass=*) returned entries having any value for the objectclass attribute (which means all of them, since each must have an objectclass attribute).

Listing Four is a more complicated search that uses additional options of ldapsearch and assumes we are searching in a more fully-populated directory than the one we have created so far. This example shows how we can control exactly what data is returned from the query. For this query, we wish to use simple authentication (-x), then start the search at the base entry dc=ahania,dc=com (-b), and sort the entries by the cn attribute (-S).

Listing Four: A More Advanced ldapsearch Example

# ldapsearch -x -b ‘dc=ahania,dc=com’ \
-S cn ‘(&(objectclass=person)(cn=Mike*))’ \
telephoneNumber \

dn: cn=Mike Frisch, ou=MyList, dc=ahania, dc=com
telephoneNumber: 18
description: Computational chemist

dn: cn=Mike Loukides, ou=MyList, dc=ahania, dc=com
telephoneNumber: 14
description: Editor and writer

The search criteria says that the objectclass should be person AND the cn should start with “Mike” (notice the syntax for a conditional AND statement). The other arguments ask that the attributes telephoneNumber and description be displayed in addition to the dn.

A nice feature of LDAP is it can be a distributed service, so we need to know how to make an LDAP query to a directory that resides on a remote host. This is done by adding the -H parameter like in the following:

# ldapsearch -H ldap:
//bella.ahania.com \
-x -b ‘dc=ahania,dc=com’ \
‘(cn=Mike*)’ \
telephoneNumber description

Figure Two: Using web2ldap to access LDAP from Netscape.

If typing these queries on the command line seems too tedious, there are a variety of LDAP clients available to make directory entry viewing and manipulation easier. Some common ones are kldap, gq, and web2ldap. (See the LDAP Resources sidebar.)

Figure Two illustrates the web2ldap application, which allows LDAP directories to be accessed from within a Web browser. The window at the upper left shows an example of its search features (the results are in the window under it at the bottom right). The third window in the Figure (at the lower left) is the form used to modify an existing entry. Here we change Jerry Carter’s telephone number to 29. By now, the process of using an LDAP directory service should make sense.

Stay Tuned…

We’ve only just scratched the surface of OpenLDAP. In the next two months, we’ll discuss additional LDAP concepts and provide additional examples. In the next installment, we’ll look at integrating LDAP into normal system functions like user authentication. Until then, experiment with LDAP a bit and have fun.

LDAP Resources

Understanding and Deploying LDAP Directory Services, Timothy A. Howes, Mark C. Smith, and Gordon S. Good, Macmillan, 1999.

Information and Source Code http://www.openldap.org

Linux LDAP HOWTO http://www.linuxdoc.org/HOWTO/LDAP-HOWTO.html

Thesis Comparing LDAP Implementations http://www.daasi.de/norbert/thesis.pdf

View Standard Schema http://ldap.hklc.com

Migration Tools http://www.padl.com

kldap Client http://www.mouthpoint.ch/oliver/kldap

Browser-Based LDAP Access http://web2ldap.de

Æleen Frisch is the author of Essential System Administration. She can be reached at aefrisch@lorentzian.com.

Comments are closed.