II. Présentation de la norme LDAP▲
Ce chapitre présentera la norme LDAP, en abordant tout d'abord son historique, puis en décrivant la norme elle-même et les usages qui en sont faits.
II-A. Historique▲
II-A-1. Simplification du protocole d'accès▲
La difficulté rencontrée lors de l'implémentation du protocole DAP provient de sa modélisation basée sur la pile OSI. Pour éviter d'avoir à écrire toutes les couches OSI, d'autres protocoles ont été définis pour accéder aux annuaires X500 en s'appuyant sur TCP/IP. Il y a eu ainsi deux nouveaux protocoles de définis au début des années 90 : Directory Assistance Service (DAS) et Directory Interface to X.500 Implemented Efficiently (DIXIE). Ces deux protocoles ont malheureusement été conçus pour s'interfacer à une implémentation donnée d'un serveur X500.
C'est pour cela qu'un groupe de lIETF, le groupe Open Systems Interconnection-Directory Services (OSI-DS) s'est réuni pour concevoir une simplification du protocole DAP. Après deux premières RFC de 1993, le résultat final de ces travaux a été les RFC [rfc1777], [rfc1778] et [rfc1779] publiées en mars 1995 et définissant la version 2 du protocole DAP Allégé (Lightweight), LDAP.
À cette étape, le protocole LDAP est une simplification avancée de DAP, fournissant quasiment les mêmes fonctionnalités, mais représentant davantage d'informations sous la forme de chaînes de caractères et utilisant un sous-ensemble de l'encodage de DAP. Et bien sûr LDAP utilise TCP comme couche réseau..
II-A-2. Simplification du serveur▲
Le protocole LDAP n'étant qu'une simplification du protocole DAP, c'est-à-dire de la couche réseau, les requêtes LDAP devaient être converties en DAP par des serveurs intermédiaires avant d'être transmises à des serveurs X500. Début 1995, 99% des serveurs X500 sont accédés par LDAP. Mais les implémentations des serveurs continuent à être complexes.
Après avoir écrit la première implémentation du protocole LDAP l'Université du Michigan écrit un serveur natif LDAP, pour pouvoir se débarrasser des serveurs intermédiaires passerelles entre les requêtes DAP LDAP. Dès le départ ce serveur est fourni avec ses sources et un kit de développement, ce qui a favorisé la propagation de la norme.
Début 1996 Netscape prend la tête d'une coalition pour promouvoir l'usage de LDAP.
II-A-3. Première évolution: vers la version 3▲
Après la version 2 de la norme, il était nécessaire d'y apporter quelques modifications pour répondre à quelques difficultés rencontrées. L'évolution de la norme vers la version 3 a intégré :
- L'utilisation de l'encodage UTF-8 pour pouvoir manipuler des chaînes de n'importe quelle langue.
- Les referrals ont été normalisés. Ils n'étaient pas présents dans la version 2 de LDAP.
- L'opération de connexion à un annuaire a été modifiée pour accepter le protocole Simple Authentication and Security Layer (SASL), et Transport Layer Security (TLS).
- La norme inclut maintenant des mécanismes d'extension. Il est possible de réaliser des opérations supplémentaires à celles décrites dans la norme, tout en s'appuyant sur le protocole existant. Il est aussi possible, par le biais de contrôle, de modifier le comportement des opérations de base.
- Un annuaire peut être interrogé pour accéder à son schéma, et pour connaître les extensions et les contrôles qu'il implémente.
- Intégration dans la norme LDAP du schéma X500. Certaines classes d'objets et attributs définis dans la norme X500 doivent être reconnus par les serveurs LDAP.
La norme LDAP version 3 est définie dans la [rfc3377] qui est en réalité une méta RFC. En effet cette RFC définit la norme LDAP version 3 comme une liste de RFC.
Cette liste de RFC est la suivante :
[rfc2251] |
Définition du protocole réseau LDAP, du modèle LDAP et des différentes opérations. |
[rfc2252] |
Définition de la syntaxe des attributs. |
[rfc2253] |
Syntaxe des DN et leur représentation en UTF-8. |
[rfc2254] |
Définition des filtres de recherche. |
[rfc2255] |
Définition des url. |
[rfc2256] |
Éléments des schémas de base LDAP. |
[rfc2829] |
Méthodes d'authentification. |
[rfc2830] |
Description d'une opération Start TLS, qui permet à un client et à un serveur d'établir une connexion sécurisée. |
La version 3 de la norme est entièrement compatible avec la version 2. Les clients se basant encore sur la version 2 peuvent se connecter sur des serveurs implémentant la version 3. Dans le cas du serveur d'Openldap à partir de la version 2.1 cela nécessite un paramétrage particulier.
II-B. Description de la norme▲
II-B-1. Description générale▲
II-B-1-a. Contenu de la norme▲
Comme on vient de le voir, la norme LDAP est définie par un ensemble de RFC. Nous allons maintenant aborder ce que définissent ces RFC :
Le protocole réseau LDAP |
Il s'agit du protocole réseau, s'appuyant sur TCP/IP permettant d'accéder à l'information contenue dans l'annuaire. C'est de lui qu'est née la norme LDAP. |
Le modèle d'information |
Il définit la forme et le type d'informations stockées dans l'annuaire. |
Le modèle de nommage |
Il définit l'organisation, le référencement et l'accessibilité de l'information dans l'annuaire. |
Le modèle fonctionnel |
Il définit l'ensemble des opérations permettant d'accéder à l'information dans l'annuaire, que ce soit en lecture ou en écriture. |
Le modèle de sécurité |
Il définit les mécanismes d'authentification auprès de l'annuaire. |
Un modèle de répartition |
Il définit comment un annuaire peut être réparti entre plusieurs serveurs. |
Des méthodes d'extensions |
La norme définit des méthodes pour pouvoir d'une part ajouter de nouvelles opérations à celles définies dans le modèle fonctionnel, et d'autre part pour modifier le comportement des fonctions du modèle. |
Bien que cela ne soit pas inclus stricto sensu dans la norme définie par la [rfc3377], il est d'usage de considérer que le format de fichier LDIF défini dans la [rfc2849] fait partie de la norme, ainsi que des API de programmation en C.
II-B-1-b. Le protocole LDAP▲
Le protocole LDAP est défini dans la [rfc3377], qui est une mise à jour de la [rfc1777]. Ce protocole réseau basé sur TCP/IP décrit de façon classique les interactions entre un client et un serveur. Le protocole permet d'effectuer indifféremment des opérations synchrones ou asynchrones. Les serveurs peuvent répondent à un client par un referral, c'est-à-dire par un pointeur vers un autre serveur que le client devra contacter de lui-même.
Le protocole définit un ensemble de commandes de base standards, correspondant en fait aux opérations définies par le modèle fonctionnel. Il existe néanmoins la possibilité d'effectuer des opérations étendues, pourvu que client et serveur sachent tous deux les gérer.
Bien que la plupart des données transmises soient encodées sous la forme de chaînes, la syntaxe BER est utilisée, si bien que les données envoyées ne sont jamais de l'ASCII. L'avantage de cette syntaxe est bien sûr son indépendance vis-à-vis du système d'exploitation et de la machine. L'inconvénient est qu'il n'est pas possible de tester un serveur ou un client LDAP avec l'illustre commande telnet.
II-B-2. Modèle de données▲
Les informations de l'annuaire sont appelées des entrées. Chaque entrée est constituée d'un ensemble d'attributs, chaque attribut d'une entrée ayant une ou plusieurs valeurs. Les attributs ont une syntaxe. Les attributs peuvent aussi avoir des options. Par exemple une entrée de l'annuaire pourrait modéliser une personne et posséder un attribut s'appelant telephone, ayant une syntaxe de numéro de téléphone. Cette entrée de l'annuaire pourrait avoir deux valeurs, chacune de ces valeurs devant respecter la syntaxe numéro de téléphone.
Plus précisément chaque entrée de l'annuaire appartient à une ou plusieurs classes d'objets. Ce sont les classes d'objets qui définissent quels attributs une entrée peut avoir. Les classes d'objet qui définissent aussi les attributs qui sont obligatoires et ceux qui ne le sont pas.
Un annuaire connaît un certain nombres d'attributs et de classes d'objet. La norme LDAP et en particulier les [rfc2256] et [rfc2252] en définissent plusieurs issus des annuaires X500. L'ensemble des classes d'objets et des attributs que connaît un annuaire, ainsi que les syntaxes et les règles de correspondance que nous verrons plus tard, constituent le schéma d'un annuaire. Un chapitre dédié présente en détail les schémas d'annuaire, et par là même le modèle des données LDAP.
II-B-3. Modèle de nommage▲
Les entrées d'un annuaire sont stockées dans une structure arborescente. L'arbre des entrées s'appelle l'arbre informationnel de l'annuaire (Directory Information Tree en anglais). Le sommet de l'arbre de l'arbre s'appelle le suffixe, ou bien la racine.
Chaque entrée dans l'annuaire possède un identifiant. Cet identifiant est constitué du chemin qui mène de la racine à l'entrée. Ce chemin s'appelle le Distinguish Name, que l'on peut traduire par le nom distinctif. On préférera utiliser l'abréviation DN par la suite.
Alors que le DN est l'identifiant absolu d'une entrée dans un annuaire, le RDN, pour Relative Distinguish Name, ou encore nom distinctif relatif, est son identifiant relatif. Un RDN est constitué d'un attribut de l'entrée et d'une de ses valeurs. L'attribut choisi devra donc identifier l'entrée par rapport aux autres entrées du même parent.
Bien que cela soit peu utilisé, il est possible d'avoir plusieurs attributs qui servent de RDNs.
II-B-4. Modèle fonctionnel▲
II-B-4-a. Ensemble des opérations▲
La norme LDAP définit neuf opérations de base, que l'on peut regrouper en trois catégories :
Authentification et contrôle |
Bind |
Connexion à l'annuaire |
Unbind |
Déconnexion |
|
Abandon |
Pour interrompre une opération en cours |
|
Opérations d'interrogation |
Search |
l'opération de recherche, détaillée ci-dessous; |
Compare |
L'opération de comparaison |
|
Opération d'écriture |
add |
Pour ajouter une entrée dans l'annuaire |
delete |
Pour effacer une entrée |
|
modify |
Pour modifier le contenu d'une entrée, c'est-à-dire modifier les valeurs de ses attributs. Éventuellement rajouter des valeurs, en effacer ou supprimer, quelques valeurs ou toutes |
|
modifyDN |
L'opération précédente ne permet pas de modifier l'identifiant d'une entrée. Il n'est pas possible à l'opération modify de modifier la valeur d'un attribut qui sert de RDN(3). L'opération modifyDN est dédiée à cette action |
Nous n'entrerons pas dans le détail de chacune de ces opérations. Nous nous contenterons d'en étudier une seule, l'opération de recherche.
II-B-4-b. La fonction recherche▲
L'opération de recherche est à la fois l'une des plus utilisées, et l'une des plus significatives. Connaître son fonctionnement permet de comprendre comment marche LDAP. Sa description dans la [rfc2251] est la plus longue parmi celles des neuf opérations. Elle décrite dans la section 4.5, de la page 25 à la page 31.
La liste des paramètres de cette fonction est donc la suivante :
baseObject |
Entrée à partir de laquelle la recherche est effectuée. |
|
scope |
Profondeur de la recherche. Il y a trois types de profondeur possible : |
|
base |
La recherche ne s'effectuera que sur le baseObject. La recherche devient alors l'équivalent d'une lecture, à condition toutefois que le baseObject réponde positivement au filtre. |
|
one |
Tous les enfants directs du baseObject et seulement les enfants directs sont concernés par la recherche. |
|
sub |
Tous les descendants de baseObject, ainsi que baseObject lui-même sont concernés par la recherche |
|
derefAliases |
Ce paramètre indique comment doivent être considérés les objets de type alias. Une entrée de classe alias est une copie d'une autre entrée de l'annuaire, qui apparaît aussi à plusieurs endroits de l'annuaire. Il y a trois valeurs possibles : |
|
neverDerefAliases |
La recherche ne va jamais traiter les alias qu'elle rencontrera au sens où elle n'ira pas effectuer la recherche sur les entrées originales pointées par les éventuels alias |
|
derefInSearching |
L'alias est résolu seulement dans les entrées sous le baseObject, mais pas dans le baseObject lui même |
|
derefFindingBaseObj |
L'alias est résolu, l'entrée originale sera lue, seulement dans le baseObject |
|
derefAlways |
Les alias seront toujours résolus |
|
sizeLimit |
Nombre maximum d'entrées retournées par la recherche. 0 signifie aucune limite imposée par le client |
|
timeLimit |
Temps en secondes maximum permis pour l'exécution de la requête. 0 signifie aucune limite imposée par le client |
|
typesOnly |
Booléen indiquant si la recherche doit retourner les valeurs des attributs, avec leur type ou pas |
|
filter |
Filtre de recherche. La syntaxe des filtres est explicitée dans un autre chapitre |
|
attributes |
Liste des attributs à retourner pour les entrées récupérées par la recherche. Si ce paramètre contient une chaîne vide ou bien *, tous les attributs seront retournés. Certains attributs demandés peuvent ne pas être retournés si l'utilisateur n'a pas le droit d'accès dessus. Mais aucun message d'erreur ne sera renvoyé, puisqu'il aura accès aux autres attributs. Si l'attribut dont l'OID est 1.1 transmis, cela signifie que le client n'attend aucun attribut |
II-B-5. Modèle de sécurité▲
Un annuaire LDAP peut nécessiter une authentification. L'originalité des serveurs LDAP consiste en ce que l'utilisateur devra s'authentifier en se présentant comme une entrée de l'annuaire. Au lieu du traditionnel login utilisé par d'autres types d'applications, un DN devra être fourni.
L'opération bind est l'opération de connexion et d'authentification auprès d'un serveur annuaire en endossant l'identité d'une entrée. Cette opération peut être simple, auquel cas l'utilisateur doit donner un mot de passe, ou bien elle peut prendre en paramètre un jeton SASL.
II-B-6. Étendre LDAP▲
Dès la conception du protocole LDAP dans sa version 3, il a été prévu d'y intégrer la possibilité d'étendre la norme, soit en modifiant le comportement des opérations existantes, soit en ajoutant des nouvelles opérations. Nous allons dans cette section décrire ces deux possibilités.
II-B-6-a. Les contrôles▲
Les contrôles sont un mécanisme qui permet de modifier le comportement des opérations standards. Ils sont envoyés par le client au serveur, en même temps qu'une requête classique. Ils sont décrits dans le paragraphe 4.1.12 de la [rfc2251].
Dans une requête, un contrôle est caractérisé par :
Type |
Il s'agit d'un identifiant du contrôle, sous la forme d'un OID |
Criticité |
Un booléen qui indique si le contrôle est critique ou pas. Si le contrôle est signalé comme étant critique par le client, le serveur doit absolument exécuter la requête avec le contrôle associé. S'il ne le peut pas, par exemple parce qu'il n'implémente pas le contrôle ou parce que le contrôle est inapproprié avec la requête demandée, il doit retourner l'erreur unsupportedCriticalExtension et ne pas exécuter la requête |
Valeur |
Ce champ est utilisé pour transmettre des valeurs supplémentaires ; son contenu dépend donc du contrôle |
Les contrôles peuvent être aussi retournés par un serveur dans une réponse à un client. Ainsi des interactions sont possibles entre le client et le serveur. Un exemple d'une telle interaction est le contrôle de recherche paginée, défini dans la [rfc2696] et supporté par Openldap à partir de version 2.2.
Ce contrôle permet à un client d'effectuer une recherche, et de récupérer le résultat de sa recherche par blocs, au lieu de recevoir toutes les entrées en une seule fois. Lorsqu'il reçoit une telle requête, le serveur inclus dans sa réponse le même contrôle, en y incluant un identifiant dans le champ valeur. Cet identifiant sera ensuite renvoyé par le client à son tour, afin de demander le bloc suivant.
D'autres contrôles ne nécessitent pas une telle interaction. C'est le cas du contrôle matchedValuesOnly, dont l'OID est 1.2.826.0.1.3344810.2.2, et qui est encore à l'état de draft auprès de l'IETF. Ce contrôle, qui doit être associé à une recherche, demande à un serveur de ne retourner, parmi toutes les valeurs des attributs d'une entrée, que celles qui ont répondu positivement au filtre de la recherche. Ce contrôle est supporté par Openldap.
II-B-6-b. Les opérations étendues▲
La section 4.12 de la [rfc2251] décrit les opérations étendues. Les opérations étendues sont des opérations dont la syntaxe et la sémantique pourront être définies dans des documents futurs. Il est ainsi possible aux clients et aux serveurs LDAP d'effectuer des opérations supplémentaires aux neuf opérations vues précédemment. Il faut évidemment que le serveur implémente l'opération étendue demandée par le client.
Une opération étendue, et la réponse d'un serveur à une telle opération sont décrites très succinctement par la RFC. Elles sont composées très simplement d'un identifiant, un OID donc, de la requête ou de la réponse, et d'un champ supplémentaire contenant des données, dont la signification dépend du contexte.
Que ce soit pour les contrôles ou pour les opérations étendues, il est préférable pour le client de connaître à l'avance quelles extensions supportent le serveur. La section suivante décrit comment le client peut obtenir ces informations du serveur, en se basant toujours sur le protocole LDAP.
II-B-7. Meta recherche▲
La [rfc2251] dans sa section 3.4 a prévu un mécanisme permettant de découvrir les extensions, les contrôles et le schéma d'un serveur annuaire. Cela permet au client d'interagir au mieux avec un serveur, en évitant, par exemple, de créer ou de modifier des objets de façon illégale vis-à-vis du schéma, ou bien de ne demander que les contrôles et les opérations étendues implémentées par le serveur.
II-B-7-a. Le Root DSE▲
Pour obtenir des informations sur les capacités d'un annuaire il faut interroger une entrée spéciale qui s'appelle le Root DSE. Cette entrée n'a aucun DN, et doit être récupérée avec le filtre (objectclass=*). Elle ne doit pas être retournée autrement que par une requête avec ce filtre et dont le base_dn est vide. Elle peut être soumise à des restrictions de contrôle d'accès. La [rfc2251] précise que le serveur pourrait autoriser la modification des attributs de cette entrée, mais Openldap lui ne le permet pas.
Voici la liste des attributs d'un Root DSE définis par [rfc2251] :
namingContexts |
Liste des suffixes gérés par le serveur |
subschemaSubentry |
DN de l'entrée subschema. Cette entrée contient une description du schéma gérée par le serveur. Cet attribut peut être absent si le serveur ne gère pas lui-même des entrées schéma. Il est multiple, dans le cas où le serveur gère plusieurs annuaires, chacun ayant son propre schéma |
altServer |
Serveur à contacter si le serveur ne répond plus |
supportedExtension |
Liste des opérations étendues supportées |
supportedControl |
Liste des contrôles supportés |
supportedSASLMechanisms |
Liste des fonctionnalités SASL supportées |
supportedLDAPVersion |
Version du protocole LDAP supportée par le serveur |
II-B-7-b. Les entrées subschema▲
Nous venons de voir comment récupérer un certain nombre d'informations sur un annuaire, et en particulier comment récupérer le DN des entrées subschema. Comme le Root DSE, les entrées subschema sont des entrées particulières d'un serveur, qui ne sont pas placées sous la racine de l'annuaire. Ces entrées décrivent le schéma supporté par le serveur, c'est-à-dire la liste des objets, des attributs, des règles de comparaison, etc. qu'il connaît. Il est possible, d'après la [rfc2251] de modifier ses entrées, mais ce n'est pas obligatoire pour respecter la version 3 de la norme LDAP.
La section 3.2.2 de cette RFC définit la liste des attributs d'une entrée subschema. Certains attributs sont obligatoires, d'autres pas. Cette liste est la suivante:
cn |
Cet attribut doit être le RDN de l'entrée subschema. Cet attribut est obligatoire dans une entrée subschema |
objectClass |
Il s'agit des classes de l'entrée subschema. Il doit au moins contenir les valeurs top et subschema. Cet attribut est obligatoire dans une entrée subschema |
objectClasses |
Cet attribut multivalué contient les classes gérées par le serveur. Il a autant de valeurs que de classes gérées. Cet attribut est obligatoire dans une entrée subschema |
attributeTypes |
Cet attribut multivalué contient les attributs gérés par le serveur. Il a autant de valeurs que d'attributs gérés. Cet attribut est obligatoire dans une entrée |
matchingRules |
Liste des règles de comparaison gérées par le serveur. Cet attribut a autant de valeur que de règles, et n'est pas obligatoire |
matchingRuleUse |
Usage des règles de comparaison. Il y a autant de valeurs de cet attribut que de règles de comparaison. Et pour chaque règle, une valeur contient la liste des attributs sur lesquels elle s'applique. Cet attribut n'est pas obligatoire |
ldapSyntaxes |
Liste des syntaxes supportées par le serveur. Cet attribut n'est pas obligatoire |
Les attributs dITStructureRules, dITContentRules, nameForms existent aussi, et sont optionnels. Ils ne sont pas supportés par Openldap. Ils décrivent des règles sur l'arbre informationnel