7.4. Assigning and Managing Unique Numeric Attribute 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.

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.
The issue with assigning unique numbers is not with generating the numbers but in effectively avoiding replication conflicts. The DNA Plug-in assigns unique numbers across a single back end. For multi-master replication, when each master is running a local DNA Plug-in instance, there has to be a way to ensure that each instance is using a truly unique set of numbers. This is done by assigning different ranges of numbers to each server to assign.

7.4.1. About Dynamic Number Assignments

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 separate ranges on each replica, the servers can all continually assign numbers without overlapping with each other.

7.4.1.2. Ranges and Assigning Numbers

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 present. Adding an entry with no value for the managed attribute triggers the DNA Plug-in to assign a value. This option only works if the DNA Plug-in has been configured to assign unique values to a single attribute.
  • 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 the magic value 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. The following example, based on using ldapmodify, adds 0 as a magic number:
    dn: uid=jsmith,ou=people,dc=example,dc=com
     changetype: add
     objectClass: top
     objectClass: person
     objectClass: posixAccount
     uid: jsmith
     cn: John Smith
     uidNumber: 0
     gidNumber: 0
     ....
    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.

7.4.1.3. Multiple Attributes in the Same Range

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 will assign the same number to both attributes. To do this, then pass both managed attributes to the modify operation, specifying the magic value. Using ldapmodify:
#  ldapmodify -D "cn=Directory Manager" -W -x

dn: uid=jsmith,ou=people,dc=example,dc=com
changetype: modify
add: uidNumber
uidNumber: 0
-
add:gidNumber
gidNumber: 0
When multiple attributes are handled by the DNA Plug-in, the plug-in can assign a unique value to only one of those attributes if the object class only allows one of them. For example, the posixGroup object class does not allow a uidNumber attribute but it does allow gidNumber. If the DNA Plug-in manages both uidNumber and gidNumber, then when a posixGroup entry is created, a unique number for gidNumber is assigned from the same range as the uidNumber and gidNumber attributes. Using the same pool for all attributes manged by the plug-in keeps the assignment of unique numbers aligned and prevents situations where a uidNumber and a gidNumber on different entries are assigned from different ranges and result in the same unique number.
If multiple attributes are handled by the DNA Plug-in, then the same value will be assigned to all of the given managed attributes in an entry in a single modify operation. To assign different numbers from the same range, then you must perform separate modify operations. The following example uses ldapmodify to do so:
# ldapmodify -D "cn=Directory Manager" -W -x
dn: uid=jsmith,ou=people,dc=example,dc=com
changetype: modify
add: uidNumber
uidNumber: 0
^D

# ldapmodify -D "cn=Directory Manager" -W -x
dn: uid=jsmith,ou=people,dc=example,dc=com
changetype: modify
add: employeeId
employeeId: magic

Important

When the DNA Plug-in is configured to assign unique numbers to multiple attributes, it is necessary to specify the magic value for each attribute that requires the unique number. While this is not necessary when the DNA plug-in has been configured to provide unique numbers for a single attribute, it is necessary for multiple attributes. There may be instances where an entry does not allow each type of attribute defined for the range, or, more important, an entry allow all of the attributes types defined, but only a subset of the attributes require the unique value.

Example 7.7. DNA and Unique Bank Account Numbers

Example Bank wants to use the same unique number for a customer's primaryAccount and customerID attributes. The Example Bank administrator configured the DNA Plug-in to assign unique values for both attributes from the same range.
The bank also wants to assign numbers for secondary accounts from the same range as the customer ID and primary account numbers, but these numbers cannot be the same as the primary account numbers. The Example Bank administrator configures the DNA Plug-in to also manage the secondaryAccount attribute, but will only add the secondaryAccount attribute to an entry after the entry is created and the primaryAccount and customerID attributes are assigned. This ensures that primaryAccount and customerID share the same unique number, and any secondaryAccount numbers are entirely unique but still from the same range of numbers.

7.4.2. Looking at the DNA Plug-in Syntax

The DNA Plug-in itself is a container entry, similar to the Password Storage Schemes Plug-in. Each DNA entry underneath the DNA Plug-in entry defines a new managed range for the DNA Plug-in.
To set new managed ranges for the DNA Plug-in, create entries beneath the container entry.
The most basic configuration is to set up distributed numeric assignments on a single server, meaning the ranges will not be shared or transferred between servers. A basic DNA configuration entry defines four things:
  • The attribute that value is being managed, set in the dnaType attribute
  • The entry DN to use as the base to search for entries, set in the dnaScope attribute
  • The search filter to use to identify entries to manage, set in the dnaFilter attribute
  • The next available value to assign, set in the dnaNextValue attribute (after the entry is created, this is handled by the plug-in)
For a list of attributes supported in the cn=DNA_config_entry,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config entry, see the Red Hat Directory Server Configuration, Command, and File Reference.
To configure distributed numeric assignment on a single server for a single attribute type:
dn: cn=Account UIDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
objectClass: top
objectClass: dnaPluginConfig
cn: Account UIDs
dnatype: uidNumber
dnafilter: (objectclass=posixAccount)
dnascope: ou=people,dc=example,dc=com
dnaNextValue: 1
If multiple suppliers are configured for distributed numeric assignments, then the entry must contain the required information to transfer ranges:
  • The maximum number that the server can assign; this sets the upward bound for the range, which is logically required when multiple servers are assigning numbers. This is set in the dnaMaxValue attribute.
  • The threshold where the range is low enough to trigger a range transfer, set in the dnaThreshold attribute. If this is not set, the default value is 1.
  • A timeout period so that the server does not hang waiting for a transfer, set in the dnaRangeRequestTimeout attribute. If this is not set, the default value is 10, meaning 10 seconds.
  • A configuration entry DN which is shared among all supplier servers, which stores the range information for each supplier, set in the dnaSharedCfgDN attribute.
The specific number range which could be assigned by the server is defined in the dnaNextRange attribute. This shows the next available range for transfer and is managed automatically by the plug-in, as ranges are assigned or used by the server. This range is just "on deck." It has not yet been assigned to another server and is still available for its local Directory Server to use.
dn: cn=Account UIDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
objectClass: top
objectClass: dnaPluginConfig
cn: Account UIDs
dnatype: uidNumber
dnafilter: (objectclass=posixAccount)
dnascope: ou=People,dc=example,dc=com
dnanextvalue: 1
dnaMaxValue: 1300
dnasharedcfgdn: cn=Account UIDs,ou=Ranges,dc=example,dc=com
dnathreshold: 100
dnaRangeRequestTimeout: 60
dnaNextRange: 1301-2301
The dnaNextRange attribute should be set explicitly only if a separate, specific range has to be assigned to other servers. Any range set in the dnaNextRange attribute must be unique from the available range for the other servers to avoid duplication. If there is no request from the other servers and the server where dnaNextRange is set explicitly has reached its set dnaMaxValue, the next set of values (part of the dnaNextRange) is allocated from this deck.
The dnaNextRange allocation is also limited by the dnaThreshold attribute that is set in the DNA configuration. Any range allocated to another server for dnaNextRange cannot violate the threshold for the server, even if the range is available on the deck of dnaNextRange.

Note

If the dnaNextRange attribute is handled internally if it is not set explicitly. When it is handled automatically, the dnaMaxValue attribute serves as upper limit for the next range.
Each supplier keeps a track of its current range in a separate configuration entry which contains information about its range and its connection settings. This entry is a child of the location in dnasharedcfgdn. 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. For example:
dn: dnaHostname=ldap1.example.com+dnaPortNum=389,cn=Account UIDs,ou=Ranges,dc=example,dc=com
objectClass: dnaSharedConfig
objectClass: top
dnahostname: ldap1.example.com
dnaPortNum: 389
dnaSecurePortNum: 636
dnaRemainingValues: 1000

7.4.3. Configuring Unique Number Assignments

The unique number distribution is configured by creating different instances of the DNA Plug-in. These DNA Plug-in instances can only be created through the command line, but they can be edited through the Directory Server Console.

7.4.3.1. Configuring Unique Number Assignments

Note

Any attribute which has a unique number assigned to it must have an equality index set for it. The server must perform a sorted search, internally, to see if the dnaNextvalue is already taken, which requires an equality index on an integer attribute, with the proper ordering matching rule.
Creating indexes is described in Section 13.2, “Creating Standard Indexes”.

Note

Set up the DNA Plug-in on every supplier server, and be careful not to overlap the number range values.
  1. Create the shared container entry in the replicated subtree. The following example uses ldapmodify to do so:
    dn: ou=Ranges,dc=example,dc=coma
    changetype: add
    objectclass: top
    objectclass: extensibleObject
    objectclass: organizationalUnit
    ou: Ranges
    
    
    dn: cn=Account UIDs,ou=Ranges,dc=example,dc=coma
    changetype: add
    objectclass: top
    objectclass: extensibleObject
    cn: Account UIDs
  2. Enable the DNA Plug-in and configure it as dynamic. By default, the plug-in entry (which is the container entry) is disabled. For details on configuring dynamic plug-ins, see Section 1.9.1, “Enabling Plug-ins Dynamically”.
  3. Create the new DNA Plug-in instance beneath the container entry. For example:

    Note

    The plug-in attribute which sets which entry attributes have unique number assignments, dnaType, is multi-valued. If multiple attributes are set in the same plug-in instance, then their number assignments are taken from the same range. To use different ranges, configure different plug-in instances.
    Using ldapmodify:
    dn: cn=Account UIDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
    changetype: add
    objectClass: top
    objectClass: dnaPluginConfig
    cn: Account UIDs
    dnatype: uidNumber
    dnafilter: (objectclass=posixAccount)
    dnascope: ou=People,dc=example,dc=com
    dnanextvalue: 1
    dnaMaxValue: 1300
    dnasharedcfgdn: cn=Account UIDs,ou=Ranges,dc=example,dc=com
    dnathreshold: 100
    dnaRangeRequestTimeout: 60
    dnaMagicRegen: magic
    For a list of attributes supported in the cn=DNA_config_entry,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config entry, see the Red Hat Directory Server Configuration, Command, and File Reference.
  4. For servers in multi-master replication, create a configuration entry for the host, which specifies its connection information and range.
    The DN of the entry is a combination of the host name and the port number (dnaHostname+dnaPortNum).
    Using ldapmodify:
    dn: dnaHostname=ldap1.example.com+dnaPortNum=389,cn=Account UIDs,ou=Ranges,dc=example,dc=com
    changetype: add
    objectClass: dnaSharedConfig
    objectClass: top
    dnahostname: ldap1.example.com
    dnaPortNum: 389
    dnaSecurePortNum: 636
    dnaRemainingValues: 1000
  5. If the server is not configured to enable dynamic plug-in, restart the server to load the new plug-in instance.
    # systemctl restart dirsrv@instance

7.4.3.2. Editing the DNA Plug-in in the Console

Note

Any attribute which has a unique number assigned to it must have an equality index set for it. The server must perform a sorted search, internally, to see if the dnaNextvalue is already taken, which requires an equality index on an integer attribute, with the proper ordering matching rule.
Creating indexes is described in Section 13.2, “Creating Standard Indexes”.
The Directory Server Console can be used to edit the DNA Plug-in instances.
  1. Click the Directory tab.
  2. Open the config folder, and then expand the plugins folder.
  3. Click the Distributed Numeric Assignment plug-in folder. All of the DNA Plug-in instances are listed in the main window.
  4. Highlight the DNA instance entry, and right-click on the Advanced link to open the property editor.
  5. Edit the DNA-related attributes.

7.4.4. Distributed Number Assignment Plug-in Performance Notes

There can be thread locking issues as DNA configuration is changed dynamically, so that new operations which access the DNA configuration (such as a DNA task or additional changes to the DNA configuration) will access the old configuration because the thread with the new configuration has not yet been released. This can cause operations to use old configuration or simply cause operations to hang.
To avoid this, preserve an interval between dynamic DNA configuration changes of 35 seconds. This means have a sleep or delay between both DNA configuration changes and any directory entry changes which would trigger a DNA plug-in operation.