 | Concepts and architecture
This section covers material for topic 301.1 for the Senior Level Linux
Professional (LPIC-3) exam 301. This topic has a weight of 3.
In this section, learn about:
- LDAP and X.500 technical specification
- Attribute definitions
- Directory namespaces
- Distinguished names
- LDAP Data Interchange Format
- Meta-directories
- Changetype operations
Most of the LPIC-3 exam focuses on the use of the Lightweight Directory
Access Protocol (LDAP). Accordingly, the first objective involves
understanding what LDAP is, what it does, and some of the basic
terminology behind the concept. When you understand this, you will be
able to move on to designing your directory and integrating your
applications with the directory.
LDAP, what is
it?
Before talking about LDAP, let's review the concept of directories. The
classic example of a directory is the phone book, where people are
listed in alphabetical order along with their phone numbers and
addresses. Each person (or family) represents an object, and the phone
number and address are attributes of that object. Though not always
obvious at a glance, some objects are businesses instead of people,
and these may include fax numbers or hours of operation.
Unlike its printed counterpart, a computer directory is hierarchical in
nature, allowing for objects to be placed under other objects to
indicate a parent-child relationship. For instance, the phone
directory could be extended to have objects representing areas of the
city, each with the people and business objects falling into their
respective area objects. These area objects would then fall under a
city object, which might further fall under a state or province
object, and so forth, much like Figure 1. This would make a printed
copy much harder to use because you would need to know the name and
geographical location, but computers are made to sort information and
search various parts of the directory, so this is not a problem.
Figure 1. A sample
directory
Looking at Figure 1, knowing where the Simpson's record is tells you
more than just the address and phone number. You also know they are in
the East end in the town of Springfield. This structure is called a
tree. Here, the root of the tree is the Springfield object, and the
various objects represent further levels of branching.
This directory-based approach to storing data is quite different than
the relational databases that you may be familiar with. To compare the
two models, Figure 2 shows what the telephone data might look like if
modeled as a relational database.
Figure 2. Directory
data modeled in relational form
In the relational model, each type of data is a separate table that
allows different types of information to be held. Each table also has
a link to its parent table so that the relationships between the
objects can be held. Note that the tables would have to be altered to
add more information fields.
Remember that nothing about the directory model places any restrictions
on how the data may be stored on disk. In fact, OpenLDAP supports many
back ends including flat files and Structured Query Language (SQL)
databases. The mechanics of laying out the tables on disk are largely
hidden from you. For instance, Active Directory provides an LDAP
interface to its proprietary back end.
The history of
LDAP
LDAP was conceived in Request for Comments (RFC) 1487 as a lightweight
way to access an X.500 directory instead of the more complex Directory
Access Protocol. (See the Resources
section for links to this and related RFCs.) X.500 is a standard (and
a family of standards) from the International Telecommunication Union
(ITU, formerly the CCITT) that specifies how directories are to be
implemented. You may be familiar with the X.509 standard that forms
the core of most Public Key Infrastructure (PKI) and Secure Sockets
Layer (SSL) certificates. LDAP has since evolved to version 3 and is
defined in RFC 4511.
Connecting to an X.500 database initially required the use of the Open
Systems Interconnection (OSI) suite of protocols and, in true ITU
fashion, required understanding of thick stacks of protocol
documentation. LDAP allowed Internet Protocol (IP)-based networks to
connect to the same directory with far fewer development cycles than
using OSI protocols. Eventually the popularity of IP networks led to
the creation of LDAP servers that support only as many X.500 concepts
as necessary.
Despite the triumph of LDAP and IP over X.500 and OSI, the underlying
organization of the directory data is still X.500-ish. Concepts that
you will learn over the course of this tutorial, such as Distinguished
Names and Object Identifiers, are brought up from X.500.
X.500 was intended as a way to create a global directory system, mostly
to assist with the X.400 series of standards for e-mail. LDAP can be
used as a global directory with some effort, but it is mostly used
within an enterprise.
A closer look
at naming and attributes
In the LDAP world, names are important. Names let you access and search
records, and often the name gives an indication of where the record is
within the LDAP tree. Figure 3 shows a typical LDAP tree.
Figure 3. A typical
LDAP tree showing a user
At the top, or root, of the tree is an entity called
dc=ertw,dc=com. The
dc is short for domain component.
Because ertw is under the
.com top-level domain, the two are
separated into two different units. Components of a name are
concatenated with a comma when using the X.500 nomenclature, with the
new components being added to the left. Nothing technically prevents
you from referring to the root as
dc=ertw.com, though in the interest of
future interoperability it is best to have the domain components
separate (in fact, RFC 2247 recommends the separate domain
components).
dc=ertw,dc=com is a way to uniquely
identify that entity in the tree. In X.500 parlance, this is called
the distinguished name, or the DN. The DN is much like a
primary key in the relational-database world because there can be only
one entity with a given DN within the tree. The DN of the topmost
entry is called the Root DN.
Under the root DN is an object with the DN of
ou=people,dc=ertw,dc=com.
ou means organizational unit, and
you can be sure it falls under the root DN because the
ou appears immediately to the left of the
root DN. You can also call ou=people the
relative distinguished name, or RDN, because it is
unique within its level. Put in recursive terms, the DN of an entity
is the entity's RDN plus the DN of the parent. Most LDAP browsers show
only the RDN because it eliminates redundancy.
Moving down the tree to
cn=Sean Walberg,ou=people,dc=ertw,dc=com,
you find the record for a person. cn means
common name. For the first time, though, a record has some
additional information in the form of attributes. Attributes
provide additional information about the entity. In fact, you'll see
the leftmost component of the DN is duplicated; in this case, it's the
cn attribute. Put another way, the RDN of
an entity is composed of one (or more) attributes of the entity.
While mail and
description are easy enough to understand,
objectClass is not as obvious. An object
class is a group of attributes that correspond to a particular entity
type. One object class may contain attributes for people and another
for UNIX accounts. By applying the two object classes to an entity,
both sets of attributes are available to be stored.
Each object class is assigned an object identifier (OID) that uniquely
identifies it. The object class also specifies the attributes, and
which ones are mandatory and which are optional. Mandatory attributes
must have some data for the entity to be saved. The object class also
identifies the type of data held and whether multiple attributes of
the same name are allowed. For instance, a person might have only one
employee number but multiple first names (for example, Bob, Robert,
and Rob).
The bottom-level objects are not the only ones to have object classes
associated with them. These objects, called containers, also
have object classes and attributes. The
people ou is of type
organizationalUnit and has a description
attribute along with ou=people to create
the RDN. The root of the tree is of type
dcObject and
organization. Knowing which object classes
to assign an object depends on what is being held in the object and
under it. Refer to the Schemas section for
more details.
The root DN also defines the namespace of the tree or, to be
more technical, the Directory Information Tree (DIT). Something
ending in dc=ibm,dc=com would fall outside
of the namespace from Figure 3, whereas the record
for Sean Walberg falls within the
namespace. With that in mind, though, it is possible that one LDAP
server contains multiple namespaces. A somewhat abstract item called
the Root DSE contains the information about all the namespaces
available on the server. DSE means the DSA-Specific Entry, and DSA
means Directory System Agent (that is, the LDAP server).
Figure 4 summarizes the terminology associated
with the LDAP tree.
Figure 4. Summary of
LDAP terminology
Finally, an LDAP tree can be synchronized with other trees or data
sources. For instance, one branch of the tree could come from a
security system, another from a customer database, and the rest could
be stored in the LDAP server. This is called a meta-directory
and is intended to be a single source of data for applications such as
single sign-on.
The LDIF
file
Data can get into an LDAP server in one of two ways. Either it can be
loaded in over the network, using the LDAP protocol, or it can be
imported from the server through a file in the LDAP Data
Interchange Format (LDIF). LDIF can be used at any time, such
as to create the initial tree, and to perform a bulk add or modify of
the data some time later. The output of a search can also be in LDIF
for easy parsing or import to another server. The full specification
for LDIF is in RFC 2849 (see Resources
for a link).
Adding
records
The LDIF that generated the tree from Figure 3 is shown in Listing
1.
Listing 1. A simple LDIF file to populate a tree
# This is a comment
dn: dc=ertw,dc=com
dc: ertw
description: This is my company
the description continues on the next line
indented by one space
objectClass: dcObject
objectClass: organization
o: ERTW.COM
dn: ou=people,dc=ertw,dc=com
ou: people
description: Container for users
objectclass: organizationalunit
dn: cn=Sean Walberg,ou=people,dc=ertw,dc=com
objectclass: inetOrgPerson
cn: Sean Walberg
cn: Sean A. Walberg
sn: Walberg
homephone: 555-111-2222
mail: sean@ertw.com
description: Watch out for this guy
ou: Engineering
|
Before delving into the details of the LDIF file, note that the
attribute names are case insensitive. That is,
objectclass is the same as both
objectClass and
OBJECTCLASS. Many people choose to
capitalize the first letter of each word except the first, such as
objectClass,
homePhone, and
thisIsAReallyLongAttribute.
The first line of the LDIF shows a UNIX-style comment, which is
prefixed by a hash sign (#), otherwise known as a pound sign or an
octothorpe. LDIF is a standard ASCII file and can be edited by humans,
so comments can be helpful. Comments are ignored by the LDAP server,
though.
Records in the LDIF file are separated by a blank line and contain a
list of attributes and values separated by a colon (:). Records begin
with the dn attribute, which identifies the
distinguished name of the record. Figure 1,
therefore, shows three records: the
dc=ertw,
ou=people, and
cn=Sean Walberg RDNs, respectively.
 |
Choosing attributes
The attribute names may be confusing at this point. How do you
choose which object class to assign a record? How do you find out
which attributes are available? How do you know that
o stands for organization?
To put it very simply, the answers to all of these questions lie in
the schema, which is covered in
Schemas. The schema provides a
description of which attributes mean what. The schema also maps
attributes into object classes. Adding an object class to a record
allows you to use the attributes that fall within it.
The final piece of the puzzle is to understand how the LDAP tree is
to be used. If you're going to be authenticating UNIX accounts
against the tree, your users had better have an object class that
gives them the same userid attribute
that your system is looking for.
|
|
Looking back at Figure 1, you can see the first
record defined is the root of the tree. The distinguished name comes
first. Next comes a list of all the attributes and values, separated
by a colon. Colons within the value do not need any special treatment.
The LDAP tools understand that the first colon separates the attribute
from the value. If you need to define two values for an attribute,
then simply list them as two separate lines. For example, the root
object defines two object classes.
Each record must define at least one object class. The object class, in
turn, may require that certain attributes be present. In the case of
the root object, the dcObject object class
requires that a domain component, or
dc, be defined, and the
organization object class requires that an
organization attribute, or o, be
defined. Because an object must have an attribute and value
corresponding to the RDN, the dcObject
object class is required to import the dc
attribute. Defining an o attribute is not
required to create a valid record.
A description is also used on the root
object to describe the company. The purpose here is to demonstrate the
comment format. If your value needs to span multiple lines, start each
new line with a leading space instead of a value. Remember that
specifying multiple attribute: value pairs
defines multiple instances of the attribute.
The second record in Figure 1 defines an
organizationalUnit, which is a container
for people objects in this case. The third defines a user of type
inetOrgPerson, which provides common
attributes for defining people within an organization. Note that two
cn attributes are defined; one is also used
in the DN of the record. The second, with the middle initial, will
help for searching, but it is the first that is required to satisfy
the condition that the RDN be defined.
In the user record there is also an ou that
does not correspond to the
organizationalUnit the user is in. The
container the user object belongs to can always be found by parsing
the DN. This ou attribute refers to
something defined by the user, in this case a department. No
referential integrity is imposed by the server, though the application
may be looking for a valid DN such as
ou=Engineering,ou=Groups,dc=ertw,dc=com.
The only other restriction placed on LDIF files that add records is
that the tree must be built in order, from the root.
Figure 1 shows the root object being built, then
an ou, then a user within that
ou. Now that the structure is built, users
can be added directly to the people
container, but if a new container is to be used, it must be created
first.
The LDIF behind adding objects is quite easy. The format gets more
complex when objects must be changed or deleted. LDIF defines a
changetype, which can be one of the
following:
-
add adds an item (default).
-
delete deletes the item specified by
the DN.
-
modrdn renames the specified object
within the current container, or moves the object to another part
of the tree.
-
moddn is synonymous with
modrdn.
-
modify makes changes to attributes
within the current DN.
Deleting
users
Deleting an item is the simplest case, only requiring the
dn and
changetype. Listing 2 shows a user being
deleted.
Listing 2. Deleting a user with LDIF
dn: cn=Fred Smith,ou=people,dc=ertw,dc=com
changetype: delete
|
Manipulating
the DN
Manipulating the DN of the object is slightly more complex. Despite the
fact that there are two commands, moddn and
modrdn, they do the same thing! The
operation consists of three separate parts:
- Specify the new RDN (leftmost component of the DN).
- Determine if the old RDN should be replaced by the new RDN within
the record, or if it should be left.
- Optionally, move the record to a new part of the tree by
specifying a new parent DN.
Consider Jane Smith, who changes her name to Jane Doe. The first thing
to do is change her cn attribute to reflect
the name change. Because the new name is the primary way she wishes to
be referred to, and the common name forms part of the DN, the
moddn operation is appropriate. (If the
common name weren't part of the DN, this would be an attribute change,
which is covered in the next section.) The second choice is to
determine if the cn: Jane Smith should stay
in addition to cn: Jane Doe, which allows
people to search for her under either name. Listing 3 shows the LDIF
that performs the change.
Listing 3. LDIF to change a user's RDN
# Specify the record to operate on
dn: cn=Jane Smith,ou=people,dc=ertw,dc=com
changetype: moddn
# Specify the new RDN, including the attribute
newrdn: cn=Jane Doe
# Should the old RDN (cn=Jane Smith) be deleted? 1/0, Default = 1 (yes)
deleteoldrdn: 0
|
Listing 3 begins by identifying Jane's record, then the
moddn operator. The new RDN is specified,
continuing to use a common name type but with the new name. Finally,
deleteoldrdn directs the server to keep the
old name. Note that while newrdn is the
only necessary option to the moddn
changetype, if you omit deleteoldrdn, the
action is to delete the old RDN. According to RFC 2849,
deleteoldrdn is a required element.
Should the new Mrs. Jane Doe be sent to a new part of the tree, such as
a move to ou=managers,dc=ertw,dc=com, the
LDIF must specify the new part of the tree somehow, such as in Listing
4.
Listing 4. Moving a record to a new part of the tree
dn: cn=Jane Doe,ou=people,dc=ertw,dc=com
changetype: modrdn
newrdn: cn=Jane Doe
deleteoldrdn: 0
newsuperior: ou=managers,dc=ertw,dc=com
|
Curiously, a new RDN must be specified even though it is identical to
the old one, and the OpenLDAP parser now requires that
deleteoldrdn is present despite it being
meaningless when the RDN stays the same.
newsuperior follows, which is the DN of the
new parent in the tree.
One final note on the modrdn operation is
that the order matters, unlike most other LDIF formats. After the
changetype comes the
newrdn, followed by
deleteoldrdn, and, optionally,
newsuperior.
Modifying
attributes
The final changetype is
modify, which is used to modify attributes
of a record. Based on the earlier discussion of
moddn, it should be clear that
modify does not apply to the DN or the RDN
of a record.
Listing 5 shows several modifications made to a single record.
Listing 5. Modifying a record through LDIF
dn: cn=Sean Walberg,dc=ertw,dc=com
changetype: modify
replace: homePhone
homePhone: 555-222-3333
-
changetype: modify
add: title
title: network guy
-
changetype: modify
delete: mail
-
|
The LDIF for the modify operation looks
similar to the others. It begins with the DN of the record, then the
changetype. After that comes either
replace:, add:,
or delete:, followed by the attribute. For
delete, this is enough information. The
others require the attribute:value pair. Each change is followed by a
dash (-) on a blank line, including the final change.
LDIF has an easy-to-read format, both for humans and computers. For
bulk import and export of data, LDIF is a useful tool.
|  |