Depuis la version 2.4, le moteur de stockage recommandé par défaut pour OpenLDAP est MDB ou LMDB (Lightning Memory-Mapped Database). Dans les distributions Red Hat par contre, c'est toujours le moteur BDB (Berkeley DataBase), ou son évolution HDB (Hierarchical Database) qui est recommandé et utilisable, vu la version ancienne utilisé : 2.4.23.
HDB est une variante du backend BDB. HDB utilise un modèle hiérarchique, qui supporte notamment le renommage d'un sous-arbre. Etant basé sur BDB, les mêmes options de configurations sont présentes.
OpenLDAP recommande d'utiliser la version la plus récente de l'annuaire, qui corrige des bugs et apporte des améliorations. En cette fin d'année 2013, c'est actuellement la version 2.4.38.
Si l'on a installé un OpenLDAP depuis plusieurs années, on peut vouloir changer le moteur, afin d'améliorer les performances et de s'assurer du support OpenLDAP.
On peut facilement créer un suffixe avec une base BDB ou HDB, via la commande :
ldapadd -c -x -D cn=admin,cn=config -w password -f newbdb.ldif
Si on utilise une authentification système (par défaut), la commande sera la suivante :
ldapadd -Y EXTERNAL -H ldapi:/// -f newbdb.ldif
Le contenu du fichier newbdb.ldif étant le suivant :
dn: olcDatabase=bdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcBdbConfig
olcDatabase: bdb
olcSuffix: dc=example,dc=bdb
olcDbDirectory: /data/openldap/example-bdb
olcRootDN: cn=Manager,dc=example,dc=bdb
olcRootPW: secret
olcDbIndex: uid pres,eq
olcDbIndex: cn,sn pres,eq,approx,sub
olcDbIndex: objectClass eq
olcDbCacheSize: 20000
olcDbCheckpoint: 512 30
olcDbConfig: set_cachesize 0 10485760 0
olcDbConfig: set_lg_bsize 2097512
olcDbConfig: set_flags DB_LOG_AUTOREMOVE
olcAccess: to attrs=userPassword
by self write
by anonymous auth
by dn.base="cn=Manager,dc=example,dc=bdb" write
by * none
olcAccess: to *
by self write
by dn.base="cn=Manager,dc=example,dc=bdb" write
by * read
Idem pour un backend HDB :
dn: olcDatabase=hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: hdb
olcSuffix: dc=example,dc=hdb
olcDbDirectory: /data/openldap/example-hdb
olcRootDN: cn=Manager,dc=example,dc=hdb
olcRootPW: secret
olcDbIndex: uid pres,eq
olcDbIndex: cn,sn pres,eq,approx,sub
olcDbIndex: objectClass eq
olcDbCacheSize: 20000
olcDbCheckpoint: 512 30
olcDbIDLcacheSize: 320000
olcDbConfig: set_lg_bsize 2097512
olcDbConfig: set_flags DB_LOG_AUTOREMOVE
olcAccess: to attrs=userPassword
by self write
by anonymous auth
by dn.base="cn=Manager,dc=example,dc=hdb" write
by * none
olcAccess: to *
by self write
by dn.base="cn=Manager,dc=example,dc=hdb" write
by * read
Les options olcDbConfig permettent de générer le fichier DB_CONFIG dans le répertoire des données.
Note : pour une database de type hdb, la valeur idlcachesize doit être importante pour avoir de bonnes performances en lecture / recherche, typiquement 3 fois ou plus la taille du cache d'entrées.
Note : il faut auparavant avoir créer le répertoire correspondant à olcDbDirectory, et mettre le compte ldap comme propriétaire de ce répertoire. Par exemple :
mkdir -p /data/openldap/example-hdb
chown ldap:ldap /data/openldap/example-hdb
Si on utilise les 2 backends conjointement sur le même serveur, le démarrage du daemon slapd donne un message d'avertissement :
back-bdb/back-hdb monitor: "olmBDBAttributes" previously defined "1.3.6.1.4.1.4203.666.1.55.0.1.1"
back-bdb/back-hdb monitor: "olmBDBObjectClasses" previously defined "1.3.6.1.4.1.4203.666.3.16.0.1.1"
Le modèle HDB permet de renommer un sous-arbre complet via l'opération modrdn, mais pas BDB. Par exemple, si on a le fichier ldif suivant :
dn: ou=BACKEND-HDB,ou=users,dc=example,dc=corp
changetype: modrdn
newrdn: ou=BACKEND-RENAMED
deleteoldrdn: 1
Sur l'annuaire 121 cette database utilise BDB. On a alors :
ldapmodify -x -h 192.168.56.121 -D "cn=admin,dc=example,dc=corp" -w secret modrdn.ldif
ldap_initialize( ldap://192.168.56.121 )
modifying rdn of entry "ou=BACKEND-HDB,ou=users,dc=example,dc=corp"
new RDN: "ou=BACKEND-RENAMED" (do not keep existing values)
ldap_rename: Operation not allowed on non-leaf (66)
additional info: subtree rename not supported
Sur l'annuaire 122, la database utilise HDB. Le résultat est différent :
ldapmodify -x -h 192.168.56.122 -D "cn=admin,dc=example,dc=corp" -w secret modrdn.ldif
ldap_initialize( ldap://192.168.56.122 )
modifying rdn of entry "ou=BACKEND-HDB,ou=users,dc=example,dc=corp"
new RDN: "ou=BACKEND-RENAMED" (do not keep existing values)
rename complete
On peut tout à fait avec deux moteurs différents sur 2 serveurs qui se répliquent. Ceci permet par exemple de procéder par étape pour un changement de backend sur une architecture avec de multiples serveurs.
Les tests effectués en mode master / miroir ont montré que la réplication fonctionnait de manière tout à fait normale, sauf dans un cas : le renommage de subtree sur l'annuaire utilisant HDB. Dans ce cas, l'opération n'est pas répliquée sur le serveur utilisant BDB.
Le backend MDB peut être instancié avec peu d'éléments :
dn: olcDatabase=mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: mdb
olcSuffix: dc=example,dc=mdb
olcDbDirectory: /data/openldap/example-mdb
olcRootDN: cn=Manager,dc=example,dc=mdb
olcRootPW: secret
olcDbMaxSize: 1073741824
La variable olcDbMaxSize doit être égale (ou supérieure) à la taille des données de l'annuaire, car le moteur MDB travaille en mémoire.
Les backends n'étant pas compatible physiquement, il n'est pas possible de modifier uniquement la configuration de la Database. Le changement de type de backend comporte également une migration de données, qui doit s'effectuer de manière "logique" :
Deux options peuvent être envisagées :
Dans ce cas, on copie / renomme les fichiers /etc/openldap/slapd.d/cn=config/olcDatabase={X}bdb.ldif en /etc/openldap/slapd.d/cn=config/olcDatabase={X}hdb.ldif et on modifie les instances bdb par hdb :
dn: olcDatabase={2}bdb
objectClass: olcBdbConfig
olcDatabase: {2}bdb
structuralObjectClass: olcBdbConfig
devient
dn: olcDatabase={2}hdb
objectClass: olcHdbConfig
olcDatabase: {2}hdb
structuralObjectClass: olcHdbConfig
Les modifications doivent être faites une fois l'annuaire arrêté.
Si on a mis en place des overlays, il faut également renommer le répertoire content la définition de ces overlays. Dans notre cas, le répertoire
/etc/openldap/slapd.d/cn=config/olcDatabase={2}bdb
sera renommé en
/etc/openldap/slapd.d/cn=config/olcDatabase={2}hdb
Dans cette option, il faut supprimer la database déclarée avec bdb, et ajouter la même database utilisant hdb. En effet, il n'est pas possible d'utiliser 2 databases pour le même root Suffix.
Il faut tout d'abord identifier le numéro de la database utilisée :
ldapsearch -D 'cn=admin,cn=config' -w secret -x -b "cn=config" "objectclass=olcbdbconfig"
# {4}bdb, config
dn: olcDatabase={4}bdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcBdbConfig
olcDatabase: {4}bdb
olcDbDirectory: /product/openldap/data/example-bdb
olcSuffix: dc=example-bdb,dc=com
olcAccess:: ezB9dG8gYXR0cnM9dXNlclBhc3N3b3JkIGJ5IHNlbGYgd3JpdGUgIGJ5IGFub255bW
91cyBhdXRoICBieSBkbi5iYXNlPSJjbj1BZG1pbixkYz1leGFtcGxlLWJkYixkYz1jb20iIHdyaXR
lIGJ5ICogbm9uZSA=
olcAccess: {1}to * by self write by dn.base="cn=Admin,dc=example-bdb,dc=com" w
rite by * read
olcRootDN: cn=Manager,dc=example-bdb,dc=com
olcRootPW: secret
olcDbIndex: uid pres,eq
olcDbIndex: cn,sn pres,eq,approx,sub
olcDbIndex: objectClass eq
Dans notre exemple, c'est la database numéro 4 qu'il faudra supprimer.
La suppression n'est pas (a priori) faisable via une commande ldap. Il faut donc arrêter le service slapd, et supprimer le fichier manuellement.
Il faut également se positionner dans le répertoire des données, et supprimer tous les fichiers (que l'on aura sauvegardé auparavant, bien sûr).
La nouvelle database peut être crée via un fichier LDIF, une fois le service redémarré. Dans notre exemple, le fichier LDIF est :
dn: olcDatabase=hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: hdb
olcSuffix: dc=example-bdb,dc=com
olcDbDirectory: /product/openldap/data/example-bdb
olcRootDN: cn=Manager,dc=example-bdb,dc=com
olcRootPW: secret
olcDbIndex: uid pres,eq
olcDbIndex: cn,sn pres,eq,approx,sub
olcDbIndex: objectClass eq
olcAccess: to attrs=userPassword
by self write
by anonymous auth
by dn.base="cn=Admin,dc=example-bdb,dc=com" write
by * none
olcAccess: to *
by self write
by dn.base="cn=Admin,dc=example-bdb,dc=com" write
by * read
La création s'effectue de la manière suivante :
service slapd start
ldapadd -D 'cn=admin,cn=config' -w secret -x -f hdb-conf.ldif
On peut alors charger les données issues du slapcat, après avoir arrêté le daemon via la commande :
service slapd stop
slapadd -b BASE -q -l FICHIER.ldif
Il faut ensuite remettre les droits corrects sur les données.
Si on passe d'un serveur à un autre, il faut également récupérer toutes les définitions de schéma.
De même, il faut s'assurer que les overlays soient en place sur les 2 configurations, sinon l'import des données risque de tombe en erreur. Notamment les attributs liés aux password policy
Note : Le core.ldif ne contient plus l'attribut userPassword ? (commenté dans /etc/ldap/schema/core.ldif). Il faut alors modifier : pwdAttribute: userPassword en pwdAttribute: 2.5.4.35
syntaxe de pwdAttribute = OID