PingDS 7.5.1

Strong and safe passwords

The difficulty with passwords is that they tend to be relatively easy to guess. Despite decades of advice on how to pick strong passwords, people still routinely pick very weak passwords using common words and phrases or simple variations of them. This makes them extremely easy to guess. Attackers with access to even modest hardware can make billions of guesses per second.

DS servers provide flexible password validation to fit your policies about password content, and to reject weak passwords when users try to save them. It also provides a variety of one-way and reversible password storage schemes. Password strength is a function of both password minimum length, which you can set as part of password policy, and password quality, which requires password validation.

Password validation

When a password is added or updated, a password validator determines whether the server should accept it. Validation does not affect existing passwords.

A user’s password policy specifies which password validators apply whenever that user provides a new password.

Subentry password policies can include attributes of password validator object classes. Each object class derives from the abstract ds-pwp-validator class:

The example that follows shows a password policy that requires new passwords to have at least three of the following four character classes:

  • English lowercase characters (a through z)

  • English uppercase characters (A through Z)

  • Base 10 digits (0 through 9)

  • Punctuation characters (for example, !, $, #, %)

Notice how the character-set values are constructed. The initial 0: means the set is optional, whereas 1: means the set is required:

$ ldapmodify \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=admin \
 --bindPassword password << EOF
dn: cn=Policy with character set validation,dc=example,dc=com
objectClass: top
objectClass: subentry
objectClass: ds-pwp-password-policy
objectClass: ds-pwp-validator
objectClass: ds-pwp-character-set-validator
cn: Policy with character set validation
ds-pwp-password-attribute: userPassword
ds-pwp-default-password-storage-scheme: PBKDF2-HMAC-SHA256
ds-pwp-character-set-allow-unclassified-characters: true
ds-pwp-character-set-character-set-ranges: 0:a-z
ds-pwp-character-set-character-set-ranges: 0:A-Z
ds-pwp-character-set-character-set-ranges: 0:0-9
ds-pwp-character-set-character-set: 0:!$%^.#
ds-pwp-character-set-min-character-sets: 3
subtreeSpecification: { base "ou=people", specificationFilter "(uid=bjensen)" }
EOF

$ ldappasswordmodify \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=admin \
 --bindPassword password \
 --authzID "u:bjensen" \
 --newPassword '!ABcd$%^'

An attempt to set an invalid password fails as shown in the following example:

$ ldappasswordmodify \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=admin \
 --bindPassword password \
 --authzID "u:bjensen" \
 --newPassword hifalutin

The LDAP password modify operation failed: 19 (Constraint Violation)
Additional Information:  The provided new password failed the validation
checks defined in the server: The provided password did not contain characters
from at least 3 of the following character sets or ranges: '!$%^.#', '0-9',
'A-Z', 'a-z'

Per-server password policies use validators that are separate configuration objects. The following example lists the password validators available by default for per-server password policies. By default, no password validators are configured in the default password policy:

$ dsconfig \
 list-password-validators \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

Password Validator                  : Type                : enabled
------------------------------------:---------------------:--------
At least 8 characters               : length-based        : true
Attribute Value                     : attribute-value     : true
Character Set                       : character-set       : true
Common passwords                    : dictionary          : true
Dictionary                          : dictionary          : false
Length-Based Password Validator     : length-based        : true
Repeated Characters                 : repeated-characters : true
Similarity-Based Password Validator : similarity-based    : true
Unique Characters                   : unique-characters   : true

Make sure you keep per-server password policy settings aligned across replicated DS servers. When per-server password policy settings differ between replicas, the results can be surprising to end users.

As an example, suppose the user’s password policy depends on a password storage scheme enabled on the replica where the user changes their password and disabled on the replica where they later authenticate:

  • The user changes their password on the first replica.

    The password update succeeds.

    Replication replays the change.

  • The user authenticates on the second replica.

    Authentication fails even though the second replica has the correct password hash. The password storage scheme is disabled in the local per-server configuration.

For details, refer to Password Validator.

For an example showing how to test password quality, refer to Check password quality.

Password storage

Password storage schemes, described in Password Storage Scheme, encode new passwords and store the encoded version. When a client application authenticates with the password, the server encodes the plaintext password using the configured storage scheme, and checks whether the result matches the encoded value stored by the server. If the encoded version is appropriately secure, it is difficult to guess the plaintext password from its encoded value.

DS servers offer a variety of reversible and one-way password storage schemes. With a reversible encryption scheme, an attacker who gains access to the server can recover the plaintext passwords. With a one-way hash storage scheme, the attacker who gains access to the server must still crack the password by brute force, encoding passwords over and over to generate guesses until a match is found. If you have a choice, use a one-way password storage scheme.

Some one-way hash functions are not designed specifically for password storage, but also for use in message authentication and digital signatures. Such functions, like those defined in the Secure Hash Algorithm (SHA-1 and SHA-2) standards, are designed for high performance. Because they are fast, they allow the server to perform authentication at high throughput with low response times. However, high-performance algorithms also help attackers use brute force techniques. One estimate in 2017 is that a single GPU can calculate over one billion SHA-512 hashes per second.

Some one-way hash functions are designed to be computationally intensive. Such functions, like PBKDF2, Argon2, and Bcrypt, are designed to be relatively slow, even on modern hardware. This makes them generally less susceptible to brute force attacks.

However, computationally intensive functions reduce authentication throughput and increase response times. With the default number of iterations, the GPU mentioned above might only calculate 100,000 PBKDF2 hashes per second (or 0.01% of the corresponding hashes calculated with SHA-512). If you use these functions, be aware of the potentially dramatic performance impact and plan your deployment accordingly.

Modern hardware and techniques to pre-compute attempts, such as rainbow tables, make it increasingly easy for attackers to crack passwords by brute force. Password storage schemes that use salt make brute force attacks more expensive. In this context, salt is a random value appended to the password before encoding. The salt is then stored with the encoded value and used when comparing an incoming password to the stored password.

Reversible password storage schemes, such as AES and Blowfish, use symmetric keys for encryption.

The following example lists available alternatives, further described in Password storage schemes:

$ dsconfig \
 list-password-storage-schemes \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

Password Storage Scheme : Type               : enabled
------------------------:--------------------:--------
3DES (DEPRECATED)       : triple-des         : false
AES (LEGACY)            : aes                : false
Argon2                  : argon2             : true
Base64 (LEGACY)         : base64             : false
Bcrypt                  : bcrypt             : true
Blowfish (DEPRECATED)   : blowfish           : false
Clear (LEGACY)          : clear              : false
CRYPT                   : crypt              : false
PBKDF2                  : pbkdf2             : false
PBKDF2-HMAC-SHA256      : pbkdf2-hmac-sha256 : true
PBKDF2-HMAC-SHA512      : pbkdf2-hmac-sha512 : true
PKCS5S2                 : pkcs5s2            : false
Salted SHA-1 (LEGACY)   : salted-sha1        : false
Salted SHA-256          : salted-sha256      : false
Salted SHA-384          : salted-sha384      : false
Salted SHA-512          : salted-sha512      : false
SCRAM-SHA-256           : scram-sha256       : true
SCRAM-SHA-512           : scram-sha512       : true
SHA-1 (LEGACY)          : sha1               : false

As shown in Adjust the default password policy, the default password storage scheme for users is PBKDF2-HMAC-SHA256. When you add users or import user entries with userPassword values in plaintext, the DS server hashes them with the default password storage scheme. The default directory superuser has a different password policy, shown in Assign a password policy to a group. The Root Password Policy uses PBKDF2-HMAC-SHA256 by default.

The choice of default password storage scheme for normal users can significantly impact server performance. Each time a normal user authenticates using simple bind (username/password) credentials, the directory server encodes the user’s password according to the storage scheme in order to compare it with the encoded value in the user’s entry.

Schemes such as Salted SHA-512 call for relatively high-performance encoding. Schemes such as PBKDF2-HMAC-SHA256, which are designed to make the encoding process computationally intensive, reduce the bind throughput that can be achieved on equivalent hardware.

Take this performance impact into consideration when sizing your deployment. With a computationally intensive scheme such as PBKDF2-HMAC-SHA256, make sure the directory service has enough compute power to absorb the additional load.

Password storage schemes

Name Type of Algorithm Notes

3DES(1)

Reversible encryption(2)

Triple DES (Data Encryption Standard) in EDE (Encrypt Decrypt Encrypt) mode.

Key size: 168 bits.

AES(1)

Reversible encryption(2)

Advanced Encryption Standard, successor to DES, published by the US National Institute of Standards and Technology (NIST).

Key size: 128 bits.

Argon2

One-way hash

Computationally intensive, memory-hard hashing function.

For default settings, refer to Additional password storage scheme settings.

Base64

Reversible encoding

Transfer encoding for representing binary password values in text.

Not intended as a secure storage scheme.

Bcrypt

One-way hash

Computationally intensive hashing function, based on the Blowfish cipher.

Default cost: 12 (2^12 iterations).

Blowfish(1)

Reversible encryption(2)

Public domain cipher designed by Bruce Schneier as a successor to DES.

Key size: 128 bits.

Clear

Cleartext, no encoding

For backwards compatibility and use with certain legacy applications.

Not intended as a secure storage scheme.

CRYPT

One-way hash

Based on the UNIX Crypt algorithm.

For backwards compatibility and use with certain legacy applications.

Not intended as a secure storage scheme.

Default algorithm: unix.

MD5

One-way hash

Based on the MD5 algorithm defined in RFC 1321.

For backwards compatibility and use with certain legacy applications.

Not intended as a secure storage scheme.

PBKDF2

One-way hash

Computationally intensive hashing function, based on PBKDF2 algorithm defined in RFC 8018, 5.2. PBKDF2.

Default iterations: 10,000.

The pseudorandom function for the algorithm corresponds to the HMAC based on SHA-1.

PBKDF2-HMAC-SHA256

One-way hash

Computationally intensive hashing function using PBKDF2.

Default iterations: 10,000.

When you install DS, the setup command configures a PBKDF2-HMAC-SHA256 password storage scheme with 10 iterations instead of the default 10,000 iterations.

The server’s default password policy uses this storage scheme.

The pseudorandom function for the algorithm corresponds to the HMAC based on SHA-2, where the hash function is SHA-256.

PBKDF2-HMAC-SHA512

One-way hash

Computationally intensive hashing function using PBKDF2.

Default iterations: 10,000.

The pseudorandom function for the algorithm corresponds to the HMAC based on SHA-2, where the hash function is SHA-512.

PKCS5S2

One-way hash

Computationally intensive hashing function, based on Atlassian’s adaptation of the PBKDF2.

Number of iterations: 10,000.

RC4(1)

Reversible encryption(2)

Based on the Rivest Cipher 4 algorithm.

For backwards compatibility and use with certain legacy applications.

Not intended as a secure storage scheme.

Key size: 128 bits.

Salted MD5

One-way hash

Based on MD5, with 64 bits of random salt appended to the plaintext before hashing, and then appended to the hash.

Salted SHA-1

One-way hash

Based on SHA-1, with 64 bits of random salt appended to the plaintext before hashing, and then appended to the hash.

Salted SHA-256

One-way hash

Based on the SHA-256 hash function using 32-bit words and producing 256-bit digests.

SHA-256 is defined in the SHA-2 (Secure Hash Algorithm 2) standard developed by the US National Security Agency (NSA) and published by NIST.

The salt is applied as for Salted SHA-1.

Salted SHA-384

One-way hash

Based on the SHA-384 hash function that effectively truncates the digest of SHA-512 to 384 bits.

SHA-384 is defined in the SHA-2 (Secure Hash Algorithm 2) standard developed by the NSA and published by NIST.

The salt is applied as for Salted SHA-1.

Salted SHA-512

One-way hash

Based on the SHA-512 hash function using 64-bit words and producing 512-bit digests.

SHA-512 is defined in the SHA-2 (Secure Hash Algorithm 2) standard developed by the NSA and published by NIST.

The salt is applied as for Salted SHA-1.

SCRAM-SHA-256

One-way hash

For use with the standard SASL Salted Challenge Response Authentication Mechanism (SCRAM), named SCRAM-SHA-256.

A SASL SCRAM mechanism provides a secure alternative to transmitting plaintext passwords during binds. It is an appropriate replacement for DIGEST-MD5 and CRAM-MD5.

With a SCRAM SASL bind, the client must demonstrate proof that it has the original plaintext password. During the SASL bind, the client must perform computationally intensive processing to prove that it has the plaintext password. This computation is like what the server performs for PBKDF2, but the password is not communicated during the bind.

Once the server has stored the password, the client pays the computational cost to perform the bind. The server only pays a high computational cost when the password is updated, for example, when an entry with a password is added or during a password modify operation. A SASL SCRAM mechanism therefore offers a way to offload the high computational cost of secure password storage to client applications during authentication.

Passwords storage using a SCRAM storage scheme is compatible with simple binds and SASL PLAIN binds. When a password is stored using a SCRAM storage scheme, the server pays the computational cost to perform the bind during a simple bind or SASL PLAIN bind.

The SCRAM password storage scheme must match the SASL SCRAM mechanism used for authentication. In other words, SASL SCRAM-SHA-256 requires a SCRAM-SHA-256 password storage scheme. SASL SCRAM-SHA-512 requires a SCRAM-SHA-512 password storage scheme.

Default iterations: 10,000.

The pseudorandom function for the algorithm corresponds to the HMAC based on SHA-2, where the hash function is SHA-256.

SCRAM-SHA-512

One-way hash

Like SCRAM-SHA-256, but the hash function is SHA-512. The corresponding SASL mechanism is named SCRAM-SHA-512.

SHA-1

One-way hash

SHA-1 (Secure Hash Algorithm 1) standard developed by the NSA and published by NIST.

Not intended as a secure storage scheme.

(1) Reversible encryption schemes are deprecated. To stop using them, refer to Eliminate outdated password storage (after upgrading in place) or Eliminate outdated password storage (after adding new servers).

(2) When you configure a reversible password storage scheme, enable the adminRoot backend, and configure a replication domain for cn=admin data. These additional steps let the replicas store and replicate the secret keys for password encryption.

Password storage schemes listed in the following table have additional configuration settings.

Additional password storage scheme settings

Scheme Setting Description

Argon2

argon2-iterations

The number of iterations to perform. Default: 2.

argon2-memory

The amount of memory to use for a single hash, expressed in kibibytes. Default: 15,360.

argon2-memory-pool-size

The amount of memory dedicated to Argon2 password hashing, expressed in kibibytes. Default: 122,880.

argon2-parallelism

The number of threads that work in parallel to compute a hash. Default: 1.

argon2-variant

The variant of Argon2 algorithm to use (I, D, or ID). Default: ID.

argon2-length

The length of the resulting hash. Default: 32.

argon2-salt-length

The length of the salt used when hashing passwords. Default: 16.

rehash-policy

Whether the server should rehash passwords after the cost has been changed. Default: never.

Bcrypt

bcrypt-cost

The cost parameter specifies a key expansion iteration count as a power of two.

A default value of 12 (212 iterations) is considered in 2016 as a reasonable balance between responsiveness and security for regular users.

rehash-policy

Whether the server should rehash passwords after the cost has been changed. Default: never.

Crypt

crypt-password-storage-encryption-algorithm

Specifies the crypt algorithm to use to encrypt new passwords.

The following values are supported:

unix

The password is encrypted with the weak Unix crypt algorithm.

This is the default setting.

md5

The password is encrypted with the BSD MD5 algorithm and has a $1$ prefix.

sha256

The password is encrypted with the SHA256 algorithm and has a $5$ prefix.

sha512

The password is encrypted with the SHA512 algorithm and has a $6$ prefix.

PBKDF2

PBKDF2-HMAC-SHA256

PBKDF2-HMAC-SHA512

pbkdf2-iterations

The number of algorithm iterations. Default: 10,000.

When you install DS, the setup command configures a PBKDF2-HMAC-SHA256 password storage scheme with 10 iterations instead of the default 10,000 iterations.

The server’s default password policy uses this storage scheme.

rehash-policy

Whether the server should rehash passwords after the cost has been changed. Default: never.

SCRAM

SCRAM-SHA-256

SCRAM-SHA-512

scram-iterations

The number of algorithm iterations. Default: 10,000.

Change a password storage scheme

You change the default password policy storage scheme for users by changing the applicable password policy:

$ dsconfig \
 set-password-policy-prop \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --policy-name "Default Password Policy" \
 --set default-password-storage-scheme:PBKDF2-HMAC-SHA512 \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

Notice that the change in default password storage scheme does not cause the DS server to update any stored password values. By default, the server only stores a password with the new storage scheme the next time the password is changed.

The setting in the default password policy is a per-server setting.

Make sure you keep per-server password policy settings aligned across replicated DS servers. When per-server password policy settings differ between replicas, the results can be surprising to end users.

As an example, suppose the user’s password policy depends on a password storage scheme enabled on the replica where the user changes their password and disabled on the replica where they later authenticate:

  • The user changes their password on the first replica.

    The password update succeeds.

    Replication replays the change.

  • The user authenticates on the second replica.

    Authentication fails even though the second replica has the correct password hash. The password storage scheme is disabled in the local per-server configuration.

For subentry password policies, set the ds-pwp-default-password-storage-scheme attribute to the common name of an enabled password storage scheme. To list the names of enabled password storage schemes, use the dsconfig list-password-storage-schemes command. The name appears in the first column of the output. The third column shows whether the scheme is enabled.

DS servers prefix passwords with the scheme used to encode them, which means it is straightforward to determine the password storage scheme in use. After the default password storage scheme is changed to PBKDF2-HMAC-SHA512, old user passwords remain encoded with PBKDF2-HMAC-SHA256:

$ ldapsearch \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=bjensen,ou=people,dc=example,dc=com \
 --bindPassword hifalutin \
 --baseDN dc=example,dc=com \
 "(uid=bjensen)" \
 userPassword

dn: uid=bjensen,ou=People,dc=example,dc=com
userPassword: {PBKDF2-HMAC-SHA256}10:<hash>

When the password is changed, the new default password storage scheme takes effect:

$ ldappasswordmodify \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=admin \
 --bindPassword password \
 --authzID "u:bjensen" \
 --newPassword changeit

The LDAP password modify operation was successful

$ ldapsearch \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=bjensen,ou=people,dc=example,dc=com \
 --bindPassword changeit \
 --baseDN dc=example,dc=com \
 "(uid=bjensen)" \
 userPassword

dn: uid=bjensen,ou=People,dc=example,dc=com
userPassword: {PBKDF2-HMAC-SHA512}10000:<hash>

When you change the password storage scheme for users, realize that the user passwords must change in order for the DS server to encode them with the chosen storage scheme. If you are changing the storage scheme because the old scheme was too weak, then you no doubt want users to change their passwords anyway.

If, however, the storage scheme change is not related to vulnerability, use the deprecated-password-storage-scheme property in per-server password policies, or the ds-pwp-deprecated-password-storage-scheme attribute in subentry password policies. This setting causes the DS server to store the password in the new format after successful authentication. This makes it possible to do password migration for active users as users gradually change their passwords:

$ ldapsearch \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=kvaughan,ou=people,dc=example,dc=com \
 --bindPassword bribery \
 --baseDN dc=example,dc=com \
 "(uid=kvaughan)" \
 userPassword

dn: uid=kvaughan,ou=People,dc=example,dc=com
userPassword: {PBKDF2-HMAC-SHA256}10:<hash>

$ dsconfig \
 set-password-policy-prop \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --policy-name "Default Password Policy" \
 --set deprecated-password-storage-scheme:PBKDF2-HMAC-SHA256 \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

$ ldapsearch \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=kvaughan,ou=people,dc=example,dc=com \
 --bindPassword bribery \
 --baseDN dc=example,dc=com \
 "(uid=kvaughan)" \
 userPassword

dn: uid=kvaughan,ou=People,dc=example,dc=com
userPassword: {PBKDF2-HMAC-SHA512}10000:<hash>

Notice that with deprecated-password-storage-scheme set appropriately, Kirsten Vaughan’s password was hashed again after she authenticated successfully.

Password generation

DS servers use password generators when responding with a generated password for the LDAP Password Modify extended operation. A directory administrator resetting a user’s password has the server generate the new password, and the server sends the new password in the response:

$ ldappasswordmodify \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=admin \
 --bindPassword password \
 --authzID "u:bjensen"

The LDAP password modify operation was successful
Generated Password:  <random>

The default password policy uses the Random Password Generator, described in Random Password Generator:

$ dsconfig \
 get-password-policy-prop \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --policy-name "Default Password Policy" \
 --property password-generator \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

Property           : Value(s)
-------------------:--------------------------
password-generator : Random Password Generator

$ dsconfig \
 get-password-generator-prop \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --generator-name "Random Password Generator" \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

Property               : Value(s)
-----------------------:-------------------------------------------------------
enabled                : true
password-character-set : alphanum:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS
                       : TUVWXYZ0123456789
password-format        : alphanum:10

Notice that the default configuration for the Random Password Generator sets the password-character-set property, and references the settings in the password-format property. Generated passwords have eight characters: three from the alpha set, followed by two from the numeric set, followed by three from the alpha set. The password-character-set name must be ASCII.

Subentry password policies configure ds-pwp-random-generator object class attributes. The following example creates a password with password generation, and demonstrates its use:

$ ldapmodify \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=admin \
 --bindPassword password << EOF
dn: cn=Policy with random password generation,dc=example,dc=com
objectClass: top
objectClass: subentry
objectClass: ds-pwp-password-policy
objectClass: ds-pwp-validator
objectClass: ds-pwp-length-based-validator
objectClass: ds-pwp-random-generator
cn: Policy with random password generation
ds-pwp-password-attribute: userPassword
ds-pwp-default-password-storage-scheme: PBKDF2-HMAC-SHA256
ds-pwp-random-password-character-set: alpha:ABCDEFGHIJKLMNOPQRSTUVWabcdefghijklmnopqrstuvwxyz
ds-pwp-random-password-character-set: punct:,.!&+=-_
ds-pwp-random-password-character-set: numeric:0123456789
ds-pwp-random-password-format: alpha:3,punct:1,numeric:2,punct:2,numeric:3,alpha:3,punct:2
ds-pwp-length-based-min-password-length: 8
subtreeSpecification: { base "ou=people" }
EOF

$ ldappasswordmodify \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=admin \
 --bindPassword password \
 --authzID "u:bjensen"

The LDAP password modify operation was successful
Generated Password:  <random>

For details, refer to ds-pwp-random-generator attributes.

When configuring both password validators and password generators, make sure the generated passwords are acceptable to the validator. In this case, the minimum length is less than the generated password length, for example.