Advanced OpenLDAP part 2 - online configuration (cn=config)

(Jan Hedström)

Digging down into cn=config

For many years now, OpenLDAP has been able to store its own configuration into an internal LDAP directory, much like Oracle and other relational databases do, rather than in a plain text file. This is often referred to as “cn=config” because of the root DN that is normally used for configuration, and it provides one really, really big benefit: on-line configuration, where many configuration changes take effect immediately without needing to restart OpenLDAP and interrupt client applications.

When we perform on-line reconfiguration, the OpenLDAP server will also perform syntax checking to avoid complete mess-ups. The downside is that the server management becomes a bit harder, but in my opinion the on-line configuration makes it worthwhile to use cn=config instead of the traditional slapd.conf file, altough that method still remains as an option. If we take a look at the modern server distributions, both Red Hat 6 / CentOS 6 and Debian 7 uses cn=config by default.

Where is the configuration actually stored?

In the traditional OpenLDAP configuration we basically used a single static file, slapd.conf, for all settings except the schema. This has changed with the on-line configuration which is split up over a dozen or more files. To ease migration from the old style there is a conversion feature in the slaptest utility.

Even though cn=config is a proper LDAP directory, it is stored in a collection of text files under /etc/openldap/slapd.d. But don't be fooled by that – never edit those files by hand while the server is running! Sure, they reflect the configuration, but the active configuration is stored in memory and should only be manipulated through the LDAP protocol. When the slapd server is shut down though, the text files can be edited if you know what you are doing – they will be read into memory on the next startup.

cn=config.ldif, the master configuration file:


So here we have the top-level file cn=config.ldif, which contains global settings necessary for startup, for example defining where the configuration itself is located (”olcConfigDir: /etc/openldap/slapd.d”) and attributes that are necessary for getting the TLS encryption to work (i.e. olcTLSCACertificatePath, olcTLSCertificateFile and olcTLSVerifyClient). As you can see, the configuration files are formatted as LDIF, which really makes sense regarding that the configurations are maintained and manipulated as LDAP data.

Schema definitions

Lower down the directory tree, we find more specific configurations. For example, we find the schema, where attributes and object classes are defined, distributed over a number of text files. Let's take another look at the above example - the file names begin with a number that determines in what order they will be read into memory on startup. The file in the highest directory, cn=schema.ldif, will be read first of all:

│   ├── cn=schema.ldif
│   ├── cn=schema/
│   │   ├── cn={0}corba.ldif
│   │   ├── cn={1}core.ldif
│   │   ├── cn={2}cosine.ldif
│   │   ├── cn={3}duaconf.ldif
│   │   ├── cn={4}dyngroup.ldif
│   │   ├── cn={5}inetorgperson.ldif
│   │   ├── cn={6}java.ldif
│   │   ├── cn={7}misc.ldif
│   │   ├── cn={8}nis.ldif
│   │   └── cn={9}openldap.ldif
│   │   ├── cn={10}ppolicy.ldif
│   │   ├── cn={11}collective.ldif

Normally there are few reasons to edit or even read these files, but if you need to add custom attributes this can be done by inserting a new file into the cn=schema directory. But as mentioned before, the LDAP interface is preferred for configuring the schema too.

Configuration database

In the configuration directory tree, we can also find the database-specific settings, yet again the files are numbered to control the startup order:

│   ├── olcDatabase={0}config.ldif
│   ├── olcDatabase={-1}frontend.ldif
│   ├── olcDatabase={1}monitor.ldif
│   └── olcDatabase={2}bdb.ldif

The first file contains settings for the configuration database itself. Yes, these settings actually define how the file they are stored in should be treated! Note in particular the ”olcRootDN” and ”olcRootPW” entries – this is the directory manager account for the configurations. There are separate ”olcRootDN's” for each individual backend database, but more on that later.


The real database(s)

Another example is our file ”olcDatabase={2}bdb.ldif”. This defines the settings for our first default database, the Berkeley DB4 database that will hold our real user and group information. Besides the directory manager account, here we have a lot more parameters that can be configured. Here's an excerpt:


One of the most important lines is ”olcDbDirectory: /var/lib/ldap” which determines where this particular database will be stored. One database per directory only! When you configure two or more databases you need to set separate directories for each database.

On a standard Debian/Ubuntu or Red Hat/CentOS installation, I prefer to clean out the /var/lib/ldap directory and create sub-directories like /var/lib/ldap/database1, /var/lib/ldap/database2 and so on. This way, the LDAP data remains where a systems administrator would expect to find it, and keeping it under the same directory lets us store the data without needing to modify the SELinux configuration. (You do use SELinux, don't you? You should definetly consider doing so, but that is another story).

So, now we have taken a look into the structure of OpenLDAP's configuration. In the next post, we will go through the steps to get a baseline server configuration up and running.