The Uniqueness Overlay

The last overlay that we will examine in this section is the uniqueness overlay. The uniqueness overlay enforces uniqueness for a configurable set of attributes in the directory. It prevents attributes in different records from containing the same values. This is desirable, for example, when working with the uid attribute, where we would clearly not want to have the same UID for multiple users in the system. By default, SLAPD only enforces uniqueness when it comes to DNs—no two DNs may be the same. But other attribute values are unchecked. Using the uniqueness overlay, we can specify which attributes we want SLAPD to ensure uniqueness for.

The first step in configuring the uniqueness overlay is to load the module:

modulepath      /usr/local/libexec/openldap
moduleload      back_hdb
moduleload      denyop
moduleload      refint
moduleload      unique

In the Basics section of slapd.conf, we add one more moduleload directive. The module we want to load is named unique.

Next we want to add this overlay, along with a few specific directives, to the relevant database sections:

overlay unique
unique_base dc=example,dc=com
unique_attributes uid

This is a very basic configuration for the uniqueness overlay. The unique_base directive indicates which parts of the directory information tree we want to enforce uniqueness in. For our exercise we want to enforce uniqueness across our entire directory tree, dc=example,dc=com.

The unique_attributes directive takes a whitespace-separated list of attributes that the uniqueness overlay will enforce uniqueness constraints. In this example we just want to enforce uniqueness on the UID attribute.

Thus, according to our configuration, no two UID values for any records in the dc=example,dc=com directory information tree should be identical.

Now let's see how this overlay works in practice.

In the discussion of the RefInt overlay, we created the following record:

dn: uid=cicero,ou=users,dc=example,dc=com
uid: marcus
uid: cicero
sn: Tullius
cn: Marcus Tullius
givenName: Marcus
ou: users
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson

Note that this record has the UID marcus, even though this attribute is not used in the DN. Now let's try to add the following record:

dn: uid=marcus,ou=users,dc=example,dc=com
uid: marcus
sn: Aurelius
cn: Marcus Aurelius
givenName: Marcus
ou: users
objectclass: person
objectclass: organizationalperson
objectclass: inetOrgPerson

This record also uses the UID marcus. Without the uniqueness overlay, SLAPD would allow both records to have the same UID. This, of course, will cause problems for applications that assume that a Unique ID is really unique—only zero or one results will be returned for a search on the UID attribute.

But with the uniqueness overlay, as we have configured it, SLAPD will prevent clients from adding a UID value that matches an existing UID value. The uniqueness overlay does this by checking the attributes in add, modify, or modrdn operations. If we try to add the given record for uid=marcus, we get an error:

$ ldapadd -U matt -f unique-example.ldif
SASL/DIGEST-MD5 authentication started
Please enter your password: 
SASL username: matt
SASL SSF: 128
SASL installing layers

adding new entry "uid=marcus,ou=users,dc=example,dc=com"
ldap_add: Constraint violation (19)
          additional info: some attributes not unique

SLAPD sends back a Constraint violation error because the uniqueness overlay will not allow a duplicate UID attribute value. To work around this, we would have to either delete the extra UID attribute from the uid=cicero record or use a different UID for Marcus Aurelius's record.

The example configuration we have just seen represents the most typical use of the uniqueness overlay. There are two additional uniqueness directives that provide more complex configurations:

The first is the unique_ignore directive. Typically, this is used instead of unique_attributes.

The unique_ignore directive takes a whitespace-separated list of attributes that should not be tested for uniqueness. There are attributes, such as ou, sn, and objectclass, that are likely to be legitimately used more than once in a directory. For example, it is perfectly possible for multiple people in an organization to have the same surname, and thus have identical sn attribute values.

But when unique_attributes is not specified, then by default all non-operational attributes are assumed to require uniqueness. Consider this example configuration:

  overlay unique
  unique_base dc=example,dc=com
  unique_ignore objectclass sn ou description

According to this configuration, all of the attribute values in the directory information tree except objectclass, sn, ou, and description will be required to have unique values. Obviously, this configuration is far more restrictive than our first example and it should be used with care.

Finally, there is one additional directive for the unique overlay. The unique_strict directive, which takes no parameters, can be used to turn on "strict" uniqueness enforcement.

By default, the uniqueness overlay allows multiple attributes to have empty (null) values. For example, if we enforce uniqueness on the uid attribute, SLAPD would still allow multiple records to have a UID attribute with an empty value. But this is not always desirable. Under some circumstances, it might be necessary to ensure that no more than one attribute has an empty value. The unique_strict directive is used for this purpose.

When the unique_strict directive is present, the uniqueness overlay will not allow a client to set an attribute value to empty (null) if another instance of the same attribute already exists and already has an empty value.

At this point, you should have a good idea of how to use overlays. We have looked at three different overlays but in the coming chapters we will look at several more.