LDAP simple binds compare the password a user supplies against the value stored in userPassword. For one-way storage schemes, Directory Server does not retain a decryptable copy of the original password. Instead it applies a configured scheme, stores an encoded result, and verifies future binds against that value. Reversible or clear-text schemes such as CLEAR or AES behave differently and must not be treated as equivalent to one-way hashing.
This guide explains supported schemes, how to inspect prefixes safely, how to change the global or local policy, what happens to existing hashes, how password hash rewrite after bind works, and how to test applications, replicas, and FIPS-related deployments. Password complexity, history, expiration, grace logins, and lockout belong in password policy. That topic is not covered here.
Before you start:
- Manage users and groups — create test users and reset passwords
- dsconf commands — online configuration including
pwpolicy - TLS, STARTTLS, and LDAPS — secure administrative LDAP access
- Enable and verify FIPS mode — host and NSS FIPS prerequisites
Tested on: Rocky Linux 10.2; 389 Directory Server 3.2.0.
The primary lab uses instance ldap1 on ldap1.example.com with suffix dc=example,dc=com, LDAP port 389, and LDAPS port 636.
How password storage works in 389 Directory Server
When a client sets or changes a password with clear text over a protected connection, Directory Server hashes the supplied value and writes the result to userPassword. Privileged or explicitly enabled workflows can instead store a pre-hashed {SCHEME} value. Later binds hash the supplied password the same way and compare the result to the stored value.
User submits a password
|
v
Directory Server applies the configured storage scheme
|
v
Encoded value is stored in userPassword
|
v
Future binds verify the supplied password against that valueOne-way schemes do not store a decryptable copy of the original password. If an attacker obtains a hashed value, they must guess passwords and run the same scheme to test each guess. Reversible schemes such as AES and clear-text storage such as CLEAR do not provide the same protection model.
Directory Server stores one-way results with a scheme prefix:
{SCHEME}encoded-valueExamples of prefixes you may see during an audit:
{PBKDF2-SHA512}...
{SSHA512}...
{SSHA}...Never publish complete production userPassword values in tickets, logs, or documentation. Inspect prefixes only.
Supported password storage schemes
List the schemes your installed instance actually exposes before you plan a change:
dsconf ldap1 pwpolicy list-schemesSample output on the tested host:
AES
CLEAR
CRYPT
CRYPT-MD5
CRYPT-SHA256
CRYPT-SHA512
CRYPT-YESCRYPT
GOST_YESCRYPT
MD5
NS-MTA-MD5
PBKDF2
PBKDF2-SHA1
PBKDF2-SHA256
PBKDF2-SHA512
PBKDF2_SHA256
SHA
SHA256
SHA384
SHA512
SMD5
SSHA
SSHA256
SSHA384
SSHA512The exact plug-in names on your build may differ. For example, PBKDF2_SHA256 is distinct from PBKDF2-SHA256. Use the names returned by list-schemes when you set policy.
| Classification | Examples | Guidance |
|---|---|---|
| Preferred default | PBKDF2-SHA512 |
Use for new deployments unless compatibility testing requires otherwise |
| Strong compatibility option | SSHA512 |
Use only when an integration cannot handle PBKDF2 |
| Other supported schemes | PBKDF2_SHA256, PBKDF2-SHA256, PBKDF2-SHA1 |
Supported does not mean equally recommended |
| Legacy one-way schemes | SSHA, SHA, SMD5, MD5, CRYPT variants |
Migration or confirmed compatibility only |
| Reversible or clear storage | AES, CLEAR where present |
Not equivalent to one-way password hashing; avoid for normal LDAP user passwords |
Salt prevents identical passwords from producing identical stored values. Iterative schemes such as PBKDF2 increase the work required to test guessed passwords. Unsalted and legacy schemes should not be selected for new deployments. CLEAR exposes the actual password to anyone who can read userPassword.
Red Hat Directory Server documents PBKDF2 as its strongest supported storage-scheme family, with PBKDF2-SHA512 as the default.
Check the current password storage scheme
Read the global password policy first. On the Directory Server host you can call dsconf with the instance name alone:
dsconf ldap1 pwpolicy getSample output:
Global Password Policy: cn=config
------------------------------------
passwordstoragescheme: PBKDF2-SHA512
passwordchange: on
passwordhistory: off
passwordlockout: offThe passwordstoragescheme line shows which scheme Directory Server uses for newly stored user passwords under the global policy only.
When you administer the instance remotely, connect over LDAPS and pass the Directory Manager password from a protected file. Point OpenLDAP client tools at the instance CA certificate first:
export LDAPTLS_CACERT=/root/ldap1-ca-chain.pemRun dsconf over LDAPS with that trust file in place:
dsconf -D "cn=Directory Manager" -y /root/ldap1-dm.pw ldaps://ldap1.example.com:636 pwpolicy getYou can also inspect the underlying cn=config entry with an authenticated ldapsearch command:
ldapsearch -x -H ldaps://ldap1.example.com:636 -D "cn=Directory Manager" -y /root/ldap1-dm.pw -b "cn=config" -s base passwordStorageSchemeSample output:
dn: cn=config
passwordStorageScheme: PBKDF2-SHA512That confirms the same global value the pwpolicy interface reports. It does not prove which scheme applies to a particular user.
Determine the effective policy for a user or subtree
Directory Server checks user-level policies first, then parent-subtree policies, and finally the global policy. A subtree or user-level policy can supersede the global scheme when fine-grained local policies are enabled.
Check whether fine-grained local password policies are enabled:
dsconf ldap1 pwpolicy get | grep -i nsslapd-pwpolicy-localSample output on the tested host:
nsslapd-pwpolicy-local: offYou can also read the switch directly:
dsconf -D "cn=Directory Manager" -y /root/ldap1-dm.pw ldap1 config get nsslapd-pwpolicy-localWhen nsslapd-pwpolicy-local is off, user and subtree policies are ignored and the global policy is enforced.
When nsslapd-pwpolicy-local is on, list local policies:
dsconf ldap1 localpwp listFor each returned policy DN, inspect the effective settings:
dsconf ldap1 localpwp get "uid=user1,ou=people,dc=example,dc=com"If no local policy applies to that entry, the command reports that no password policy was found and the global policy remains in effect.
Read password policy for full local-policy creation and management.
Understand the default PBKDF2-SHA512 scheme
Directory Server 12 and 13 use PBKDF2-SHA512 as the default scheme for newly stored user passwords.
PBKDF2 is preferable to older SHA-based schemes because it applies salting and repeated iterations, which increases the cost of offline guessing. The exact iteration count is managed by Directory Server for the installed version; treat it as an implementation detail and verify behaviour on your target release rather than hard-coding numbers from another version.
Applications should authenticate with LDAP binds and let Directory Server verify passwords. If an external program retrieves userPassword and checks the hash itself, it must understand the stored prefix. That is a common reason to keep a legacy scheme temporarily during migration.
Check the scheme used by existing users
Audit scheme prefixes without printing complete userPassword values. The pipeline below uses -LLL, disables LDIF wrapping, and extracts only the {SCHEME} prefix. Export the CA path for LDAPS first:
export LDAPTLS_CACERT=/root/ldap1-ca-chain.pemRun the prefix audit against ou=people:
ldapsearch -LLL -o ldif-wrap=no -x -H ldaps://ldap1.example.com:636 -D "cn=Directory Manager" -y /root/ldap1-dm.pw -b "ou=people,dc=example,dc=com" "(uid=*)" uid userPassword | python3 -c '
import base64
import re
import sys
for block in sys.stdin.read().strip().split("\n\n"):
uid = ""
passwords = []
for line in block.splitlines():
if line.startswith("uid: "):
uid = line.partition(": ")[2]
elif line.startswith("userPassword:: "):
encoded = line.partition(":: ")[2]
try:
passwords.append(
base64.b64decode(encoded).decode("utf-8", "replace")
)
except Exception:
pass
elif line.startswith("userPassword: "):
passwords.append(line.partition(": ")[2])
for value in passwords:
match = re.match(r"\{[^}]+\}", value)
if uid and match:
print(uid, match.group())
'Sample output:
user1 {PBKDF2-SHA512}
user2 {PBKDF2-SHA512}Each line lists a uid and the scheme prefix only. Access to userPassword should be tightly restricted, and prefix-only output is still sensitive enough to protect in logs and tickets.
Pre-hashed passwords and normal password writes
Normal LDAP add and modify operations should submit a clear-text password over LDAPS or STARTTLS and let Directory Server apply the effective policy. That is not universally true for every write path.
Directory Manager can set pre-hashed values, and nsslapd-allow-hashed-passwords controls whether other authorized users may submit them:
dsconf -D "cn=Directory Manager" -y /root/ldap1-dm.pw ldap1 config get nsslapd-allow-hashed-passwordsSample output:
nsslapd-allow-hashed-passwords: offWith the default off, non-Directory Manager users cannot supply values that are already prefixed with {SCHEME}. A value already prefixed with {SCHEME} is treated as pre-hashed in privileged or explicitly enabled workflows. Delegating pre-hashed-password writes can bypass normal hashing and some policy expectations.
LDIF migration files that contain hashes must preserve exact prefixes and encoding. Audit imported hashes after migration rather than assuming they match the new global scheme. For normal add and modify operations, submit the clear-text password only over LDAPS or over LDAP port 389 with STARTTLS, and let Directory Server hash it using the effective password policy. Red Hat requires encrypted connections when transmitting Directory Manager password material; apply the same principle to normal user-password changes.
Change the global password storage scheme
Set the preferred scheme through the password-policy interface:
dsconf ldap1 pwpolicy set --pwdscheme PBKDF2-SHA512Sample output:
Successfully updated global password policyVerify the change:
dsconf ldap1 pwpolicy getSample output:
passwordstoragescheme: PBKDF2-SHA512The change affects passwords stored after the policy update. It does not instantly rewrite every existing userPassword value.
Confirm the exact scheme names your build accepts before you script the change:
dsconf ldap1 pwpolicy set --helpSample output:
--pwdscheme PWDSCHEME
The password storage schemeTest the workflow on a disposable account:
- Create a test user with dsidm.
- Set a password with
dsidm ldap1 account reset_password. - Inspect only the stored scheme prefix.
- Authenticate as the test user with
ldapwhoami.
Delete the test user when you finish.
Configure a different scheme for a subtree or user
Local password policies can define a storage scheme that differs from the global policy. Typical reasons include temporary application compatibility, a staged migration, or a limited legacy subtree.
Use cases belong here. The full localpwp creation workflow is covered in password policy. When local policies are enabled, list them with:
dsconf ldap1 localpwp listRunning several schemes permanently increases operational complexity. Keep a non-default scheme only when a tested integration requires it, and document the exception until you remove it.
Existing password hashes and migration
Changing the configured scheme does not require knowing users' clear-text passwords.
Existing users continue to authenticate with their current stored hashes as long as Directory Server still supports those prefixes. A password is stored with the newly configured scheme when:
- A user changes the password
- An administrator resets the password
- A new user password is created
- Directory Server rewrites the hash after a successful simple bind while
nsslapd-enable-upgrade-hashis enabled
There is no safe offline conversion from one one-way hash to another without the original password.
Use a staged migration workflow:
- Set the preferred storage scheme.
- Confirm new passwords use it.
- Keep password hash rewrite on bind enabled unless a verified integration requires otherwise.
- Let active users migrate through successful authentication.
- Reset passwords for accounts that do not log in during the migration window.
- Audit remaining legacy prefixes.
- Remove legacy compatibility only after verification.
The lab demonstrated this behaviour on ldap1. After temporarily setting the global scheme to SSHA512, a new test user stored {SSHA512} while an older account keeps its existing prefix until its password is changed or reset, or until a successful simple bind causes an eligible rewrite while nsslapd-enable-upgrade-hash is enabled. A narrow local compatibility policy is safer than temporarily weakening the global scheme for all users.
Password hash rewrite after bind
Check whether Directory Server may rewrite stored hashes after a successful simple bind:
dsconf -D "cn=Directory Manager" -y /root/ldap1-dm.pw ldap1 config get nsslapd-enable-upgrade-hashSample output:
nsslapd-enable-upgrade-hash: onWhen the setting is on, Directory Server can rewrite an eligible stored hash to the scheme currently configured by the applicable policy after a successful simple bind, because it temporarily holds the supplied clear-text password. That rewrite can move a hash to a stronger scheme or to a weaker one if you changed policy for compatibility. Not every stored scheme is eligible.
Check which schemes are excluded from rewrite-on-bind:
dsconf -D "cn=Directory Manager" -y /root/ldap1-dm.pw ldap1 config get nsslapd-scheme-list-no-upgrade-hashSample output:
nsslapd-scheme-list-no-upgrade-hash: CRYPT,CLEARPasswords stored with an excluded scheme are not rewritten after a successful bind even when nsslapd-enable-upgrade-hash is enabled. Those accounts require a password reset, a policy-approved migration path, or removal from the exclusion list after compatibility testing.
Before you temporarily set a weaker global scheme, disable rewrite-on-bind so existing PBKDF2-SHA512 passwords are not downgraded during login:
dsconf -D "cn=Directory Manager" -y /root/ldap1-dm.pw ldap1 config replace nsslapd-enable-upgrade-hash=offAfter you restore the preferred scheme:
dsconf ldap1 pwpolicy set --pwdscheme PBKDF2-SHA512Re-enable hash rewrite so successful binds can migrate eligible passwords again:
dsconf -D "cn=Directory Manager" -y /root/ldap1-dm.pw ldap1 config replace nsslapd-enable-upgrade-hash=onTo preserve a legacy hash format for an integration that reads userPassword directly, leave rewrite disabled until that integration no longer needs the legacy prefix.
On the tested host, a user created under SSHA512 kept the {SSHA512} prefix after a successful bind while rewrite was disabled. With rewrite enabled and the global scheme set back to PBKDF2-SHA512, the same account migrated to {PBKDF2-SHA512} after the next successful bind.
Configure the Directory Manager storage scheme
Normal user passwords and the Directory Manager password use separate settings.
| Setting | Purpose |
|---|---|
passwordStorageScheme in password policy |
Hashes normal users' userPassword values |
nsslapd-rootpwstoragescheme |
Hashes the Directory Manager password |
nsslapd-rootpw |
Stores the Directory Manager password hash |
Inspect the Directory Manager scheme:
dsconf -D "cn=Directory Manager" -y /root/ldap1-dm.pw ldap1 config get nsslapd-rootpwstorageschemeSample output:
nsslapd-rootpwstoragescheme: PBKDF2-SHA512Set the scheme Directory Server should use for future Directory Manager password processing:
dsconf -D "cn=Directory Manager" -y /root/ldap1-dm.pw ldap1 config replace nsslapd-rootpwstoragescheme=PBKDF2-SHA512Changing nsslapd-rootpwstoragescheme does not rehash the existing Directory Manager password. It controls how a future plain-text nsslapd-rootpw value or pwdhash -D operation is processed. Change the Directory Manager password over an encrypted connection to store it with the new scheme.
Illustrative LDAPS example. Replace the placeholder with your approved secret-handling method. Trust the server CA before you connect:
export LDAPTLS_CACERT=/root/ldap1-ca-chain.pemSet the new Directory Manager password over LDAPS:
dsconf -D "cn=Directory Manager" -y /root/ldap1-dm.pw ldaps://ldap1.example.com:636 config replace nsslapd-rootpw='NEW_DIRECTORY_MANAGER_PASSWORD'Directory Server stores the supplied value using the scheme configured in nsslapd-rootpwstoragescheme. Do not publish a production password in documentation, tickets, or shell history. The -y option protects the existing Directory Manager bind password only. The new password shown in this example is still a command-line argument. Use the Directory Server web console or a temporary root-readable LDIF file submitted over LDAPS when the new secret must not appear in shell history.
Do not use curly braces in a plain-text Directory Manager password supplied through nsslapd-rootpw. Directory Server interprets text inside braces as a password-storage-scheme prefix, which can make the Directory Manager unable to bind.
Generate a disposable test hash with the instance configuration. The password below is for lab use only; command-line arguments can appear in shell history and process listings:
pwdhash -D /etc/dirsrv/slapd-ldap1 'temporary-test-password'Sample output (prefix only):
{PBKDF2-SHA512}100000$27Drpq3V...pwdhash -D uses the Directory Manager storage scheme configured for the selected instance. For broader password-policy administration, including password administrators and local policies, see password policy.
Application compatibility, replication, and FIPS considerations
Before you change schemes in production, test applications that:
- Retrieve
userPassword - Verify hashes outside Directory Server
- Synchronize password values
- Expect an
SSHAorCRYPTprefix - Use legacy RADIUS or authentication integrations
- Import or export LDAP password hashes
Prefer LDAP bind authentication instead of reading password hashes wherever possible. Red Hat notes that some FreeRADIUS configurations may not support PBKDF2-SHA512, which can require a temporary compatibility decision.
Replicated entries retain their stored userPassword values. Every replica must understand the prefixes present in the directory, and password-policy configuration should stay consistent across suppliers. LDIF imports that contain pre-hashed passwords preserve the supplied scheme, while plain-text passwords supplied during normal add or modify operations are stored using the applicable policy. Test mixed-version upgrades before you enable a new scheme in production. Detailed replication password-policy behaviour belongs in the replication chapter.
In a FIPS-targeted deployment, test the configured scheme, existing legacy hashes, Directory Manager authentication, password changes, hash rewrite after successful binds, and imported values on the actual platform. Recognizing a scheme name in Directory Server does not, by itself, establish compliance. Host FIPS mode, NSS behaviour, and the applicable validation boundary also matter. Read Enable and verify FIPS mode for the full enablement workflow.
Verify and test a storage-scheme change
Run the instance health check and review password-scheme findings:
dsctl ldap1 healthcheckWith PBKDF2-SHA512 configured, the tested run reported no issues. After temporarily setting the global scheme to weak SSHA, the same check reported a high-severity finding:
Check: config:passwordscheme
Your configured scheme (SSHA) for 'passwordStorageScheme' is not secure
===== End Of Report (1 Issue found) =====Restore the preferred scheme before you leave the instance in production:
dsconf ldap1 pwpolicy set --pwdscheme PBKDF2-SHA512Use this matrix during a controlled change:
| Test | Expected result |
|---|---|
| Newly created password | Uses the configured scheme |
| Existing legacy password | Still authenticates |
| Successful bind with rewrite enabled | Hash rewrites to the effective configured scheme where eligible |
| Successful bind with rewrite disabled | Original prefix remains |
| Administrative password reset | Uses the configured scheme |
| Directory Manager password | Uses nsslapd-rootpwstoragescheme |
| Application authentication | Continues working |
| Replicated password | Works on every replica |
Record prefix-only audits before and after the change so you can prove migration progress without exposing full hashes.
Troubleshoot password storage schemes
| Symptom | Likely cause | Fix |
|---|---|---|
| New passwords still use the old scheme | Local password policy overrides the global policy, or the password was not actually changed | Run dsconf ldap1 pwpolicy get and dsconf ldap1 localpwp list; reset the password on the server that accepted the update |
| Existing hashes do not change after login | nsslapd-enable-upgrade-hash is off, the bind failed on the inspected server, the stored hash is not eligible for rewrite, or the scheme is listed in nsslapd-scheme-list-no-upgrade-hash |
Confirm nsslapd-enable-upgrade-hash: on, verify the bind succeeded, check nsslapd-scheme-list-no-upgrade-hash, and recheck the entry on the same replica |
| Application authentication fails after migration | The application reads and verifies userPassword locally instead of binding |
Test LDAP binds, temporarily keep a compatible scheme for that integration, or update the application |
| Imported password does not authenticate | Wrong scheme prefix, broken base64, unsupported scheme, or double hashing | Inspect only the prefix, validate LDIF formatting, and re-import with a supported scheme |
| Directory Manager cannot bind after a manual hash edit | Wrong nsslapd-rootpwstoragescheme, missing braces, curly braces in a plain-text password, or pwdhash aimed at the wrong instance directory |
Regenerate with pwdhash -D /etc/dirsrv/slapd-INSTANCE and restore from backup if needed |
| Health check reports a weak scheme | Global policy, local policy, or Directory Manager storage still uses a legacy algorithm | Identify which policy entry owns the finding and move it to PBKDF2-SHA512 when compatibility testing permits |
Summary
- Use
PBKDF2-SHA512unless a tested integration requires another scheme. - Keep user and Directory Manager storage settings separate.
- Changing the scheme does not immediately rewrite existing hashes.
- Use password hash rewrite on bind and administrative resets for migration.
- Audit local policies and legacy password prefixes.
- Test applications, replicas, imports, and FIPS environments before you enforce the change in production.
What's Next
- Password policy — complexity, history, and expiration rules
- Account lockout — failed-bind thresholds after hashing is settled
- FIPS mode — scheme restrictions on compliance-bound hosts
References
- Red Hat Directory Server 13 — User management and authentication
- Red Hat Directory Server 13 — Core server configuration attributes
- Red Hat Directory Server 13 — Designing a secure directory (password storage schemes)
- Red Hat Directory Server 13 release notes — PBKDF2-SHA512 default and rewrite-on-bind warning
- 389 Directory Server — Password Upgrade on Bind

