There are times when the standard schema files distributed with your LDAP server don't meet the needs of your application. Creating a custom schema file for OpenLDAP is a simple process:
Assign a unique OID for all new attribute types and object classes.
Create the schema file and include it in slapd.conf.
It's also possible to create alternate schema syntaxes and matching rules, but implementing them is beyond the scope of this book; typically, they require implementing a plug-in for the directory server or modifying the server's source code. For more information on this process, you should consult the OpenLDAP source code or your vendor's documentation for other directory servers.
Chapter 2 described how to obtain a private enterprise number from IANA (see the form at http://www.iana.org/cgi-bin/enterprise.pl and RFC 3383). When creating new attributes or object classes, it is a good idea to use an OID that is guaranteed to be unique, whether or not the schema will ever be used outside of your organization. The best way to guarantee that the OID is unique is to obtain a private enterprise number and place all your definitions under that number.
For example, suppose that an LDAP client application requires a new object class based on person. This new object class should contain all of the attributes possessed by the person object, with the addition of the userPassword and mail attributes.
In order to create this new object, I have allocated the OID arc of 184.108.40.206.4.1.7220.127.116.11 for the new object classes:
iso (1) org (3) dod (6) internet (1) private (4) enterprise (1) SAMBA.org (7165) plainjoe.org (1) O'Reilly LDAP Book(1)
The private enterprise number 7165 has been issued by IANA for use by the Samba developers, the 7165.1 arc has been allocated to the plainjoe.org domain, and 7165.1.1 has been set aside for this book; I can't touch the numbers above 7165.1 in the tree, but I have complete freedom to assign numbers below it as I see fit. I've chosen to allocate 718.104.22.168 to ldap object classes that I create and 722.214.171.124 for new attributes. I could put my new objects directly under plainjoe.org, but that might cause problems if I want to create other kinds of objects (for example, private SNMP MIBs):
SAMBA.org (7165) plainjoe.org (1) O'Reilly LDAP Book(1) |-- objectclasses (1) |-- attributeTypes (2)
Let's call the new object plainjoePerson. Add the following definition to a custom schema file named plainjoe.schema; you'll use this file for all custom objects that you define.
## objectclass definition for 'plainjoePerson' depends on core.schema. objectclass ( 126.96.36.199.4.1.7188.8.131.52.1 NAME 'plainjoePerson' SUP person STRUCTURAL MUST (userPassword $ mail) )
LDAP's object inheritance allows this new object to reuse the existing characteristics of person; you need to add only the new required attributes. If new attributes are defined as well, they must be defined prior to their use in the plainjoePerson object. The new object has to be defined as STRUCTURAL since it is derived from a structural class.
New attributes can be defined in the same way or even be derived from existing attributes. RFC 2252 should be considered required reading in this case, as it describes the various LDAPv3 syntaxes and matching rules. For example, you could create a new attribute named plainjoePath to store a single, case-sensitive pathname by defining the following in plainjoe.schema:
## Store a case-sensitive path to a directory. attributetype( 184.108.40.206.4.1.7220.127.116.11.1 NAME 'plainjoePath' DESC 'A directory on disk' SUBSTR caseExactIA5SubstringsMatch EQUALITY caseExactIA5Match SYNTAX 18.104.22.168.4.1.1422.214.171.124.26 SINGLE-VALUE )
Finally, you need to add an include line in slapd.conf for your new schema file:
# /usr/local/etc/openldap/slapd.conf # Global section ## Include the minimum schema required. include /usr/local/etc/openldap/schema/core.schema ## **NEW** ## Include support for special plainjoe objects. include /usr/local/etc/openldap/schema/plainjoe.schema
After restarting slapd, you can now add objects of the type plainjoePerson or include the plainjoePath in entries that use the extensibleObject class.