LDAP directory services are nearly
ubiquitous these days. Every sysadmin should know how to work with directories, understand how they are constructed,
and have a certain level of familiarity with the LDAP protocol itself. In this,
part one of two, we will introduce LDAP and explain how entries and schemas
work. Next week, the second part will cover the LDAP protocol, working with LDAP
entries, and searching and storing data.
LDAP is actually quite simple, even though it does make use of the ITU X.500 standard—a
notoriously complex specification. X.500 directories were accessed via DAP, or
Directory Access Protocol. It was large, complex, and unruly, so Lightweight DAP
was created. That’s almost accurate; in fact, LDBP (Lightweight Directory
Browsing Protocol) came first, because all you could do was search. When the
functionality to modify entries was implemented, LDAP was born.
A directory can be defined as a set of objects with similar attributes,
organized in a hierarchical manner. Sorry, but I must use the old phone book
analogy now. In a phone book, an object is a person, and each person has a set
of similar attributes: a phone number and perhaps an address. LDAP is the same,
but you may make use of many other types of attributes.
LDAP directories are organized in a tree manner, and the design often will
reflect organizational or geographic boundaries. X.500 tells us:
- A directory is a tree of directory entries
- An entry contains a set of attributes
- An attribute has a name, and one or more values.
Attributes are defined in a schema, which specifies what types of things can
be attributes and whether or not you can multiple values per attribute.
Every entry in a directory has a unique identifier, called the Distinguished
Name (DN). The Relative DN (RDN) is part that specifies the current attribute
you’re dealing with, sort of like a relative path in Unix (./file). The DN,
then, would be a full path (/var/lib/file). A sample directory entry’s DN,
therefore, would look like: cn=”john doe”,dc=mytree. The RDN is cn=”john doe”,
and the DN is the full path, starting at the top of the tree. A “cn” simply
means the “common name” that the entry is referred to as, and “dc” is the
You will often see examples of LDAP structures that use DNS names for the domain
component, such as: dc=example,dc=com. This is not necessary, but since DNS
itself often implies organizational boundaries, it usually makes sense to just
use your existing naming structure. One final note about a DN; it changes over
time. If you change a DN, you’re effectively moving an entry in the tree. Some
LDAP servers support unique identifiers that will track the movement of
entries, but you often don’t need to care. Just know that even though a DN is
unique, it changes over time.
A sample directory entry (of a person) looks like this:
dn: cn=John Doe,dc=myplace
cn: John Doe
telephoneNumber: +1 555 555 1234
telephoneNumber: +1 555 555 5555
mail: [email protected]
manager: cn=Bob Smith,dc=example,dc=com
All of the attributes (objects) listed above are associated with the DN; it
is a single directory entry. Objects (givenName, sn, etc) are defined by
schemas. Every entry must list the objectClass that every attribute is
using. For example, organizationalPerson defines what values can live in the
attribute called “manager.” If the objectClass wasn’t listed, the LDAP server
wouldn’t know what values were allowed, so it wouldn’t allow you to define an
attribute called manager.
The example above is an LDIF , LDAP Data Interchange
Format, entry. That is the entire LDAP entry in text form. You could insert the
data into a directory, and in fact, this is exactly what a backup of your
directory looks like. It’s just text, and that’s all there is to an LDAP
entry. Well almost: most servers also support aliases and references. An LDAP
alias can point to another local entry in the same directory, to avoid
duplicating information. A reference will provide a new DN to an LDAP client and
tell it to go ask another server. Some LDAP servers even support chained
references, where the server will go get the answer and return it to the client;
the client never knows a referral has taken place. Regardless, LDAP entries are
A schema defines the attribute types that entries can contain, as well as the
format of their values. It will specify that: Mail contains a well-formed e-mail
address, Photo contains a JPEG image, and uidNumber contains an integer, for
Here is an example schema we recently created:
attributeTypes: ( 188.8.131.52.1
DESC 'A pod for people to belong in'
objectClasses: ( 184.108.40.206.1
DESC 'A person who belongs in some pods'
The objectClass is defined, as well as the allowed attributeTypes. Each
schema must have a unique OID (object identifier), which is part of the way
X.500 works (SNMP is the same way). We
created an objectClass called podPerson, gave it a description, an said the
entry must contain a ‘cn,’ and may contain a ‘pod.’ The pod attribute can
contain any value, because the only restriction specified is that case doesn’t
matter. After loading that scheme into our LDAP server, we could then add a
‘pod’ attribute to each person entry.
Since LDAP is so lightweight and simple, it is not suitable for a few
things. It’s very tempting to store tons of data in LDAP, since so many
applications can reference LDAP. Unix machines can use LDAP for passwd, shadow,
group, netgroup, protocols, and just about everything in nsswitch.conf. LDAP is
a database, so print accounting programs, configuration management systems, and
just about everything that stores data in a DB will support LDAP. It’s fine for
most of these things, but LDAP is not ideal for replicating a relational
database. The data in LDAP is not ordered, which means you could get results in
any order. If your application is querying for only one result at a time, this
is fine, but if multiple results are common and order is important, LDAP just
Join us next week for a look at the protocol, and practical examples of
querying and using LDAP data.