There are two daemons that come packaged with OpenLDAP: SLAPD server and SLURPD server. SLAPD, sometimes called the OpenLDAP server, handles client requests and directory management, while SLURPD manages replicating changes to other directories. SLURPD is now deprecated in favor of a newer, more robust replication process, and will be removed from future versions of OpenLDAP.
In the next chapter we will talk more about what these two daemons do. Right now we are only concerned with getting the SLAPD server up and running so we can start connecting to (and using) our directory.
SLAPD has one main configuration file and any number of auxiliary configuration files. In this section we are going to edit the main configuration file. It is called
slapd.conf, and in Ubuntu’s distribution it is located at
/etc/ldap/ (if you built from source, the default location is
While Ubuntu provides a good basic
slapd.conf file that you can work with, if you choose, we will not use it. For our purpose, we will start with an empty file and create a
slapd.conf configuration from scratch. You may want to make a backup copy of the original
slapd.conf file before we begin. You can do this from a terminal by running:
$ sudo mv /etc/ldap/slapd.conf /etc/ldap/slapd.conf.orig
This will rename the file from
By default, Ubuntu does not activate the
root account. Any time you want to perform a function as the superuser, you should use sudo. However, if you need to become
root (to run, for instance, several commands in sequence), you can type
Now we are ready to create our new
slapd.conf file. Open the text editor and create a basic
# slapd.conf - Configuration file for LDAP SLAPD ########## # Basics # ########## include /etc/ldap/schema/core.schema include /etc/ldap/schema/cosine.schema include /etc/ldap/schema/inetorgperson.schema pidfile /var/run/slapd/slapd.pid argsfile /var/run/slapd/slapd.args loglevel none modulepath /usr/lib/ldap # modulepath /usr/local/libexec/openldap moduleload back_hdb ########################## # Database Configuration # ########################## database hdb suffix "dc=example,dc=com" rootdn "cn=Manager,dc=example,dc=com" rootpw secret directory /var/lib/ldap # directory /usr/local/var/openldap-data index objectClass,cn eq ######## # ACLs # ######## access to attrs=userPassword by anonymous auth by self write by * none access to * by self write by * none
There are three headings in the file (Basics, Database Configuration, and ACLs), and we will now see each heading in detail.
If a file is not found using the locate command, the database might be simply out of date and needs to be re-run. Updatedb is maybe also not indexing partitions such as those contained on removable media (USB sticks), and the file may be present there instead of the regular system partitions.
The first section of the configuration file, labeled Basics, contains a variety of configuration parameters:
########## # Basics # ########## include /etc/ldap/schema/core.schema include /etc/ldap/schema/cosine.schema include /etc/ldap/schema/inetorgperson.schema pidfile /var/run/slapd/slapd.pid argsfile /var/run/slapd/slapd.args loglevel none modulepath /usr/lib/ldap # modulepath /usr/local/libexec/openldap moduleload back_hdb
First note that all lines that start with a hash (
#) are treated as comments, and ignored by SLAPD.
The first three functional (non-comment) lines all begin with the
include directive. The
include directive should always be followed by a full path to a file on the file system. When SLAPD finds the
include directive it will attempt to load the indicated file. Those files will then be treated as part of the current configuration file. So, when SLAPD reads these three lines, it will try to load the three schema files (
include directive can be used to load any configuration parameters (in the next chapter, we will use it to include a file that contains ACLs). Traditionally, the schema information is stored separately from other configuration directives, and loaded (using
include directives) at server startup. This improves the readability of the code and helps prevent the accidental modification of the schema information.
Schemas provide definitions of (amongst other things) the different object classes and attribute types that OpenLDAP should support. Using these, OpenLDAP can determine what entries it is allowed to store, whether any given entry is valid, and how entries should optimally be stored.
The three schemas loaded here contain the most frequently used options.
core.schema contains all of the attribute and object class definitions from the LDAP v.3 specification. The
inteorgperson.schema files contain schema definitions for commonly used standardized extensions (see RFCs 4524 and 2798). There are a host of other schemas available with OpenLDAP.
After the schemas are included the next two directives,
argsfile, tell SLAPD where to store (and look for) files that contain information on:
The process ID for the SLAPD server process
The arguments that were passed into the
slapdcommand at startup
Since SLAPD needs to write to these files, the user that runs
slapd needs to have permissions to
read from and
write to these files. Since the files are removed when the SLAPD server shuts down, the user that runs
slapd will also need write permissions on the directory where these files are stored (
/var/run/slapd/, in this case).
loglevel directive is set to
loglevel directive specifies how much information SLAPD should send to the system log (by way of
syslogd). The loglevel directive accepts keywords (
trace, and so on), integers (
32768), and hexidecimal numbers (
Setting this to
none will cause SLAPD to only log critical events. In order to turn off the logging altogether, use
0. To turn on all the logging, which will generate massive amounts of logging for every request, use
any. The SLAPD man page (
man slapd) provides a complete list of all the supported log levels.
The last few directives in the Basics section are
moduleload. These are instructions for loading OpenLDAP modules.
A module is a special type of library that can be loaded when SLAPD starts up. Instead of compiling all of SLAPD’s code into one large binary, the modules make it possible to create smaller library files for discrete functional units of LDAP code.
Typically, there are two different kinds of modules:
- Backends: The OpenLDAP server can use different storage backends, including BDB, SQL database, flat files (in LDIF format), or even another LDAP directory server. Each of these backends can be compiled into its own module. Then, during configuration, we have the option of only loading the module (or modules) that we need.
- Overlays: OpenLDAP includes a number of optional extensions, called overlays, which can modify behavior of the server. These, too, are stored in modules.
Let’s have a look at the directives we have used in our
modulepathdirective provides the full path to the directory where the modules (the compiled libraries) are stored. By default, Ubuntu puts LDAP libraries in
/usr/lib/ldap. If, for some reason, you have modules stored in multiple directories you can specify a list of paths, separated by colons:
moduleloaddirective instructs OpenLDAP to load a particular module. The directive takes either the file name of the module to be loaded (such as
back_hdb) or a full path (beginning with
/) to a module file. If just the name is specified, SLAPD will look in the directories specified in
modulepath. If the entire path is specified, it will attempt to load from exactly that path (it will not use
moduleload back_hdbinstructs SLAPD to load the module that provides services for storing the directory in the Hierarchical Database (HDB) backend. This is the database that we will configure in the Database Configuration section.
The next section of our
slapd.conf file is the database configuration section. This section handles the configuration of the database storage mechanisms. OpenLDAP is not limited to one database. More than one database can be used per server, where each database stores its own directory tree (or subtree). For example, a single OpenLDAP instance can serve a directory tree whose base is
o=My Company,c=US from one database, and a directory tree whose root is
dc=example,dc=com from a second database.
As we saw in Chapter 1, the base DN for a directory tree is made up of attribute name/attribute value pairs. For example, the DN
o=My Company, c=US indicates that the organization name
(o) is My Company, and its country of origin
(c) is United States (whose two-letter ISO code is US). Likewise, the second DN is composed of attribute name/value pairs, this time representing domain components
(dc) from the organization’s registered domain name, here, the fictitious
In our simple
slapd.conf file, we are defining only one database:
########################## # Database Configuration # ########################## database hdb suffix "dc=example,dc=com" rootdn "cn=Manager,dc=example,dc=com" rootpw secret directory /var/lib/ldap # directory /usr/local/var/openldap-data index objectClass,cn eq
The first directive in the database configuration section is the
database directive. This specifies which database backend will be used. In this case we will be using the Hierarchical Database (HDB), so we specify
HDB is the new generation storage mechanism for OpenLDAP. Like its predecessor, the BDB backend, HDB uses the Oracle Berkeley DB database for storage, but HDB stores entries hierarchically, a perfect fit for LDAP’s tree strucutre. The old BDB backend is still supported, and you can use it by specificing
bdb instead of
hdb in the
The next directive,
suffix, indicates which parts of the directory tree this database will hold. Basically, it indicates that this database’s base will be the entry with the Distinguished Name (DN) specified in the
suffix directive (
When the server receives a request for something in that tree (for example,
dc=com), it will search in this database. The following figure gives a better idea:
Here, the client is searching for a specific DN,
dc=example,dc=com. The SLAPD server contains a directory information tree whose base DN is
dc=com is subordinate to
dc=com. It exists in the
dc=com tree. So, SLAPD searches the
dc=com database for a record whose DN is
dc=com. Once the record is found, it is returned to the client.
What will happen if a client requests the record of
dc=net? Since this DN does not contain a base DN handled by this server, the server will not search for the record. Depending on the configuration, it may either send an error back to the client or redirect the client to another server that might be able to handle such a request.
Likewise, if a client tries to add a record with a base DN other than the one specified in the suffix directive, the LDAP server will refuse to add the record to the directory information tree.
suffix directive in
slapd.conf specifies what the base DN will be for information stored or referenced in this database. This will determine, to a large degree, what records this database will contain, search for, or allow to be added.
The next two lines assign a record for the directory manager and give the manager entry a password. The
rootdn directive specifies the DN that will be considered the administrator of this directory. By convention, the root DN is created by prepending
cn=Manager to the base DN of the directory tree. Thus, our directory manager is
dc=com. The next field,
rootpw, is used to assign a password for the directory manager. Note that this is stored outside the directory rather than inside it. For example, the
userPassword attribute of a record in the directory. This is to prevent the manager from being locked out of the directory.
The directory manager is a special user with special privileges. The manager’s requests are not filtered through ACLs—the manager’s access cannot be restricted. Furthermore, the manager has write access to all records in the directory under the specified suffix or suffixes. For that reason, the manager DN should be used for administrative tasks only and not for anything else.
Further, since the necessary fields for the manager are stored here in the
slapd.conf file, there should not be a record in the directory with the manager’s DN (this is recommended for best practices, though it is not explicitly prevented by SLAPD).
Since the manager’s DN and password are stored in the
slapd.conf file, and since the manager has access to everything in the directory, we should keep file system permissions on the
slapd.conf file as restrictive as possible.
directory directive indicates which directory on the file system should hold the database files. In this case the database is stored at
index directive is composed of a list of attributes that should be indexed, followed by the type of matching that the index will be used for. Our example looked like this:
index objectClass,cn eq
This means that we are creating an index that will support equality (
eq) matching on the attributes
cn. When the server gets a request for all the entries with
cn Rob or
commonName Rob, the server can greatly expedite service by accessing the index instead of searching the entire database. However, if the request was for
Rob* (note the
* wildcard character), then the server would not be looking for a CN that equals “Rob*”, but for any CN that starts with “Rob”. In this case, the index we created would not be used.
Multiple index directives can be used, and we could support faster CN searches for queries like
Rob* by splitting the index directive into two different directives:
index objectClass eq index cn eq,sub
Certain attributes do not support all index types. The
objectClass attribute, for example, does not support substring (
sub) index matching. When we will look at performance tuning in Chapter 5, we will see the indexing directive more carefully.
Once you have a database created, every time you modify the
index directives in
slapd.conf, you should rebuild the indexes with the
slapindex command-line utility. Since we have not yet put any data in the database though, we don’t need to run this command now.
Now we are ready to move on to the third and final section of our configuration file.
The last section in the
slapd.conf file is the ACL section. ACLs (Access Control Lists) determine which clients can access what data, and under what conditions. In Chapter 4, we will cover ACLs in much more detail. However, it is important to have some basic ACLs configured from the beginning, so we will briefly walk through two simple ACLs:
######## # ACLs # ######## access to attrs=userPassword by anonymous auth by self write by * none access to * by self write by * none
ACLs are just fancy directives—directives with a complex syntax. They begin with the access directive, followed by a list of conditions. The conditions can span multiple lines as long as each continuation line begins with one or more white space characters (such as a tab or a space).
Let’s look at the first access control in detail:
access to attrs=userPassword by anonymous auth by self write by * none
The purpose of this access control is to keep a user’s password protected. Specifically, it allows anonymous users to request that the server perform an authentication comparison (during the process of logging on) on a password. Additionally, it grants a user permission to change his or her own password. Finally, it denies everyone else any access to the password. That’s what this rule is supposed to do. Now, how do we get that?
Each line of code having
by should be indented:
access to [resources]
by [who] [type of access granted]
by [who] [type of access granted]
by [who] [type of access granted]
access directive can have one
to phrase, and any number of
by phrases. Our first rule has three
by phrases. Let’s see these in more detail:
access to attrs=userPassword,
attrsindicates that a list of one or more attributes will follow. In our case there is only one attribute:
userPasswordattribute is used to store the value of a password for an object in the directory.
In this access control there is no explicit mention of particular parts of the directory to which this rule applies. Given this, the ACL will be enforced for all instances of
userPassword. So, the rule specifies access to the
userPassword attribute. The next three phrases will indicate who has access to
userPassword attributes, and what kind of access they have.
by anonymous auth. This phrase grants an anonymous user (one who has not yet authenticated) permission to authenticate using a password. More accurately, it indicates that when a user submits a request for authentication, the directory server is allowed to perform an authentication operation (which amounts to comparing the submitted password with the value in the
userPasswordattribute for the corresponding user’s entry).
The last part of the
byphrase specifies what sort of permissions are granted to the record. The permissions level can be granted in a few ways,
For the time being, though, we will look at four keywords that can be used in ACLs to grant common permission levels:
auth: The server can perform an authentication operation using this resource.
read: The client can have
authaccess and can also read this resource, but cannot make any changes.
write: The client can have
readaccess to this resource and can also perform add, modify, and delete operations on whatever is specified by resource.
none: The server should not give the client any access at all to this resource.
when we look at ACLs in depth, we will look at other keywords and explore creating finer-grained permissions levels, such as allowing write access without granting read access.
So, the second
by self write, means that once a DN (usually a user) has successfully connected and authenticated to the LDAP server, it can change the value of
Finally, the last
by phrase says
by * none. The
* is a wildcard that will apply to everyone. And
none, as we came to know, denies any sort of access to the
userPassword attribute. This rule says that everyone should be denied access to the password attribute.
by phrase provides a good illustration of how ACLs are applied. The ACL is evaluated in order. In the rules above, as soon as the server finds a rule that applies to the current DN, it will stop processing the ACL. Consider an example. When an anonymous user tries to authenticate (bind) with a DN and password, the server will check the ACLs to see if the DN has the right to request an authentication comparison using the
As SLAPD evaluates this ACL, it will see that the first
by phrase applies; use that rule and skip the other two. But, on the other hand, if an authenticated user tries to read
userPassword of another DN, the server will search
by phrases until it finds one that matches. It will evaluate and skip the first two before applying the third, which denies that user the access to another record’s
The Default by Phrase
When processing an ACL, SLAPD denies access by default. This means that every access directive ends with an implicit
by phrase of
by * none. So, to save space, we could have omitted the last phrase from both of our ACLs.
Now that we understand the first ACL, the second should be a breeze. Let’s see the second one:
access to * by self write by * none
This last ACL becomes our default rule for the directory. It can be paraphrased this way: for any object and all its attributes (
to *), if the currently connected DN is the DN of this object, it can write to the object (
by self write). Otherwise, the currently connected DN has no access whatsoever (
by * none). In short, it lets objects write to themselves, but denies everyone else all the permissions to the object.
Restricting the Manager
It should be noted that ACLs cannot be used to restrict the special directory manager account named in the
Keep in mind that ACLs are processed sequentially. So this second rule will only apply if the earlier rule did not apply.
These access controls are very strict and will prevent directory users from getting much out of the directory.
Verifying a Configuration File
We are now done working through the configuration file. The last thing to do before we start the server is to verify that the configuration file is valid.
OpenLDAP includes a tool for testing the configuration file to make sure that it is well-formed and that the directives are all used correctly. It also checks elements of the OpenLDAP environment to ensure that the requisite files are in the correct locations. The testing tool is called
slaptest and it appears as:
$ sudo slaptest -v -f /etc/ldap/slapd.conf
Since the file system permissions on
slapd.conf are very restrictive, we used
sudo to execute the test as the root user. The
slaptest command needs to know where the
slapd.conf file is. This is specified with the
-f parameter followed by the path to the configuration file. We also used the
-v flag to require verbose output. Since nothing was wrong with
slapd.conf, only one line was printed:
config file testing succeeded
But if anything is incorrect,
slaptest will provide diagnostic information. Let’s look at a misconfigured
# slapd.conf - Configuration file for LDAP SLAPD ########## # Basics # ########## include /etc/ldap/schema/core.schema include /etc/ldap/schema/cosine.schema include /etc/ldap/schema/inetorgperson.schema pidfile /var/run/slapd/slapd.pid argsfile /var/run/slapd/slapd.args loglevel none modulepath /usr/lib/ldap # modulepath /usr/local/libexec/openldap moduleload back_hdb ########################## # Database Configuration # ########################## database hdb suffix "dc=example,dc=com" rootdn "cn=Manager,dc=example,dc=com" rootpw secret directory /var/lib/ldap # directory /usr/local/var/openldap-data index objectClass sub,eq index cn sub,eq ######## # ACLs # ######## access to attrs=userPassword by anonymous auth by self write by * none access to * by self write by * none
This configuration file is a minor variation of the one we have been examining throughout this section. The problem is that the
objectClass attribute cannot handle substring matches. The reason for this is that the schema does not allow substring matching on the
Having made the above change, we run the
$ sudo slaptest -v -f slapd.conf
The following messages appear:
slapd.conf: line 48: substr index of attribute "objectClass" disallowed slaptest: bad configuration file!
As you can see this information is useful for quickly finding and fixing problems before attempting to start the server.
An Ubuntu Oversight
Due to a configuration oversight by Ubuntu packager maintainers, the slaptest program does not issue a warning if an unknown directive is found. As a result, a mistaken directive name may slip through the verification stage unnoticed. For example, misspelling index as idnex will not result in an error.
Testing slapd.conf with slapd
The slaptest command is actually nothing more than a symbolic link to slapd, the command used to start the server. While there are no distinct advantages to doing so, you can use the slapd program to test
$ slapd -T dest -f /etc/ldap/slapd.conf
Once the configuration file passes muster with the
slaptest program, we are ready to start our server.
At this point, we have walked through our basic
slapd.conf configuration file. This configuration will get our directory up and running, and in later chapters of this book we will cover some more advanced settings that can be included here in the configuration file.
If you are interested in reading more about configuration options for
slapd.conf, you may want to take a look at the manual (man) pages. The man pages for OpenLDAP provide a thorough (though sometimes tersely worded) reference. In particular, the
slapd.conf page is very useful.
$ man slapd.conf
At the bottom of that page there is a list of other related manual pages, such as
slapd-hdb, which lists directives specific to the HDB database.