---
title: Passwords and accounts
description: Examples in this documentation depend on features activated in the ds-evaluation setup profile.
component: pingds
version: 8.1
page_id: pingds:ldap-guide:passwords-and-accounts
canonical_url: https://docs.pingidentity.com/pingds/8.1/ldap-guide/passwords-and-accounts.html
revdate: 2025-10-22T14:42:39Z
keywords: ["Authentication", "LDAP"]
page_aliases: ["change-password.adoc"]
section_ids:
  password-reset: Reset a password
  change-own-password: Change your password
  password-quality-check: Check password quality
  non-ascii-password: Passwords with special characters
  ldap-read-pwp-state: Read password policy state
  ldap-action-account-usability: Check account usability
---

# Passwords and accounts

|   |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| - | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|   | Examples in this documentation depend on features activated in [the `ds-evaluation` setup profile](../install-guide/setup-ds.html#about-ds-evaluation).The code samples demonstrate how to contact the server over HTTPS using the deployment CA certificate. Before trying the samples, generate the CA certificate in PEM format from the server deployment ID and password:```console
$ dskeymgr \
 export-ca-cert \
 --deploymentId $DEPLOYMENT_ID \
 --deploymentIdPassword password \
 --outputFile ca-cert.pem
``` |

The `ldappasswordmodify` command lets authorized users change their own passwords and reset other users' passwords.

## Reset a password

Whenever one user changes another user's password, DS servers consider it a password reset. Often password policies specify that users must change their passwords again after a password reset.

Assume password administrator Kirsten Vaughan has the `password-reset` privilege. The following example shows Kirsten resetting Andy Hall's password:

```console
$ ldappasswordmodify \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN "uid=kvaughan,ou=people,dc=example,dc=com" \
 --bindPassword bribery \
 --authzID "dn:uid=ahall,ou=people,dc=example,dc=com"
```

> **Collapse: Show output**
>
> ```
> The LDAP password modify operation was successful
> Generated Password:  <password>
> ```

> **Collapse: More information**
>
> If a client application performs the LDAP password modify extended operation on a connection that is bound to a user (in other words, when a user first does a bind on the connection, then requests the LDAP Password Modify extended operation), then the operation is performed as the user associated with the connection. If the user associated with the connection is not the same user whose password is being changed, then DS servers consider it a password reset.
>
> To change, rather than reset, the password as the user while binding as an application or an administrator, use the LDAP Password Modify extended operation with an authorization ID. Alternatively, use proxied authorization, as described in [Proxied authorization](proxied-authz.html).

If you reset a password, and do not want it to count as a password reset, use the `manage-account` command with the `set-password-is-reset` hidden option, supported only for testing:

```console
$ manage-account \
 set-password-is-reset \
 --hostname localhost \
 --port 4444 \
 --bindDN uid=admin \
 --bindPassword password \
 --targetDN uid=ahall,ou=people,dc=example,dc=com \
 --operationValue true \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin
```

## Change your password

Users can change their own passwords with the `ldappasswordmodify` command as long as they know their current password:

```console
$ ldappasswordmodify \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN "uid=ahunter,ou=people,dc=example,dc=com" \
 --bindPassword egregious \
 --newPassword chngthspwd
```

The same operation works for directory superusers, such as `uid=admin`:

```console
$ ldappasswordmodify \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --authzID dn:uid=admin \
 --currentPassword password \
 --newPassword OzNOkkfkTJDSW9Bg
```

## Check password quality

The `ldappasswordmodify` and `ldapmodify` commands support password quality advice controls to get additional information about why a password update failed. When you use the request control and a password update fails, the server can send the response control with details indicating which validators rejected the new password.

You can use this as a means to test a password, and to evaluate the effectiveness of a new password policy.

|   |                                                           |
| - | --------------------------------------------------------- |
|   | The new LDAP control has interface stability: *Evolving*. |

The following commands demonstrate how the tools show the information from the response control:

```console
$ ldapmodify \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=admin \
 --bindPassword password << EOF
dn: dc=example,dc=com
changetype: modify
add: aci
aci: (targetcontrol="PasswordQualityAdvice") (version 3.0; acl
  "Authenticated users can check password quality";
  allow(read) userdn="ldap:///all";)
EOF
$ ldapmodify \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=admin \
 --bindPassword password << EOF
dn: cn=Minimum length policy,dc=example,dc=com
objectClass: top
objectClass: subentry
objectClass: ds-pwp-password-policy
objectClass: ds-pwp-validator
objectClass: ds-pwp-length-based-validator
cn: Minimum length policy
ds-pwp-password-attribute: userPassword
ds-pwp-default-password-storage-scheme: PBKDF2-HMAC-SHA512
ds-pwp-length-based-min-password-length: 8
subtreeSpecification: {base "ou=people", specificationFilter "(uid=pshelton)" }
EOF
$ ldappasswordmodify \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=pshelton,ou=People,dc=example,dc=com \
 --bindPassword nosedive \
 --control PasswordQualityAdvice:true \
 --control NoOp \
 --newPassword passwd
```

> **Collapse: Show output**
>
> ```
> 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 is shorter than the minimum required length of 8 characters
>
> The new password was rejected by the password policy located in "cn=Minimum length policy,dc=example,dc=com"
>
> The following password quality criteria were not satisfied:
> * length-based with parameters {max-password-length=0, min-password-length=8}
> ```

Notice that the check can be performed as a no-op.

## Passwords with special characters

DS servers expect passwords to be UTF-8 encoded and base64-encoded when included in LDIF. UTF-8 characters such as `à` or `ô` must be correctly encoded:

```console
$ export LANG=en_US.UTF-8
$ ldappasswordmodify \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=wlutz,ou=People,dc=example,dc=com \
 --bindPassword bassinet \
 --newPassword pàsswȏrd
$ ldapsearch \
 --hostname localhost \
 --port 1636 \
 --useSsl \
 --trustStorePath /path/to/opendj/config/keystore \
 --trustStoreType PKCS12 \
 --trustStorePassword:file /path/to/opendj/config/keystore.pin \
 --bindDN uid=wlutz,ou=People,dc=example,dc=com \
 --bindPassword pàsswȏrd \
 --baseDN dc=example,dc=com \
 "(uid=wlutz)" \
 1.1
```

> **Collapse: Show output**
>
> ```
> dn: uid=wlutz,ou=People,dc=example,dc=com
> ```

## Read password policy state

DS servers have a password policy state virtual attribute enabled by default. It provides information similar to the `manage-account get-all` command.

Accounts with access to read the operational attribute `ds-pwp-state-json` get information from the following fields. Many of the fields only appear when the situation requires:

| Field                                          | Description                                                                           |
| ---------------------------------------------- | ------------------------------------------------------------------------------------- |
| `account-expiration-time`                      | Expiration time                                                                       |
| `account-is-disabled`                          | Boolean                                                                               |
| `account-is-expired`                           | Boolean                                                                               |
| `account-is-idle-locked`                       | Boolean                                                                               |
| `account-is-reset-locked`                      | Boolean, `true` if the password was not changed soon enough after reset               |
| `account-is-usable`                            | Boolean                                                                               |
| `authentication-failure-times`                 | Authentication failure times                                                          |
| `current-authentication-failure-count`         | Number of recorded authentication failures                                            |
| `expire-passwords-without-warning`             | Boolean                                                                               |
| `failure-lockout-count`                        | Maximum number of authentication failures allowed before lockout                      |
| `failure-lockout-expiration-interval`          | Duration in seconds of account lockout after too many authentication failures         |
| `force-change-on-add`                          | Boolean, `true` when the password must change immediately after DS adds the account   |
| `force-change-on-reset`                        | Boolean, `true` when the password must change after another user resets it            |
| `grace-login-use-times`                        | Grace login times                                                                     |
| `idle-lockout-interval-seconds`                | Maximum seconds an account can remain idle (no recent authentications) before lockout |
| `idle-lockout-time`                            | Time account locks for being idle (no recent authentications)                         |
| `idle-lockout`                                 | Seconds until the account locks for being idle                                        |
| `is-within-minimum-password-age`               | Boolean, whether the password is too new to change                                    |
| `last-login-time`                              | Time of the last successful authentication                                            |
| `max-password-reset-age-seconds`               | Maximum seconds to change the password after reset                                    |
| `maximum-grace-login-count`                    | Number of grace logins allowed after expiration to set a new password                 |
| `maximum-password-age-seconds`                 | Maximum seconds the password can remain the same                                      |
| `maximum-password-history-count`               | Maximum number of records allowed in the account's list of old password               |
| `maximum-password-history-duration-seconds`    | Maximum number of seconds DS retains old passwords                                    |
| `minimum-password-age-expiration-time`         | Time the password is old enough to change                                             |
| `minimum-password-age-seconds`                 | Minimum seconds between password changes                                              |
| `must-change-password`                         | Boolean, `true` when the password must change as the next action on the account       |
| `password-change-time`                         | Time the password changed                                                             |
| `password-expiration-time`                     | Time the password expires                                                             |
| `password-expiration-warning-interval-seconds` | Seconds before bind responses include expiry notifications                            |
| `password-expiration-warning-issued`           | Boolean, `true` if DS has returned a notification about expiry                        |
| `password-expiration-warning-time`             | Time DS first returned a notification about expiry                                    |
| `password-expiration-warning`                  | Seconds ago DS first returned a notification about expiry                             |
| `password-expiration`                          | Seconds until the password expires                                                    |
| `password-is-expired`                          | Boolean                                                                               |
| `password-policy-dn`                           | The password policy governing the current account                                     |
| `recent-login-history`                         | Array, times of the last successful authentications                                   |
| `remaining-authentication-failure-count`       | Number, difference between the maximum and current authentication failures            |
| `remaining-grace-login-count`                  | Number, difference between the maximum and used grace login count                     |
| `require-secure-authentication`                | Boolean, `true` when authentication must prevent exposing the credentials             |
| `require-secure-password-changes`              | Boolean, `true` when password changes must prevent exposing the credentials           |
| `reset-lockout-time`                           | Time the account locks after reset unless the password changes                        |
| `seconds-remaining-in-failure-lockout`         | Number of seconds before the locked account unlocks                                   |
| `seconds-remaining-in-minimum-password-age`    | Seconds until the password is old enough to change                                    |
| `seconds-since-account-expiration`             | Seconds since the account expired                                                     |
| `seconds-since-idle-lockout`                   | Seconds since the account locked for being idle (no recent authentications)           |
| `seconds-since-last-login`                     | Seconds since the last successful authentication                                      |
| `seconds-since-password-change`                | Seconds since the password changed                                                    |
| `seconds-since-password-expiration-warning`    | Seconds since DS sent the first bind response with an expiry notification             |
| `seconds-since-password-expiration`            | Seconds since the password expired                                                    |
| `seconds-until-account-expiration`             | Seconds until the account expires                                                     |
| `seconds-until-idle-lockout`                   | Seconds until the account locks for being idle (no recent authentications)            |
| `seconds-until-password-expiration-warning`    | Seconds until DS starts sending bind responses with expiry notifications              |
| `seconds-until-password-expiration`            | Seconds until the password expires                                                    |
| `seconds-until-reset-lockout`                  | Seconds until the account locks after reset unless the password changes               |
| `used-grace-login-count`                       | Number of recorded grace logins                                                       |

To read the attribute:

1. Make sure the reader has access:

   ```console
   $ ldapmodify \
    --hostname localhost \
    --port 1636 \
    --useSsl \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --bindDN uid=admin \
    --bindPassword password << EOF
   dn: dc=example,dc=com
   changetype: modify
   add: aci
   aci: (targetattr="ds-pwp-state-json")(version 3.0;
     acl "Read pwp state"; allow (read,search,compare)
     userdn="ldap:///uid=kvaughan,ou=people,dc=example,dc=com";)
   EOF
   ```

2. Read the attribute on an account:

   ```console
   $ ldapsearch \
    --hostname localhost \
    --port 1636 \
    --useSsl \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --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)" \
    ds-pwp-state-json
   ```

   > **Collapse: Show output**
   >
   > ```
   > dn: uid=bjensen,ou=People,dc=example,dc=com
   > ds-pwp-state-json: { "require-secure-authentication": true, "password-policy-dn": "cn=Default Password Policy,cn=Password Policies,cn=config", "force-change-on-reset": false, "account-is-expired": false, "account-is-idle-locked": false, "account-is-disabled": false, "account-is-reset-locked": false, "must-change-password": false, "password-is-expired": false, "is-within-minimum-password-age": false, "account-is-usable": true, "require-secure-password-changes": true, "force-change-on-add": false }
   > ```

## Check account usability

The [account usability control](../ldap-reference/controls.html#account-usability-control) lets a password administrator read information about whether the user can authenticate to the directory:

* The remote LDAP directory service must support the LDAP control, which has OID `1.3.6.1.4.1.42.2.27.9.5.8`.

* The password administrator must be able to use the LDAP control.

To try the account usability control:

1. Enable the password administrator to use the LDAP account usability control.

   The following example sets a global access control instruction (ACI) *(tooltip: \<div class="paragraph">
   \<p>An instruction or rule that can be used to grant or deny access to users to perform operations on a server.\</p>
   \</div>)* for Kirsten Vaughan:

   ```console
   $ dsconfig \
    set-access-control-handler-prop \
    --hostname localhost \
    --port 4444 \
    --bindDN uid=admin \
    --bindPassword password \
    --add global-aci:"(targetcontrol=\"AccountUsability\")\
    (version 3.0; acl \"Account usability access\"; allow(read) \
    userdn=\"ldap:///uid=kvaughan,ou=People,dc=example,dc=com\";)" \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --no-prompt
   ```

2. Use a password policy that produces results for account usability, as in the following example:

   ```console
   $ ldapmodify \
    --hostname localhost \
    --port 1636 \
    --useSsl \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --bindDN uid=admin \
    --bindPassword password << EOF
   dn: cn=Lockout with max age and grace logins,dc=example,dc=com
   objectClass: top
   objectClass: subentry
   objectClass: ds-pwp-password-policy
   cn: Lockout with max age and grace logins
   ds-pwp-password-attribute: userPassword
   ds-pwp-default-password-storage-scheme: PBKDF2-HMAC-SHA256
   ds-pwp-lockout-failure-expiration-interval: 10 m
   ds-pwp-grace-login-count: 3
   ds-pwp-lockout-duration: 5 m
   ds-pwp-lockout-failure-count: 3
   ds-pwp-max-password-age: 30 d
   subtreeSpecification: { base "ou=people", specificationFilter "(uid=bjensen)" }
   EOF
   ```

3. Use the account usability control to get information about an account:

   ```console
   $ ldapsearch \
    --hostname localhost \
    --port 1636 \
    --useSsl \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --bindDN uid=kvaughan,ou=people,dc=example,dc=com \
    --bindPassword bribery \
    --baseDN dc=example,dc=com \
    --control AccountUsability:true \
    "(uid=bjensen)" \
    1.1
   ```

   > **Collapse: Show output**
   >
   > ```
   > # Account Usability Response Control
   > # The account is usable
   > # Time until password expiration:  <time>
   > dn: uid=bjensen,ou=People,dc=example,dc=com
   > ```

4. Perform actions to change the account usability information on the account:

   ```console
   $ ldapsearch \
    --hostname localhost \
    --port 1636 \
    --useSsl \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --bindDN uid=bjensen,ou=people,dc=example,dc=com \
    --bindPassword wrong-password \
    --baseDN dc=example,dc=com \
    "(uid=bjensen)" \
    1.1
   $ ldapsearch \
    --hostname localhost \
    --port 1636 \
    --useSsl \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --bindDN uid=bjensen,ou=people,dc=example,dc=com \
    --bindPassword wrong-password \
    --baseDN dc=example,dc=com \
    "(uid=bjensen)" \
    1.1
   $ ldapsearch \
    --hostname localhost \
    --port 1636 \
    --useSsl \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --bindDN uid=bjensen,ou=people,dc=example,dc=com \
    --bindPassword wrong-password \
    --baseDN dc=example,dc=com \
    "(uid=bjensen)" \
    1.1
   ```

5. Use the account usability control again to get the changes:

   ```console
   $ ldapsearch \
    --hostname localhost \
    --port 1636 \
    --useSsl \
    --trustStorePath /path/to/opendj/config/keystore \
    --trustStoreType PKCS12 \
    --trustStorePassword:file /path/to/opendj/config/keystore.pin \
    --bindDN uid=kvaughan,ou=people,dc=example,dc=com \
    --bindPassword bribery \
    --baseDN dc=example,dc=com \
    --control AccountUsability:true \
    "(uid=bjensen)" \
    1.1
   ```

   > **Collapse: Show output**
   >
   > ```
   > # Account Usability Response Control
   > # The account is not usable
   > # The account is locked
   > # Time until the account is unlocked:  <time>
   > ```
