Clément OUDOT : OpenLDAP et l'overlay "constraint" : augmentez la qualité des données de votre annuaire
jeudi 30 mai 2013 à 14:15Enlarge your quality
Un annuaire LDAP n'est pas une base de données : les données d'un annuaire sont organisées de manière hiérarchique et respectent un schéma définissant les classes d'objet et attributs autorisés, en plus des syntaxes et règles de comparaison associées aux attributs.
Ces éléments permettent déjà d'assurer une certaine maîtrise de la qualité des données, par exemple :
- Forcer la présence d'attributs dans une entrée en rendant ces attributs obligatoires pour la classe d'objet de l'entrée
- Contrôler que la valeur saisie est un DN en définissant la syntaxe de l'attribut comme
DistinguishedName
Toutefois, ces vérifications peuvent s'avérer insuffisantes et autoriser des valeurs incohérentes dans l'annuaire LDAP.
Un manager exemplaire
Prenons l'exemple de l'attribut manager
: il permet de définir le supérieur hiérarchique d'une personne. Sa définition technique est la suivante :
olcAttributeTypes: ( 0.9.2342.19200300.100.1.10 NAME 'manager' DESC 'RFC127 4: DN of manager' EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115 .121.1.12 )
Comme les créateurs de LDAP font bien les choses, la syntaxe de cet attribut est un DN (1.3.6.1.4.1.1466.115.121.1.12
), ce qui semble assez logique puisque l'on renseignera comme valeur le DN d'une autre entrée dans l'annuaire. Ainsi, impossible de définir la valeur suivante :
manager: Bill Gates
Par contre, cette valeur sera correcte :
manager: CN=Bill Gates,CN=users,DC=Microsoft,DC=com
Correcte syntaxiquement peut-être, mais fonctionnellement ?
En tant qu'utilisateurs émérites d'un annuaire LDAP, nous sommes en droit d'exiger plus de contrôle, par exemple :
- Que l'entrée existe dans l'annuaire
- Qu'elle fasse soit située dans la branche des utilisateurs
- Qu'elle possède la classe d'objet
inetOrgPerson
- Qu'elle soit dans le même département ou structure
- ...
Travaillons sous la contrainte
OpenLDAP possède un système de greffons nommé overlay. Chaque overlay permet l'activation d'une fonctionnalité, comme par exemple la gestion des groupes dynamiques (voir l'article dédié).
Pour notre problématique du jour, nous allons nous intéresser à l'overlay constraint
. Cet overlay doit être compilé pour pouvoir être chargé, c'est le cas si vous utilisez les RPMs de LDAP Tool Box.
L'overlay constraint
permet d'ajouter des contraintes sur les valeurs des attributs. Comme tout overlay, il n'agit que sur les opérations LDAP, et ne corrigera donc pas les données déjà enregistrées, cet overlay retournera par contre un message d'erreur si une opération LDAP modifie une valeur non compatible avec les règles déclarées (code d'erreur 19 - CONSTRAINT_VIOLATION
).
Il existe cinq types de contraintes :
- regex : comparaison de la valeur avec une expression régulière
- size : taille maximale de la valeur (nombre de caractères)
- count : nombre maximum de valeurs
- uri : les valeurs doivent correspondre à une recherche LDAP interne
- set : utilisation des capacités des sets des ACLs OpenLDAP
Le champ d'application de ces contraintes peut-être restreint à l'aide d'une recherche LDAP interne (clause restrict
).
Les doigts dedans
Maintenant que les présentations sont faites, voyons comment implémenter nos contraintes.
La création de l'overlay doit se faire dans le backend cn=config. Vous pouvez utiliser la ligne de commande, un navigateur LDAP, ou (et je vous le conseille bien entendu), LinID OpenLDAP Manager.
En LDIF, cela donne par exemple :
dn: olcOverlay={3}constraint,olcDatabse={1}bdb,cn=config objectClass: olcConfig objectClass: olcConstraintConfig objectClass: olcOverlayConfig objectClass: top olcOverlay: {3}constraint
Reste à définir ensuite les contraintes en tant que telles, dans l'attribut olcConstraintAttribute
.
Commençons par le plus simple : la valeur de l'attribut manager doit correspondre à une entrée existante de l'annuaire :
olcConstraintAttribute: manager uri ldap:///dc=example,dc=com?entrydn?sub?(objectClass=*)
Si on souhaite que cette entrée soit explicitement un utilisateur (présence dans la branche ou=users, et avec la classe inetOrgPerson) :
olcConstraintAttribute: manager uri ldap:///ou=users,dc=example,dc=com?entrydn?sub?(objectClass=inetOrgPerson)
Peut-être qu'en fait cette contrainte ne doit être appliquée que pour les entrées de la branche ou=users, dans ce cas :
olcConstraintAttribute: manager uri ldap:///ou=users,dc=example,dc=com?entrydn?sub?(objectClass=inetOrgPerson) restrict "ldap:///ou=users,dc=example,dc=com??sub?(objectClass=*)"
Je pense que vous avez saisi le concept.
Set épatant
Avant de terminer, voyons une règle un peu plus complexe : il faut que le manager de l'utilisateur appartienne au même service que lui. En considérant que le service d'un utilisateur est défini dans son attribut departmentNumber
, on utilisera alors la règle suivante :
olcConstraintAttribute: manager set "this/departmentNumber & this/manager/departmentNumber" restrict "ldap:///ou=users,dc=example,dc=com??sub?(objectClass=*)"
On mesure ici la puissance des sets d'OpenLDAP, créés initialement pour définir des ACLs complexes, et très utiles ici pour la définition de contraintes.
À très bientôt pour de nouveaux articles sur les configurations avancées d'OpenLDAP !
Original post of Clément OUDOT.Votez pour ce billet sur Planet Libre.
Articles similaires
- Clément OUDOT : Sujet du jour : comment instaurer une politique des mots de passe commune à OpenLDAP et Samba ? (04/03/2011)
- Clément OUDOT : Nouveaux RPMs pour OpenLDAP 2.4.24 sur LTB-project (25/03/2011)
- Clément OUDOT : Sortie des RPMs OpenLDAP 2.4.28 sur LDAP Tool Box Project (02/12/2011)
- Clément OUDOT : Mémoriser la dernière authentification dans OpenLDAP (12/06/2012)
- Clément OUDOT : Astuce OpenLDAP : Des groupes dynamiques ? Jamais sans tri des valeurs ! (07/01/2013)