Directory design
This section covers material for topic 301.2 for the Senior Level Linux
Professional (LPIC-3) exam 301. The topic has a weight of 2.
In this section, learn about:
- Defining LDAP directory content
- Directory organization
- How to plan appropriate Directory Information Trees
Determining if
LDAP is appropriate
Like any other tool, LDAP is not appropriate for every solution. Before
choosing LDAP, you must ask yourself some questions:
- How often will changes be made, and what kind of changes are
they?
- What will be using the data?
- What kind of queries will be made against the data?
- Is the information hierarchical in nature?
LDAP databases are geared toward read-intensive operations. People may
only change personal information a few times a year, but we can expect
to look up attributes far more than that, such as resolving the
UserID owning a file to a printable name
when looking through a directory. LDAP data tends to be heavily
indexed, which means every change to the underlying data requires
multiple changes to the indexes that help the server find the data
later. LDAP also doesn't offer a means to make mass updates to the
tree, other than performing a search and then modifying each
individual DN.
The LDAP specifications do not define transactions, which are common in
relational databases. Transactions ensure that all the operations
within the transaction succeed, or else the data is rolled back to the
pre-transaction state (individual servers may implement this, but it
is not a requirement). These limitations on updating data and the lack
of transactions make LDAP a poor choice for bank transactions.
Determining the user, or the consumer, of the data is also important.
If none of the consumers speak LDAP, then LDAP may not be a good fit.
To LDAP's credit, it is an extremely simple protocol to implement and
is available for most languages on most platforms. With a mere handful
of available operations defined, it can be integrated into existing
applications with ease.
LDAP provides search functionality, but with nowhere near the level of
a relational database. The LDAP server may store the underlying data
using SQL, but you as the user are abstracted from this and cannot
make use of it. Thus, you are limited to the search filters that are
supported by your LDAP server. These filters will be investigated in
more detail in later articles in this series, but for now understand
that the filters are just that -- filters. You can perform some
powerful searches, such as "show me all the employees who live in
Washington and those that live in Texas who are over 40." Statements
equivalent to the SQL GROUP BY are not
available, though. LDAP is best suited for look-up style operations,
such as "show me the username of the person with UID 4131," and "give
me the names of everyone working for Jim Smith."
Finally, the information you are trying to store should lend itself to
hierarchical storage. You could store a flat list of data in an LDAP
server, but it would probably be a waste of resources.
When you can answer these questions and have determined that LDAP is
the correct solution, it is time to design the directory tree.
Organizing
your tree
The foremost idea to keep in your mind is that reorganization of the
tree is undesirable. The goal is to break down your objects such that
each branch of the tree holds objects of a similar type, but the
chances of an object having to be moved is low. The reasons for this
are twofold. One is that it's just a hassle to do. The second is that
a move changes the DN of the object, and then you have to update all
the objects that reference the moved object.
The root
DN
The root of your tree should be something that represents your company.
RFC 2247 calls for the use of the dc
attribute and the familiar
dc=example,dc=com format to map the
company's primary domain into a DN. Your company probably has many
Internet domains but has one that is preferred. It is also common to
choose something under the local top-level
domain (TLD), which doesn't currently exist on the Internet. Microsoft
has long suggested using this TLD for their Active Directory
implementations despite it not being a reserved TLD.
If you don't want to use a domain name in your root DN, you can simply
have an object with
objectclass: organization, which gives a
root DN of o=My Corporation.
Filling in the
structure
Deciding what goes at the next level of the DIT is difficult. It is
often tempting to describe the company's organizational structure as a
series of nested organizationalUnit
objects, but companies are constantly reorganizing, which breaks the
first rule. Instead, consider using attributes to store this
information instead.
Depending on your use of the LDAP server and how you choose to name
objects, you may want to keep all users in one tree or separate them
according to role. For instance, you can create one container for
employees and one for customers, or you can group them all into a
single container. The choice depends on your applications and how you
plan on managing the tree. If the sales department takes care of
managing the customer list, and the systems administrators take care
of the staff, it might be better to create two containers. Figure 5
shows a DIT that has been broken down into customers and users.
Figure 5. An LDAP tree
with separate branches for users and customers
Figure 5 shows one grouping for staff and one for customers. All staff
reside in the same organizational unit (OU), but customers are broken
up by region. In this situation, this allows different people to
manage their own region's customers.
If you plan on using LDAP for authentication of UNIX resources, you
must then decide where to store that information. User accounts have
already been taken care of earlier, but you will need to store groups,
and possibly other maps such as hosts, services, networks, and
aliases. Which of these you store in LDAP, and which you leave as
local files depends on you and if you need to be able to update them
centrally.
The simplest case is to store each map in a separate
organizationalUnit. You will find that when
configuring your UNIX system to read this information, you need to
specify the DN of the container and any filters. If you store groups
in the user OU, you will have to write some filters. You also may have
to adjust the filters if you ever make any structural changes to the
staff OU.
Determining
the object classes
So far the discussion has centered on the layout of the LDAP tree with
the basic goal being to avoid having to rename objects in the future.
After you decide upon the tree, you must then decide which object
classes to use. It is certainly possible to assign different object
classes to objects under the same branch of the tree, but this will
almost certainly lead to maintenance problems in the future.
To add more stress to the situation, it's not always possible to add
more object classes to an object if you make a mistake. LDAP schemas
define two types of object classes: structural and
auxiliary. Structural object classes usually inherit
properties from other object classes in a chain that ends up at an
object class called top. Structural object
classes can be said to define the object's identity, while auxiliary
object classes are there to add attributes.
organizationalUnit is a structural object
class, as is inetOrgPerson. Going back to
Listing 1, the top-level entry had two object
classes: dcObject and
organization.
organization is the structural object
class. dcObject plays the auxiliary role by
defining the dc attribute . The part
that can cause problems is that an entry can only have one structural
object class. Sometimes you see
inetOrgPerson,
organizationalPerson,
person, and top
in the same record, but they are all part of the same inheritance
tree. inetOrgPerson and
account are both structural, are not in the
same inheritance tree, and therefore can't be used together. Some LDAP
servers permit this, but eventually this behavior may change and cause
problems.
There is a third type of object class called abstract. It is
much like structural except that it must be inherited to be used.
top is such a class.
Without getting into the specifics of each application there are some
general structural object classes that are useful:
-
inetOrgPerson: Defines a generic
person, along with some contact information.
-
organizationalRole: Much like a person,
but it defines a generic role such as
IT Helpdesk or
Fire Warden.
-
organizationalUnit: A generic
container, may describe a department within a container or may be
used to separate various parts of the LDAP tree such as groups,
people, and servers
-
organization: A company or other
organization.
-
groupOfNames: Stores one or more DNs
referring to members of a group. Not necessarily useful for UNIX
groups, but helpful for meeting invitations or other simple
things.
Stick to these for your people and organizations and you will be safe.
Most extensions, such as authentication, use auxiliary attributes.
When in doubt, consult the schema.
The final design consideration is the choice of DNs. Most branches are
fairly easy because there is no chance of duplication. A UNIX group's
name and ID is unique, so using cn as the
RDN of a group is possible. What happens when you have two employees
called Fred Smith? Because the DN must be unique,
cn=Fred Smith,ou=People,dc=example,dc=com
could be either of them. Either something else must be used, such as
employeeNumber, or the RDN will have to be
made from two different attributes separated by a plus sign (+). For
example,
cn=Fred Smith+userid=123, ou=people, dc=example, dc=com
has an RDN made from two different attributes. Whatever you do, do it
consistently!
|