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