| Tested on | Rocky Linux 10.2 (Red Quartz) |
|---|---|
| Package | 389-ds-base 3.2.0-8.el10_2 |
| Applies to | RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora |
| Privilege | sudo or root |
| Scope | Configure the 389 Directory Server Distributed Numeric Assignment plug-in for automatic uidNumber and gidNumber allocation, magic regeneration values, separate or shared ranges, multi-supplier range transfer, monitoring, and troubleshooting. |
| Related guides | Install 389 Directory Server Manage users and groups dsconf commands dsidm commands |
POSIX users and groups need numeric uidNumber and gidNumber values. In a growing directory, tracking the next free ID by hand does not scale, and overlapping ranges between suppliers can create collisions. The Distributed Numeric Assignment (DNA) plug-in assigns numbers from administrator-defined ranges when qualifying entries are added or modified.
This guide covers the complete automatic numeric-value allocation workflow in 389 Directory Server:
- Assigning
uidNumberandgidNumber - Scope and entry filters
- Starting and maximum values
- Magic regeneration values
- Managing one or multiple attributes
- Assigning the same or different values to multiple attributes
- Equality indexes with integer ordering matching rules
- Range exhaustion
- Multi-supplier ranges
- Shared range configuration
- Automatic range transfer
- Monitoring and troubleshooting
The DNA plug-in assigns numbers from configured ranges. It does not guarantee uniqueness for manually supplied values. Administrators can still add an explicit number, and the plug-in does not reject it merely because another entry already has that value. Use Attribute Uniqueness where all manual and generated values must be checked.
Before you start:
- Install 389 Directory Server — running instance with a suffix (this lab uses
ldap1ondc=example,dc=com) - Manage users and groups —
ou=People,ou=Groups, and POSIX object classes - dsconf commands — online plug-in configuration
How the DNA plug-in works
When a qualifying entry is added or modified, DNA generates a number when a managed attribute equals dnaMagicRegen. When the configuration manages only one attribute, DNA can also generate the value when that attribute is omitted. For configurations managing multiple attributes, include the magic value on each attribute that should receive a generated number.
dnaMagicRegen when clients may submit explicit numeric values. Without a magic regeneration value, DNA can replace values supplied for managed attributes. With dnaMagicRegen: -1, normal explicit values are preserved and only -1 triggers regeneration.
New posixAccount entry
|
| uidNumber equals dnaMagicRegen
| or omitted when only one attribute is managed
v
DNA plug-in checks:
scope + LDAP filter
|
v
Assigns the next number from the configured range
|
v
Increments dnaNextValue| Setting | Purpose |
|---|---|
dnaType |
Attribute or attributes whose values are generated |
dnaScope |
Directory subtree managed by the configuration |
dnaFilter |
Entry types eligible for number assignment |
dnaNextValue |
Next number available for assignment |
dnaMaxValue |
Upper limit of the current range |
dnaMagicRegen |
Placeholder value that triggers number generation |
dnaNextRange |
Reserve range used after the current range |
dnaSharedCfgDN |
Replicated location containing supplier range information |
dnaThreshold |
Remaining-value threshold that triggers a range request |
dnaRangeRequestTimeout |
Time to wait for a supplier to provide a range |
Compare DNA with Attribute Uniqueness
| Feature | DNA plug-in | Attribute Uniqueness plug-in |
|---|---|---|
| Generates values | Yes | No |
| Manages numeric ranges | Yes | No |
| Rejects manually entered duplicates | No | Yes |
| Coordinates supplier ranges | Yes | No |
| Works with nonnumeric attributes | Limited by attribute syntax | Yes |
The plug-ins complement each other:
DNA generates uidNumber values
+
Attribute Uniqueness rejects manually introduced duplicatesPrepare the directory and POSIX entries
The lab tree under dc=example,dc=com uses dedicated DNA test users so the guide does not disturb existing course accounts:
dc=example,dc=com
├── ou=People
│ └── posixAccount users
└── ou=Groups
└── posixGroup groupsPlanned numeric range for the primary UID lab:
Initial number: 10000
Maximum number: 19999
Magic value: -1The runnable single-server lab manages:
uidNumberLater sections explain alternative configurations that manage gidNumber separately or manage both uidNumber and gidNumber from one shared pool.
The selected range must not overlap:
- Existing LDAP values in the suffix
- Local operating-system accounts on client hosts
- Other identity providers
- Ranges assigned to other suppliers
Do not enable DNA until the proposed range is confirmed safe.
Audit existing UID and GID values
Search current POSIX users under ou=People:
ldapsearch -LLL -x -H ldap://127.0.0.1:389 -D "cn=Directory Manager" -y /root/dm.pw -b "ou=People,dc=example,dc=com" "(uidNumber=*)" dn uid uidNumber gidNumberSample output:
dn: uid=user1,ou=people,dc=example,dc=com
uid: user1
uidNumber: 3001
gidNumber: 3001
dn: uid=user2,ou=people,dc=example,dc=com
uid: user2
uidNumber: 3002
gidNumber: 3002Search current groups under ou=Groups:
ldapsearch -LLL -x -H ldap://127.0.0.1:389 -D "cn=Directory Manager" -y /root/dm.pw -b "ou=Groups,dc=example,dc=com" "(gidNumber=*)" dn cn gidNumberOn this lab host the group search returned no gidNumber values. The displayed user IDs are well below the proposed DNA range beginning at 10000.
Before you enable DNA, identify:
- The highest existing UID and GID
- Duplicate values
- Values inside the proposed DNA range
- Ranges reserved by another supplier or identity system
Create required indexes
The DNA plug-in performs sorted internal searches when checking available values. Every managed attribute needs an equality index configured with its appropriate ordering matching rule in the backend that contains the scoped entries.
Confirm the uidNumber index on userroot:
dsconf ldap1 backend index get userroot --attr uidNumberSample output before adding the ordering rule:
dn: cn=uidnumber,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
cn: uidnumber
nsIndexType: eqIf the index is missing, create equality indexing with integerOrderingMatch and reindex:
dsconf ldap1 backend index add --attr uidNumber --index-type eq --matching-rule integerOrderingMatch --reindex userrootWhen an equality index already exists but lacks the ordering rule, update the index entry and reindex it:
ldapmodify -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket <<'EOF'
dn: cn=uidnumber,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
changetype: modify
replace: nsMatchingRule
nsMatchingRule: integerOrderingMatch
EOFSample output:
modifying entry "cn=uidnumber,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config"Rebuild the index:
dsconf ldap1 backend index reindex --attr uidNumber userrootSample output:
Index task index_attrs_2026-07-17T22:41:28.732248 completed successfully
Successfully reindexed databaseVerify the active index:
dsconf ldap1 backend index get userroot --attr uidNumberSample output:
dn: cn=uidnumber,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config
cn: uidnumber
nsIndexType: eq
nsMatchingRule: integerOrderingMatchRepeat the same check and update for gidNumber. Full index creation and reindexing steps are covered in index design and maintenance.
Keep each DNA configuration scope within one database backend. The plug-in is not designed to manage one range across multiple backends.
Check the current DNA plug-in configuration
Review the plug-in state:
dsconf ldap1 plugin dna showSample output:
dn: cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
cn: Distributed Numeric Assignment Plugin
nsslapd-pluginEnabled: off
nsslapd-pluginInitfunc: dna_init
nsslapd-pluginPath: libdna-plugin
nsslapd-pluginType: bepreoperationList existing DNA configuration entries:
ldapsearch -LLL -Y EXTERNAL -H ldapi://%2Fvar%2Frun%2Fslapd-ldap1.socket -b "cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config" "(objectClass=dnaPluginConfig)" cnOn a fresh instance this search returns no configuration entries. If the search finds an existing configuration, inspect it using the returned cn value:
dsconf ldap1 plugin dna config "EXISTING_CONFIG_NAME" showRecord any existing configurations before you add a new one.
Review these settings before you enable DNA:
dnaType
dnaFilter
dnaScope
dnaNextValue
dnaMaxValue
dnaMagicRegen
dnaNextRange
dnaSharedCfgDN
dnaThresholdConfirm option names on your installed version:
dsconf ldap1 plugin dna config "Account UIDs" add --helpConfigure automatic uidNumber assignment
Create a configuration for POSIX users under ou=People:
dsconf ldap1 plugin dna config "Account UIDs" add --type uidNumber --filter "(objectClass=posixAccount)" --scope "ou=People,dc=example,dc=com" --next-value 10000 --max-value 19999 --magic-regen -1Sample output:
Successfully created the cn=Account UIDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=configEnable the plug-in:
dsconf ldap1 plugin dna enableSample output:
Enabled plugin 'Distributed Numeric Assignment Plugin'Restart the instance so the plug-in loads:
dsctl ldap1 restartConfirm the instance is running:
dsctl ldap1 statusSample output:
Instance "ldap1" is runningVerify the configuration:
dsconf ldap1 plugin dna config "Account UIDs" showSample output:
cn: Account UIDs
dnaFilter: (objectClass=posixAccount)
dnaMagicRegen: -1
dnaMaxValue: 19999
dnaNextValue: 10000
dnaScope: ou=People,dc=example,dc=com
dnaType: uidNumberThe dnaNextValue: 10000 line shows the next UID waiting to be assigned.
Trigger assignment with a magic value
Save the following as /tmp/dna-test1.ldif:
dn: uid=dna-test1,ou=people,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
uid: dna-test1
cn: DNA Test One
sn: One
homeDirectory: /home/dna-test1
uidNumber: -1
gidNumber: 3001Add the entry:
ldapadd -x -H ldap://127.0.0.1:389 -D "cn=Directory Manager" -y /root/dm.pw -f /tmp/dna-test1.ldifSample output:
adding new entry "uid=dna-test1,ou=people,dc=example,dc=com"Verify the assigned number:
ldapsearch -LLL -x -H ldap://127.0.0.1:389 -D "cn=Directory Manager" -y /root/dm.pw -b "uid=dna-test1,ou=people,dc=example,dc=com" -s base uidNumber gidNumberSample output:
dn: uid=dna-test1,ou=people,dc=example,dc=com
uidNumber: 10000
gidNumber: 3001DNA replaced the magic value with 10000. The magic value must sit outside the generated range so it cannot be assigned as a normal ID.
Check that dnaNextValue advanced:
dsconf ldap1 plugin dna config "Account UIDs" show | grep dnaNextValueSample output:
dnaNextValue: 10001Assign a number when the attribute is missing
When the DNA configuration manages only one attribute, you can omit that attribute from a qualifying posixAccount entry. DNA assigns the next value during the add operation. This does not apply when the configuration manages multiple attributes; in that case supply the magic value on each attribute that should be generated.
ldapadd -x -H ldap://127.0.0.1:389 -D "cn=Directory Manager" -y /root/dm.pw <<'EOF'
dn: uid=dna-omit,ou=people,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
uid: dna-omit
cn: DNA Omit Test
sn: Omit
homeDirectory: /home/dna-omit
gidNumber: 3001
EOFSample output:
adding new entry "uid=dna-omit,ou=people,dc=example,dc=com"ldapsearch -LLL -x -H ldap://127.0.0.1:389 -D "cn=Directory Manager" -y /root/dm.pw -b "uid=dna-omit,ou=people,dc=example,dc=com" -s base uidNumberSample output:
dn: uid=dna-omit,ou=people,dc=example,dc=com
uidNumber: 10001Explicitly using the magic value in bulk LDIF templates is usually clearer because it makes the intended DNA behavior visible to operators reviewing the file.
Assign uidNumber and gidNumber from one shared range
Some deployments use one numeric namespace for automatically generated user and group IDs. Configure both managed attributes in one DNA configuration entry:
dsconf ldap1 plugin dna config "POSIX IDs" add \
--type uidNumber gidNumber \
--filter "(|(objectClass=posixAccount)(objectClass=posixGroup))" \
--scope "dc=example,dc=com" \
--next-value 10000 \
--max-value 19999 \
--magic-regen -1Do not run this on the same server as a separate Account UIDs configuration that already manages uidNumber. Use one design per attribute namespace.
When both attributes are requested in one operation with the magic value:
uidNumber: -1
gidNumber: -1the plug-in can assign the same generated number to both attributes on that entry.
uidNumber to the gidNumber of a separate posixGroup entry. Provisioning a matching private group requires a separate workflow, such as the Managed Entries plug-in, that reads the assigned user UID and explicitly uses that value for the group's GID.
Use cases:
- A
posixAccountentry whoseuidNumberand primarygidNumbershould have the same value - One generated number pool shared by
uidNumberandgidNumber - Preventing automatically generated user UIDs from overlapping automatically generated group GIDs
Assign different values with a multi-attribute configuration
This behaviour applies only when one active DNA configuration manages both uidNumber and gidNumber. It does not work with the earlier Account UIDs configuration, which manages only uidNumber.
When multiple managed attributes are supplied in one operation, the plug-in can assign the same generated number to all of them. To allocate different numbers from the same range, trigger DNA separately for each attribute in separate modify operations.
First modify uidNumber with the magic value. Then modify gidNumber with the magic value in a second request. After both operations complete, verify the result:
ldapsearch -LLL -x -H ldap://127.0.0.1:389 -D "cn=Directory Manager" -y /root/dm.pw -b "uid=dna-test1,ou=people,dc=example,dc=com" -s base uidNumber gidNumberExample structure when separate regeneration requests consume separate values from the range:
dn: uid=dna-test1,ou=people,dc=example,dc=com
uidNumber: 10002
gidNumber: 10003DNA can assign one generated value to multiple requested attributes in one operation, or consume separate values when regeneration occurs in separate operations.
Configure separate UID and GID ranges
An alternative design keeps user and group namespaces independent:
Account UIDs:
10000–19999
Group GIDs:
20000–29999Create two DNA configuration entries:
Account UIDs → uidNumber → posixAccount → ou=People
Group GIDs → gidNumber → posixGroup → ou=GroupsExample group configuration:
dsconf ldap1 plugin dna config "Group GIDs" add --type gidNumber --filter "(objectClass=posixGroup)" --scope "ou=Groups,dc=example,dc=com" --next-value 20000 --max-value 29999 --magic-regen -1Sample output:
Successfully created the cn=Group GIDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=configSeparate ranges are preferable when:
- Users and groups use independently managed namespaces
- Existing GIDs already occupy a different range
- Applications require clear separation
- Private-user groups are not used
Compare the shared-pool and separate-range designs before you choose one for production.
| Design | Best when |
|---|---|
| One shared UID/GID pool | Automatically generated user and group IDs must never overlap |
| Separate UID and GID pools | Users and groups have independent namespaces or existing range requirements |
| Matching private-user group | Provisioning explicitly copies the user UID to the separate group GID |
Understand explicitly supplied values
Add an entry with an explicit UID inside the DNA range:
ldapadd -x -H ldap://127.0.0.1:389 -D "cn=Directory Manager" -y /root/dm.pw <<'EOF'
dn: uid=dna-explicit,ou=people,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: posixAccount
uid: dna-explicit
cn: DNA Explicit
sn: Explicit
homeDirectory: /home/dna-explicit
uidNumber: 15000
gidNumber: 3001
EOFSample output:
adding new entry "uid=dna-explicit,ou=people,dc=example,dc=com"ldapsearch -LLL -x -H ldap://127.0.0.1:389 -D "cn=Directory Manager" -y /root/dm.pw -b "uid=dna-explicit,ou=people,dc=example,dc=com" -s base uidNumberSample output:
uidNumber: 15000Because this configuration defines dnaMagicRegen: -1, DNA preserves 15000. Without a configured magic value, explicitly supplied managed values can be replaced. DNA also does not verify that 15000 is unused. A manually assigned number can collide with a generated or existing value. Use Attribute Uniqueness when duplicate rejection is required.
Monitor the current range
Inspect the active configuration:
dsconf ldap1 plugin dna config "Account UIDs" showSample output:
cn: Account UIDs
dnaFilter: (objectClass=posixAccount)
dnaMagicRegen: -1
dnaMaxValue: 19999
dnaNextValue: 10002
dnaScope: ou=People,dc=example,dc=com
dnaType: uidNumberWith dnaMaxValue: 19999 and dnaNextValue: 10002, the remaining values in the current range are:
19999 - 10002 + 1 = 9998Monitor:
dnaNextValue
dnaMaxValue
dnaNextRange
dnaThresholdEstimate remaining values in the current range:
Remaining current values =
dnaMaxValue - dnaNextValue + 1In a multi-supplier deployment, also review the shared range entries:
dnaHostname
dnaPortNum
dnaSecurePortNum
dnaRemainingValuesMonitor remaining capacity before the range reaches the configured threshold.
Handle range exhaustion on one server
On a single supplier, number assignment succeeds until dnaMaxValue. When no next range is available, new qualifying add or modify operations fail. Existing entries remain unchanged.
Before you assign another range:
- Audit existing values.
- Check every supplier's range.
- Confirm the new range is unused.
- Back up the DNA configuration.
- Add or update
dnaNextRange. - Test with a new entry.
Never reset dnaNextValue to a lower value merely to make assignments resume.
Configure DNA in a multi-supplier topology
Before you split the lab into two suppliers, remove the temporary explicit-value test entry:
ldapdelete -x -H ldap://127.0.0.1:389 -D "cn=Directory Manager" -y /root/dm.pw "uid=dna-explicit,ou=people,dc=example,dc=com"That frees 15000 for Supplier 2's starting range. In an existing environment, audit the complete proposed range instead of deleting production entries.
Verify that 15000 is free:
ldapsearch -LLL -x -H ldap://127.0.0.1:389 -D "cn=Directory Manager" -y /root/dm.pw -b "dc=example,dc=com" "(|(uidNumber=15000)(gidNumber=15000))" dn uidNumber gidNumberA successful empty search prints no entries.
Each writable supplier needs:
- A local DNA configuration
- A non-overlapping active range
- The same managed attributes, scope, and filter
- Access to a shared configuration entry
- Replication authentication for range requests
The DNA configuration under cn=plugins,cn=config is local to each supplier and must be created separately. The shared range container belongs in a replicated data suffix so every participating supplier receives the shared range records. DNA suppliers need non-overlapping local ranges and replicated shared range information.
Example layout:
Supplier 1:
Current range 10000–14999
Supplier 2:
Current range 15000–19999
Shared range information:
Stored inside a replicated suffixDirectory Server tracks each supplier's range in replicated shared entries so one supplier can request values from another when its local range is nearly exhausted.
Create the shared range configuration
Save the following as /tmp/dna-ranges.ldif:
dn: ou=Ranges,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
objectClass: extensibleObject
ou: Ranges
dn: cn=Account UIDs,ou=Ranges,dc=example,dc=com
objectClass: top
objectClass: extensibleObject
cn: Account UIDsldapadd -x -H ldap://127.0.0.1:389 -D "cn=Directory Manager" -y /root/dm.pw -f /tmp/dna-ranges.ldifSample output:
adding new entry "ou=Ranges,dc=example,dc=com"
adding new entry "cn=Account UIDs,ou=Ranges,dc=example,dc=com"Configure the first supplier with shared-range settings. Confirm the current range before you lower the maximum:
dsconf ldap1 plugin dna config "Account UIDs" showOnly lower --max-value if dnaNextValue has not already passed the new maximum. Then apply the Supplier 1 multi-supplier settings:
dsconf ldap1 plugin dna config "Account UIDs" set --max-value 14999 --shared-config-entry "cn=Account UIDs,ou=Ranges,dc=example,dc=com" --threshold 500 --range-request-timeout 60Sample output:
Successfully changed the cn=Account UIDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=configVerify Supplier 1 after lowering the maximum:
dsconf ldap1 plugin dna config "Account UIDs" showSample output:
dnaMaxValue: 14999
dnaSharedCfgDN: cn=Account UIDs,ou=Ranges,dc=example,dc=com
dnaThreshold: 500
dnaRangeRequestTimeout: 60Create the Supplier 2 configuration with a non-overlapping range:
dsconf ldap2 plugin dna config "Account UIDs" add --type uidNumber --filter "(objectClass=posixAccount)" --scope "ou=People,dc=example,dc=com" --next-value 15000 --max-value 19999 --magic-regen -1 --shared-config-entry "cn=Account UIDs,ou=Ranges,dc=example,dc=com" --threshold 500 --range-request-timeout 60Enable and verify Supplier 2:
dsconf ldap2 plugin dna enabledsctl ldap2 restartdsctl ldap2 statusSample output:
Instance "ldap2" is runningVerify the Supplier 2 configuration:
dsconf ldap2 plugin dna config "Account UIDs" showWhen ldap2 is running with the same suffix and replicated shared range container, the output should show a non-overlapping range such as:
dnaMaxValue: 19999
dnaNextValue: 15000
dnaSharedCfgDN: cn=Account UIDs,ou=Ranges,dc=example,dc=comThe shared DN must live under a suffix replicated to every participating supplier.
After both suppliers are configured, verify that each server created its automatically maintained dnaSharedConfig child entry:
ldapsearch -LLL -x -H ldap://127.0.0.1:389 -D "cn=Directory Manager" -y /root/dm.pw -b "cn=Account UIDs,ou=Ranges,dc=example,dc=com" "(objectClass=dnaSharedConfig)" dnaHostname dnaPortNum dnaSecurePortNum dnaRemainingValuesExpected structure:
dn: dnaHostname=ldap1.example.com+dnaPortNum=389,cn=Account UIDs,ou=Ranges,dc=example,dc=com
dnaHostname: ldap1.example.com
dnaPortNum: 389
dnaSecurePortNum: 636
dnaRemainingValues: ...
dn: dnaHostname=ldap2.example.com+dnaPortNum=389,cn=Account UIDs,ou=Ranges,dc=example,dc=com
dnaHostname: ldap2.example.com
dnaPortNum: 389
dnaSecurePortNum: 636
dnaRemainingValues: ...Use the actual ports from your topology. Each supplier automatically maintains a child entry under dnaSharedCfgDN, and these entries are what other suppliers use to discover donors and their available capacity.
Understand automatic range transfer
Supplier 1 approaches dnaThreshold
|
v
Reads replicated shared range entries
|
v
Contacts another supplier
|
v
Requests part of its remaining range
|
v
Transferred range becomes Supplier 1's next available range| Setting | Purpose |
|---|---|
dnaThreshold |
Starts the range-request process before exhaustion |
dnaRangeRequestTimeout |
Limits how long one supplier is contacted |
dnaSharedCfgDN |
Provides supplier and remaining-range information |
dnaNextRange |
Stores the transferred reserve range |
DNA range requests use the connection and authentication information associated with replication between the participating suppliers. The requesting supplier must be recognized and authorized by the donor. When the replication agreement uses TLS or certificate authentication, the DNA range request follows that security design. If range transfer fails, verify the replication bind identity, credentials, TLS trust, supplier hostname and ports, and the replicated shared entries.
A donor transfers values from the upper end of its available range. It does not donate its complete remaining range. It retains enough values to continue local allocation, and transfer size is constrained by the available range and threshold.
Use TLS-protected server-to-server connections where your deployment requires them.
Test range transfer safely
Use small lab ranges on two suppliers, for example:
Supplier 1: 10000–10004
Supplier 2: 20000–20020
Threshold: 2Create enough users through Supplier 1 to approach the threshold, then verify:
- Supplier 1 sends a range request
- Supplier 2's remaining range decreases
- Supplier 1 receives a next range
- No duplicate values are generated
- Shared configuration entries update on both suppliers
Do not force a production range to exhaustion merely to demonstrate the feature.
Add or remove a supplier
Before enabling DNA on a new writable supplier:
- Create a local configuration matching the topology.
- Assign a non-overlapping initial range.
- Confirm the shared configuration has replicated.
- Verify connection details and credentials.
- Enable the plug-in.
- Test one user creation through the new supplier.
- Confirm the generated value does not overlap other suppliers.
Before decommissioning a supplier, record its active and next ranges, prevent new writes, and confirm whether unused values will be transferred or recovered manually.
Performance and indexing considerations
DNA uses internal searches to identify available values, so unindexed managed attributes increase add and modify latency.
Monitor:
- Add and modify latency
- Unindexed search messages in the access log
- Size of the managed subtree
- Number of managed attributes
- Range-request delays
- Supplier connectivity
- Write activity during bulk imports
Keep DNA scopes within one backend.
Troubleshoot the DNA plug-in
| Symptom | Likely cause | Fix |
|---|---|---|
uidNumber is not generated |
Plug-in disabled, scope or filter mismatch, magic value not supplied when required, single-attribute omission used with multi-attribute config, range exhausted | Enable plug-in, restart instance, confirm scope, filter, magic value, managed-attribute count, and remaining range |
| Magic value remains unchanged | Supplied value does not exactly match dnaMagicRegen |
Align the client value with the configured magic regeneration value |
| Explicit value replaced unexpectedly | dnaMagicRegen absent or overlaps valid IDs |
Use a dedicated magic value outside every active range |
Assignment fails after dnaMaxValue |
No dnaNextRange or no transferable supplier range |
Add next range or fix shared configuration and supplier connectivity |
| Range transfer times out | Hostname, port, TLS, bind credentials, or replication delay | Review dnaRangeRequestTimeout, shared entry replication, and network path |
| Results differ across suppliers | Mismatched scope, filter, range, or magic value | Compare full configuration and replication status on every supplier |
| User UID collides with a group GID | Separate namespaces without planning | Use one shared UID/GID pool or separate ranges deliberately |
| Bulk import does not assign IDs | Offline database import does not run normal add-operation plug-ins | Include final numeric values in imported LDIF, or perform subsequent LDAP add or modify operations that trigger DNA |
Disable or remove a DNA configuration
Before disabling DNA:
- Record
dnaNextValue,dnaMaxValue, anddnaNextRange. - Stop automated user provisioning that depends on DNA.
- Confirm how new entries will receive numeric IDs.
- Disable the plug-in or delete only the intended configuration.
- Test a controlled user add.
- Preserve range records for possible rollback.
Disable the plug-in:
dsconf ldap1 plugin dna disableSample output:
Disabled plugin 'Distributed Numeric Assignment Plugin'Restart the instance:
dsctl ldap1 restartdsctl ldap1 statusSample output:
Instance "ldap1" is runningDisabling the plug-in retains its configuration and current range state.
Delete one configuration entry:
dsconf ldap1 plugin dna config "Account UIDs" deleteSample output:
Successfully deleted the cn=Account UIDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=configDeleting a configuration removes that allocation definition. Neither disabling the plug-in nor deleting a configuration removes numeric values already assigned to directory entries.
Do not reuse an abandoned range elsewhere until every assigned value has been audited.
What's next
After you complete this guide, continue with:
- Enforce Unique LDAP Attributes in 389 Directory Server — uniqueness rules alongside allocated IDs
- Create a Custom Schema in 389 Directory Server — custom attributes that use DNA values
- Configure Managed Entries and Linked Attributes in 389 Directory Server — derived entries that share identifiers
- Automatically Add Users to Groups with 389 DS Auto Membership — group membership after POSIX account creation
- Configure 389 Directory Server Indexes for Faster LDAP Searches — indexes on attributes populated by DNA
Summary
- Audit existing UID and GID values.
- Create equality indexes with integer ordering matching rules.
- Define the managed attribute, scope, filter, and range.
- Use a magic value outside the valid range.
- Test automatic assignment on new and existing entries.
- Decide whether UID and GID use one shared pool or separate ranges.
- Monitor the next and maximum values.
- Use shared range configuration for multiple writable suppliers.
- Test range transfer before production exhaustion.
- Pair DNA with Attribute Uniqueness when manual duplicates must be rejected.
A basic single-server configuration requires the managed attribute, filter, scope, and next value. Multi-supplier configurations add maximum values, shared configuration, thresholds, request timeouts, and optionally a reserve range.
References
- 389 Directory Server project
- Red Hat Directory Server 13 — Management, configuration, and operations, section 5.3: Assigning and managing unique numeric attribute values
- Red Hat Directory Server — Plug-in implemented server functionality reference
- 389 Directory Server — DNA plug-in design

