Toolinux Linto.AI OpenPAAS OBM Hubl.IN Linagora

OpenLDAP et l’overlay "constraint" : augmentez la qualité des données de votre annuaire

lundi 3 juin 2013

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=3constraint,olcDatabse=1bdb,cn=config
objectClass : olcConfig
objectClass : olcConstraintConfig
objectClass : olcOverlayConfig
objectClass : top
olcOverlay : 3constraint

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.

- Clément OUDOT