Directory Services 7.4.3

Assign password policies

Type To Assign…​

Per-server password policy

Set the ds-pwp-password-policy-dn operational attribute on the user’s account.

Subentry password policy

Use one of the following methods:

  • Set the ds-pwp-password-policy-dn 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. Refine the scope of application by setting the subtreeSpecification 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:

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

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

    $ 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, refer to Collective attributes:

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

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

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

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

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

    $ 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, refer to About subentry scope.

  3. Check that an account under ou=People has the policy:

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

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.

Copyright © 2010-2024 ForgeRock, all rights reserved.