5.6. About Dynamically Assigning Unique Number Values

Some entry attributes require having a unique number, such as uidNumber and gidNumber. The Directory Server can automatically generate and supply unique numbers for specified attributes using the Distributed Numeric Assignment (DNA) Plug-in.
Many situations require a unique numeric attribute, such as UID/GID numbers or PIN numbers. The server uses DNA Plug-in instances to specify the attributes for which to generate the numbers, so whenever that attribute is added to an entry, the unique value can be assigned.

Note

Attribute uniqueness is not necessarily preserved with the DNA Plug-in. The plug-in only assigns non-overlapping ranges, but it does allow manually-assigned numbers for its managed attributes, and it does not verify or require that the manually-assigned numbers are unique.

5.6.1. How the Directory Server Manages Unique Numbers

The issue with assigning unique numbers is not with generating the numbers but in effectively managing numbers so that there are not any conflicts with other assigned numbers when entries are replicated and that every server has a sufficient range of numbers to assign.
The DNA Plug-in for a server assigns a range of available numbers that that instance can issue. The range definition is very simple and is set by two attributes: the server's next available number (the low end of the range) and its maximum value (the top end of the range). The initial bottom range is set when the plug-in instance is configured. After that, the bottom value is updated by the plug-in. By breaking the available numbers into ranges, the servers can all continually assign numbers without overlapping with each other.
The server performs a sorted search, internally, to see if the next specified range is already taken, requiring the managed attribute to have an equality index with the proper ordering matching rule.
For multi-master replication, each supplier can be configured with a threshold, so that when it begins running out of numbers in its range, it can request additional ranges from other suppliers. Each supplier keeps a track of its current range in a separate configuration entry. The configuration entry is replicated to all of the other suppliers, so each supplier can check that configuration to find a server to contact for a new range.
The range set on the individual servers and the range configuration entries are how the Directory Server distributes numbers efficiently for entries.
The DNA Plug-in can assign unique numbers to a single attribute type or across multiple attribute types from a single range of unique numbers.
This provides several options for assigning unique numbers to attributes:
  • A single number assigned to a single attribute type from a single range of unique numbers.
  • The same unique number assigned to two attributes for a single entry.
  • Two different attributes assigned two different numbers from the same range of unique numbers.
In many cases, it is sufficient to have a unique number assigned per attribute type. When assigning an employeeID to a new employee entry, it is important each employee entry is assigned a unique employeeID.
However, there are cases where it may be useful to assign unique numbers from the same range of numbers to multiple attributes. For example, when assigning a uidNumber and a gidNumber to a posixAccount entry, the DNA Plug-in can be configured to assign the same number to both attributes.
The DNA Plug-in is applied, always, to a specific area of the directory tree (the scope) and to specific entry types within that subtree (the filter).
Frequently, entirely different users are stored in different branches of the directory tree. For example, a hosting service may have one clients' users in the ou=Example Corp. branch and another clients' users in the ou=Acme Company branch. In this case, the assigned numbers have to be unique within the subtree but not necessarily across the entire directory. In this case, it is all right for Barbara Jensen in the ou=Example Corp. branch to have uidNumber:5 in her entry and for John Smith in the ou=Acme Company branch to have uidNumber:5 in his entry, because these are separate organizations. Applying ranges to a specific subtree is set in the DNA scope, such as dnaScope: ou=people,dc=example,dc=com.
The unique number can also be distinguished between ranges by using a prefix to identify the different kinds of user entries. For example, if the DNA prefix is set to acme, then the unique numbers in the Acme Company branch have acme in front of the number, like uid: acme5.

5.6.2. Using DNA to Assign Values to Attributes

There are several different ways that the Directory Server can handle generating attribute values.
In the simplest case, a user entry is added to the directory with an object class which requires the unique-number attribute, but without the attribute. Adding (or requiring) the managed attribute without a value triggers the DNA Plug-in to assign a value. When an entry is added, the plug-in checks whether the entry matches the defined range according to the scope and filter set for the plug-in. If the entry matches the range and the attribute that DNA is managing for that range is missing from the entry being added, then the DNA Plug-in assigns the next value. This option only works if the DNA Plug-in has been configured to assign unique values to a single attribute.
For example, the posixAccount object class requires the uidNumber attribute. If the uidNumber attribute is managed by the DNA Plug-in and a user entry is added without the uidNumber attribute within the scope of the filter, then the server checks the new entry, sees that it needs the managed uidNumber attribute, and adds the attribute with an automatically assigned value.
 ldapmodify -a -D "cn=directory manager" -W -p 389 -h server.example.com -x

 dn: uid=jsmith,ou=people,dc=example,dc=com
 objectClass: top
 objectClass: person
 objectClass: posixAccount    
 uid: jsmith
 cn: John Smith
 ....
The plug-in processes the missing attribute, asks for the next available number from the server, and supplies the value for the entry.
A similar and more manageable option is to use a magic number. This magic number is a template value for the managed attribute, something outside the server's range, a number or even a word, that the plug-in recognizes it needs to replace with a new assigned value. When an entry is added with that number, and the entry is within the scope and filter of the configured DNA Plug-in, then using the magic number automatically triggers the plug-in to generate a new value.
When the DNA Plug-in has been configured to assign the same unique number to both a uidNumber and a gidNumber to a posixAccount entry, the DNA Plug-in will assign the same number to both attributes. To do this, then pass both managed attributes to the modify operation, specifying the magic number. For example:
 ldapmodify -a -D "cn=directory manager" -W -p 389 -h server.example.com -x

 dn: uid=jsmith,ou=people,dc=example,dc=com
 objectClass: top
 objectClass: person
 objectClass: posixAccount
 uid: jsmith
 cn: John Smith
 uidNumber: magic    
 gidNumber: magic    
 ....
The magic number is very useful for importing entries from LDIF or for triggering the DNA Plug-in to generate unique numbers for several different attributes.
The DNA Plug-in only generates new, unique values. If an entry is added or modified to use a specific value for an attribute controlled by the DNA Plug-in, the specified number is used; the DNA Plug-in will not overwrite it.

Note

Attribute uniqueness is not necessarily preserved with the DNA Plug-in. The plug-in only assigns non-overlapping ranges, but it does allow manually-assigned numbers for its managed attributes, and it does not verify or require that the manually-assigned numbers are unique.

5.6.3. Using the DNA Plug-in with Replication

With multi-master replication, there are two entries referenced by the server:
  • The managed ranges for the DNA Plug-in
  • A shared configuration entry which stores the information about the server's available ranges
When the plug-in instance is created, then the DNA Plug-in automatically creates an entry beneath the shared configuration entry with the supplier configuration. For example:
dn: dnaHostname=ldap1.example.com+dnaPortNum=389,cn=Account UIDs,ou=Ranges,dc=example,dc=com
objectClass: extensibleObject
objectClass: top
dnahostname: ldap1.example.com
dnaPortNum: 389
dnaSecurePortNum: 636
dnaRemainingValues: 1000
When a server needs a new range of numbers, it searches the configuration entries under the container entry. When it finds the server with the highest available range, it sends an extended operation request to have part of the range assigned to it. If the second server agrees, the second server sends the requesting server the new range assignment.