Table of Contents
LDAP con slapd 2.5.13
Aggiornando da Debian 11 a Debian 12 Bookworm che installa slapd 2.5.13, non è più supportato il vecchio backend HDB, in syslog si legge l'errore:
slapd[1081465]: lt_dlopenext failed: (back_hdb) file not found
Il backend alternativo consigliato è LMDB.
Durante l'aggiornamento (fallito) del pacchetto è stato comunque creato il backup della vecchia installazione, questa si trova in /var/backups/slapd-2.4.57+dfsg-3+deb11u1/. Conviene copiare i file presenti per lavorare su quelli.
Migrazione da HDB a MDB
La Service - Migrating from OpenLDAP 2.4.x to 2.5.x non ha funzionato; fallisce quando si tenta di ricaricare il database dc=rigacci,dc=org.ldif con il comando slapadd.
Per ripristinare il servizio si sono eseguite ex-nove tutte le operazoni necessarie, in particolare:
- Caricato lo schema mozillaAbPersonAlpha.
- Creato il database #2 per gestire il suffisso ou=Addressbook,dc=rigacci,dc=org.
- Creata la organizationalUnit Addressbook.
- Creata la inetOrgPerson cn=guest.
- Caricate tutte le entry objectClass mozillaAbPersonAlpha.
(Re)installation from scratch
By installing the slapd package from scratch, an empty LDAP database is created using the dn (distinguished name) dc=lan,dc=rigacci,dc=net (i.e. the output of the hostname --domain
- which in our case is lan.rigacci.net
- is used to generate the dc domain content parts of the name). During configuration you are asked for a password to be assigned to the admin user, i.e. to the item cn=admin,dc=rigacci,dc=net.
The LDAP database is numbered as #1; initially it contains only the root objext objectClass: organization. You can view it with the command
slapcat -n1
If you run dpkg-reconfigure slapd it is possibile to generate the LDAP database again; you can change the distinguished name, assign a different organization name and the admin password.
Actually a special database numbered #0 named cn=config is created too. Here you can view the configuration options of the database #1, the (hashed) password of the admin user, etc. You can view that special database using:
slapcat -n0
Reading the dump of database #0, you can see that the cn=config database has the olcRootDN: cn=admin,cn=config, but it does not have an olcRootPW, so you cannot modify the config database connecting with a login/password pair. See below on how to modify the cn=config database (e.g. to add a new database backend).
Enable SSL
Create a self signed certificate or get it from some provider, like Let's Encrypt. Copy the files into /etc/ldap/ssl/ and give them permissions for the openldap user.
Create the following file config-ssl.ldif:
dn: cn=config changetype: modify replace: olcTLSCertificateFile olcTLSCertificateFile: /etc/ldap/ssl/fullchain.pem - replace: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ldap/ssl/privkey.pem - replace: olcTLSCACertificatePath olcTLSCACertificatePath: /etc/ssl/cert
and load it into the slapd 2.5 configuration:
ldapmodify -Y EXTERNAL -H ldapi:/// -f config-ssl.ldif
Enable ldaps into /etc/default/slapd:
SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"
Restart the slapd service.
Adding a second (new) database
Suppose you want to create a new LDAP database, beside the #0 (the cn=config
one) and the #1 (with the suffix dc=lan,dc=rigacci,dc=net
). This is possibile because the slapd daemon can serve different DITs (Directory Information Tree) eventually using different database backends, different olcRootDN, etc. The only constraint is that different databases must have different suffixes belonging to different hierarchy trees.
To add a new LDAP database you will use the ldapadd command. You may find several tutorials on the net that instruct on how to use the slapadd command, but beware that slappadd
is not intended for incremental use; it is used for the initial configuration of the slapd service, when you feed it a single complete LDIF.
Using ldapadd
to create a new database, requires the privilege to modify the cn=config
database. The default Debian installation does not assign a password to the cn=admin,cn=config
entry, so you cannot use a standard TCP connection to the server, you must use the EXTERNAL SASL mechanism.
Here it is the example of an LDIF file to create a new DIT database, supposed to contain an addressbook. We will use the MDB backend and the /var/lib/ldap/abook/
directory will contain the data. The database will be populated later. The item cn=admin,ou=Addressbook,dc=rigacci,dc=org
is defined here and it will be used as an administrator account with full privileges on the database itself. Beware that the olcSuffix must not be a child of an already existing database suffix (notice that we used the org
top level domain instead of net
used in the previous examples).
The file was named abook-db.ldif:
dn: olcDatabase=mdb,cn=config objectClass: olcDatabaseConfig objectClass: olcMdbConfig olcDatabase: mdb olcDbDirectory: /var/lib/ldap/abook olcRootDN: cn=admin,ou=Addressbook,dc=rigacci,dc=org olcRootPW: MySecret olcSizeLimit: 1500 olcDbMaxSize: 104857600 olcSuffix: ou=Addressbook,dc=rigacci,dc=org olcDbIndex: objectClass eq olcDbIndex: cn,givenName,mail,sn eq,sub olcAccess: to * by dn="cn=admin,ou=Addressbook,dc=rigacci,dc=org" write by anonymous auth by dn="cn=guest,ou=Addressbook,dc=rigacci,dc=org" read
Notice we will grant read-only privileges to an item cn=guest in the same LDAP tree; that item will be added into the database later. Before creating the database we create the destination directory and assign the required permissions:
mkdir /var/lib/ldap/abook chmod 750 /var/lib/ldap/abook chown openldap:openldap /var/lib/ldap/abook
Method #1: connecting without a password
To integrate the new configuration into the existing one and to activete it, just run the following command as root:
ldapadd -Y EXTERNAL -H ldapi:/// -f abook-db.ldif
The new database will be created and it will be assigned the number #2. An LDIF configuration file will be created into /etc/ldap/slapd.d/cn=config/olcDatabase={2}mdb.ldif.
If the suffix is child of an already existing database, we will get the following error:
adding new entry "olcDatabase=mdb,cn=config" ldap_add: Other (e.g., implementation specific) error (80) additional info: <olcSuffix> namingContext "ou=Addressbook,dc=rigacci,dc=org" already served by a preceding mdb database
Method #2: setting a password for the cn=config database
If you want to use ldapadd
over a standard TCP connection to alter the cn=config
database, you must first add the olcRootPW attribute to the database. Create an config-chpasswd.ldif file:
dn: olcDatabase={0}config,cn=config changetype: modify replace: olcRootPW olcRootPW: ConfigMySecret
then feed this file to the running slapd service, authenticating with the EXTERNAL SASL mechanism:
ldapmodify -Y EXTERNAL -H ldapi:/// -f config-chpasswd.ldif
Now it is possibile to connect the slapd service and feed the abook.ldif, we will bind using the cn=admin,cn=config
name with the associated password:
ldapadd -x -W -D "cn=admin,cn=config" -f abook-db.ldif
Adding an additional schema
The default installation of slapd in Debian 12 creates some LDAP schemas into the default configuration; namely (see the /etc/ldap/slapd.d/cn=config/cn=schema/ directory):
- cn={0}core.ldif
- cn={1}cosine.ldif
- cn={2}nis.ldif
- cn={3}inetorgperson.ldif
Suppose you want to install an additional schema, e.g. the mozillaAbPersonAlpha, to create an address book database. Get the schema file from the Mozilla Wiki and have a look inside it; from the comments you can see that this schema depends upon core, cosine and inetorgperson, this means that no other schemas are required. Save the schema file into /etc/ldap/schema/mozillaabpersonalpha.schema.
We will use the slaptest tool in a tricky manner. First we will create a slapd-tmp.conf using the old slapd.conf(5) syntax (OpenLDAP pre-2.5 versions), then slaptest
will be used to generate, into a temporary directory, the configuration files using the new slapd-config(5) syntax. From the temporary directory only the ldif file relative the mozillaAbPersonAlpha schema will be copied into the actual slapd configuration directory.
echo "Creating a slapd-tmp.conf file..." cat << EOF > slapd-tmp.conf include /etc/ldap/schema/core.schema include /etc/ldap/schema/cosine.schema include /etc/ldap/schema/nis.schema include /etc/ldap/schema/inetorgperson.schema include /etc/ldap/schema/mozillaabpersonalpha.schema EOF echo "Converting slapd.conf(5) file into slapd-config(5) ldif files..." mkdir slapd-tmp.d slaptest -f slapd-tmp.conf -F slapd-tmp.d echo "Copying mozillaAbPersonAlpha schema into actual Slapd config..." systemctl stop slapd.service cp "slapd-tmp.d/cn=config/cn=schema/cn={4}mozillaabpersonalpha.ldif" "/etc/ldap/slapd.d/cn=config/cn=schema/" chown openldap:openldap "/etc/ldap/slapd.d/cn=config/cn=schema/cn={4}mozillaabpersonalpha.ldif" chmod 0600 "/etc/ldap/slapd.d/cn=config/cn=schema/cn={4}mozillaabpersonalpha.ldif" systemctl start slapd.service
Restore from the backup file
The upgrade process created a backup of the existing LDAP database into the /var/backups/slapd-2.4.57+dfsg-3+deb11u1/ directory. In our case there is a single file dc=rigacci,dc=org.ldif containing all the required entries. In the following examples we extracted from the file the logically different items to be restored.
Beware that the restore will be not a perfect copy of the previous database. Several tags must be purged from the backup file before feeding it back to the LDAP server because they are not allowed to be set directly. They are:
- structuralObjectClass
- entryUUID
- creatorsName
- createTimestamp
- entryCSN
- modifiersName
- modifyTimestamp
Once a snippet of the file is ready, you can feed it to the slapd service with the following command:
ldapadd -x -W -D "cn=admin,ou=Addressbook,dc=rigacci,dc=org" -f file.ldif
In the following three paragraphs we will see what is needed for a full restore.
Create the Addressbook organizationalUnit
dn: ou=Addressbook,dc=rigacci,dc=org objectClass: top objectClass: organizationalUnit ou: Addressbook
Create the Addressbook guest person
dn: cn=guest,ou=Addressbook,dc=rigacci,dc=org objectclass: top objectclass: person objectclass: organizationalPerson objectclass: inetOrgPerson sn: guest cn: guest userPassword: ReadOnlySecret
Load all the mozillaAbPersonAlpha entries
Each mozillaAbPersonAlpha item is somethink like this, after removing the unallowed tags:
dn: cn=Niccolo Rigacci,ou=Addressbook,dc=rigacci,dc=org objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson objectClass: mozillaAbPersonAlpha cn: Niccolo Rigacci givenName: Niccolo sn: Rigacci mail: niccolo@rigacci.org telephoneNumber: 055-0118525 mobile: 327-5556667 facsimileTelephoneNumber: 055-0118525 homePhone: 055-8979395 mozillaWorkUrl: http://www.rigacci.org/
Testing an ldapsearch
Finally you can test if the LDAP database is working doing a full search with ldapsearch:
ldapsearch -W \ -H ldap://127.0.0.1/ \ -D "cn=guest,ou=Addressbook,dc=rigacci,dc=org" \ -b 'ou=Addressbook,dc=rigacci,dc=org'
The ldap protocol is on port 389/tcp, ldaps is on 636/tcp.