14.7. LDAP — A Directory Service

It is crucial within a networked environment to keep important
information structured and quickly available. Data chaos does not only loom
when using the Internet. The search for important data in the company network
can just as quickly grow disproportionately. “What is the extension
number of colleague XY? What is his e-mail address?” This problem is
solved by a directory service that, like the common yellow pages, keeps
information available in a well-structured, quickly searchable form.

In the ideal case, a central server keeps the data in a directory and
distributes it to all clients using a certain protocol. The data is
structured in a way that a wide range of applications can access them. That
way, it is not necessary for every single calendar tool and e-mail client to
keep its own database — a central repository can be accessed instead.
This notably reduces the administration effort for the concerned information.
The use of an open and standardized protocol like LDAP ensures that as many
different client applications as possible can access such information.

A directory in this context is a type of database optimized for quick
and effective reading and searching:

To make numerous (concurrent) reading accesses possible, the writing
access is limited to a small number of updates by the administrator.
Conventional databases are optimized for accepting the largest possible
data volume in a short time.

Because writing accesses can only be executed in a restricted fashion,
a directory service is employed for administering mostly unchanging, static
information. Data in a conventional database typically changes very often
(dynamic data). Phone numbers in a company directory
do not change nearly as often as, for instance, the figures administered in
accounting.

When static data is administered, updates of the existing data sets
are very rare. When working with dynamic data, especially when data sets
like bank accounts or accounting are concerned, the consistency of the data
is of primary importance. If an amount should be subtracted from one
place to be added to another, both operations must happen concurrently,
within a transaction, to ensure the balance over the whole
data stock. Databases support such transactions. Directories do not.
Short-term inconsistencies of the data are quite acceptable in
directories.

The design of a directory service like LDAP is not laid out to support
complex update or query mechanisms. All applications accessing this service
should gain access quickly and easily.

Many directory services have previously existed and still exist both in
Unix and outside it. Novell NDS, Microsoft ADS, Banyan's Street Talk, and the
OSI standard X.500 are just a few examples. LDAP was originally planned as a
lean flavor of the DAP, the Directory Access Protocol, which was developed
for accessing X.500. The X.500 standard regulates the hierarchical
organization of directory entries.

LDAP is relieved of a few functions of the DAP. Without having to miss
the X.500 entry hierarchy you profit from LDAP's cross-platform capabilities
and save resources. and can be employed, The use of TCP/IP makes it
substantially easier to establish interfaces between a docking application
and the LDAP service.

LDAP, meanwhile, has evolved and is increasingly employed as a
stand-alone solution without X.500 support. LDAP supports
referrals with LDAPv3 (the protocol version in package
openldap2), making it possible to realize
distributed databases. The usage of SASL (Simple Authentication and Security
Layer) is also new.

LDAP is not limited to querying data from X.500 servers, as it was
originally planned. There is an open source server
slapd, which can store object information in a
local database. There is also an extension called
slurpd, which is responsible for replicating
multiple LDAP servers.

The openldap2 package
consists of:

slapd

A stand-alone LDAPv3 server that administers object information in a
BerkeleyDB-based database.

slurpd

This program enables the replication of modifications to data on the
local LDAP server to other LDAP servers installed on the network.

additional tools for system maintenance

slapcat,
slapadd,
slapindex

14.7.1. LDAP versus NIS

The Unix system administrator traditionally uses the NIS service for
name resolution and data distribution in a network. The configuration data
contained in the files in /etc and
the directories group, hosts, mail, netgroup, networks, passwd, printcap, protocols, rpc, and services are distributed by clients all over
the network. These files can be maintained without major effort because they
are simple text files. The handling of larger amounts of data, however,
becomes increasingly difficult due to nonexistent structuring. NIS is only
designed for Unix platforms, which makes its employment as a central data
administrator in a heterogeneous network impossible.

Unlike NIS, the LDAP service is not restricted to pure Unix
networks. Windows servers (from 2000) support LDAP as a directory service.
Novell also offers an LDAP service. Application tasks mentioned above are
additionally supported in non-Unix systems.

The LDAP principle can be applied to any data structure that should be
centrally administered. A few application examples are:

Employment as a replacement for the NIS service.

Mail routing (postfix, sendmail).

Address books for mail clients like
Mozilla, Evolution,
and Outlook.

Administration of zone descriptions for a BIND9 name server.

This list can be extended because LDAP is extensible as opposed to NIS.
The clearly-defined hierarchical structure of the data greatly helps the
administration of very large amounts of data, because it can be searched
better.

14.7.2. Structure of an LDAP Directory Tree

An LDAP directory has a tree structure. All entries (called objects) of
the directory have a defined position within this hierarchy. This hierarchy
is called the directory information tree or, for short,
DIT. The complete path to the desired entry, which unambiguously identifies
it, is called distinguished name or DN. The single
nodes along the path to this entry are called relative
distinguished name or RDN. Objects can generally be assigned to
one of two possible types:

container

These objects can themselves contain other objects. Such object
classes are root (the root element of the directory
tree, which does not really exist), c (country),
ou (organizational unit), and dc
(domain component). This model is comparable to the directories (folders)
in a file system.

leaf

These objects sit at the end of a branch and have no subordinate
objects. Examples are person,
InetOrgPerson, or
groupofNames.

The top of the directory hierarchy has a root element
root. This can contain c (country),
dc (domain component), or o
(organization) as subordinate elements. The relations within an LDAP
directory tree become more evident in the following example, shown in
Figure 14.4. “Structure of an LDAP Directory”.

Figure 14.4. Structure of an LDAP Directory

The complete diagram comprises a fictional directory information tree.
The entries on three levels are depicted. Each entry corresponds to one box
in the picture. The complete, valid distinguished name
for the fictional SUSE employee Geeko
Linux, in this case, is cn=Geeko
Linux,ou=doc,dc=suse,dc=de. It is composed by adding the RDN
cn=Geeko Linux to the DN of the preceding entry
ou=doc,dc=suse,dc=de.

The global determination of which types of objects should be stored in
the DIT is done following a scheme. The type of an
object is determined by the object class. The object
class determines what attributes the concerned object
must or can be assigned. A scheme,
therefore, must contain definitions of all object classes and attributes
used in the desired application scenario. There are a few common schemes
(see RFC 2252 and 2256). It is, however, possible to create custom schemes
or to use multiple schemes complementing each other if this is required by
the environment in which the LDAP server should operate.

The attribute type organizationalUnitName and the
corresponding object class organizationalUnit serve as an
example here. Line 1 features the name of the attribute, its unique OID
(object identifier) (numerical), and the abbreviation
of the attribute.

Line 2 gives brief description of the attribute with
DESC. The corresponding RFC on which the definition is
based is also mentioned here. SUP in line 3 indicates a
superordinate attribute type to which this attribute belongs.

The definition of the object class
organizationalUnit begins in line 4, like in the
definition of the attribute, with an OID and the name of the object class.
Line 5 features a brief description of the object class. Line 6 with its
entry SUP top indicates that this object class is not
subordinate to another object class. Line 7, starting with
MUST, lists all attribute types that
must be used in conjunction with an object of the type
organizationalUnit. Line 8 starting with
MAY lists all attribute types that are allowed to be used
in conjunction with this object class.

A very good introduction in the use of schemes can be found in the
documentation of OpenLDAP. When installed, find
it in /usr/share/doc/packages/openldap2/admin-guide/index.html.

14.7.3. Server Configuration with slapd.conf

Your installed system contains a complete configuration file for your
LDAP server at /etc/openldap/slapd.conf. The single
entries are briefly described here and necessary adjustments are explained.
Entries prefixed with a hash prefix (#) are inactive. This comment character
must be removed to activate them.

14.7.3.1. Global Directives in slapd.conf

Example 14.18. slapd.conf: Include Directive for Schemes

include /etc/openldap/schema/core.schema
include /etc/openldap/schema/inetorgperson.schema

This first directive in slapd.conf, shown in
Example 14.18. “slapd.conf: Include Directive for Schemes”,
specifies the scheme by which the LDAP directory is organized. The entry
core.schema is compulsory. Additionally required
schemes are appended to this directive
(inetorgperson.schema has been added here as an
example). More available schemes can be found in the directory
/etc/openldap/schema. For replacing NIS with an
analogous LDAP service, include the two schemes
rfc2307.schema and cosine.schema.
Information can be found in the included
OpenLDAP documentation.

Example 14.19. slapd.conf: pidfile and argsfile

pidfile /var/run/slapd.pid
argsfile /var/run/slapd.args

These two files contain the PID (process ID) and some of the arguments
with which the slapd process is started. There
is no need for modifications here.

Example 14.20. “slapd.conf: Access Control” is the excerpt from
slapd.conf that regulates the access permissions for
the LDAP directory on the server. The settings made here in the global
section of slapd.conf are valid as long as no custom
access rules are declared in the database-specific section. These would
overwrite the global declarations. As presented here, all users have read
access to the directory, but only the administrator
(rootdn) can write into this directory. Access control
regulation in LDAP is a highly complex process. The following tips can
help:

Every access rule has the following structure:

access to <what> by <who> <access>

what is a placeholder for the object or
attribute to which access is granted. Individual directory branches can
explicitly be protected with separate rules. It is also possible to
process whole regions of the directory tree with one rule by using
regular expressions. slapd evaluates all rules
in the order in which they are listed in the configuration file. More
general rules should be listed after more specific ones — the first
rule slapd regards as valid is evaluated and
all following entries are ignored.

who determines who should be granted
access to the areas determined with what.
Regular expressions may be used. slapd again
aborts the evaluation of who after the first match so
more specific rules should be listed before the more general ones. The
entries shown in Table 14.10. “User Groups and Their Access Grants” are possible.

Table 14.10. User Groups and Their Access Grants

Tag

Scope

*

all users without exception

anonymous

not authenticated (“anonymous”)
users

users

authenticated users

self

users connected with the target object

dn=<regex>

all users matching the regular expression

access specifies the type of access. It
is distinguished from the options listed below in Table 14.11. “Types of Access”.

Table 14.11. Types of Access

Tag

Scope of Access

none

no access

auth

for contacting the server

compare

to objects for comparison access

search

for the employment of search filters

read

read access

write

write access

slapd compares the access right requested
by the client with those granted in slapd.conf. The
client is granted access if the rules allow a higher or equal right than
the requested one. If the client requests higher rights than those
declared in the rules, it is denied access.

access to dn.regex="ou=([^,]+),dc=suse,dc=de"
by cn=administrator,ou=$1,dc=suse,dc=de write
by user read
by * none

This rule declares that only its respective administrator has write
access to an individual ou entry. All other
authenticated users have read access and the rest of the world has no
access.

Establishing Access Rules

If there is no access to rule or no matching
bywho directive, access is denied.
Only explicitly declared access rights are granted. If no rules are
declared at all, the default principle is write access for the
administrator and read access for the rest of the world.

Find detailed information and an example configuration for LDAP
access rights in the online documentation of the installed
openldap2 package.

Apart from the possibility to administer access permissions with
the central server configuration file (slapd.conf),
there is ACI, access control information. ACI allows storage of the access
information for individual objects within the LDAP tree. This type of
access control is not yet common and is still considered experimental by
the developers. Refer to http://www.openldap.org/faq/data/cache/758.html for
information.

14.7.3.2. Database-Specific Directives in slapd.conf

Example 14.22. slapd.conf: Database-Specific Directives

database ldbm
suffix "dc=suse,dc=de"
rootdn "cn=admin,dc=suse,dc=de"
# Cleartext passwords, especially for the rootdn, should
# be avoided. See slappasswd(8) and slapd.conf(5) for details.
# Use of strong authentication encouraged. rootpw secret
# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd/tools. Mode 700 recommended.
directory /var/lib/ldap
# Indices to maintain
index objectClass eq

The type of database, LDBM in this case, is determined in the first
line of this section (see Example 14.22. “slapd.conf: Database-Specific Directives”). The second line determines, with
suffix, for which portion of the LDAP tree this server
should be responsible. The following rootdn determines
who owns administrator rights to this server. The user declared here does
not need to have an LDAP entry or exist as regular user. The administrator
password is set with rootpw. Instead of using
secret here, it is possible to enter the hash of the
administrator password created by slappasswd.
The directory directive indicates the directory (in the
file system) where the database directories are stored on the server. The
last directive, index objectClass eq, results in the
maintenance of an index over all object classes. Attributes for
which users search
most often can be added here according to experience. Custom
Access rules defined here for the database are used
instead of the global Access rules.

14.7.3.3. Starting and Stopping the Servers

Once the LDAP server is fully configured and all desired entries have
been made according to the pattern described below in Section 14.7.4. “Data Handling in the LDAP Directory”, start the LDAP server as
root by entering
rcldap start.
To stop the server manually, enter the command
rcldapstop. Request the status of the
running LDAP server with rcldapstatus.

The YaST runlevel editor, described in Section 13.5. “The YaST Runlevel Editor”, can be used to have
the server started and stopped automatically on boot and halt of the
system. It is also possible to create the corresponding links to the
starting and stopping scripts with the insserv command
from a command prompt as described in Section 13.4.1. “Adding init Scripts”.

14.7.4. Data Handling in the LDAP Directory

OpenLDAP offers a series of tools for the
administration of data in the LDAP directory. The four most important tools
for adding to, deleting from, searching through, and modifying the data
stock are briefly explained below.

14.7.4.1. Inserting Data into an LDAP Directory

Once the configuration of your LDAP server in
/etc/openldap/lsapd.conf is correct and ready to go,
meaning that it features appropriate entries for suffix,
directory, rootdn,
rootpw, and index, proceed to
entering records. OpenLDAP offers the
ldapadd command for this task. If possible, add the
objects to the database in bundles for practical reasons. LDAP is able to
process the LDIF format (LDAP Data Interchange Format) to accomplish this.
An LDIF file is a simple text file that can contain an arbitrary number of
pairs of attribute and value. Refer to the schema files declared in
slapd.conf for the available object classes and
attributes. The LDIF file for creating a rough framework for the example in
Figure 14.4. “Structure of an LDAP Directory” would look like
that in File 14.23. “Example for an LDIF File”.

LDAP works with UTF-8 (Unicode). Umlauts therefore must be encoded
correctly. Use an editor that supports UTF-8 (such as
Kate or recent versions of
Emacs). Otherwise, it would be necessary to
avoid umlauts and other special characters or to use
recode to recode the input to UTF-8.

The file is saved with the .ldif suffix and is
passed to the server with the following command:

ldapadd -x -D <dn of the administrator> -W -f <file>.ldif

The first option -x switches off the authentication
with SASL in this case. The -D switch declares the user
that calls the operation. The valid DN of the administrator is entered here
just like it has been configured in slapd.conf. In the
current example, this would be cn=admin,dc=suse,dc=de.
The switch -W circumvents entering the password on the
command line (in clear text) and activates a separate password requesting
prompt. This password was previously determined in
slapd.conf with rootpw. The
-f switch passes the file name. See the details of
running ldapadd in Example 14.24. “ldapadd with example.ldif”.

An LDIF file can contain an arbitrary number of objects. It is
possible to pass entire directory branches to the server at once or only
parts of it as shown in the example of individual objects. If it is
necessary to modify some data relatively often, a fine subdivision of
single objects is recommended.

14.7.4.2. Modifying Data in the LDAP Directory

The tool ldapmodify is provided for modifying the
data stock. The easiest way to do this is to modify the corresponding LDIF
file then pass this modified file to the LDAP server. To change the
telephone number of colleague Tux from +49 1234 567-8 to
+49 1234 567-10, the LDIF file must be edited like in
Example 14.26. “Modified LDIF File tux.ldif”.

Read detailed information about ldapmodify and its
syntax in its corresponding man page.

14.7.4.3. Searching or Reading Data from an LDAP Directory

OpenLDAP provides, with
ldapsearch, a command line tool for searching data
within an LDAP directory and reading data from it. A simple query would
have the following syntax:

ldapsearch -x -b dc=suse,dc=de "(objectClass=*)"

The option -b determines the search base —
the section of the tree within which the search should be performed. In the
current case, this is dc=suse,dc=de. To perform a more
finely-grained search in specific subsections of the LDAP directory (for
instance, only within the devel department), pass this
section to ldapsearch with
-b. The -x switch requests the
activation of simple authentication. (objectClass=*)
declares that all objects contained in the directory should be read. This
command option can be used after the creation of a new directory tree to
verify that all entries have been recorded correctly and the server
responds as desired. More information about the use of
ldapsearch can be found in the corresponding man page
(manldapsearch).

14.7.4.4. Deleting Data from an LDAP Directory

Delete unwanted entries with ldapdelete. The syntax
is similar to that of the commands described above. To delete, for example,
the complete entry for Tux Linux, issue the
following command:

14.7.5. For More Information

More complex subjects, like SASL configuration or establishment of
a replicating LDAP server that distributes the workload among multiple
slaves, were intentionally not included in this chapter.
Detailed information about both subjects can be found in the
OpenLDAP 2.1 Administrator's Guide (see below for
references).

The web site of the OpenLDAP project offers
exhaustive documentation for beginning and advanced LDAP users:

http://www.openldap.org/doc/admin21/quickstart.html
or on an installed system in
/usr/share/doc/packages/openldap2/admin-guide/quickstart.html

OpenLDAP 2.1 Administrator's Guide

A detailed introduction to all important aspects of LDAP
configuration, including access controls and encryption. http://www.openldap.org/doc/admin21/ or on an installed system
in
/usr/share/doc/packages/openldap2/admin-guide/index.html

The following redbooks from IBM exist regarding the subject of
LDAP:

Understanding LDAP

A detailed general introduction to the basic principles of LDAP:
http://www.redbooks.ibm.com/redbooks/pdfs/sg244986.pdf.

LDAP Implementation Cookbook

The target audience consists of administrators of IBM
SecureWay Directory. However, important general information
about LDAP is also contained here:
http://www.redbooks.ibm.com/redbooks/pdfs/sg245110.pdf.