---
title: Passwords
description: DS servers simplify safe, centralized password management. DS servers use password policies to govern passwords.
component: pingds
version: 7.2
page_id: pingds:security-guide:passwords
canonical_url: https://docs.pingidentity.com/pingds/8.1/security-guide/passwords.html
llms_txt: https://docs.pingidentity.com/pingds/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
revdate: 2022-03-09T13:13:20Z
superseded_by: https://docs.pingidentity.com/pingds/8.1/security-guide/passwords.html
section_ids:
  pwp-application: Which password policy applies
  configure-pwp: Configure password policies
  default-pwp: Adjust the default password policy
  recommended-pwp: Configure a NIST-inspired subentry policy
  create-per-server-pwp: Create a per-server password policy
  test-password-policies: Test password policies
  list_subentry_password_policies: List subentry password policies
  assign-pwp: Assign password policies
  assign-pwp-to-individual: Assign a password policy to a user
  assign-pwp-to-group: Assign a password policy to a group
  assign-pwp-for-branch: Assign a password policy to a branch
  subentry-scope: About subentry scope
  auth-enforce-strong-passwords: Strong and safe passwords
  configure-pwd-validation: Password validation
  configure-pwd-storage: Password storage
  configure-pwd-generation: Password generation
  sample-password-policies: Sample password policies
  example-lock-after-repeated-bind-failures: Lock accounts after repeated bind failures
  example-enforce-regular-password-changes: Enforce regular password changes
  example-track-last-login: Track last login time
  example-deprecate-storage-scheme: Deprecate a password storage scheme
  example-lock-idle-accounts: Lock idle accounts
  example-allow-grace-login: Allow log in to change an expired password
  example-require-password-change-on-add-or-reset: Require password change on add or reset
  about-password-policy: About password policies
  pwp-per-server: Per-server password policies
  pwp-replicated: DS subentry password policies
  pwp-i-d-support: Interoperable subentry password policies
---

# Passwords

DS servers simplify safe, centralized password management. DS servers use password policies to govern passwords.

## Which password policy applies

The operational attribute, `pwdPolicySubentry`, identifies an account's password policy. The default global access control instructions prevent this operational attribute from being visible to normal users. The following example grants access to a group of administrators:

```bash
$ 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: ou=People,dc=example,dc=com
changetype: modify
add: aci
aci: (targetattr = "pwdPolicySubentry||ds-pwp-password-policy-dn")
 (version 3.0;acl "Allow Administrators to manage user's password policy";
 allow (all) (groupdn = "ldap:///cn=Directory Administrators,ou=Groups,dc=example,dc=com");)
EOF

$ 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=bjensen)" \
 pwdPolicySubentry

dn: uid=bjensen,ou=People,dc=example,dc=com
pwdPolicySubentry: cn=Default Password Policy,cn=Password Policies,cn=config
```

## Configure password policies

### Adjust the default password policy

You can reconfigure the default password policy, for example, to check that passwords do not contain complete attribute values, and to prevent password reuse. The default policy is a per-server password policy.

1. Apply the changes to the default password policy:

   ```bash
   $ dsconfig \
    set-password-policy-prop \
    --hostname localhost \
    --port 4444 \
    --bindDN uid=admin \
    --bindPassword password \
    --policy-name "Default Password Policy" \
    --set password-history-count:7 \
    --set password-validator:Attribute\ Value \
    --usePkcs12TrustStore /path/to/opendj/config/keystore \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --no-prompt
   ```

2. Check your work:

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

   Property                                  : Value(s)
   ------------------------------------------:--------------------------
   account-status-notification-handler       : -
   allow-expired-password-changes            : false
   allow-user-password-changes               : true
   default-password-storage-scheme           : PBKDF2-HMAC-SHA256
   deprecated-password-storage-scheme        : -
   expire-passwords-without-warning          : false
   force-change-on-add                       : false
   force-change-on-reset                     : false
   grace-login-count                         : 0
   idle-lockout-interval                     : 0 s
   last-login-time-attribute                 : -
   last-login-time-format                    : -
   lockout-duration                          : 0 s
   lockout-failure-count                     : 0
   lockout-failure-expiration-interval       : 0 s
   max-password-age                          : 0 s
   max-password-reset-age                    : 0 s
   min-password-age                          : 0 s
   password-attribute                        : userPassword
   password-change-requires-current-password : false
   password-expiration-warning-interval      : 5 d
   password-generator                        : Random Password Generator
   password-history-count                    : 7
   password-history-duration                 : 0 s
   password-validator                        : Attribute Value
   previous-last-login-time-format           : -
   require-change-by-time                    : -
   require-secure-authentication             : true
   require-secure-password-changes           : true
   ```

3. Test changes to the default password policy.

   For example, the following tests demonstrate the attribute value password validator. The attribute value password validator rejects a new password when the password is contained in attribute values on the user's entry.

   By default, the attribute value password validator checks all attributes, checks whether portions of the password string match attribute values, where the portions are strings of length 5, and checks the reverse of the password as well:

   ```bash
   $ dsconfig \
    get-password-validator-prop \
    --hostname localhost \
    --port 4444 \
    --bindDN uid=admin \
    --bindPassword password \
    --validator-name Attribute\ Value \
    --usePkcs12TrustStore /path/to/opendj/config/keystore \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --no-prompt

   Property               : Value(s)
   -----------------------:--------------------------------------------------
   check-substrings       : true
   enabled                : true
   match-attribute        : All attributes in the user entry will be checked.
   min-substring-length   : 5
   test-reversed-password : true
   ```

   Consider the attributes present on Babs Jensen's entry:

   ```bash
   $ 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)"

   dn: uid=bjensen,ou=People,dc=example,dc=com
   objectClass: person
   objectClass: cos
   objectClass: oauth2TokenObject
   objectClass: inetOrgPerson
   objectClass: organizationalPerson
   objectClass: posixAccount
   objectClass: top
   classOfService: bronze
   cn: Barbara Jensen
   cn: Babs Jensen
   departmentNumber: 3001
   description: Original description
   diskQuota: 10 GB
   facsimileTelephoneNumber: +1 408 555 1992
   gidNumber: 1000
   givenName: Barbara
   homeDirectory: /home/bjensen
   l: San Francisco
   mail: bjensen@example.com
   mailQuota: 1 GB
   manager: uid=trigden, ou=People, dc=example,dc=com
   oauth2Token: {"access_token":"123","expires_in":59,"token_type":"Bearer","refresh_token":"456"}
   ou: Product Development
   ou: People
   preferredLanguage: en, ko;q=0.8
   roomNumber: 0209
   sn: Jensen
   street: 201 Mission Street Suite 2900
   telephoneNumber: +1 408 555 1862
   uid: bjensen
   uidNumber: 1076
   ```

   Using the attribute value password validator, passwords like `bjensen12` and `babsjensenspwd` are not valid because substrings of the password match complete attribute values:

   ```bash
   $ ldappasswordmodify \
    --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 \
    --newPassword bjensen12

   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 was found in another
   attribute in the user entry

   $ ldappasswordmodify \
    --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 \
    --newPassword babsjensenspwd

   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 was found in another
   attribute in the user entry
   ```

   The attribute value password validator does not check, however, whether the password contains substrings of attribute values:

   ```bash
   $ ldappasswordmodify \
    --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 \
    --newPassword babsp4ssw0rd

   The LDAP password modify operation was successful

   $ ldappasswordmodify \
    --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 babsp4ssw0rd \
    --newPassword example.com

   The LDAP password modify operation was successful
   ```

   To avoid the problem of the latter example, you could use a dictionary password validator where the dictionary includes `example.com`.

### Configure a NIST-inspired subentry policy

You can configure a password policy inspired by NIST 800-63 requirements:

* Use a strong password storage scheme.

* Enforce a minimum password length of 8 characters.

* Check for matches in a dictionary of compromised passwords.

* Do not use composition rules for password validation.

  In other words, do not require a mix of special characters, upper and lower case letters, numbers, or other composition rules.

* Do not enforce arbitrary password changes.

  In other words, do not set a maximum password age.

Follow these steps to set up a replicated, NIST-inspired LDAP subentry password policy:

1. Gzip a copy of a text file of common compromised passwords, one word per line.

   This example shows the gzipped text file as `/tmp/10k_most_common.gz`. After successfully updating a subentry password policy with the dictionary data, the input file is no longer required. Lists of common passwords can be found online.

2. Make sure you have enabled a strong storage scheme.

   Creating a password storage scheme requires access to edit the server configuration, which you might not have when creating a subentry password policy. This example therefore uses the `PBKDF2-HMAC-SHA512` storage scheme, which is enabled by default to use 10,000 iterations.

   *This scheme is intentionally much slower and more CPU-intensive* than the `PBKDF2-HMAC-SHA256` scheme with 10 iterations used by the default password policy when you install DS. Test that you have enough resources to sustain the expected peak rates of impacted operations before using a much stronger password storage scheme in your production deployment.

   Impacted operations include:

   * Adding or importing entries with passwords.

   * Authenticating using a password, such as simple bind.

   * Updating or resetting a password.

3. Make sure password policy administrators have the `subentry-write` privilege, and any required ACIs needed to write password policy subentries in the directory data.

   The following example grants access to password administrators. The administrator accounts are in the data where the password policy is to be stored:

   ```bash
   $ 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=subentry-write privilege for administrators,dc=example,dc=com
   objectClass: collectiveAttributeSubentry
   objectClass: extensibleObject
   objectClass: subentry
   objectClass: top
   cn: subentry-write privilege for administrators
   ds-privilege-name;collective: subentry-write
   subtreeSpecification: {base "ou=people", specificationFilter
     "(isMemberOf=cn=Directory Administrators,ou=Groups,dc=example,dc=com)" }

   dn: dc=example,dc=com
   changetype: modify
   add: aci
   aci: (target="ldap:///dc=example,dc=com")
    (targetattr = "*||ds-pwp-password-policy-dn||pwdPolicySubentry||subtreeSpecification")
    (version 3.0; acl "Admins can manage entries and password policies"; allow(all)
    groupdn = "ldap:///cn=Directory Administrators,ou=Groups,dc=example,dc=com";)
   EOF
   ```

   Notice here that the directory superuser, `uid=admin`, assigns privileges. Any administrator with the `privilege-change` privilege can assign privileges. However, if the administrator can update administrator privileges, they can assign themselves the `bypass-acl` privilege. Then they are no longer bound by access control instructions, including both user data ACIs and global ACIs. For this reason, do not assign the `privilege-change` privilege to normal administrator users.

4. Create the password policy as one of the password policy administrators:

   ```bash
   $ ldapmodify \
    --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 << EOF
   dn: cn=NIST inspired policy,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-dictionary-validator
   cn: NIST inspired policy
   ds-pwp-password-attribute: userPassword
   ds-pwp-default-password-storage-scheme: PBKDF2-HMAC-SHA512
   ds-pwp-length-based-min-password-length: 8
   ds-pwp-dictionary-data:<file:///tmp/10k_most_common.gz
   subtreeSpecification: {base "ou=people", specificationFilter "(objectclass=person)" }
   EOF
   ```

   After successfully adding the policy with the dictionary data, you can delete the input file.

5. Check the password policy works appropriately.

   The following example shows a rejected password modification:

   ```bash
   $ ldappasswordmodify \
    --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 \
    --newPassword secret12

   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 was found in another
   attribute in the user entry
   ```

   The following example shows an accepted password modification:

   ```bash
   $ ldappasswordmodify \
    --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 \
    --newPassword aET1OjQeVJECSMgxDPs3U6In

   The LDAP password modify operation was successful
   ```

### Create a per-server password policy

This example adds a per-server password policy for new users who have not yet used their credentials to bind:

1. Create the new password policy:

   ```bash
   $ dsconfig \
    create-password-policy \
    --hostname localhost \
    --port 4444 \
    --bindDN uid=admin \
    --bindPassword password \
    --policy-name "New Account Password Policy" \
    --set default-password-storage-scheme:PBKDF2-HMAC-SHA256 \
    --set force-change-on-add:true \
    --set password-attribute:userPassword \
    --type password-policy \
    --usePkcs12TrustStore /path/to/opendj/config/keystore \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --no-prompt
   ```

   As per-server password policies are not replicated, repeat this step on all replica directory servers.

2. Check your work:

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

   Property                                  : Value(s)
   ------------------------------------------:-------------------
   account-status-notification-handler       : -
   allow-expired-password-changes            : false
   allow-user-password-changes               : true
   default-password-storage-scheme           : PBKDF2-HMAC-SHA256
   deprecated-password-storage-scheme        : -
   expire-passwords-without-warning          : false
   force-change-on-add                       : true
   force-change-on-reset                     : false
   grace-login-count                         : 0
   idle-lockout-interval                     : 0 s
   last-login-time-attribute                 : -
   last-login-time-format                    : -
   lockout-duration                          : 0 s
   lockout-failure-count                     : 0
   lockout-failure-expiration-interval       : 0 s
   max-password-age                          : 0 s
   max-password-reset-age                    : 0 s
   min-password-age                          : 0 s
   password-attribute                        : userPassword
   password-change-requires-current-password : false
   password-expiration-warning-interval      : 5 d
   password-generator                        : -
   password-history-count                    : 0
   password-history-duration                 : 0 s
   password-validator                        : -
   previous-last-login-time-format           : -
   require-change-by-time                    : -
   require-secure-authentication             : false
   require-secure-password-changes           : false
   ```

3. Change the user's password policy after the password is successfully updated.

   For instructions on assigning a per-server password policy, see [Assign a password policy to a user](#assign-pwp-to-individual).

## Test password policies

Use the LDAP password quality advice control to test passwords, and to validate that a password policy produces the expected failures when a new password does not comply with its requirements.

The feature is available [over LDAP](../ldap-guide/change-password.html#password-quality-check), and also [over REST](../rest-guide/action-rest.html#rest-action-password-quality-check) for HTTP applications.

## List subentry password policies

Per-server password policies are part of the DS server configuration. Use the `dsconfig` command to list, read, and edit them.

Subentry policies are part of the DS directory data. Use the `ldapsearch` command to list and read them.

The following command lists the subentry password policies under `dc=example,dc=com`:

```bash
$ 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 \
 "(&(objectClass=subEntry)(objectClass=ds-pwp-password-policy))"

dn: cn=NIST inspired policy,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-dictionary-validator
cn: NIST inspired policy
ds-pwp-default-password-storage-scheme: PBKDF2-HMAC-SHA512
ds-pwp-dictionary-data:: <data>
ds-pwp-length-based-min-password-length: 8
ds-pwp-password-attribute: userPassword
```

## Assign password policies

| Type                       | To Assign…​                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Per-server password policy | Set the [ds-pwp-password-policy-dn](../schemaref/at-ds-pwp-password-policy-dn.html) operational attribute on the user's account.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| Subentry password policy   | Use one of the following methods:- Set the [ds-pwp-password-policy-dn](../schemaref/at-ds-pwp-password-policy-dn.html) operational attribute on the user's account.

- Add the policy to an LDAP subentry whose immediate superior is the root of the subtree containing the accounts.

  For example, add the subentry password policy under `ou=People,dc=example,dc=com`. It applies to all accounts under `ou=People,dc=example,dc=com`.

- Use the capabilities of [LDAP subentries](https://www.rfc-editor.org/info/rfc3672). Refine the scope of application by setting the [subtreeSpecification](../schemaref/at-subtreeSpecification.html) attribute on the policy entry. |

|   |                                                                                                                                                                                                                                                     |
| - | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Do not assign more than one password policy to the same account. Conflicting password policies will yield inconsistent results.You can review the password policy assigned to an account by reading the `pwdPolicySubentry` attribute on the entry. |

### Assign a password policy to a user

1. Make sure the password administrator has access to manage password policies:

   ```bash
   $ 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=subentry-write privilege for administrators,dc=example,dc=com
   objectClass: collectiveAttributeSubentry
   objectClass: extensibleObject
   objectClass: subentry
   objectClass: top
   cn: subentry-write privilege for administrators
   ds-privilege-name;collective: subentry-write
   subtreeSpecification: {base "ou=people", specificationFilter
     "(isMemberOf=cn=Directory Administrators,ou=Groups,dc=example,dc=com)" }

   dn: dc=example,dc=com
   changetype: modify
   add: aci
   aci: (target="ldap:///dc=example,dc=com")
    (targetattr = "*||ds-pwp-password-policy-dn||pwdPolicySubentry||subtreeSpecification")
    (version 3.0; acl "Admins can manage entries and password policies"; allow(all)
    groupdn = "ldap:///cn=Directory Administrators,ou=Groups,dc=example,dc=com";)
   EOF
   ```

   Notice here that the directory superuser, `uid=admin`, assigns privileges. Any administrator with the `privilege-change` privilege can assign privileges. However, if the administrator can update administrator privileges, they can assign themselves the `bypass-acl` privilege. Then they are no longer bound by access control instructions, including both user data ACIs and global ACIs. For this reason, do not assign the `privilege-change` privilege to normal administrator users.

2. Set the user's `ds-pwp-password-policy-dn` attribute as the password administrator:

   ```bash
   $ ldapmodify \
    --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 << EOF
   dn: uid=newuser,ou=People,dc=example,dc=com
   uid: newuser
   objectClass: person
   objectClass: organizationalPerson
   objectClass: inetOrgPerson
   objectClass: top
   cn: New User
   sn: User
   ou: People
   mail: newuser@example.com
   userPassword: chngthspwd
   ds-pwp-password-policy-dn: cn=NIST inspired policy,dc=example,dc=com
   EOF
   ```

3. Check your work:

   ```bash
   $ 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=newuser)" \
    pwdPolicySubentry

   dn: uid=newuser,ou=People,dc=example,dc=com
   pwdPolicySubentry: cn=NIST inspired policy,dc=example,dc=com
   ```

### Assign a password policy to a group

You can use a collective attribute to assign a password policy. Collective attributes provide a standard mechanism for defining attributes that appear on all the entries in a subtree. For details, see [Collective attributes](../config-guide/collective-attrs.html):

1. Make sure the password administrator has the privilege to write subentries:

   ```bash
   $ 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: uid=kvaughan,ou=People,dc=example,dc=com
   changetype: modify
   add: ds-privilege-name
   ds-privilege-name: subentry-write
   EOF
   ```

   Notice here that the directory superuser, `uid=admin`, assigns privileges. Any administrator with the `privilege-change` privilege can assign privileges. However, if the administrator can update administrator privileges, they can assign themselves the `bypass-acl` privilege. Then they are no longer bound by access control instructions, including both user data ACIs and global ACIs. For this reason, do not assign the `privilege-change` privilege to normal administrator users.

2. Create a subentry defining the collective attribute that sets the `ds-pwp-password-policy-dn` attribute for group members' entries:

   ```bash
   $ ldapmodify \
    --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 << EOF
   dn: cn=Password Policy for Dir Admins,dc=example,dc=com
   objectClass: collectiveAttributeSubentry
   objectClass: extensibleObject
   objectClass: subentry
   objectClass: top
   cn: Password Policy for Dir Admins
   ds-pwp-password-policy-dn;collective: cn=Root Password Policy,cn=Password Policies,cn=config
   subtreeSpecification: { base "ou=People", specificationFilter
     "(isMemberOf=cn=Directory Administrators,ou=Groups,dc=example,dc=com)"}
   EOF
   ```

3. Check your work:

   ```bash
   $ 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)" \
    pwdPolicySubentry

   dn: uid=kvaughan,ou=People,dc=example,dc=com
   pwdPolicySubentry: cn=Root Password Policy,cn=Password Policies,cn=config
   ```

### Assign a password policy to a branch

These steps apply only to subentry password policies:

1. Give an administrator the privilege to write subentries, such as those used for setting password policies:

   ```bash
   $ 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: uid=kvaughan,ou=People,dc=example,dc=com
   changetype: modify
   add: ds-privilege-name
   ds-privilege-name: subentry-write
   EOF
   ```

   Notice here that the directory superuser, `uid=admin`, assigns privileges. Any administrator with the `privilege-change` privilege can assign privileges. However, if the administrator can update administrator privileges, they can assign themselves the `bypass-acl` privilege. Then they are no longer bound by access control instructions, including both user data ACIs and global ACIs. For this reason, do not assign the `privilege-change` privilege to normal administrator users.

2. Configure a subentry password policy with a `subtreeSpecification` attribute that defines which accounts are assigned the policy.

   The following example assigns `cn=NIST inspired policy` to accounts under `ou=People,dc=example,dc=com`:

   ```bash
   $ ldapmodify \
    --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 << EOF
   dn: cn=NIST inspired policy,dc=example,dc=com
   changetype: modify
   replace: subtreeSpecification
   subtreeSpecification: { base "ou=people" }
   EOF
   ```

   The subtree specification assigns the policy to the people branch with `{ base "ou=people" }`. You could relax the subtree specification value to `{}` to apply the policy to all entries anywhere underneath `dc=example,dc=com`. You could further restrict the subtree specification by adding a `specificationFilter`. For details, see [About subentry scope](#subentry-scope).

3. Check your work to see that an account under `ou=People` has the policy:

   ```bash
   $ 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=alutz)" \
    pwdPolicySubentry

   dn: uid=alutz,ou=People,dc=example,dc=com
   pwdPolicySubentry: cn=NIST inspired policy,dc=example,dc=com
   ```

### About subentry scope

[LDAP subentries](https://www.rfc-editor.org/info/rfc3672) reside with the user data and so the server replicates them. Subentries hold operational data. They are not visible in search results unless explicitly requested. This section describes how a subentry's `subtreeSpecification` attribute defines the scope of the subtree that the subentry applies to.

An LDAP subentry's subtree specification identifies a subset of entries in a branch of the DIT. The subentry scope is these entries. In other words, these are the entries that the subentry affects.

The attribute value for a `subtreeSpecification` optionally includes the following parameters:

* `base`

  Indicates the entry, *relative to the subentry's parent*, at the base of the subtree.

  By default, the base is the subentry's parent.

* `specificationFilter`

  Indicates an LDAP filter. Entries matching the filter are in scope.

  DS servers extend the standard implementation to allow any search filter, not just an assertion about the `objectClass` attribute.

  By default, all entries under the base entry are in scope.

The following illustration shows this for an example collective attribute subentry:

![A subentry's subtreeSpecification defines the scope of the subtree that the subentry applies to.](../_images/subtree-specification.png)

Notice that the base of `ou=People` on the subentry `cn=Silver Class of Service,dc=example,dc=com` indicates that the base entry is `ou=People,dc=example,dc=com`.

The filter `"(classOfService=silver)"` means that Kirsten Vaughan and Sam Carter's entries are in scope. Babs Jensen's entry, with `classOfService: bronze` does not match and is therefore not in scope. The `ou=People` organizational unit entry does not have a `classOfService` attribute, and so is not in scope, either.

## 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:

* [ds-pwp-attribute-value-validator attributes](#table-ds-pwp-attribute-value-validator)

* [ds-pwp-character-set-validator attributes](#table-ds-pwp-character-set-validator)

* [ds-pwp-dictionary-validator attributes](#table-ds-pwp-dictionary-validator)

* [ds-pwp-length-based-validator attributes](#table-ds-pwp-length-based-validator)

* [ds-pwp-repeated-characters-validator attributes](#table-ds-pwp-repeated-characters-validator)

* [ds-pwp-similarity-based-validator attributes](#table-ds-pwp-similarity-based-validator)

* [ds-pwp-unique-characters-validator attributes](#table-ds-pwp-unique-characters-validator)

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:

```bash
$ 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:

```bash
$ 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:

```bash
$ 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
```

For details, see [Password Validator](../configref/objects-password-validator.html).

For an example showing how to test password quality, see [Check Password Quality](../ldap-guide/change-password.html#password-quality-check).

### Password storage

Password storage schemes, described in [Password Storage Scheme](../configref/objects-password-storage-scheme.html), 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](https://en.wikipedia.org/wiki/Rainbow_table), 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](#pwd-storage-schemes):

```bash
$ 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                    : triple-des         : false
AES                     : aes                : false
Argon2                  : argon2             : true
Base64                  : base64             : false
Bcrypt                  : bcrypt             : true
Blowfish                : blowfish           : false
Clear                   : 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            : 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                   : sha1               : false
```

As shown in [Adjust the default password policy](#default-pwp), 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](#assign-pwp-to-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, see [Additional Password Storage Scheme Settings](#pwd-storage-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](https://www.rfc-editor.org/info/rfc1321).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](https://www.rfc-editor.org/rfc/rfc8018#section-5.2).Default iterations: 10000.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: 10000.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: 10000.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: 10000.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| 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: 10000.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.

(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: 15360.                                                                                                                                                                                                                                                                                                                                                                                                    |
|                                            | `argon2-migration-memory`                     | The memory requirement expected during an Argon2 password migration. Ignored if less than `argon2-memory`. Default: 0.                                                                                                                                                                                                                                                                                                                                                                    |
|                                            | `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. |
| PBKDF2PBKDF2-HMAC-SHA256PBKDF2-HMAC-SHA512 | `pbkdf2-iterations`                           | The number of algorithm iterations.The default is 10000.                                                                                                                                                                                                                                                                                                                                                                                                                                  |
|                                            | `rehash-policy`                               | Whether the server should rehash passwords after the cost has been changed. Default: never.                                                                                                                                                                                                                                                                                                                                                                                               |
| SCRAMSCRAM-SHA-256SCRAM-SHA-512            | `scram-iterations`                            | The number of algorithm iterations.The default is 10000.                                                                                                                                                                                                                                                                                                                                                                                                                                  |

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

```bash
$ 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.

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 see which password storage scheme is used. After the default password storage scheme is changed to PBKDF2-HMAC-SHA512, old user passwords remain encoded with PBKDF2-HMAC-SHA256:

```bash
$ 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:

```bash
$ 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:

```bash
$ 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](https://www.rfc-editor.org/info/rfc3062). 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:

```bash
$ 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](../configref/objects-random-password-generator.html):

```bash
$ 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:

```bash
$ 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, see [ds-pwp-random-generator attributes](#table-ds-pwp-random-generator).

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.

## Sample password policies

### Lock accounts after repeated bind failures

To help you prevent brute-force attacks, where an attacker tries many passwords in the hope of eventually guessing correctly, DS password policies support configurable account lockout. This feature is an important part of a secure password policy.

|   |                                                                                                                                                                                                                                                                                                                                          |
| - | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | When you configure account lockout as part of password policy, DS servers lock an account after the specified number of consecutive authentication failures. *Account lockout is not transactional across all replicas in a deployment.* Global account lockout occurs as soon as the authentication failure times have been replicated. |

The following commands demonstrate a subentry password policy that locks accounts for five minutes after three consecutive bind failures. With this policy, the directory server records failure times, and slowly discards them. As a result, a brute-force attack is hopefully too slow to be effective, but no administrative action is needed when a user temporarily forgets or mistypes their password.

Once an account is locked, binds continue to fail for the lockout period, even if the credentials are correct. An account administrator can use the `manage-account` command to view the account status, and to change it if necessary:

> **Collapse: Show example commands**
>
> ```bash
> # Set the password policy:
> $ 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=Lock After Repeated Bind Failures,dc=example,dc=com
> objectClass: top
> objectClass: subentry
> objectClass: ds-pwp-password-policy
> cn: Lock After Repeated Bind Failures
> ds-pwp-password-attribute: userPassword
> ds-pwp-default-password-storage-scheme: PBKDF2-HMAC-SHA256
> ds-pwp-lockout-duration: 5 m
> ds-pwp-lockout-failure-count: 3
> ds-pwp-lockout-failure-expiration-interval: 2 m
> subtreeSpecification: { base "ou=people", specificationFilter "(objectClass=posixAccount)" }
> EOF
>
> # Attempt to bind three times using the wrong password:
> $ 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 wrongPassword \
>  --baseDn dc=example,dc=com \
>  "(uid=bjensen)"
>
> The LDAP bind request failed: 49 (Invalid Credentials)
>
> $ 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 wrongPassword \
>  --baseDn dc=example,dc=com \
>  "(uid=bjensen)"
>
> The LDAP bind request failed: 49 (Invalid Credentials)
>
> $ 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 wrongPassword \
>  --baseDn dc=example,dc=com \
>  "(uid=bjensen)"
>
> The LDAP bind request failed: 49 (Invalid Credentials)
>
> # Observe the results:
> $ manage-account \
>  get-all \
>  --hostname localhost \
>  --port 4444 \
>  --bindDN uid=admin \
>  --bindPassword password \
>  --targetDN uid=bjensen,ou=people,dc=example,dc=com \
>  --usePkcs12TrustStore /path/to/opendj/config/keystore \
>  --trustStorePassword:file /path/to/opendj/config/keystore.pin
>
> Password Policy DN:  cn=Lock After Repeated Bind Failures,dc=example,dc=com
> Seconds Until Authentication Failure Unlock:  <seconds>
> ```

### Enforce regular password changes

The following commands configure a subentry password policy that sets age limits on passwords, requiring that users change their passwords at least every 13 weeks, but not more often than every 4 weeks. The policy also sets the number of passwords to keep in the password history of the entry, preventing users from reusing the same password on consecutive changes:

```bash
$ 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=Enforce Regular Password Changes,dc=example,dc=com
objectClass: top
objectClass: subentry
objectClass: ds-pwp-password-policy
cn: Enforce Regular Password Changes
ds-pwp-password-attribute: userPassword
ds-pwp-default-password-storage-scheme: PBKDF2-HMAC-SHA256
ds-pwp-max-password-age: 13 w
ds-pwp-min-password-age: 4 w
ds-pwp-password-history-count: 7
subtreeSpecification: { base "ou=people" }
EOF
```

### Track last login time

The following command configures a subentry password policy that keeps track of the last successful login:

1. Create the password policy to write the timestamp to the attribute on successful login:

   ```bash
   $ dsconfig \
    create-password-policy \
    --hostname localhost \
    --port 4444 \
    --bindDN uid=admin \
    --bindPassword password \
    --policy-name "Track Last Login Time" \
    --type password-policy \
    --set default-password-storage-scheme:PBKDF2-HMAC-SHA256 \
    --set password-attribute:userPassword \
    --set last-login-time-attribute:ds-last-login-time \
    --set last-login-time-format:"yyyyMMddHH'Z'" \
    --usePkcs12TrustStore /path/to/opendj/config/keystore \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --no-prompt
   ```

### Deprecate a password storage scheme

The following commands configure a subentry password policy for deprecating a password storage scheme. This policy uses elements from [Enforce regular password changes](#example-enforce-regular-password-changes). The DS server applies the new password storage scheme to re-encode passwords:

* When they change.

* When the user successfully binds with the correct password, and the password is currently hashed with a deprecated scheme.

```bash
$ dsconfig \
 set-password-storage-scheme-prop \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --scheme-name "Salted SHA-512" \
 --set enabled:true \
 --usePkcs12TrustStore /path/to/opendj/config/keystore \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --no-prompt

$ 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=Deprecate a Password Storage Scheme,dc=example,dc=com
objectClass: top
objectClass: subentry
objectClass: ds-pwp-password-policy
cn: Deprecate a Password Storage Scheme
ds-pwp-password-attribute: userPassword
ds-pwp-default-password-storage-scheme: PBKDF2-HMAC-SHA256
ds-pwp-deprecated-password-storage-scheme: Salted SHA-512
ds-pwp-max-password-age: 13 w
ds-pwp-min-password-age: 4 w
ds-pwp-password-history-count: 7
subtreeSpecification: { base "ou=people" }
EOF
```

### Lock idle accounts

The following commands configure a subentry password policy that locks accounts idle for more than 13 weeks. This policy extends the example from [Track last login time](#example-track-last-login). The DS server must track last successful login time to calculate how long the account has been idle:

```bash
$ 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=Lock Idle Accounts,dc=example,dc=com
objectClass: top
objectClass: subentry
objectClass: ds-pwp-password-policy
cn: Lock Idle Accounts
ds-pwp-password-attribute: userPassword
ds-pwp-default-password-storage-scheme: PBKDF2-HMAC-SHA256
ds-pwp-idle-lockout-interval: 13 w
ds-pwp-last-login-time-attribute: ds-last-login-time
ds-pwp-last-login-time-format: yyyyMMddHH'Z'
subtreeSpecification: { base "ou=people" }
EOF
```

### Allow log in to change an expired password

The following commands configure a subentry password policy that lets users log in twice with an expired password to set a new password:

```bash
$ 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=Allow Grace Login,dc=example,dc=com
objectClass: top
objectClass: subentry
objectClass: ds-pwp-password-policy
cn: Allow Grace Login
ds-pwp-password-attribute: userPassword
ds-pwp-default-password-storage-scheme: PBKDF2-HMAC-SHA256
ds-pwp-grace-login-count: 2
subtreeSpecification: { base "ou=people" }
EOF
```

### Require password change on add or reset

The following commands configure a subentry password policy that requires new users to change their password after logging in for the first time. This policy also requires users to change their password after it is reset:

```bash
$ 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=Require Password Change on Add or Reset,dc=example,dc=com
objectClass: top
objectClass: subentry
objectClass: ds-pwp-password-policy
cn: Require Password Change on Add or Reset
ds-pwp-password-attribute: userPassword
ds-pwp-default-password-storage-scheme: PBKDF2-HMAC-SHA256
ds-pwp-force-change-on-add: true
ds-pwp-force-change-on-reset: true
subtreeSpecification: { base "ou=people" }
EOF
```

## About password policies

DS password policies govern passwords, account lockout, and account status notification.

DS servers support per-server password policies stored in the configuration, and subentry password policies stored in the (replicated) directory data:

| Type                                             | Notes                                                                                                                                                                                                                        |
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Per-server password policies](#pwp-per-server)  | * Use for default policies, and policies for top-level administrative accounts.

* You must manually apply policy updates to each replica server configuration.

* Updates require write access to the server configuration. |
| [DS subentry password policies](#pwp-replicated) | - Use for all user accounts stored in application data.

- Replication applies each policy update to all replicas.

- Updates require the `subentry-write` privilege, and ACIs to write the policy.                          |

![Per-server policies are not replicated](../_images/pwd-policy-types.png)Figure 1. Per-Server and Subentry Password Policies

### Per-server password policies

You manage per-server password policies with the `dsconfig` command. When changing a per-server policy, you must update each replica in your deployment.

By default, there are two per-server password policies:

* The `Default Password Policy` for users.

* The `Root Password Policy` for the directory superuser, `uid=admin`.

The following example displays the default per-server password policy for users:

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

Property                                  : Value(s)
------------------------------------------:------------------------------------
account-status-notification-handler       : -
allow-expired-password-changes            : false
allow-multiple-password-values            : false
allow-pre-encoded-passwords               : false
allow-user-password-changes               : true
default-password-storage-scheme           : PBKDF2-HMAC-SHA256
deprecated-password-storage-scheme        : -
expire-passwords-without-warning          : false
force-change-on-add                       : false
force-change-on-reset                     : false
grace-login-count                         : 0
idle-lockout-interval                     : 0 s
java-class                                : org.opends.server.core.PasswordPoli
                                          : cyFactory
last-login-time-attribute                 : -
last-login-time-format                    : -
lockout-duration                          : 0 s
lockout-failure-count                     : 0
lockout-failure-expiration-interval       : 0 s
max-password-age                          : 0 s
max-password-reset-age                    : 0 s
min-password-age                          : 0 s
password-attribute                        : userPassword
password-change-requires-current-password : false
password-expiration-warning-interval      : 5 d
password-generator                        : Random Password Generator
password-history-count                    : 0
password-history-duration                 : 0 s
password-validator                        : At least 8 characters, Common
                                          : passwords
previous-last-login-time-format           : -
require-change-by-time                    : -
require-secure-authentication             : true
require-secure-password-changes           : true
skip-validation-for-administrators        : false
state-update-failure-policy               : reactive
```

For detailed descriptions of each property, see [Password Policy](../configref/objects-password-policy.html).

These settings are configured by default:

* When granted access, users can change their passwords.

* DS servers use the standard `userPassword` attribute to store passwords.

  DS servers also support the alternative standard `authPassword` attribute.

* When you import LDIF with `userPassword` values, DS servers apply a one-way hash to the passwords before storing them.

  When a user provides a password value during a bind, for example, the server hashes the incoming password, and compares it with the stored value. This mechanism helps prevent even the directory superuser from recovering the plain text password:

  ```bash
  $ ldapsearch \
   --hostname localhost \
   --port 1636 \
   --useSsl \
   --usePkcs12TrustStore /path/to/opendj/config/keystore \
   --trustStorePassword:file /path/to/opendj/config/keystore.pin \
   --bindDN uid=admin \
   --bindPassword password \
   --baseDN dc=example,dc=com \
   "(uid=bjensen)" \
   userpassword

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

* The server can set a random password when a password administrator resets a user's password.

Many capabilities are not set by default:

* No lockout.

* No password expiration.

* No password validator to check that passwords contain the appropriate mix of characters.

If the directory service enforces password policy, configure at least the default password policy accordingly.

### DS subentry password policies

You manage password policies as LDAP subentries in the application data. Replication applies updates to subentry password policies to all other replicas. Password policy administrators do not need access to the server configuration.

The DS subentry password policy entries have the object classes:

* `ds-pwp-password-policy` for most password policy features.

* A set of password validator object classes for specific validators that derive from the abstract `ds-pwp-validator` class for password validation configuration.

* `ds-pwp-random-generator` for password generation on reset.

The following tables describe password policy attributes per object class:

**ds-pwp-password-policy Attributes**

| Attribute                                           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ds-pwp-password-attribute` (required)              | The attribute type used to hold user passwords.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `ds-pwp-default-password-storage-scheme` (required) | Names of enabled password storage schemes used to encode plaintext passwords.Default: PBKDF2-HMAC-SHA256.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `cn`                                                | Name of the password policy                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `ds-pwp-allow-user-password-changes`                | Whether users can change their passwords, assuming access control allows it.Default: true.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `ds-pwp-account-status-notification-handler`        | Names of enabled account status notification handlers to use with this policy.Use the `dsconfig list-account-status-notification-handlers` command. The first column of the output shows the names. The third column shows whether the handler is enabled.                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `ds-pwp-allow-expired-password-changes`             | Whether the user can change an expired password with the password modify extended operation.Default: false.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `ds-pwp-allow-multiple-password-values`             | Whether user entries can have multiple distinct passwords. Any password is sufficient to authenticate.Default: false.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `ds-pwp-allow-pre-encoded-passwords`                | Whether users can change their passwords by providing a pre-encoded value.Default: false.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `ds-pwp-deprecated-password-storage-scheme`         | Names of deprecated password storage schemes for this policy.On successful authentication, encode the password with the default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `ds-pwp-expire-passwords-without-warning`           | Whether to allow a user's password to expire even if that user has never seen an expiration warning notification.Default: false.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `ds-pwp-force-change-on-add`                        | Whether users are forced to change their passwords upon first authentication after their accounts are added.Default: false.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `ds-pwp-force-change-on-reset`                      | Whether users are forced to change their passwords after password reset by an administrator. For this purpose, anyone with permission to change a given user's password other than that user is an administrator.Default: false.                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `ds-pwp-grace-login-count`                          | Number of grace logins that a user is allowed after the account has expired so the user can update their password.Default: 0 (disabled).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `ds-pwp-idle-lockout-interval`                      | Maximum number of seconds that an account may remain idle (the associated user does not authenticate to the server) before that user is locked out. Requires maintaining a last login time attribute.Default: 0 seconds (inactive).                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `ds-pwp-last-login-time-attribute`                  | Name or OID of the attribute type that is used to hold the last login time for users.Default: The `last-login-time-attribute` setting from the default password policy. By default, `last-login-time-attribute` is not set.                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `ds-pwp-last-login-time-format`                     | Format string that is used to generate the last login time value for users.The format string must match the syntax of the `ds-pwp-last-login-time-attribute` attribute, and must be a valid format string for the `java.text.SimpleDateFormat` class.Default: `yyyyMMddHHmmss'Z'`.                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `ds-pwp-lockout-duration`                           | Duration that an account is locked after too many authentication failures.Default: 0 seconds (account remains locked until the administrator resets the password).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `ds-pwp-lockout-failure-count`                      | Maximum number of authentication failures that a user is allowed before the account is locked out.Default: 0 (disabled).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `ds-pwp-lockout-failure-expiration-interval`        | Duration before an authentication failure is no longer counted against a user for the purposes of account lockout.Default: 0 seconds (never expire).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `ds-pwp-max-password-age`                           | Duration that a user can continue using the same password before it must be changed (the password expiration interval).Default: 0 seconds (passwords never expire).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `ds-pwp-max-password-reset-age`                     | Maximum number of seconds that users have to change passwords after they have been reset by an administrator before they become locked.Default: 0 seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `ds-pwp-min-password-age`                           | Minimum duration after a password change before the user is allowed to change the password again.Default: 0 seconds.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `ds-pwp-password-change-requires-current-password`  | Whether user password changes must include the user's current password before the change is allowed. This can be done with either the password modify extended operation, or a modify operation using delete and add.Default: false.                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `ds-pwp-password-expiration-warning-interval`       | Duration before a user's password actually expires that the server begins to include warning notifications in bind responses for that user.Default: 5 days.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `ds-pwp-password-history-count`                     | Maximum number of former passwords to maintain in the password history.A value of zero indicates that either no password history is to be maintained if the password history duration has a value of zero seconds, or that there is no maximum number of passwords to maintain in the history if the password history duration has a value greater than zero seconds.Default: 0.                                                                                                                                                                                                                                                                                                                   |
| `ds-pwp-password-history-duration`                  | Maximum number of seconds that passwords remain in the password history.Default: 0 seconds (inactive).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `ds-pwp-previous-last-login-time-format`            | Format string(s) that might have been used with the last login time at any point in the past for users associated with the password policy.Default: `yyyyMMddHHmmss'Z'`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `ds-pwp-require-change-by-time`                     | Time by which all users with the associated password policy must change their passwords. Specified in generalized time form.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `ds-pwp-require-secure-authentication`              | Whether users with the associated password policy are required to authenticate in a secure manner.Default: false.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `ds-pwp-require-secure-password-changes`            | Whether users with the associated password policy are required to change their password in a secure manner that does not expose the credentials.Default: false.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `ds-pwp-skip-validation-for-administrators`         | Whether passwords set by administrators are allowed to bypass the password validation process.Default: false.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `ds-pwp-state-update-failure-policy`                | How the server deals with the inability to update password policy state information during an authentication attempt.One of the following:- `ignore`: If a bind attempt would otherwise be successful, then do not reject it if a problem occurs while attempting to update the password policy state information for the user.

- `proactive`: Proactively reject any bind attempt if it is known ahead of time that it would not be possible to update the user's password policy state information.

- `reactive` (default): Even if a bind attempt would otherwise be successful, reject it if a problem occurs while attempting to update the password policy state information for the user. |

**ds-pwp-attribute-value-validator Attributes**

| Attribute                                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ds-pwp-attribute-value-test-reversed-password` | Whether this password validator should test the reversed value of the provided password as well as the order in which it was given.Default: false.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `ds-pwp-attribute-value-match-attribute`        | Name(s) of the attribute(s) whose values should be checked to determine whether they match the provided password.If no values are provided, then the server checks if the proposed password matches the value of any user attribute in the user's entry. The server does not check values of operational attributes.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `ds-pwp-attribute-value-check-substrings`       | Whether this password validator is to match portions of the password string against attribute values.When false, the server checks whether the entire password matches any user attribute values. When true, the server checks whether the password contains any user attribute values.Consider the case of Babs Jensen (`uid: bjensen`) changing her password. The following table describes the effects of the settings:Setting	New Password	Password Modification Result&#xA;&#xA;ds-pwp-attribute-value-check-substrings: false&#xA;&#xA;&#x9;&#xA;&#xA;bjense&#xA;&#xA;&#x9;&#xA;&#xA;Success&#xA;&#xA;&#xA;&#xA;&#xA;ds-pwp-attribute-value-check-substrings: false&#xA;&#xA;&#x9;&#xA;&#xA;bjensen&#xA;&#xA;&#x9;&#xA;&#xA;Failure: 19 (Constraint Violation)&#xA;&#xA;&#xA;&#xA;&#xA;ds-pwp-attribute-value-check-substrings: false&#xA;&#xA;&#x9;&#xA;&#xA;bjensens&#xA;&#xA;&#x9;&#xA;&#xA;Success&#xA;&#xA;&#xA;&#xA;&#xA;ds-pwp-attribute-value-check-substrings: true&#xA;&#xA;&#x9;&#xA;&#xA;bjense&#xA;&#xA;&#x9;&#xA;&#xA;Success&#xA;&#xA;&#xA;&#xA;&#xA;ds-pwp-attribute-value-check-substrings: true&#xA;&#xA;&#x9;&#xA;&#xA;bjensen&#xA;&#xA;&#x9;&#xA;&#xA;Failure: 19 (Constraint Violation)&#xA;&#xA;&#xA;&#xA;&#xA;ds-pwp-attribute-value-check-substrings: true&#xA;&#xA;&#x9;&#xA;&#xA;bjensens&#xA;&#xA;&#x9;&#xA;&#xA;Failure: 19 (Constraint Violation)In summary:- `bjense` is allowed in both cases because the password does not contain any of the attribute values in Babs's entry.

- `bjensen` is rejected in both cases because the password exactly matches and contains Babs's user ID.

- `bjensens` is allowed when the setting is false because the password does not exactly match, and rejected when the setting is true because the password contains Babs's user ID.Default: false. |
| `ds-pwp-attribute-value-min-substring-length`   | The minimal length of the substring within the password when substring checking is enabled.Default: 0.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |

**ds-pwp-character-set-validator Attributes**

| Attribute                                            | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ds-pwp-character-set-allow-unclassified-characters` | Whether this password validator allows passwords to contain characters outside of any of the user-defined character sets and ranges.Default: false.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `ds-pwp-character-set-min-character-sets`            | Minimum number of character sets and ranges that a password must contain.Use in conjunction with optional character sets and ranges (those requiring zero characters). The value must include any mandatory character sets and ranges (those requiring greater than zero characters). This is useful in situations where a password must contain characters from mandatory character sets and ranges, and characters from at least N optional character sets and ranges. For example, it is quite common to require that a password contains at least one non-alphanumeric character as well as characters from two alphanumeric character sets (lower-case, upper-case, digits). In this case, this property should be set to 3. |
| `ds-pwp-character-set-character-set`                 | A character set containing characters that a password may contain, and a value indicating the minimum number of characters required from that set.Each value must be an integer (indicating the minimum required characters from the set which may be zero, indicating that the character set is optional) followed by a colon and the characters to include in that set. For example, `3:abcdefghijklmnopqrstuvwxyz` indicates that a user password must contain at least three characters from the set of lowercase ASCII letters.Multiple character sets can be defined in separate values, although no character can appear in more than one character set.                                                                   |
| `ds-pwp-character-set-character-set-ranges`          | A character range containing characters that a password may contain, and a value indicating the minimum number of characters required from that range. Each value must be an integer (indicating the minimum required characters from the range which may be zero, indicating that the character range is optional) followed by a colon and one or more range specifications.A range specification is 3 characters: the first character allowed, a minus, and the last character allowed. For example, `3:A-Za-z0-9`. The ranges in each value should not overlap, and the characters in each range specification should be ordered.                                                                                              |

**ds-pwp-dictionary-validator Attributes**

| Attribute                                     | Description                                                                                                                                                                    |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ds-pwp-dictionary-data` (required)           | A gzipped password dictionary, one word per line.This is a single-valued attribute.                                                                                            |
| `ds-pwp-dictionary-case-sensitive-validation` | Whether this password validator should treat password characters in a case-sensitive manner.Default: false.                                                                    |
| `ds-pwp-dictionary-check-substrings`          | Whether this password validator is to match portions of the password string against dictionary words.Default: false (match only the entire password against dictionary words). |
| `ds-pwp-dictionary-min-substring-length`      | The minimal length of the substring within the password in case substring checking is enabled.Default: 0.                                                                      |
| `ds-pwp-dictionary-test-reversed-password`    | Whether this password validator should test the reversed value of the provided password as well as the order in which it was given.Default: false.                             |

**ds-pwp-length-based-validator Attributes**

| Attribute                                 | Description                                               |
| ----------------------------------------- | --------------------------------------------------------- |
| `ds-pwp-length-based-max-password-length` | Minimum plaintext password length.Default: 0 (undefined). |
| `ds-pwp-length-based-min-password-length` | Minimum plaintext password length.Default: 6.             |

**ds-pwp-repeated-characters-validator Attributes**

| Attribute                                              | Description                                                                                                                            |
| ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| `ds-pwp-repeated-characters-max-consecutive-length`    | The maximum number of times that any character can appear consecutively in a password value.Default: 0 (no maximum limit is enforced). |
| `ds-pwp-repeated-characters-case-sensitive-validation` | Whether this password validator should treat password characters in a case-sensitive manner.Default: false.                            |

**ds-pwp-similarity-based-validator Attributes**

| Attribute                                         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ds-pwp-similarity-based-min-password-difference` | The minimum difference the new and old password.The implementation uses the Levenshtein Distance algorithm to determine the minimum number of changes (where a change may be inserting, deleting, or replacing a character) to transform one string into the other. It can prevent users from making only minor changes to their current password when setting a new password. Note that for this password validator to be effective, it must have access to the user's current password. Therefore, if this password validator is to be enabled, also set `ds-pwp-password-change-requires-current-password: true`.Default: 0 (no difference between passwords is acceptable). |

**ds-pwp-unique-characters-validator Attributes**

| Attribute                                            | Description                                                                                                                   |
| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `ds-pwp-unique-characters-case-sensitive-validation` | Whether this password validator should treat password characters in a case-sensitive manner.Default: false.                   |
| `ds-pwp-unique-characters-min-unique-characters`     | The minimum number of unique characters that a password will be allowed to contain.Default: 0 (no minimum value is enforced). |

**ds-pwp-random-generator Attributes**

| Attribute                                         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ds-pwp-random-password-character-set` (required) | Named character sets. The format of the character set is the name of the set followed by a colon and the characters that are in that set. For example, the value `alpha:abcdefghijklmnopqrstuvwxyz` defines a character set named `alpha` containing all of the lower-case ASCII alphabetic characters.                                                                                                                                                                                                                              |
| `ds-pwp-random-password-format` (required)        | The format to use for the generated password. The value is a comma-delimited list of elements in which each of those elements is comprised of the name of a character set defined in the password-character-set property, a colon, and the number of characters to include from that set. For example, a value of `alpha:3,numeric:2,alpha:3` generates an 8-character password in which the first three characters are from the `alpha` set, the next two are from the `numeric` set, and the final three are from the `alpha` set. |

### Interoperable subentry password policies

DS servers support the Internet-Draft, [Password Policy for LDAP Directories](https://datatracker.ietf.org/doc/html/draft-behera-ldap-password-policy-09) (version 09). The password policies are expressed as LDAP subentries with `objectClass: pwdPolicy`. An Internet-Draft password policy effectively overrides settings in the default per-server password policy for users, inheriting settings that it does not support or does not include from the per-server password policy.

The following table describes Internet-Draft policy attributes:

**pwdPolicy Attributes**

| Attribute                 | Description                                                                                                                                                                          |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `pwdAttribute` (required) | The attribute type used to hold user passwords.                                                                                                                                      |
| `pwdAllowUserChange`      | Whether users can change their passwords.Default: true.                                                                                                                              |
| `pwdExpireWarning`        | Maximum number of seconds before a user's password actually expires that the server begins to include warning notifications in bind responses for that user.Default: 432000 seconds. |
| `pwdFailureCountInterval` | Length of time before an authentication failure is no longer counted against a user for the purposes of account lockout.Default: 0 seconds (never expire).                           |
| `pwdGraceAuthNLimit`      | Number of grace logins that a user is allowed after the account has expired so the user can update their password.Default: 0 (disabled).                                             |
| `pwdInHistory`            | Maximum number of former passwords to maintain in the password history.Default: 0 (disabled).                                                                                        |
| `pwdLockoutDuration`      | Number of seconds that an account is locked after too many authentication failures.Default: 0 seconds (account remains locked indefinitely).                                         |
| `pwdMaxAge`               | Maximum number of seconds that a user can continue using the same password before it must be changed (the password expiration interval).Default: 0 seconds (disabled).               |
| `pwdMaxFailure`           | Maximum number of authentication failures that a user is allowed before the account is locked out.Default: 0.                                                                        |
| `pwdMinAge`               | Minimum number of seconds after a password change before the user is allowed to change the password again.Default: 0 seconds (disabled).                                             |
| `pwdMustChange`           | Whether users are forced to change their passwords after password reset by an administrator.Default: false.                                                                          |
| `pwdSafeModify`           | Whether user password changes must use the password modify extended operation, and must include the user's current password before the change is allowed.Default: false.             |

The following table lists Internet-Draft policy attributes that override the per-server policy properties:

| Internet-Draft Policy Attribute | Overrides This Server Policy Property       |
| ------------------------------- | ------------------------------------------- |
| `pwdAllowUserChange`            | `allow-user-password-changes`               |
| `pwdMustChange`                 | `force-change-on-reset`                     |
| `pwdGraceAuthNLimit`            | `grace-login-count`                         |
| `pwdLockoutDuration`            | `lockout-duration`                          |
| `pwdMaxFailure`                 | `lockout-failure-count`                     |
| `pwdFailureCountInterval`       | `lockout-failure-expiration-interval`       |
| `pwdMaxAge`                     | `max-password-age`                          |
| `pwdMinAge`                     | `min-password-age`                          |
| `pwdAttribute`                  | `password-attribute`                        |
| `pwdSafeModify`                 | `password-change-requires-current-password` |
| `pwdExpireWarning`              | `password-expiration-warning-interval`      |
| `pwdInHistory`                  | `password-history-count`                    |

DS servers *ignore* the following Internet-Draft password policy attributes:

* `pwdCheckQuality`, because DS servers have password validators.

* `pwdMinLength`, because you can use a length-based password validator instead.

* `pwdLockout`, because DS servers use other lockout-related password policy attributes.

Internet-Draft based password policies inherit these settings from the default per-server policy for users:

* `account-status-notification-handlers`

* `allow-expired-password-changes`

* `allow-multiple-password-values`

* `allow-pre-encoded-passwords`

* `default-password-storage-schemes`

* `deprecated-password-storage-schemes`

* `expire-passwords-without-warning`

* `force-change-on-add`

* `idle-lockout-interval`

* `last-login-time-attribute`

* `last-login-time-format`

* `max-password-reset-age`

* `password-generator`

* `password-history-duration`

* `password-validators`

* `previous-last-login-time-formats`

* `require-change-by-time`

* `require-secure-authentication`

* `require-secure-password-changes`

* `skip-validation-for-administrators`

* `state-update-failure-policy`
