The Complete Magazine on Open Source

OpenLDAP, Part 3: Understanding the LDAP Schema

, / 343 1

Understanding the OpenLDAP schema

In this article, we will explore LDAP concepts such as schema, ObjectClasses and attributes — these will help us build an LDAP server capable of authenticating Linux users.

To understand ACLs and LDAP security better (we learned the basics in Part 2), we need to understand the underlying structure of data in a directory. To do this, let us go back to the LDIF file that we created in the Part 1 of this series, to populate our directory:

[[email protected] openldap]$ cat /tmp/ldap.ldif
dn: dc=knafl,dc=org
dc: knafl
objectClass: top
objectClass: domain

dn: ou=addressbook,dc=knafl,dc=org
ou: addressbook
objectClass: top
objectClass: organizationalUnit

dn:cn=Varad Gupta,ou=addressbook,dc=knafl,dc=org
cn: Varad Gupta
sn: Gupta
l: Gurgaon
street: M-37, Old DLF Colony, Sector-14
st: Haryana
postalCode: 122003
homePhone: 0124 22222222
mobile: 0999999999
mail: [email protected]
objectClass: top
objectClass: inetOrgPerson

From the above file, the following facts can be deduced:

  1. The directory consists of three records or entities:
    • The Distinguished Name (DN) of the first record (entity) is dc=knafl,dc=org.
    • The other two DNs are ou=addressbook, dc=knafl, dc=org, and cn=Varad Gupta, ou=addressbook, dc=knafl, dc=org.
  2. There are no duplicate DNs (there cannot be!).
  3. The data can be represented in a hierarchical tree format. (We can see that dc=knafl is below dc=org and that ou=addressbook is below dc=knafl and so on.)

We now understand what DN is, but what is dc, or cn for that matter? What does ObjectClass mean or represent?

To understand these terms, we need to look at the structure or schema of the underlying directory. Simply put, a schema is the structure in which data units (and, therefore, records/entities) are organised in a directory. All of us confront schemas on a daily basis. Any spreadsheet that we make consists of rows and columns. The columns define the schema of the spreadsheet. Those of us who are familiar with database management systems create tables and define their schemas regularly.

Similarly, a directory has a schema. The ability to use different schemas (or schemata) for a single record enables a directory to store records with different data — providing much greater flexibility.

Going back to our discussion on the slapd.conf configuration file, the top few files in the global section define the various schemas that can be used:

[[email protected] ~]# head -n 10 /etc/openldap/slapd.conf
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
include		/etc/openldap/schema/core.schema
include		/etc/openldap/schema/cosine.schema
include		/etc/openldap/schema/inetorgperson.schema
include		/etc/openldap/schema/nis.schema

The include directive in slapd.conf reads information from other files. The schema files are generally included using this directive. Each schema file can be understood to be analogous to a spreadsheet file. Each schema file defines certain ObjectClasses and attributes.

Continuing with our analogy, ObjectClasses can be considered to be similar to each sheet within a spreadsheet file. Attributes are then analogous to each column within a sheet. In other words, multiple attributes are grouped together in an ObjectClass. Multiple ObjectClasses can be grouped to form a record.

The first schema file included in the slapd.conf configuration file, by default, is core.schema. This file defines the “core” schema of OpenLDAP. Going by the above analogy, the ObjectClasses defined in this file are:

[[email protected] ~]# cat /etc/openldap/schema/core.schema | egrep ^objectclass
objectclass ( NAME 'country'
objectclass ( NAME 'locality'
objectclass ( NAME 'organization'
objectclass ( NAME 'organizationalUnit'
objectclass ( NAME 'person'
objectclass ( NAME 'organizationalPerson'
objectclass ( NAME 'organizationalRole'
objectclass ( NAME 'groupOfNames'
objectclass ( NAME 'residentialPerson'
objectclass ( NAME 'applicationProcess'
objectclass ( NAME 'applicationEntity'
objectclass ( NAME 'dSA'
objectclass ( NAME 'device'
objectclass ( NAME 'strongAuthenticationUser'
objectclass ( NAME 'certificationAuthority'
objectclass ( NAME 'groupOfUniqueNames'
objectclass ( NAME 'userSecurityInformation'
objectclass ( NAME 'certificationAuthority-V2'
objectclass ( NAME 'cRLDistributionPoint'
objectclass ( NAME 'dmd'
objectclass ( NAME 'pkiUser'
objectclass ( NAME 'pkiCA'
objectclass ( NAME 'deltaCRL'
objectclass ( NAME 'labeledURIObject'
objectclass ( 0.9.2342.19200300.100.4.19 NAME 'simpleSecurityObject'
objectclass ( NAME 'dcObject'
objectclass ( NAME 'uidObject'

In other words, our spreadsheet file, called core.schema, has 27 sheets called country, locality, and so on.

Let us now look closely at the definition of our sheet called country:

[[email protected] ~]# cat /etc/openldap/schema/core.schema | grep -A 5 "objectclass ( NAME 'country'"
objectclass ( NAME 'country'
	DESC 'RFC2256: a country'
	MAY ( searchGuide $ description ) )

Let us now look for the columns in this sheet called country. These columns can be found in the MUST and the MAY directives within the ObjectClass definition.

Going by this, the columns in the country sheet are:

c, searchGuide and description

The next question that naturally arises is: what are c, searchGuide and description? Going by the spreadsheet analogy, can we fill in numbers, date, characters as data into these columns? What kind of data can we put into these columns? This is also defined in the schema file:

[[email protected] ~]# cat /etc/openldap/schema/core.schema | grep ^attribute | grep searchGuide
attributetype ( NAME 'searchGuide'

[[email protected] ~]# cat /etc/openldap/schema/core.schema | grep -A 3 "attributetype ( NAME 'searchGuide'"
attributetype ( NAME 'searchGuide'
	DESC 'RFC2256: search guide, deprecated by enhancedSearchGuide'

The above lines contain the definition for the attribute searchGuide. The important things to note are:

  1. attributetype ( NAME 'searchGuide' — This specifies that a new attribute definition follows. The name (NAME) of the attribute is searchGuide and its OID number is OID are Object Identifiers assigned by IANA. We will discuss these in more detail later. At this point, it is sufficient to understand the following:
    • OID 2 refers to ISO/ITU-T jointly assigned OIDs
    • OID 2.5 refers to X.500 Directory Services
    • OID 2.5.4 refers to X.500 attribute types, and
    • OID refers to the attribute searchGuide. The searchGuide attribute type specifies information of suggested search criteria, which may be included in some entries expected to be a convenient base-object for the search operation — for example, country or organisation. You can find more details here. Visit this URL to understand in greater detail how OIDs are assigned and what OIDs have been assigned to whom.
  2. DESC 'RFC2256: search guide, deprecated by enhancedSearchGuide' — This gives a description for the attribute (where one can understand what the attribute is for).
  3. SYNTAX 1.1.25 — The SYNTAX keyword defines the syntax, or in other words, the format of this attribute — viz. numerical, string, etc. The syntax is defined in terms of Syntax OIDs again. The list of these OIDs can be referenced from RFC 2252.

Let us look at another example — that of the attribute type sn or surname. This attribute would contain the surname of any person, for example, “Tendulkar” for “Sachin Tendulkar” or “Gupta” for “Varad Gupta”. The requirements for this would be character type data (char or varchar for database admins/developers), since normally no human would have a surname with numerals.

[[email protected] ~]# cat /etc/openldap/schema/core.schema | grep -A 5 "attributetype ( NAME ( 'sn' 'surname' )"

attributetype ( NAME ( 'sn' 'surname' )
	DESC 'RFC2256: last (family) name(s) for which the entity is known by'
	SUP name )

It’s important to note the following:

  1. attributetype ( NAME ( 'sn' 'surname' ) — This attribute has two names or, in other words, it has an alias. It can be referred to as 'sn' or 'surname' in a record.
  2. SUP name ) — This specifies that this attribute has a superior attribute (specified by the keyword SUP) called name. Like class hierarchies (OOPs, for programmers), attributes also have hierarchies.

This definition specifies that the attribute sn will inherit the properties of its superior attribute, or in other words sn is derived from name. The superior attribute for sn is name. name is a system (inbuilt) attribute in OpenLDAP. Its definition, though, is depicted in the core.schema file, but commented. The attribute name is defined thus:

#attributetype ( NAME 'description'
##       DESC 'RFC2256: descriptive information'
##       EQUALITY caseIgnoreMatch
##       SUBSTR caseIgnoreSubstringsMatch
##       SYNTAX{1024} )

The syntax for the name attribute is defined as:


The SYNTAX OID means a directory string and {1024} specifies the maximum length. Therefore, the name attribute can be a string of up to 1,024 characters.

Since the sn attribute is derived from its superior attribute name, it too can be a string of up to 1,024 characters.

We will cover the EQUALITY and SUBSTR clauses later when we deal with indexes. I hope that you can now figure out how data types are defined and used in OpenLDAP. Having seen how attributes (or columns in an individual sheet) are defined, in this article, we will probe deeper into ObjectClasses (individual sheets of a spreadsheet file, going by our analogy) in the next article.

It is left as an exercise to the reader to understand the attributes used in our sample of an LDIF file given above — dc, ou, cn, l, street, st, postalCode, homePhone, mobile and mail. Refer to this documentation to understand attributes and ObjectClasses.