My-Tiny.Net :: Networking with Virtual Machines



LDAP Concepts and Terms



Even though the  L  in LDAP stands for "lightweight" it still can seem pretty heavy. Nonetheless, it is a very popular way to provide common logins across corporate networks. That makes it worth the time and effort it takes to get familiar with the basic concepts and terminology - these apply equally to the tiny system we set up here and Microsoft Active Directory, which is probably the most popular application of LDAP in the real world.

We need to get a grip on some LDAP concepts and terms. For a more complete introduction, with some worked examples, see http://www.zytrax.com/books/ldap/ch2/ (but note that our build does not have Data Synchronisation and Replication capability).

Data in a LDAP directory is organized in a tree structure, as opposed to a typical Relational Database (RDBMS) where the data is organized in rows and columns (conceptually). RDBMS are suitable for add, delete, modify, etc. whereas LDAP is optimized for large number of reads and very few modifications or write.

LDAP has its own (recursive) jargon to describe this

LDAP tree

Term Description
DIT DIT stands for Directory Information Tree. The entire LDAP database is called the DIT.
entry An entry (or node) groups sets of objectclasses within a DIT.
attribute attributes are various fields for which values can be given to every tree node. For example if a node in DIT tree represents a person then address, phone number, email address, password etc. can be attributes for that entry. An attribute defined in one schema can be used by an objectClass defined in another schema.
schema schema files are used to define various types of attributes and group them into objectClasses. All the schemas which include definitions of the objectClasses and attributes used in a DIT must be known to the LDAP server (there are some objectClasses and attributes defined as being operational which are embedded in the LDAP server software and do not need definition, but we can mostly ignore them).
objectClass An objectClass is a set of attributes (an attribute container in the jargon). The objectClass defines whether an attribute is mandatory (MUST be present) or optional (MAY be present) within an entry. Every entry (DIT node) must belong to at least one objectClass, and it is possible for an entry to belong to several objectClasses. An objectClass can be derived from other objectClasses as a child class. Child classes support all attributes of all parent classes.
dn dn stands for Distinguished Name. Every entry in the DIT must have a unique dn so that it can be uniquely identified. A dn is usually a list of attributes (examples below).
rootDSE The top-most entry in the DIT is abstract (the null DN, denoted as ""), and all other entries are created as children of rootDSE. This is similar to object-oriented programming where all objects are automatically inherited from the object class.
rootDN a confusingly named directive in openLDAP configuration which defines the DN of a superuser for each DIT that can bypass normal directory access rules. The rootdn does not need to appear in the directory, or even be related, in any way, to the DIT structure.
RDN RDN stands for Relative Distinguished Name, and refers to an attribute that is unique at its level in the hierarchy. A DN is a series of RDNs that, taken together, are unique in the DIT. RDN is usually used to refer to each individual attribute or a subset of DN attributes on the path up the DIT from any entry to the rootDSE or search base-dn.
base The dn of the first child of rootDSE in the DIT and the starting point for a search are both called the base or base-dn.
bind When connection is made to an LDAP server the first operation of the sequence is called a bind. The bind operation sends the dn of the entry that will be used for authentication and the password to be used. In the case of an anonymous bind both values will be NULL.
ACL an Access Control List defines whether anonymous binds are supported, and which users are allowed to see particular attributes.
LDIF LDAP Data Interchange Format, a plain text file format used to import and export directory information between servers, or to describe a set of changes to be applied to a directory.


A more abstract representation: when you create an entry in a DIT its data contents are contained in attributes, which are grouped into objectclasses, which are packaged into schemas. SUP denotes inheritance - the class or attribute below extends the one above.

LDAP tree

The complexity and power of LDAP comes from the fact that there are loads of attributes and loads of objectClasses (apparently randomly) included in a load of (generally unhelpfully named) schemas.

While many objectClasses show no MUST attributes you actually have to follow the full hierarchy to determine if this is the really case. Thus, if you want to create an entry with the inetOrgPerson objectClass you MUST specify at least one cn and sn attribute value or it will fail.

Names of some important attributes are:
Short name       Full name
dn distinguished name
cn commonName
sn surname (family name)
gn given name
uid userid
userPassword userPassword
ou organizationalUnitName
o organizationName
dc domain component

LDIF and the DIT

The people at zytrax offer this helpful advice:
Designing the DIT is actually a very important step and you can spend the rest of your life designing your DIT. ... Much wailing and gnashing of teeth usually accompanies selecting the primary objectClass. This is an essential LDAP ritual so start practising now.
Here we will just use some well-known objectclasses and attributes. Later you might want to invest some time to dig deeper so that you can discover which objectClasses and attributes are truly best for an application - or even create your own.

The inetorgperson schema has a BIG hierarchy with lots of attributes, so we include it and its SUPerclasses in /etc/openldap/slapd.conf. There are some additional notes on this at the end.

Attributes dc or o are commonly used to define the base of the DIT. Similar to the first diagram above, our slapd.conf is ready for two DITs: o=tinynet.edu and dc=tinynet,dc=edu.

LDAP command line tools, such as ldapadd(1) and ldapsearch(1), read and write LDIF entry records. ldapmodify(1) reads LDIF change records. A formal specification of LDIF is published in RFC 2849, and man 5 ldif has complete information. However, doing LDAP queries and creating LDIF by hand is tedious, boring, and prone to obscure typing errors, which is why we have PHPLDAPAdmin (PLA) for searching and updating the DIT.

We also have two LDIF files prepared as a starting point: topclass.ldif to populate the top levels of the DIT, and userdata.ldif to create some entries for testing.

Here is an entry from userdata.ldif
dn: cn=Barbara Jensen,ou=UserNetA,o=tinynet.edu
ou: UserNetA
cn: Barbara Jensen
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
mail: bjensen@net-a.tinynet.edu
givenname: Barbara
sn: Jensen
uid: bjensen
title: Account Executive
userPassword: {PLAIN}LetMeIn
Each entry starts with a dn: line. In general, any attribute may be used for this purpose as long as the whole string is unique and includes the base dn, but to save excessive searching it will typically have the attributes most frequently used to access the entry. So the value cn=Barbara Jensen,ou=UserNetA,o=tinynet.edu implies that cn= and ou= will be the attributes most frequently used to access entries.

Before we created the LDIF file we checked the schema files to find the data that MUST be present, and in this case only attributes cn and sn are mandatory. Every objectClass pertaining to the entry must be defined - we cannot just define the children classes and let the parent ones be included implicitly. The objectClass top is one of those defined as being operational which we should be able to ignore, but it is required in the definition of the person objectClass, so we put it in.

A dn is written with the lowest level of the DIT hierarchy on the left and the highest on the right, similar to a domain name. Every component attribute of the dn must be individually defined except the topmost (the base-dn, called the suffix in slapd.conf). So in this case, cn and ou need to be defined, but o does not.

userPassword encoding is {PLAIN} because some of our other applications want it that way. Everything else should be clear enough from the discussion of concepts above.

Let's go back to questions about designing the schema for a moment. By convention, one cn for an entry is the same as givenname joined to sn; other ones might be cn=B. Jensen or cn=Jensen, Barbara etc.. We can have more than one, as long as the dn is unique and the schema allows it. BUT, using cn in the dn means people have to guess - it might make more sense to have dn: sn=Jensen,gn=Barbara,ou=UserNetA,o=tinynet.edu to make this easier.

Also on schema design, topclass.ldif sets up the ou= groups so we can have more than one person with the same name in our directory. Reality has proven that people's names are not unique! (have you Googled your name lately?)




Note: The other schema that is commonly used in examples is nis.schema which can be known by their use of "posixAccount" in the examples. This works for system administrators that want to replace the normal /etc/passwd and /etc/shadow with LDAP for system-wide logins. On linux this requires a utility called PAM, which only very recently got included in the Slackware distro but is still not in our mytyVM distro.

If an entry will be used for system-wide authentication (with the NIS schema and "posixaccount" attributes) then this DN MUST be used with any secure Bind Operation. In this case a DN like uid=bjensen,ou=UserNetA,o=tinynet.edu may be more appropriate than one that uses cn. While this initial or "creation" dn has no special terminology within the LDAP standards, when used for authentication it is sometimes referred to as the Principal DN.




There is a lot more that can be said about LDAP, but let's get on with trying it in practice.