I've set password policies on my OpenLDAP 2.4. Unfortunately things do not work as expected and although extensively searched on forums and Google, I cannot get the proper results. What am I missing in what I did or should have done?
What goes wrong:
- Password policies seem not to be validated or I do get a failure message The failures depend on pwdinHistory setting to zero (no failure) to > 0 failure like given below
5798c94a <= acl_access_allowed: granted to database root 5798c94a bdb_modify_internal: replace userPassword 5798c94a bdb_modify_internal: replace pwdChangedTime 5798c94a bdb_modify_internal: add pwdHistory 5798c94a bdb_modify_internal: replace pwdChangedTime 5798c94a bdb_modify_internal: add pwdHistory 5798c94a bdb_modify_internal: 20 modify/add: pwdHistory: value #0 already exists 5798c94a hdb_modify: modify failed (20) 5798c94a send_ldap_result: conn=1000 op=18 p=3 5798c94a send_ldap_result: err=20 matched="" text="modify/add: pwdHistory: value #0 already exists" 5798c94a send_ldap_response: msgid=62 tag=103 err=20 ber_flush2: 61 bytes to sd 15 0000: 30 3b 02 01 3e 67 36 0a 01 14 04 00 04 2f 6d 6f 0;..>g6....../mo 0010: 64 69 66 79 2f 61 64 64 3a 20 70 77 64 48 69 73 dify/add: pwdHis 0020: 74 6f 72 79 3a 20 76 61 6c 75 65 20 23 30 20 61 tory: value #0 a 0030: 6c 72 65 61 64 79 20 65 78 69 73 74 73 lready exists ldap_write: want=61, written=61 0000: 30 3b 02 01 3e 67 36 0a 01 14 04 00 04 2f 6d 6f 0;..>g6....../mo 0010: 64 69 66 79 2f 61 64 64 3a 20 70 77 64 48 69 73 dify/add: pwdHis 0020: 74 6f 72 79 3a 20 76 61 6c 75 65 20 23 30 20 61 tory: value #0 a 0030: 6c 72 65 61 64 79 20 65 78 69 73 74 73 lready exists 5798c94a conn=1000 op=18 RESULT tag=103 err=20 text=modify/add: pwdHistory: value #0 already exists 5798c94a slap_graduate_commit_csn: removing 0x7f8a0c107960 20160727144634.392449Z#000000#000#000000
This makes, as far as I tested, no difference with just using a default policy or when using a default and specific policy with pwdPolicySubentry attribute in the user. I've used ACL's on my LDAP schema.
My purpose: Use a default policy which basically says to use no policy Add a specific policy for users in a subtree.
Below are the steps and LDAP LDIF files used to build the OpenLDAP.
Included here are the LDIF files for: config, base and sub part of tree, replication ou and user, application users (service accounts), ldap managers ou, ACL's, OU's needed for application specific content, policy. Excluded here (but done) are the LDIF files for: enable logging, replication, TLS/SSL.
The LDIF files first line contains the LDIF filename and the command used to apply them # ldapadd -Y EXTERNAL -H ldapi:/// -f 01_addrootpw.ldif dn: olcDatabase={0}config,cn=config changetype: modify add: olcRootPW olcRootPW: {SSHA}hashhashhashhashhashhash
# ldapadd -Y EXTERNAL -H ldapi:/// -f 02_root-base.ldif # change olcRootPW to your Root password # change domain parts to your domain dn: olcDatabase={1}monitor,cn=config changetype: modify replace: olcAccess olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read by dn.base="cn=Manager,ou=ldapbeheerders,dc=example,dc=nl" read by * none
dn: olcDatabase={2}hdb,cn=config changetype: modify replace: olcSuffix olcSuffix: dc=example,dc=nl
dn: olcDatabase={2}hdb,cn=config changetype: modify replace: olcRootDN olcRootDN: cn=Manager,ou=ldapbeheerders,dc=example,dc=nl
dn: olcDatabase={2}hdb,cn=config changetype: modify replace: olcRootPW olcRootPW: {SSHA} hashhashhashhashhashhash
dn: olcDatabase={2}hdb,cn=config changetype: modify replace: olcAccess olcAccess: {0}to attrs=userPassword,shadowLastChange by dn="cn=Manager,ou=ldapbeheerders,dc=example,dc=nl" write by anonymous auth by self write by * none olcAccess: {1}to dn.base="" by * read
# ldapadd -x -D cn=Manager,ou=ldapbeheerders,dc=example,dc=nl -W -f 03_ldap-manager.ldif dn: dc=example,dc=nl objectClass: top objectClass: dcObject objectclass: organization o: example nl dc: example
dn: ou=ldapbeheerders,dc=example,dc=nl objectclass: organizationalUnit ou: ldapbeheerders
dn: cn=Manager,ou=ldapbeheerders,dc=example,dc=nl objectclass: organizationalRole cn: Manager description: Directory Manager
# ldapadd -x -D cn=Manager,ou=ldapbeheerders,dc=example,dc=nl -W -f 04_replication_user.ldif dn: ou=replicatie,dc=example,dc=nl objectclass: organizationalUnit ou: replicatie description: replicatie groep
dn: cn=replicator,ou=replicatie,dc=example,dc=nl cn: replicator sn: user objectClass: person userPassword: passwordincleartext
# ldapadd -x -D cn=Manager,ou=ldapbeheerders,dc=example,dc=nl -W -f 05_applications.ldif # Create ou generic application scheme dn: ou=applicaties,dc=example,dc=nl objectclass: organizationalUnit ou: applicaties
# Aanmaak ou APP1 applicatieschema dn: ou=APP1,dc=example,dc=nl objectclass: organizationalUnit ou: APP1
# Aanmaak ou APP2 applicatieschemas dn: ou=APP2,dc=example,dc=nl objectclass: organizationalUnit ou: APP2
# ldapadd -x -D cn=Manager,ou=ldapbeheerders,dc=example,dc=nl -W -f 06_ServiceAccounts.ldif dn: ou=ServiceAccounts,dc=example,dc=nl objectclass: organizationalUnit ou: ServiceAccounts description: Service Accounts Applicaties
#Service account APP1 dn: cn=SAAPP1,ou=ServiceAccounts,dc=example,dc=nl cn: SAAPP1 sn: user objectClass: person userPassword: {SSHA}hashedpassword description: Service Account APP1
#Service account APP2 dn: cn=SAAPP2,ou=ServiceAccounts,dc=example,dc=nl cn: SAAPP2 sn: user objectClass: person userPassword: {SSHA} hashedpassword description: Service Account APP2
# ldapadd -x -D cn=Manager,ou=ldapbeheerders,dc=example,dc=nl -W -f 07_ACL.ldif dn: olcDatabase={2}hdb,cn=config changetype: modify replace: olcAccess olcAccess: to attrs=userPassword by anonymous auth by self write by * break olcAccess: to dn="ou=replicatie,dc=example,dc=nl" by self write by * none olcAccess: to * by dn.base="cn=replicator,ou=replicatie,dc=example,dc=nl" read by * break olcAccess: to dn.subtree="cn=default,ou=policies,dc=example,dc=nl" by dn.children="ou=ldapbeheerders,dc=example,dc=nl" write by * none olcAccess: to dn="ou=ldapbeheerders,dc=example,dc=nl" by dn.children="ou=ldapbeheerders,dc=example,dc=nl" write by * none olcAccess: to dn="ou=ServiceAccounts,dc=example,dc=nl" by self search by * none olcAccess: to dn.subtree="ou=applicaties,dc=example,dc=nl" by dn.children="ou=ServiceAccounts,dc=example,dc=nl" write by * none olcAccess: to dn.subtree="ou=APP1,dc=example,dc=nl" by dn.base="cn=SAAPP1,ou=ServiceAccounts,dc=example,dc=nl" write by * none olcAccess: to dn.subtree="ou=APP2,dc=example,dc=nl" by dn.base="cn=SAAPP2,ou=ServiceAccounts,dc=example,dc=nl" write by * none olcAccess: to dn.children="dc=example,dc=nl" by * read olcAccess: to dn.children="dc=nl" by * read
# ldapadd -x -D cn=Manager,ou=ldapbeheerders,dc=example,dc=nl -W -f 08_Add-testusers.ldif dn: uid=APP1_1,ou=APP1gebruikers,ou=APP1,dc=example,dc=nl objectClass: inetOrgPerson objectClass: organizationalPerson ObjectClass: person objectClass: top uid: APP1_1 cn: APP1_1 gebruiker sn: gebruiker pwdPolicySubentry: cn=default,ou=policies,ou=APP1,dc=example,dc=nl
dn: uid=APP1_2,ou=APP1gebruikers,ou=APP1,dc=example,dc=nl objectClass: inetOrgPerson objectClass: organizationalPerson ObjectClass: person objectClass: top uid: APP1_2 cn: APP1_2 gebruiker sn: gebruiker pwdPolicySubentry: cn=default,ou=policies,ou=APP1,dc=example,dc=nl
dn: cn=APP2_1,ou=APP2gebruikers,ou=APP2,dc=example,dc=nl objectClass: inetOrgPerson objectClass: organizationalPerson ObjectClass: person objectClass: top uid: APP2_1 cn: APP2_1 gebruiker sn: gebruiker
dn: cn=APP2_2,ou=APP2gebruikers,ou=APP2,dc=example,dc=nl objectClass: inetOrgPerson objectClass: organizationalPerson ObjectClass: person objectClass: top uid: APP2_2 cn: APP2_2 gebruiker sn: gebruiker
dn: cn=APP2_3,ou=gebruikers,ou=applicaties,dc=example,dc=nl objectClass: inetOrgPerson objectClass: organizationalPerson ObjectClass: person objectClass: top uid: APP2_3 cn: APP2_3 gebruikercat sn: gebruiker
dn: cn=APP2_4,ou=gebruikers,ou=applicaties,dc=example,dc=nl objectClass: inetOrgPerson objectClass: organizationalPerson ObjectClass: person objectClass: top uid: APP2_4 cn: APP2_4 gebruiker sn: gebruiker
Below is the part where the password policies are configured. # ldapadd -Y EXTERNAL -H ldapi:/// -f P01_ppolicymodule.ldif dn: cn=module,cn=config objectClass: olcModuleList cn: module olcModuleLoad: ppolicy.la olcModulePath: /usr/lib64/openldap
# ldapadd -Y EXTERNAL -H ldapi:/// -f P02_ppolicyoverlay.ldif dn: olcOverlay=ppolicy,olcDatabase={2}hdb,cn=config objectClass: olcPPolicyConfig olcOverlay: ppolicy olcPPolicyDefault: cn=default,ou=policies,dc=example,dc=nl olcPPolicyUseLockout: TRUE olcPPolicyHashCleartext: TRUE
# ldapadd -x -D 'cn=Manager,ou=ldapbeheerders,dc=example,dc=nl' -W -f P03_default_ppolicy.ldif dn: ou=policies,dc=example,dc=nl objectClass: top objectClass: organizationalUnit ou: policies
dn: cn=default,ou=policies,dc=example,dc=nl objectClass: top objectClass: device objectClass: pwdPolicyChecker objectClass: pwdPolicy cn: default pwdAttribute: userPassword pwdInHistory: 8 pwdMinLength: 8 pwdMaxFailure: 5 pwdFailureCountInterval: 1800 pwdCheckQuality: 1 pwdMustChange: TRUE pwdGraceAuthNLimit: 0 pwdMaxAge: 7776000 pwdExpireWarning: 1209600 pwdLockoutDuration: 900 pwdLockout: TRUE pwdSafeModify: FALSE
# ldapadd -x -D 'cn=Manager,ou=ldapbeheerders,dc=example,dc=nl' -W -f P04_APP1_ppolicies.ldif dn: ou=policies,ou=APP1,dc=example,dc=nl ou: policies objectClass: top objectClass: organizationalUnit
dn: cn=default,ou=policies,ou=APP1,dc=example,dc=nl objectClass: top objectClass: device objectClass: pwdPolicy cn: default pwdAttribute: userPassword pwdAllowUserChange: TRUE pwdCheckQuality: 0 pwdExpireWarning: 374400 pwdFailureCountInterval: 1800 pwdGraceAuthNLimit: 5 pwdInHistory: 12 pwdLockout: TRUE pwdLockoutDuration: 0 pwdMaxAge: 2592000 pwdMaxFailure: 5 pwdMinAge: 0 pwdMinLength: 8 pwdMustChange: TRUE pwdSafeModify: FALSE
openldap-technical@openldap.org