OpenDJ supports defining password policies that are quite complete in term of security measures to reduce the risks associated with textual passwords. It also defines 2 default policies, one for the administrators such as “cn=Directory Manager”, and one for all other users : the “Default Password Policy”. But it is possible to define additional password policies and assign them to individual users or group of users. Today, we are considering how to assign a password policy to all users under a specific subtree. In the article below, I first define a new custom password policy and then I demonstrate 2 ways of assigning that password policy to all persons under the ou=people,dc=example,dc=com subtree.
Defining a custom password policy using dsconfig:
$ dsconfig create-password-policy \ --set default-password-storage-scheme:Salted\ SHA-256 \ --set password-attribute:userpassword \ --type generic \ --policy-name Custom\ PP \ --hostname lpmac.local \ --port 4444 \ --bindDN cn=Directory\ Manager \ --bindPassword ****** \ -X -n
1- Assigning the password policy through a Virtual Attribute.
$ dsconfig create-virtual-attribute \ --set attribute-type:ds-pwp-password-policy-dn \ --set enabled:true \ --set value:cn=Custom\ PP,cn=Password\ Policies,cn=config \ --set base-dn:ou=people,dc=example,dc=com \ --set filter:\(objectClass=person\) \ --type user-defined \ --name Custom\ PP\ Assignment \ --hostname lpmac.local \ --port 4444 \ --bindDN cn=Directory\ Manager \ --bindPassword ****** \ -X -n
Check that the password policy is assigned properly:
$ ldapsearch -D "cn=directory manager" -w secret12 -p 1389 -b "" 'uid=user.1' '+' userPassword dn: uid=user.1,ou=People,dc=example,dc=com userPassword: {SSHA}u+52Ld6iaTvFoNlQvqTHrn1BBW9IjjT2/I25hg== numSubordinates: 0 ds-pwp-password-policy-dn: cn=Custom PP,cn=Password Policies,cn=config structuralObjectClass: inetOrgPerson pwdPolicySubentry: cn=Custom PP,cn=Password Policies,cn=config subschemaSubentry: cn=schema hasSubordinates: false entryDN: uid=user.1,ou=people,dc=example,dc=com entryUUID: 4e9b7847-edcb-3791-b11b-7505f4a55af4
Change the user password, the new password should be encoded with the scheme specified (SSHA-256)
$ ldappasswordmodify -p 1389 -D uid=user.1,ou=People,dc=example,dc=com -w password -A -n newPassword The LDAP password modify operation was successful $ ldapsearch -D "cn=directory manager" -w secret12 -p 1389 -b "" 'uid=user.1' userPassword dn: uid=user.1,ou=People,dc=example,dc=com userPassword: {SSHA256}vjIdZEtF1AIiM0EgY9unZUXXublwQwlOCoe4RYEIHtpzumW1hYyvNg==
2 – Assigning the password policy using Collective Attributes :
$ ldapmodify -D cn=directory\ manager -w secret12 -p 1389 dn: cn=Pwp for Users,dc=example,dc=com changetype: add objectclass: collectiveAttributeSubEntry objectclass: extensibleObject objectclass: subentry objectclass: top ds-pwp-password-policy-dn;collective: cn=Custom PP,cn=Password Policies,cn=config subtreeSpecification: { base "ou=people", specificationFilter "(objectclass=person)"} Processing ADD request for cn=Pwp for Users,dc=example,dc=com ADD operation successful for DN cn=Pwp for Users,dc=example,dc=com
Now we can check that the password policy is well assigned, and that it’s used when changing password for example.
$ ldapsearch -D "cn=directory manager" -w secret12 -p 1389 -b "" 'uid=user.1' '+' userPassword dn: uid=user.1,ou=People,dc=example,dc=com userPassword: {SSHA}6tHBLHh2C25UpAsKX0eq0d6LEXYGX+Jcm4dh7g== numSubordinates: 0 ds-pwp-password-policy-dn: cn=Custom PP,cn=Password Policies,cn=config structuralObjectClass: inetOrgPerson etag: 000000008211ac6a pwdPolicySubentry: cn=Custom PP,cn=Password Policies,cn=config subschemaSubentry: cn=schema hasSubordinates: false collectiveAttributeSubentries: cn=Pwp for Users,dc=example,dc=com entryDN: uid=user.1,ou=people,dc=example,dc=com entryUUID: 4e9b7847-edcb-3791-b11b-7505f4a55af4 $ ldappasswordmodify -p 1389 -D uid=user.1,ou=People,dc=example,dc=com -w password -A -n newPassword The LDAP password modify operation was successful $ ldapsearch -D "cn=directory manager" -w secret12 -p 1389 -b "" 'uid=user.1' userPassword dn: uid=user.1,ou=People,dc=example,dc=com userPassword: {SSHA256}WswyH9ANoKcxQWlSn/eL8h/dNk532K/e5zGlJcwiwMLsCQqw+cAX0Q==
So which method to assign a password policy to specific users is best ?
The first method should be preferred when the password policy is defined in the configuration (as we’ve done in the example). Both configuration entries, the password policy and its assignment, are under the “cn=config” tree, but need to be defined in all replicas.
The second method defines the assignment of a policy to users as an subentry collocated with the data, and will be replicated. It should be preferred if the password policy is also defined as a subEntry, along with its assignment. Such way of configuring a password policy is documented in the Administration Guide, Configuring Password Policies section, procedure 10.3 – To Create a Subentry Based Password Policy.
It would appear that entries that include the ldapSubentry or subentry objectclass are not replicated natively. Is there an option to enable replication of these entries in the userRoot or is there a solid reason for not doing it and, if so, isn’t creating a custom password policy colocated with the the same as having it in the cn=config…in both cases it appears to have to be applied to all servers in the topology.
What make you think that subentries are not replicated?
The server is replicating all entries from any replicated backend without any exception and without any consideration for objectClasses.
I have four servers in the replication topology and I make a change to a password policy on one of them and it doesn’t propagate to the others. When I make a change to a user’s entry, it propagates just fine. I was making an assumption that it had to do with the subentry objectless for some reason because everything I modify with that class does not get replicated but everything without that class replicates just fine.
The configuration backend is not replicated. Any change to a password policy under cn=config must be done on all servers. Now if the password policy is defined as an ldapSubEntry with the data, it should be replicated. But if there are multiple subEntries in the data and one is a child of another subentry, then you may have hit a known and now fixed issue: subEntries must not be children of another subEntry. Previous versions would allow that and the child subEntry would not be replicated properly.
I hope this helps.