A custom LDAP schema

One of the things I have a lot of experience with is designing, creating and maintaining a framework of custom object classes and attributes.

Some advice on that after the jump.

My own list of best practices for establishing a new directory service includes creating at least one custom person object class. This is to service any custom attributes that may need to be added to user entries beyond the standard attributes (for example, those in the person, organizationalperson and inetorgperson object classes) that are included with the schemas that ship with most directory servers.

1. Create a list of custom object classes and attributes you think you’ll need.

Rule Number One regarding an LDAP schema is to always make sure you use standard schema objects in the way they were intended to be used.

Get to know the object classes and attributes that ship with your directory product. If you don’t understand how they’re supposed to be used, consult the product documentation and the LDAP RFC’s, for example RFC 2798 on the inetorgperson object class.

A case in point: In complying with Rule Number One, if you discover a need for an attribute that contains the manager’s name (e.g. where your applications don’t know how to search using the dn value in the manager attribute), do not use the standard “manager” attribute in the inetorgperson object class. According to the relevant RFC, “manager” is supposed to hold a dn (distinguished name) value, not the text of someone’s first and last names. Instead, create a custom attribute, say, “mycorpmanagername” to meet the need.

(Note: Many LDAP applications, like the Apache’s Directory Studio (ADS), assume you’re using standard attributes in standard ways. For example, ADS will not let you put any text other than a dn value in the manager attribute no matter how you may have altered your standard schema to allow that nonstandard use.)

Rule Number Two is to never add a custom attribute to an existing standard object class.

If you have a need for custom attributes, create one or more custom object classes to hold them. For example, the “mycorpperson” custom object class would be used to hold the “mycorpmanagername” custom attribute.

2. Get a Private Enterprise Number (PEN) from IANA.

You’ll use this PEN in the unique prefix for the OID (Object IDentifier) you assign to each custom object class and attribute.

Many directory servers don’t require an “real” OID to create schema objects. All they require is that the OID value be unique. Sun/Oracle DSEE, for example, allows you to use something like “oid-mycorpmiddlename”. I don’t recommend going this route because it may lock you in to a particular vendor’s product at a particular time in its life.

3. Assign an OID to each item on the aforementioned list.

Rule Number Three regarding the schemas loaded in any LDAP server: each object class and attribute must have a unique OID value assigned to it.

Take a look at the standard schema that shipped with your directory server. You’ll notice that the format of the OIDs assigned follows a logical pattern (more or less).

Here’s the method I use to keep things sane (warning, most of the terminology is of my own invention):

Base Object Identifier

The base object identifier is a dotted decimal string following the conventions in use in the LDAP development community. A company’s base OID would be 1.3.6.1.4.1. followed by their PEN.

Forming a Complete OID

After the base object identifier comes the status bit for the OID. There are two I usually use:

.1 for Production LDAP and;

.6 for Experimental LDAP.

A production LDAP item would therefore be 1.3.6.1.4.1.[PEN].1.

Following the status bit is the LDAP item suffix. Again, there are two I usually use:

.3 for Attributes and;

.4 for Object Classes

Thus a new object class would have the OID 1.3.6.1.4.1.[PEN].1.4.x, with the specific item being numbered with the consecutive digit “x”.

The object class “mycorpperson” could then be 1.3.6.1.4.1.[MyCorp PEN].1.4.1 if it were the first custom object class defined. The next custom object class, for example “mycorpoffice” would then be 1.3.6.1.4.1.[MyCorp PEN].1.4.2, and so on.

4. Maintain a central “OID Registry” with a record of each custom object class and attribute you create.

This can be a simple spreadsheet to begin with. The important thing is that you keep it up to date and “publish” it so it can be referred to by others.

The oldest such registry I maintain is stored in a database and can be accessed read-only or read/write through a web form, depending on the user’s privileges. In my case I have one table for object classes and another for attributes. One field I wish I’d originally included for object classes was for listing which attributes were mandatory (”MUST”) and which permissive (”MAY”). That would make it much easier to see how things are categorized at a glance.

5. In implementing custom object classes and attributes:

a. Use a separate schema file for each custom object class that also contains the definitions for the custom attributes assigned to that object class, if possible. Some LDAP directories don’t let you do this, for example Sun/Oracle DSEE defaults you to the 99user.ldif schema file. So be it;

b. Don’t forget to define something as a mandatory attribute (”MUST”) in each custom object class. Don’t use anything that wouldn’t be in every entry (like “uid” or even “cn”), or you’ll regret it later. Usually “objectclass” will do;

c. Be sure to modify any user creation templates you use to include any custom object class containing commonly used custom attributes. For example, that “mycorpperson” object class that has “mycorpmanagername” and other custom attributes like it.