The LDAP protocol has no way to auto-increment an integer value. This is necessary for Directory-enabled applications that need to create new users with an incremented, unique value. There is a “race condition” which exists if two applications try to increment the same value at the same time. If both applications read the value at the same time, they will both end up thinking that they have the same value.
With the Sun Directory Server, there is an “Attribute Uniqueness Plugin” which can be used to enforce attribute uniqueness over a container. However, this method is not recommended as it is very expensive and unnecessary if you use the “uidNext” method described in this article (see below).
There is a commonly accepted solution to this which works well. However, it must be coded into the applications due to the lack of auto-incrementing functionality in LDAP servers or LDAP client libraries. This article will discuss how to use the “Atomic uidNext Auto-increment Method”. We will assume that the requirement is to automatically increment uidNumber, but this method could be used for any number that needs to be automatically incremented.
“Atomic uidNext Auto-increment Method” Basic Steps
Create a new objectClass “uidNext”.
Create a “uidNext” entry at an specific location in the directory to store the incrementing value.
Store & get the next uid value in the DIT – use the specified spot in the DIT to store a "uidNext” value.
Programmatically construct the LDAP operation so that we have a "delete+add attribute" modification, not a "modify attribute" modification. The entire delete +add operation is atomic, meaning, the whole thing succeeds or it fails. By getting either an "operation success" or "operation fail", you have avoided the race condition. If the delete fails, the add fails too, hence the entire modification fails. No two applications can modify uidNext at the same time.
When an “operation fail” is encountered, the application can back off and try again. According to RFC 2251 Section 4.6:
“Note that due to the requirement for atomicity in applying the list of modifications in the Modify Request, the client may expect that no modifications of the DIT have been performed if the Modify Response received indicates any sort of error, and that all requested modifications have been performed if the Modify Response indicates successful completion of the Modify Operation. If the connection fails, whether the modification occurred or not is indeterminate.”
UidNext ObjectClass and Entry
Create a uidNext objectclass – This objectClass is used to store the next PID.
objectClasses: ( uidNext-oid
MUST ( cn $ uidNumber ))
Create the cn=uidNext,dc=rexconsulting,dc=net entry. This is the entry in the DIT where we store the next value.
uidNumber: (this is where the next value goes)
Pseudocode for Automatically Incrementing uidNumber
Step 1. Read the uidNext value from cn=uidNext,dc=rexconsulting,dc=net.
Step 2. Submit one LDAP operation with two modifications:
Delete the specific value read from Step 1 from the uidNext attribute of entry cn=uidNext,dc=rexconsulting,dc=net.
Add the next uidNext value to cn=uidNext,dc=rexconsulting,dc=net.
NOTE: Specify the read value from step 1 when in your “delete” so it only fails if no one else runs this operation quicker than you!!! If the deletion of the specific value you read in step 1 fails, then you know some one else changed the value before you did.
Here is an LDIF of the operation:
If you get an Operation Failed (error 16: “No Such Attribute”), it is because someone else got the number already. Try again.
If you get an Operation Succeeded (error 0), you can safely use the old value from Step 2(a) for your new entry’s uidNumber value.
Performance Considerations when Using the Sun Directory Server Attribute Uniqueness Plugin
There are several severe performance hits when using the Sun Directory Server Attribute Uniqueness Plugin in a Multi-Master Replication topology. (See http://docs.sun.com/source/816-6400-10/attruniq.html#wp19648). Because of this, you should not use the Sun Directory Server Attribute Uniqueness Plugin unless you have a good reason to.
Requires Stable Topology – cannot promote/demote masters with attribute uniqueness plugin enabled.1
Directory Modification Unavailable at Startup - When the attribute value uniqueness plug-in is first enabled, the network of plug-ins must create the table of values for each monitored attribute. Hashing all values of all attributes being monitored for uniqueness and distributing those values requires some time at initialization. During this time, the server will refuse modify operations.2
Severe Modify Performance Degradation - Enforcing attribute value uniqueness in a multi-master topology involves additional communication between servers. Before any update operation can be allowed to proceed, the network of plug-ins must determine if the new value of a given attribute is already used on any of the other masters. The plug-in architecture optimizes this verification procedure, but it may still lead to measurable overhead on update operations. Client operation is blocked during this time.3
Single Point of Failure – If one server goes down, modifications will fail since uniqueness cannot be enforced. You can configure this to just log errors and continue to avoid, so the application can proceed.4
Article by Chris Paul, Seojindsa, Inc.