Introduction
Why use OpenLDAP Multiple DIT (Directory Information Tree) within the same server?
Suppose for example taht we you to offer a user database to multiple clients simultaneously giving each of them the managing of their tree without having to create instances of different openldap, or complex ACLs, so we will use different DIT on the same instance of openldap.
The use of different DIT eliminates also the possibility of experencing the keys duplications among your customers.
We’ll see how to create two DIT using the slapd.conf format and the conversion into the new slapd.d format, the alc and dynamic groups, added to the new version 2.4 of openldap
Openldap Multiple DIT
The Directory Information Tree identifies the LDAP tree root.
Usually the DIT coincides with the domain membership as expressed in the examples: dc=example, dc=com. In fact there is no precise rule, the DIT may also be simply expressed in dc=example.com. In this example we will create the two DIT: dc=oneos, c=com and dc=oneos, c=eu, and a third o=super.admin.
The slapd.conf
Once installed, openldap creates a sample SITE. I will delete it, to create a DIT that I will use as a super admin.
First of all, I eliminate the db files except DB_CONFIG.
$ sudo service slapd stop $ sudo cd /var/lib/ldap $ sudo ls -la drwx------ 6 openldap openldap 4096 gen 26 14:15 . drwxr-xr-x 57 root root 4096 gen 15 21:25 .. -rw-r--r-- 1 openldap openldap 2048 gen 17 12:15 alock -rw------- 1 openldap openldap 532479 gen 17 12:15 __db.001 -rw------- 1 openldap openldap 139263 gen 17 12:15 __db.002 -rw------- 1 openldap openldap 741375 gen 17 12:15 __db.003 -rw-r--r-- 1 openldap openldap 96 gen 15 22:23 DB_CONFIG -rw------- 1 openldap openldap 8192 gen 17 11:51 dn2id.bdb -rw------- 1 openldap openldap 393216 gen 17 11:51 id2entry.bdb -rw------- 1 openldap openldap 10485759 gen 17 12:15 log.0000000001 -rw------- 1 openldap openldap 8192 gen 17 11:51 objectClass.bd $ $ sudo find /var/lib/ldap -type f | grep -v "DB_CONFIG" | xargs rm
I eliminate also the configuration files.
$ sudo cd /etc/ldap $ sudo rm -fr slapd.d/*
You must now create the /etc/ldap/slapd.conf file with our definitions.
For convenience we divide the slapd.conf in 3 parts: Configuration, dit admin, dit1 and dit2.
# slapd.conf # file di esempio per la creazione di DITs multipli # Totali 2 DIT, uno di amministrazione completa e 1 di esempio con ACL per dare # al super admin l'acceso in RW a tutti i DIT e un utente per l'amministrazione del proprio DIT # Parte 1 - Configurazione # inclusioni schema include /etc/ldap/schema/core.schema include /etc/ldap/schema/cosine.schema include /etc/ldap/schema/inetorgperson.schema include /etc/ldap/schema/dyngroup.schema include /etc/ldap/schema/nis.schema # pid file pidfile /var/run/slapd/slapd.pid # logging loglevel 128 #ACL # moduli moduleload back_hdb.la moduleload dynlist.la database config rootpw {SSHA}Bns4pc9vnlU6MDZBDF1XLBB access to * by self manage by * none
Let’s analyze what we have written. The “include” directives tell slapd to upload diagram required for the operation.
I have set up the pid file of the process and the level of logging to 128 Ref. that identifies the only log ACL.
Load the necessary modules. hdb and dynlist for the dimanic groups.
Then I choose the database type, in this case the special db config, password, and that acl It allows the root of this db to have complete control of the db and deny access to all the others.
To create the hash in SSHA format we can use the “slappasword” utility in this so:
$ sudo slappasword -h {SSHA} -s nonteladico {SSHA}Bns4pc9vnlU6MDZBDF1XLBB6fRrNkcC5
Let’s move on to the second section of the file.
# Dit di amministrazione # # dc=super.admin # database hdb suffix "dc=super.admin" # root o superuser rootdn "cn=admin,dc=super.admin" rootpw {SSHA}Nj2+pZ5UxZr3hb3E7krvOH3ZUf+Yjkdq # nonteladico_admin # directory del db directory /var/lib/ldap # indici index objectClass eq,pres index uid eq,pres,sub index ou,cn,mail,surname,givenname eq,pres,sub index default eq,sub # ACL, il rootdn potrà accedere ad ogni DIT in RW # tutti gli altri no. access to * by * none # Impostazioni della directory cachesize 10000 checkpoint 128 15 dbnosync dirtyread searchstack 8 # gruppi dinamici overlay dynlist dynlist-attrset groupOfURLs memberURL uniqueMember
This section creates the first DIT that we will use as a overall administrative.
The database entry is “hdb” the kind of db, then I create the suffix, the password for root and rootdn.
The directory that will contain the db files, indexes, and also why the ACL.
The final part is interesting one is where mandated the use of dynamic groups.
Moving on to the third part.
# Dit 1 - oneos.it # RW access on DN "cn=admin,dc=oneos,c=it" # and for DN"cn=admin,dc=super.admin" database hdb suffix "dc=oneos,c=it" # root or superuser rootdn "cn=admin,dc=oneos,c=it" rootpw {SSHA}HXCz8umQbrq5MAcHhWwmkzjAdqaDwVln # nonteladico_1 # Dit was in a different directory, DB_CONFIG file must exists, and must wrtable for openldap user. # directory /var/lib/ldap/oneos index objectClass eq,pres index uid eq,pres,sub index ou,cn,mail,surname,givenname eq,pres,sub index default eq,sub # ACL, accesso RW per il DN "cn=admin,dc=super.admin" e accesso RW per il DN "cn=admin,dc=oneos,dc=it" access to dn.subtree="dc=oneos,c=it" by dn.exact="cn=ro,dc=oneos,c=it" read by dn="cn=admin,dc=super.admin" manage access to dn.subtree="dc=oneos,c=it" attrs=userPassword by anonymous auth access to * by * none # Impostazioni della directory cachesize 10000 checkpoint 128 15 dbnosync dirtyread searchstack 8 overlay dynlist dynlist-attrset groupOfURLs memberURL uniqueMember
Basically, the configuration is the same except for the directory where will be written
the db files, and ACLs, as we can see there is a rule that allows access to
whole tree read-only user “cn=ro, dc=oneos, c=us“.
Now that we have created multiple OpenLDAP DIT in slapd.conf we are ready to create the directory.
With the “slaptest” utility can check the quality of the settings in slapd.conf and
convertirele slapd.d in the new format.
First you need to create the directory as specified in oneos Dit 1 of slapd.conf.
$ sudo mkdir /var/lib/ldap/oneos $ sudo chown openldap:openldap /var/lib/ldap/oneos
Slapd.d
We create configurations in the new format
$ sudo slaptest -f /etc/ldap/slapd.conf -F /etc/ldap/slapd.d -Q slap_startup failed (test would succeed using the -u switch)
We can ignore this warning , because the utility attempts to start the service but the written files are not readable by the user openldap , so it fails , then you must set the proper permissions . I recommend you go and look around in slapd.d directory to see how our settings have been transformed .
$ sudo chown -R openldap:openldap /etc/ldap/slapd.d/ $ sudo chown -R openldap:openldap /var/lib/ldap/
We can start slapd
$ sudo service slapd start
If everything goes well we can start doing some query .
Ldif
At this point we have to insert the contents. I have created a file super.ldifcon the DIT information. Insert before the DN: dc=super.admin and its user ,
# Voce 1: dc=super.admin dn: dc=super.admin dc: super.admin o: super.admin objectclass: top objectclass: dcObject objectclass: organization # Voce 2: cn=admin,dc=super.admin dn: cn=admin,dc=super.admin cn: admin description: LDAP administrator objectclass: simpleSecurityObject objectclass: organizationalRole objectclass: top userpassword: {SSHA}O5ApoYquacI2RZvbg1lYFk6M4IeWsj1J # super.admin.pw
Now we insert the content using the password we put in slapd.conf for Dit administration
$ sudo ldapadd -x -D cn=admin,dc=super.admin -W -f super.ldif Enter LDAP Password: adding new entry "dc=super.admin" adding new entry "cn=admin,dc=super.admin"
Below the oneos.ldif files with statements of ldap objects , we can upload the content as per the super.ldif file.
# Voce 1: dc=oneos,c=it dn: dc=oneos,c=it dc: oneos o: oneos objectclass: top objectclass: dcObject objectclass: organization # Voce 2: cn=admin,dc=oneos,c=it dn: cn=admin,dc=oneos,c=it cn: admin description: LDAP administrator objectclass: simpleSecurityObject objectclass: organizationalRole objectclass: top userpassword: {SSHA}7E+ZwB3qy2i5Lc6fkDGZCRdBDQ1IEKcd # admin.oneos dn: cn=ro,dc=oneos,c=it cn: ro description: LDAP administrator objectclass: simpleSecurityObject objectclass: organizationalRole objectclass: top userpassword: {SSHA}ezX3jFzNKY1psbQAuZczDnlU9ECe/Vvn # ro.oneos # Voce 3: ou=Computers,dc=oneos,c=it dn: ou=Computers,dc=oneos,c=it objectclass: organizationalUnit objectclass: top ou: Computers # Voce 4: uid=marvinlap,ou=Computers,dc=oneos,c=it dn: uid=marvinlap,ou=Computers,dc=oneos,c=it description: notebook federico macaddress: b8:6b:23:4e:99:1b objectclass: account objectclass: ieee802Device uid: marvinlap # Voce 5: ou=groups,dc=oneos,c=it dn: ou=groups,dc=oneos,c=it objectclass: organizationalUnit objectclass: top ou: groups # Voce 6: cn=admin,ou=groups,dc=oneos,c=it dn: cn=admin,ou=groups,dc=oneos,c=it cn: admin memberurl: ldap:///ou=People,dc=oneos,c=it?uid?sub?(businessCategory=admin) objectclass: groupOfURLs objectclass: top # Voce 7: cn=students,ou=groups,dc=oneos,c=it dn: cn=students,ou=groups,dc=oneos,c=it cn: students memberurl: ldap:///ou=People,dc=oneos,c=it?uid?sub?(businessCategory=students) objectclass: groupOfURLs objectclass: top # Voce 8: ou=People,dc=oneos,c=it dn: ou=People,dc=oneos,c=it objectclass: organizationalUnit objectclass: top ou: People # Voce 9: uid=federico.fiordoliva,ou=People,dc=oneos,c=it dn: uid=federico.fiordoliva,ou=People,dc=oneos,c=it businesscategory: students businesscategory: admin cn: Federico Fiordoliva mail: federico.fiordoliva@gmail.com objectclass: inetOrgPerson objectclass: person objectclass: top objectclass: ieee802Device sn: federico.fiordoliva uid: federico.fiordoliva userpassword: {SSHA}XxVUDhgAwagUB7rwVej4DuFLTz7Q4wyK # federico.oneos
I have added the directory OU: People and groups . What is interesting is the use of dynamic groups , there is a fact in the user federico.fiordoliva “businesscategory” attribute in the group name , this enables the dynamic allocation of ‘ user also this attribute is multi-valued . If we look in the groups , there are two basic things for their operation , the objectclass “gropOfURLs” and “memberurl” attribute that contains a search string , it will automatically populate the “uniquemenber” attribute of the group. The inclusion of dynamic groups has made it much easier and ordered the tree research , but brings with it increased consumption of resources, especially if you abuse this mechanism .
Ldapsearch
Now that multiple OpenLDAP DIT are populated can check the ACL that we created to see if they work. We try to do a query asking the LDAP UID federico.fiordoliva in DN “dc=oneos , c=us“.
$ ldapsearch -x -LLL -s sub -D "cn=admin,dc=oneos,c=it" -b "dc=oneos,c=it" uid=federico.fiordoliva -W Enter LDAP Password:nonteladico_1 dn: uid=federico.fiordoliva,ou=People,dc=oneos,c=it businessCategory: students businessCategory: admin cn: Federico Fiordoliva mail: federico.fiordoliva@gmail.com objectClass: inetOrgPerson objectClass: person objectClass: top objectClass: ieee802Device sn: federico.fiordoliva uid: federico.fiordoliva userPassword:: e1NTSEF9RDhGajZSTWE4V0VRM3h2TWozcW0vd0xFc2FLaGNQLzI=
Now we check that the DN “cn=admin, dc=super.admin” can read the tree “dc=oneos, c=us“.
ldapsearch -x -LLL -s sub -D "cn=admin,dc=super.admin" -b "dc=oneos,c=it" uid=federico.fiordoliva -W Enter LDAP Password:nonteladico_admin dn: uid=federico.fiordoliva,ou=People,dc=oneos,c=it businessCategory: students businessCategory: admin cn: Federico Fiordoliva mail: federico.fiordoliva@gmail.com objectClass: inetOrgPerson objectClass: person objectClass: top objectClass: ieee802Device sn: federico.fiordoliva uid: federico.fiordoliva userPassword:: e1NTSEF9RDhGajZSTWE4V0VRM3h2TWozcW0vd0xFc2FLaGNQLzI=
We verified that reading works for both users , but only in the DIT cn=oneos, c=us, we also check the DIT admin.
$ ldapsearch -x -LLL -s sub -D "cn=admin,dc=oneos,c=it" -b "dc=super.admin" -W Enter LDAP Password:nonteladico_1 No such object (32)
Taking a query with DN not allowed OpenLDAP returns a message object not found , this is because the authentication is successful , but the research is prohibited, so do not show anything . At this point we checked the ACL in reading even the verifichiamole writing.
Ldapmodify
This utility allows you to edit/add/delete any attribute of an LDAP tree. Before you start, you need to create an ldif file with instructions . We use the type ” edit” and edit the user’s password federico.fiordoliva.
dn: uid=federico.fiordoliva,ou=People,dc=oneos,c=it changetype: modify replace: userPassword userPassword: {SSHA}n6oeiUdfa2n7LUnEQOIe3E48+Ht9XFIo # nonteladico.federico
$ ldapmodify -H ldapi:/// -f modify.ldif -W -D cn=admin,dc=oneos,c=it Enter LDAP Password: nonteladico_1 modifying entry "uid=federico.fiordoliva,ou=People,dc=oneos,c=it"
Let us now use the ” ro ” user to change their password.
$ ldapmodify -H ldapi:/// -f modify -W -D cn=ro,dc=oneos,c=it Enter LDAP Password: modifying entry "uid=federico.fiordoliva,ou=People,dc=oneos,c=it" ldap_modify: Insufficient access (50)
As we have seen our ACL do what we asked . Here’s how to add an attribute and populate , the test user was not a member of any dynamic group , add it to the “students” group. We create the add.ldif file with these parameters.
dn: uid=test,ou=People,dc=oneos,c=it changetype: modify add: businesscategory businesscategory: students
$ ldapmodify -H ldapi:/// -f add.ldif -W -D cn=admin,dc=oneos,c=it Enter LDAP Password: modifying entry "uid=test,ou=People,dc=oneos,c=it"
Dynamic Groups
In the creation of DIT we configured dynamic groups by loading the module “dyngroup.schema” and setting the ObjectClass “groupOfUrls memberURL uniqueMember” and ldif file we created two groups, “admin” and “students” . We verify their operation very simply . Let’s say we want to know all the members of the “students“.
$ ldapsearch -x -LLL -s sub -D "cn=ro,dc=oneos,c=it" -b "dc=oneos,c=it" -W businessCategory=students dn Enter LDAP Password: nonteladico_1 dn: uid=federico.fiordoliva,ou=People,dc=oneos,c=it dn: uid=test,ou=People,dc=oneos,c=it
The key attribute that we assigned to the user is “businesscategory” , the system reads the dynamic groups tree and dynamically adds a multi-valued attribute in it “uniquemember” with the user’s exact DN . By analyzing the user federico.fiordoliva we see that the “businesscategory” attribute , which is also multi value is populated with both groups.
ldapsearch -x -LLL -s sub -D "cn=admin,dc=super.admin" -b "dc=oneos,c=it" uid=federico.fiordoliva -W Enter LDAP Password:nonteladico_admin dn: uid=federico.fiordoliva,ou=People,dc=oneos,c=it businessCategory: students businessCategory: admin cn: Federico Fiordoliva mail: federico.fiordoliva@gmail.com objectClass: inetOrgPerson objectClass: person objectClass: top objectClass: ieee802Device sn: federico.fiordoliva uid: federico.fiordoliva userPassword:: e1NTSEF9RDhGajZSTWE4V0VRM3h2TWozcW0vd0xFc2FLaGNQLzI=
Dynamic groups are very comfortable, especially in a tree where users often change group membership or even change OU , ONLY because we need to change the value businesscategory and not the entire DN within the group as they did before . I hope this guide will be of help to those wishing to implement an OpenLDAP for your business or for those who simply wanted to study how it works .
Enjoy!
- SSH Keys pair, how to generate it and use. - Aug 18,2019
- Let’s Encrypt on pfSense – webConfigurator - Apr 04,2017
- Isc Dhcpd Openldap on Ubuntu 16.04 - Oct 03,2016
Leave a Comment