Hi!
I'm trying to implement a Kerberos server using an OpenLdap backend on a server called *ldap1.vm* and replicate those on an other called *ldap2.vm*.
My first server is working fine. Each kerberos principal is stored in his own ldap entry (with the krbPrincipalName attribut). For exemple : user1@EXEMPLE.COM --> uid=user1,ou=people,dc=exemple,dc=com ldap/ldap2.vm.exemple.com@EXEMPLE.COM --> cn=ldap2.vm,ou=ldap,dc=exemple,dc=com
I wish to replicate either the cn=config DIT and the dc=exemple,dc=com DIT to my second server.
So in my *cn=config* DIT on *ldap1.vm* I have the following configuration :
========================================================== dn: cn=config objectClass: olcGlobal cn: config olcArgsFile: /var/run/slapd/slapd.args olcAuthzRegexp: {0}uid=admin,cn=exemple.com,cn=gssapi,cn=auth cn=admin,dc=exemple,dc=com olcAuthzRegexp: {1}uid=ldap/(.*).exemple.com,cn=exemple.com,cn=gssapi,cn=auth cn=$1,ou=ldap,dc=exemple,dc=com olcAuthzRegexp: {2}uid=host/(.*).exemple.com,cn=exemple.com,cn=gssapi,cn=auth cn=$1,ou=hosts,dc=exemple,dc=com olcAuthzRegexp: {3}uid=(.*),cn=exemple.com,cn=gssapi,cn=auth uid=$1,ou=people,dc=exemple,dc=com olcSaslRealm: EXEMPLE.COM olcServerID: 1 ldap://ldap1.vm.exemple.com/ olcServerID: 2 ldap://ldap2.vm.exemple.com/ olcLogLevel: stats olcPidFile: /var/run/slapd/slapd.pid olcToolThreads: 1
dn: cn=module{0},cn=config objectClass: olcModuleList cn: module{0} olcModulePath: /usr/lib/ldap olcModuleLoad: {0}back_hdb olcModuleLoad: {1}syncprov
dn: olcBackend={0}hdb,cn=config objectClass: olcBackendConfig olcBackend: {0}hdb
dn: olcDatabase={-1}frontend,cn=config objectClass: olcDatabaseConfig objectClass: olcFrontendConfig olcDatabase: {-1}frontend olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external ,cn=auth manage by * break olcAccess: {1}to dn.exact="" by * read olcAccess: {2}to dn.base="cn=Subschema" by * read olcSizeLimit: 500
dn: olcDatabase={0}config,cn=config objectClass: olcDatabaseConfig olcDatabase: {0}config olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external ,cn=auth manage by * break olcRootDN: *cn=admin,cn=config*
dn: olcOverlay={0}syncprov,olcDatabase={0}config,cn=config objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: {0}syncprov olcSpCheckpoint: 100 10 olcSpSessionlog: 100
dn: olcDatabase={1}hdb,cn=config objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: {1}hdb olcDbDirectory: /var/lib/ldap olcSuffix: dc=exemple,dc=com olcAccess: {0}to attrs=userPassword,shadowLastChange by dn="cn=admin,dc=exemple,dc=com" write by dn.one="ou=ldap,dc=exemple,dc=com" read by anonymous auth by * none olcAccess: {1}to dn.subtree="dc=exemple,dc=com" by dn="cn=adm-srv,ou=krb5,dc=exemple,dc=com" write by dn="cn=kdc-srv,ou=krb5,dc=exemple,dc=com" read by dn="cn=admin,dc=exemple,dc=com" write by dn.one="ou=ldap,dc=exemple,dc=com" read olcAccess: {2}to attrs=loginShell by self write by users read by * none olcAccess: {3}to dn.base="" by * read olcAccess: {4}to * by users read by * none olcAccess: {5}to dn="cn=config" by dn.one="ou=ldap,dc=exemple,dc=com" write olcLastMod: TRUE olcRootDN: cn=admin,dc=exemple,dc=com olcRootPW: {SSHA}7JR5Gh0ZUbw9U4cVytBrChBjXuPAdLKh olcDbCheckpoint: 512 30 olcDbConfig: {0}set_cachesize 0 2097152 0 olcDbConfig: {1}set_lk_max_objects 1500 olcDbConfig: {2}set_lk_max_locks 1500 olcDbConfig: {3}set_lk_max_lockers 1500 olcDbIndex: objectClass eq olcDbIndex: uid eq olcDbIndex: cn eq olcDbIndex: ou eq olcDbIndex: dc eq olcDbIndex: uidNumber eq olcDbIndex: gidNumber eq olcDbIndex: memberUid eq olcDbIndex: uniqueMember eq olcDbIndex: krbPrincipalName eq,pres,sub olcDbIndex: krbPwdPolicyReference eq
dn: olcOverlay={0}syncprov,olcDatabase={1}hdb,cn=config objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: {0}syncprov olcSpCheckpoint: 100 10 olcSpSessionlog: 100 ==========================================================
And on the ldap2.vm i wanna replicate the cn=config DIT first:
========================================================== dn: olcDatabase={0}config,cn=config objectClass: olcDatabaseConfig olcDatabase: {0}config olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break olcRootDN: cn=admin,cn=config olcSyncrepl: {0}rid=001 provider="ldap://ldap1.vm.exemple.com/" type=refreshAndPersist retry="10 30 30 +" searchbase="cn=config" bindmethod=sasl saslmech=gssapi ==========================================================
There is no olcMirrorMode attributes because I wanna add other provider directives later.
Every 10 secondes, i see those logs:
========================================================== conn=1001 fd=13 ACCEPT from IP=192.168.x.x:57695 (IP=0.0.0.0:389) conn=1001 op=0 BIND dn="" method=163 conn=1001 op=0 RESULT tag=97 err=14 text=SASL(0): successful result: conn=1001 op=1 BIND dn="" method=163 conn=1001 op=1 RESULT tag=97 err=14 text=SASL(0): successful result: conn=1001 op=2 BIND dn="" method=163 conn=1001 op=2 BIND authcid="ldap/ldap2.vm.exemple.com@EXEMPLE.COM" authzid="ldap/ldap2.vm.exemple.com@EXEMPLE.COM" conn=1001 op=2 BIND dn="cn=ldap2.vm,ou=ldap,dc=exemple,dc=com" mech=GSSAPI sasl_ssf=56 ssf=56 conn=1001 op=2 RESULT tag=97 err=0 text= conn=1001 op=3 SRCH base="cn=config" scope=2 deref=0 filter="(objectClass=*)" conn=1001 op=3 SRCH attr=* + findbase failed! 32 conn=1001 op=3 SEARCH RESULT tag=101 err=32 nentries=0 text= conn=1001 op=4 UNBIND conn=1001 fd=13 closed ==========================================================
We see that the olcAuthzRegexp do is job, indeed, the authcid="ldap/ldap2.vm.exemple.com@EXEMPLE.COM" from the ticket (I use Kstart to obtain it) become dn="cn=ldap2.vm,ou=ldap,dc=exemple,dc=com".
But it fail to find the cn=config DIT.
Here is the entry on my ldap database:
========================================================== dn: cn=ldap2.vm,ou=ldap,dc=exemple,dc=com objectClass: ipHost objectClass: device objectClass: top objectClass: krbPrincipalAux objectClass: krbTicketPolicyAux cn: ldap2.vm ipHostNumber: 192.168.x.x structuralObjectClass: device entryUUID: afe9a32a-81a3-1032-85b7-7976b72b0c24 creatorsName: cn=admin,dc=exemple,dc=com createTimestamp: 20130715140754Z krbPrincipalName: ldap/ldap2.vm.exemple.com@EXEMPLE.COM krbLoginFailedCount: 0 krbPrincipalKey:: [...] krbPasswordExpiration: 19700101000000Z krbLastPwdChange: 20130715140838Z krbExtraData:: AAJmAuRRYWRtaW5ASU5URVJORS5PQlNFUlZBVE9JUkVERVNNQVJRVUVTLkZSAA= = krbExtraData:: AAgBAA== authzTo: {0}dn.regex:*cn=admin,cn=config* entryCSN: 20130716154135.008692Z#000000#001#000000 modifiersName: cn=admin,dc=exemple,dc=com modifyTimestamp: 20130716154135Z ==========================================================
The authzTo directive allow, i think, this entry to act as cn=admin,cn=config and to see the cn=config DIT, am I wrong? How can I do what I want? This configuration works well when I try to synchronise the dc=exemple,dc=com DIT.
Regards, Quentin
I solved this issue. It was in fact a mistake in my ACL directives.
For those who try to build a master-master replication between LDAP servers, for both cn=config DIT and dc=exemple,dc=com, my config DIT look like this :
On ldap1.vm : ================================================= dn: cn=config objectClass: olcGlobal cn: config olcArgsFile: /var/run/slapd/slapd.args olcAuthzRegexp: {0}uid=admin,cn=exemple.com,cn=gssapi,cn=auth cn=admin,dc=exemple,dc=com olcAuthzRegexp: {1}*uid=ldap/(.*).exemple.com,cn=exemple.com,cn=gssapi,cn=auth * *cn=$1,ou=ldap,dc=exemple,dc=com* olcAuthzRegexp: {2}uid=host/(.*).exemple.com,cn=exemple.com,cn=gssapi,cn=auth cn=$1,ou=hosts,dc=exemple,dc=com olcAuthzRegexp: {3}uid=(.*),cn=exemple.com,cn=gssapi,cn=auth uid=$1,ou=people,dc=exemple,dc=com olcLogLevel: stats olcPidFile: /var/run/slapd/slapd.pid olcSaslRealm: EXEMPLE.COM olcServerID: 1 ldap://ldap1.vm.exemple.com/ olcServerID: 2 ldap://ldap2.vm.exemple.com/ olcToolThreads: 1
dn: cn=module{0},cn=config objectClass: olcModuleList cn: module{0} olcModulePath: /usr/lib/ldap olcModuleLoad: {0}back_hdb olcModuleLoad: {1}syncprov
dn: olcBackend={0}hdb,cn=config objectClass: olcBackendConfig olcBackend: {0}hdb
dn: olcDatabase={-1}frontend,cn=config objectClass: olcDatabaseConfig objectClass: olcFrontendConfig olcDatabase: {-1}frontend olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break olcAccess: {1}to dn.exact="" by * read olcAccess: {2}to dn.base="cn=Subschema" by * read olcSizeLimit: 500
dn: olcDatabase={0}config,cn=config objectClass: olcDatabaseConfig olcDatabase: {0}config olcAccess: {0}*to ** *by dn.one="ou=ldap,dc=exemple,dc=com" read * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break olcRootDN: cn=admin,cn=config olcSyncrepl: {0}rid=001 provider="ldap://ldap1.vm.exemple.com/" type=refreshAndPersist retry="10 30 30 +" searchbase="cn=config" bind method=sasl saslmech=gssapi olcSyncrepl: {1}rid=002 provider="ldap://ldap2.vm.exemple.com/" type=refreshAndPersist retry="10 30 30 +" searchbase="cn=config" bind method=sasl saslmech=gssapi olcMirrorMode: TRUE
dn: olcOverlay={0}syncprov,olcDatabase={0}config,cn=config objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: {0}syncprov olcSpCheckpoint: 100 10 olcSpSessionlog: 100
dn: olcDatabase={1}hdb,cn=config objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: {1}hdb olcDbDirectory: /var/lib/ldap olcSuffix: dc=exemple,dc=com olcAccess: {0}*to attrs=userPassword,shadowLastChange * *by dn.one="ou=ldap,dc=exemple,dc=com" read* by anonymous auth by * none olcAccess: {1}*to dn.subtree="dc=exemple,dc=com"* *by dn.one="ou=ldap,dc=exemple,dc=com" read* by dn="cn=adm-srv,ou=krb5,dc=exemple,dc=com" write by dn="cn=kdc-srv,ou=krb5,dc=exemple,dc=com" read olcAccess: {2}to attrs=loginShell by self write by users read by * none olcAccess: {3}to dn.base="" by * read olcAccess: {4}to * by users read by * none olcLastMod: TRUE olcRootDN: cn=admin,dc=exemple,dc=com olcRootPW: {SSHA}cS3TS9Mo5wFbddEWzcNzx5fKLV7Y3AHX olcSyncrepl: {0}rid=101 provider="ldap://ldap1.vm.exemple.com/" type=refreshAndPersist retry="10 30 30 +" searchbase="dc=exemple,dc=com" bindmethod=sasl saslmech=gssapi olcSyncrepl: {1}rid=102 provider="ldap://ldap2.vm.exemple.com/" type=refreshAndPersist retry="10 30 30 +" searchbase="dc=exemple,dc=com" bindmethod=sasl saslmech=gssapi olcMirrorMode: TRUE olcDbCheckpoint: 512 30 olcDbConfig: {0}set_cachesize 0 2097152 0 olcDbConfig: {1}set_lk_max_objects 1500 olcDbConfig: {2}set_lk_max_locks 1500 olcDbConfig: {3}set_lk_max_lockers 1500 olcDbIndex: objectClass eq olcDbIndex: uid eq olcDbIndex: cn eq olcDbIndex: ou eq olcDbIndex: dc eq olcDbIndex: uidNumber eq olcDbIndex: gidNumber eq olcDbIndex: memberUid eq olcDbIndex: uniqueMember eq olcDbIndex: krbPrincipalName eq,pres,sub olcDbIndex: krbPwdPolicyReference eq olcDbIndex: entryCSN eq
dn: olcOverlay={0}syncprov,olcDatabase={1}hdb,cn=config objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: {0}syncprov olcSpCheckpoint: 100 10 olcSpSessionlog: 100 =================================================
On ldap2.vm you just need to add this line on the "*dn: olcDatabase={0}config,cn=config*" entry :
================================================= olcSyncrepl: {0}rid=001 provider="ldap://ldap1.vm.exemple.com/" type=refreshAndPersist retry="10 30 30 +" searchbase="cn=config" bind method=sasl saslmech=gssapi =================================================
The syncrepl will perform the replication of your cn=config DIT and, because you have some others olcSyncrepl on ldap1.vm, replicate also the dc=exemple,dc=com DIT.
Don't forget the kstart directive in /etc/inittab to get the necessary ticket :
KS:2345:respawn:/usr/bin/k5start -U -f*/etc/ldap/ldap.keytab* -K 10 -l 24h -k /tmp/krb5cc_*107* -o openldap
where /etc/ldap/ldap.keytab is my keytab file (see /etc/default/slapd) and 107 is the uid for openldap (use getent passwd).
Regards, Quentin.
openldap-technical@openldap.org