Greetings.
How should I use the 'unique' overlay to enforce uniqueness of an attribute across two trees?
I'd have thought that the following would work, to enforce uniqueness across ou=dept1 and ou=dept2, but it doesn't seem to.
dn: olcOverlay=unique,olcDatabase={1}mdb,cn=config objectClass: olcOverlayConfig objectClass: olcUniqueConfig olcOverlay: unique olcUniqueURI: ldap:///ou=dept1,o=example?uidnumber?sub ldap:///ou=dept2,o=example?uidnumber?sub
(and cf, slapd/overlays/unique.c:unique_new_domain).
When I configure a server with this, and load two entities with the same uidNumber, the server doesn't object. I'm clearly misunderstanding something.
The slapo-unique(5) manpage suggests that having two URIs juxtaposed like this is syntactically OK, but it doesn't make clear the semantics of this. I'd guessed that the above configuration would create a 'domain' which is the union of the two subtrees, but that doesn't seem to be the case.
Another thing that such a line could potentially specify is that a tuple of attributes is unique. For example that 'olcUniqueUri: ldap:///?sn?sub ldap:///?cn?sub' specifies that (sn,cn) is unique. There's nothing in the slapo-unique manpage that would back up this interpretation, though.
Or is the above configuration in fact equivalent to
olcUniqueURI: ldap:///ou=dept1,o=example?uidnumber?sub olcUniqueURI: ldap:///ou=dept2,o=example?uidnumber?sub
which would enforce uniqueness of uidnumber on trees ou=dept1 and ou=dept2 separately. I take it that this isn't so, because the manpage talks of multiple 'domains', each of which can have multiple URIs.
In the example below, if I instead add user uid=u2,ou=dept1,o=example, then a duplicated uidNumber is indeed rejected in the ldapadd step (so the overlay is active).
I see an older thread [1] on this topic, but that refers only to a single URI in the olcUniqueURI attribute. That was resolved by adding an index on the relevant attribute, but that index is included in the configuration below.
(The goal here is to enforce uniqueness of uidNumber attributes in (dept1 union dept2) and (dept1 union dept3), but permit duplication in dept2 and dept3.)
Thanks for any illumination,
Norman
[1] https://www.openldap.org/lists/openldap-technical/201808/msg00016.html
Witness:
% cat uniqueness-test-config.ldif dn: cn=config objectclass: olcGlobal cn: config olcPidFile: /tmp/uniquenesstest/slapd.pid
dn: cn=module,cn=config objectClass: olcModuleList cn: module olcModuleload: back_mdb.la olcModuleload: unique
dn: cn=schema,cn=config objectClass: olcSchemaConfig cn: schema
include: file:///etc/openldap/schema/core.ldif include: file:///etc/openldap/schema/cosine.ldif include: file:///etc/openldap/schema/nis.ldif
dn: olcDatabase={1}mdb,cn=config objectClass: olcDatabaseConfig objectClass: olcMdbConfig olcDatabase: mdb olcSuffix: o=example olcRootDN: cn=admin,o=example olcRootPW: dummypass olcDbIndex: default eq olcDbIndex: objectclass olcDbIndex: uidNumber eq olcDbDirectory: /tmp/uniquenesstest/data
dn: olcOverlay=unique,olcDatabase={1}mdb,cn=config objectClass: olcOverlayConfig objectClass: olcUniqueConfig olcOverlay: unique olcUniqueURI: ldap:///ou=dept1,o=example?uidNumber?sub ldap:///ou=dept2,o=example?uidNumber?sub
% cat uniqueness-test-data.ldif dn: o=example objectClass: organization o: example
dn: ou=dept1,o=example objectclass: organizationalunit ou: dept1
dn: uid=u1,ou=dept1,o=example objectclass: person objectclass: posixAccount sn: Two cn: User One uid: u1 uidNumber: 1000 gidNumber: 1000 homeDirectory: /home/u1
dn: ou=dept2,o=example objectclass: organizationalunit ou: dept2
dn: uid=u2,ou=dept2,o=example objectclass: person objectclass: posixAccount sn: Two cn: User Two uid: u2 uidNumber: 1000 gidNumber: 1000 homeDirectory: /home/u2
% slapadd -v -F /tmp/uniquenesstest/slapd.d -n0 -l uniqueness-test-config.ldif added: "cn=config" (00000001) added: "cn=module{0},cn=config" (00000001) added: "cn=schema,cn=config" (00000001) added: "cn={0}core,cn=schema,cn=config" (00000001) added: "cn={1}cosine,cn=schema,cn=config" (00000001) added: "cn={2}nis,cn=schema,cn=config" (00000001) added: "olcDatabase={1}mdb,cn=config" (00000001) added: "olcOverlay={0}unique,olcDatabase={1}mdb,cn=config" (00000001) Closing DB...
% slapd -F /tmp/uniquenesstest/slapd.d
% ldapadd -x -H ldap:/// -D cn=admin,o=example -w dummypass -f uniqueness-test-data.ldif adding new entry "o=example"
adding new entry "ou=dept1,o=example"
adding new entry "uid=u1,ou=dept1,o=example"
adding new entry "ou=dept2,o=example"
adding new entry "uid=u2,ou=dept2,o=example"
% ldapsearch -LLL -H ldap:/// -b o=example '(objectclass=person)' uidnumber dn: uid=u1,ou=dept1,o=example uidNumber: 1000
dn: uid=u2,ou=dept2,o=example uidNumber: 1000
% slapd -VVV @(#) $OpenLDAP: slapd 2.6.7 (Jan 1 1980 00:00:00) $ openldap
Included static overlays: accesslog syncprov unique Included static backends: config ldif monitor mdb relay