Attribute Uniqueness

Some attribute values must remain unique. For example, if you use uid as the RDN for millions of user entries, you must avoid two or more identical uid values. As another example, if credit card or mobile numbers are stored on directory attributes, y ou want to be certain that neither is shared with another customer.

DS servers use the unique attribute plugin to ensure attribute value uniqueness. In a deployment with multiple replicas and unique attributes, direct updates for each unique attribute to a single replica at a time as described below.

Enable Unique UIDs

By default, the unique attribute plugin is configured to ensure unique uid values:

  1. Set the base DN where the uid should have unique values, and enable the plugin:

    $ dsconfig \
     set-plugin-prop \
     --hostname localhost \
     --port 4444 \
     --bindDN uid=admin \
     --bindPassword password \
     --plugin-name "UID Unique Attribute" \
     --set base-dn:ou=people,dc=example,dc=com \
     --set enabled:true \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --no-prompt

    You can optionally specify unique values across multiple base DNs:

    $ dsconfig \
     set-plugin-prop \
     --hostname localhost \
     --port 4444 \
     --bindDn uid=admin \
     --bindPassword password \
     --plugin-name "UID Unique Attribute" \
     --set enabled:true \
     --add base-dn:ou=people,dc=example,dc=com \
     --add base-dn:ou=people,dc=example,dc=org \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --no-prompt
  2. Check your work:

    $ ldapmodify \
     --hostname localhost \
     --port 1636 \
     --useSsl \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --bindDN uid=admin \
     --bindPassword password << EOF
    dn: uid=ajensen,ou=People,dc=example,dc=com
    changetype: modify
    add: uid
    uid: bjensen
    EOF
    
    # The LDAP modify request failed: 19 (Constraint Violation)
    # Additional Information:  A unique attribute conflict was detected for attribute uid: value bjensen already exists in entry uid=bjensen,ou=People,dc=example,dc=com

    If you have set up multiple base DNs, check your work as follows:

    $ ldapmodify \
     --hostname localhost \
     --port 1636 \
     --useSsl \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --bindDN uid=admin \
     --bindPassword password << EOF
    dn: uid=bjensen,ou=People,dc=example,dc=org
    objectClass: top
    objectClass: person
    objectClass: organizationalPerson
    objectClass: inetOrgPerson
    cn: Babs
    sn: Jensen
    uid: bjensen
    EOF
    
    # The LDAP modify request failed: 19 (Constraint Violation)
    # Additional Information:  A unique attribute conflict was detected for attribute uid: value bjensen already exists in entry uid=bjensen,ou=People,dc=example,dc=com

Make Other Attributes Unique

You can configure the unique attribute plugin for use with any attributes, not just uid:

  1. Before you set up the plugin, index the attribute for equality.

    For instructions, see Configure Indexes.

  2. Set up the plugin configuration for your attribute using one of the following alternatives:

    1. Add the attribute to an existing plugin configuration:

      $ dsconfig \
       set-plugin-prop \
       --hostname localhost \
       --port 4444 \
       --bindDN uid=admin \
       --bindPassword password \
       --plugin-name "UID Unique Attribute" \
       --add type:telephoneNumber \
       --usePkcs12TrustStore /path/to/opendj/config/keystore \
       --trustStorePassword:file /path/to/opendj/config/keystore.pin \
       --no-prompt

      Choose this alternative if you want each value to be unique across all configured attributes.

    2. Create a new plugin configuration:

      $ dsconfig \
       create-plugin \
       --hostname localhost \
       --port 4444 \
       --bindDN uid=admin \
       --bindPassword password \
       --plugin-name "Unique phone numbers" \
       --type unique-attribute \
       --set enabled:true \
       --set base-dn:ou=people,dc=example,dc=com \
       --set type:telephoneNumber \
       --usePkcs12TrustStore /path/to/opendj/config/keystore \
       --trustStorePassword:file /path/to/opendj/config/keystore.pin \
       --no-prompt

      Choose this alternative if values only need to be unique within the context of a particular attribute.

  3. Check your work:

    $ ldapmodify \
     --hostname localhost \
     --port 1636 \
     --useSsl \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --bindDN uid=admin \
     --bindPassword password << EOF
    dn: uid=ajensen,ou=People,dc=example,dc=com
    changetype: modify
    replace: telephoneNumber
    telephoneNumber: +1 828 555 1212
    
    dn: uid=bjensen,ou=People,dc=example,dc=com
    changetype: modify
    replace: telephoneNumber
    telephoneNumber: +1 828 555 1212
    EOF
    
    # MODIFY operation successful for DN uid=ajensen,ou=People,dc=example,dc=com
    
    # The LDAP modify request failed: 19 (Constraint Violation)
    # Additional Information:  A unique attribute conflict was detected for attribute telephoneNumber: value +1 828 555 1212 already exists in entry uid=ajensen,ou=People,dc=example,dc=com

Scope Uniqueness

In some cases, attributes must be unique, but only in the context of a particular base DN. For example, uid values must be unique under dc=example,dc=com and under dc=example,dc=org. But it is okay to have uid=bjensen,ou=people,dc=example,dc=com and uid=bjensen,ou=people,dc=example,dc=org:

  1. If the attribute you target is not indexed for equality by default, index the attribute for equality.

    See Configure Indexes for instructions.

  2. For each base DN, set up a configuration entry that ensures the target attribute values are unique:

    $ dsconfig \
     create-plugin \
     --hostname localhost \
     --port 4444 \
     --bindDN uid=admin \
     --bindPassword password \
     --plugin-name "Unique Example.com UIDs" \
     --type unique-attribute \
     --set enabled:true \
     --set base-dn:dc=example,dc=com \
     --set type:uid \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --no-prompt
    $ dsconfig \
     create-plugin \
     --hostname localhost \
     --port 4444 \
     --bindDN uid=admin \
     --bindPassword password \
     --plugin-name "Unique Example.org UIDs" \
     --type unique-attribute \
     --set enabled:true \
     --set base-dn:dc=example,dc=org \
     --set type:uid \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --no-prompt
  3. Check your work:

    $ ldapmodify \
     --hostname localhost \
     --port 1636 \
     --useSsl \
     --usePkcs12TrustStore /path/to/opendj/config/keystore \
     --trustStorePassword:file /path/to/opendj/config/keystore.pin \
     --bindDN uid=admin \
     --bindPassword password << EOF
    dn: uid=unique,ou=People,dc=example,dc=com
    uid: unique
    givenName: Unique
    objectClass: person
    objectClass: organizationalPerson
    objectClass: inetOrgPerson
    objectClass: top
    cn: Unique Person
    sn: Person
    userPassword: 1Mun1qu3
    
    dn: uid=unique,ou=People,dc=example,dc=org
    uid: unique
    givenName: Unique
    objectClass: person
    objectClass: organizationalPerson
    objectClass: inetOrgPerson
    objectClass: top
    cn: Unique Person
    sn: Person
    userPassword: 1Mun1qu3
    
    dn: uid=copycat,ou=People,dc=example,dc=com
    uid: unique
    uid: copycat
    givenName: Copycat
    objectClass: person
    objectClass: organizationalPerson
    objectClass: inetOrgPerson
    objectClass: top
    cn: Copycat Person
    sn: Person
    userPassword: copycopy
    EOF
    
    # ADD operation successful for DN uid=unique,ou=People,dc=example,dc=com
    
    # The LDAP modify request failed: 19 (Constraint Violation)
    # Additional Information:  A unique attribute conflict was detected for attribute uid: value unique already exists in entry uid=unique,ou=People,dc=example,dc=com

Use Uniqueness With Replication

The unique attribute plugin only ensures uniqueness on the replica where the attribute is updated. If client applications write the same attribute value separately at the same time on different replicas, both replicas might use the same "unique" value, especially if the network is down between the replicas:

  1. Configure the plugin identically on all replicas.

  2. To avoid duplicate values where possible, use DS directory proxy to direct all updates of the unique attribute to the same replica.