Growing an LDAP tree

Setting up an OpenLDAP server with cn=config support

© 2009 Dennis Leeuw

Install OpenLDAP through your favourite or supplied package manager.

Growing two trees

Configuration tree setup

Create a slapd.conf file with just above the "normal" database configuration stanzas a section that looks like this:

# Configuration database
database        config
rootdn          "cn=admin,cn=config"
rootpw          {MD5}123456789===
Of course you should create your own root password, and maybe you should not use MD5 digests. The default used by OpenLDAP to look for the configuration database is in the /etc/openldap/slapd.d directory, so let's create that one:
mkdir /etc/openldap/slapd.d
chown ldap.ldap /etc/openldap/slapd.d
chmod 700 /etc/openldap/slapd.d

Example domain setup

After that you can create your own ldap tree databases like this:

# example.com tree
database        bdb
suffix          "dc=example,dc=com"
rootdn          "cn=admin,dc=example,dc=com"
# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
directory       /var/lib/ldap/example.com

index objectClass                       eq,pres
index ou,cn,mail,surname,givenname      eq,pres,sub
index uidNumber,gidNumber,loginShell    eq,pres
index uid,memberUid                     eq,pres,sub
index nisMapName,nisMapEntry            eq,pres,sub
As you can see a directory is used per domain, so we can, if we want, later on expand on this structure. As the comment say we have to create the directory before we do any thing so let's do so:
mkdir /var/lib/ldap/example.com
chown ldap.ldap /var/lib/ldap/example.com
chmod 770 /var/lib/ldap/example.com

If you do not use cn=config:

dn: cn=admin,dc=example,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
userPassword: xxxxxx
description: Domain admin

Create a minimal database

To create a minial database that we can populate later we first have to install the sleepycat database configuration file:

cd /etc/openldap
cp DB_CONFIG.example /var/lib/ldap/example.com/DB_CONFIG

Next we need a basic database before we can import the configuration database. To create and initialize the database we create the top level of our tree. Create a file called base.ldif with the following content (adjust to your local situation):

# Create a minimal base ldif file:
dn: dc=example,dc=com
objectclass: top
objectclass: dcObject
objectClass: organization
dc: example
o: Example Organization Name
We can now add this to our ldap database by using:
slapadd -l base.ldif
Since we did this as root, we have to adjust the rights on the files: chown -R ldap.ldap /var/lib/ldap/example.com.

Creating the cn=config database

The easiest way of doing this is by using the slaptest command:

slaptest -f slapd.conf -F slapd.d
Again we have to adjust the rights so our ldap server will be able to read the files:
chown -R ldap.ldap slapd.d/

Move the slap.conf file to something like old.slapd.conf so we are sure that the server is using the slapd.d directory and accidentally our slapd.conf file.

Testing the setup

Start the LDAP server like you are used to. Note that you might have to adjust the start up scripts to work with the above setup. Most scripts are not designed to be used with the cn=config setup and also not with using a directory per domain to hold the tree database. So you might be in for some shell script hacking.

If you have your ldap server running try the following command to see everything is running as should be:

ldapsearch -x -h localhost -D "dc=example,dc=com" -LLL
dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
dc: example
o: Example Organization Name

Now we are going to do the same for the cn=config domain:

ldapsearch -x -h localhost -b "cn=config" -D "cn=admin,cn=config" -W -LLL
This will give you a lot of data scrolling over your screen.

If you made it this far then you have a working LDAP directory, an empty one, but still. You can now use you favourite LDAP browser to adjust your tree to your liking. The remainder of the document will handle more about the cn=config setup and general LDAP functionality.

Adding schemas

Within the /etc/openldap directory create a file called schemas.conf with the following content:

include		/etc/openldap/schema/core.schema
include		/etc/openldap/schema/cosine.schema
include		/etc/openldap/schema/inetorgperson.schema
include		/etc/openldap/schema/nis.schema
include		/etc/openldap/schema/my_favourite_schema.schema
We also need a directory to hold the data that we want to import into the cn=config tree:
mkdir schema_ldif
In this directory we will store the converted data like this:
slaptest -f schemas.conf -F schema_ldif

Now we have to adjust the output so it can be imported into our LDAP tree. Since the to be added schema is our 5th schema we open schema_ldif/cn=config/cn=schema/cn={5}my_favourite_schema.ldif and add to the dn entry ,cn=schema,cn=config.

Add the bottom of the file remove the lines that start with:
structuralObjectClass:
entryUUID:
creatorsName:
createTimestamp:
entryCSN:
modifiersName:
modifyTimestamp:

Now we can add the schema to our tree with:

ldapadd -x -D "cn=admin,cn=config" -W -h localhost -f schema_ldif/cn\=config/cn\=schema/cn\=\{5\}my_favourite_schema.ldif

LDAP domain tree setup

RFC 2307bis has a suggested DIT structure. However we will use a bit different naming scheme which is documented here for reference.

RFC 2307bis Active Directory Our object Object Class Purpose
ou=people ou=Users posixAccount Holding accounts that are used by persons
ou=group ou=Groups posixGroup Work groups on the systems
ou=services - ipService This is handled by /etc/services and DNS SRV records
ou=protocols - ipProtocol This is handled by /etc/protocols
ou=rpc - oncRPC ???
ou=hosts ou=Computers ou=devices (?) ipHost Contains host information data and machine accounts
ou=ethers ieee802Device Contains host information data and machine accounts
ou=networks ipNetwork Contains network settings
ou=netgroup nisNetgroup
ou=nisMapName nisObject
ou=automountMapName automountMap