During the setup of a Master-Slave OpenLDAP environment we had to deal with a "strange" error log message on the slave server. The server logged:

Jun 25 06:57:02 ldapsrv02 slapd[11808]: Entry (cn=vwxyz,dc=vwxyz,dc=xy): object class 'simpleSecurityObject' requires attribute 'userPassword'

In the first step of figuring out what is causing this issue we consulted Google and found a lot of articles/questions dealing with the same problem. But none of the results was providing the right hint to solve it.

So: what is the problem here?

One sentence answer:
By default only the built-in administrator is allowed to read the attributes userPassword and shadowLastChange.

How to deal with this issue?

  1. Use the built-in administrator for replication purposes. This is the bad way to do it even if it will work right away!
  2. Create an object (user) which is used for replication purposes and assign/adjust access rights correctly.

What does this mean when using option #2?

  1. Create an object (user) which is going to be used for replication purposes (master server):

        dn: cn=ldaprepluser,dc=vwxyz,dc=xy
        objectClass: simpleSecurityObject
        objectClass: organizationalRole
        cn: ldaprepluser
        description: LDAP Replication User
        userPassword: YOURPASSWORD-TO-BE-CHANGED
  2. assign general access rights to the synchronization user (master server):

     dn: olcDatabase={0}config,cn=config
     changetype: modify
     add: olcAccess
     olcAccess: to * by dn.base="cn=ldaprepluser,dc=vwxyz,dc=xy" read by * +0 break
  3. now - this is the "magic stuff" - modify access rights for the attribute "userPassword" (master server):

        dn: olcDatabase={1}mdb,cn=config
        changetype: modify
        replace: olcAccess
        olcAccess: {0}to attrs=userPassword 
          by dn="cn=ldaprepluser,dc=vwxyz,dc=xy" read
          by anonymous auth 
          by self write 
          by * none
        olcAccess: {1}to attrs=shadowLastChange
          by self write
          by * read
        olcAccess: {2}to *
          by * read
  4. On the slave server: load the synchronization module and enable database as well as configuration synchronization:

        dn: olcDatabase={1}mdb,cn=config
        changetype: modify
        add: olcSyncrepl
        olcSyncrepl: {0}rid=020 provider=ldap://ldapsrv01
          type=refreshAndPersist
          bindmethod=simple
          binddn="cn=ldaprepluser,dc=vwxyz,dc=xy"
          credentials=YOURPASSWORD-TO-BE-CHANGED
          interval="00:00:03:00"
          retry="30 10 300 +"
          timeout=1
          tls_reqcert=never
          schemachecking=on
          searchbase="dc=vwxyz,dc=xy"
    
        dn: olcDatabase={0}config,cn=config
        changetype: modify
        add: olcSyncrepl
        olcSyncrepl: {0}rid=021 provider=ldap://ldapsrv01
          type=refreshAndPersist
          bindmethod=simple
          binddn="cn=ldaprepluser,dc=vwxyz,dc=xy"
          credentials=YOURPASSWORD-TO-BE-CHANGED
          interval="00:00:03:00"
          retry="30 10 300 +"
          timeout=1
          tls_reqcert=never
          schemachecking=on
          searchbase="cn=config"

What is the source/idea for this solution?

Simply said: read the documentation!

slapd.conf says:

# The userPassword by default can be changed
# by the entry owning it if they are authenticated.
# Others should not be able to see it, except the
# admin entry below
# These access lines apply to database #1 only
access to attrs=userPassword,shadowLastChange
        by dn="@ADMIN@" write
        by anonymous auth
        by self write
        by * none

All of the above mentioned ldifs can be dynamically added to the database/configuration by using ldapadd or ldapmodify.

Previous Post