Annuaires LDAP avec OpenLDAP

Michaël Parienti Maire

Ce cours vous apprend comment concevoir un annuaire. Les procédures d'installation, de configuration et de sécurisation d'un annuaire avec OpenLDAP vous sont présentées dans le détail.

- Titre : Annuaires LDAP avec OpenLDAP

- Auteur : Michaël Parienti Maire

- Parution : 21 février 2005

- Mise à jour : 21 janvier 2020

- Licence : Copyright (c) 2005, Michaël Parienti Maire. This work is licensed under the Creative Commons Attribution-Share Alike License. Modifications, reproductions, diffusions autorisées à condition de mentionner le nom de l'auteur original et de conserver les termes de cette licence Creative Commons.

Sommaire

- I. Présentation des annuaires

- I-A. Définition

- I-A-1. Gestion dynamique de l'annuaire

- I-A-2. Flexibilité

- I-A-3. La recherche

- I-A-4. Gestion de la sécurité

- I-B. Comparaison avec d'autres systèmes

- I-B-1. Les caractéristiques propres d'un annuaire électronique

- I-B-2. Comparaison avec les bases de données

- I-B-3. Comparaison avec d'autres systèmes de stockage

- I-B-3-a. Système de fichiers

- I-B-3-b. Serveur Web

- I-B-3-c. Serveur DNS

- I-C. Domaines d'utilisation

- I-C-1. Recherche

- I-C-2. Gestion

- I-C-3. Autres domaines d'utilisation

- I-C-3-a. Applications légères de base de données

- I-C-3-b. Application de clé publique

- I-D. Historique et Norme X500

- I-D-1. Historique, avant la norme

- I-D-2. La norme

- I-D-2-a. Apparition de la norme

- I-D-2-b. Description

- I-D-2-c. La réalité de la norme X500

- II. Présentation de la norme LDAP

- II-A. Historique

- II-A-1. Simplification du protocole d'accès

- II-A-2. Simplification du serveur

- II-A-3. Première évolution: vers la version 3

- II-B. Description de la norme

- II-B-1. Description générale

- II-B-1-a. Contenu de la norme

- II-B-1-b. Le protocole LDAP

- II-B-2. Modèle de données

- II-B-3. Modèle de nommage

- II-B-4. Modèle fonctionnel

- II-B-4-a. Ensemble des opérations

- II-B-4-b. La fonction recherche

- II-B-5. Modèle de sécurité

- II-B-6. Étendre LDAP

- II-B-6-a. Les contrôles

- II-B-6-b. Les opérations étendues

- II-B-7. Meta recherche

- II-B-7-a. Le Root DSE

- II-B-7-b. Les entrées subschema

- III. Présentation de quelques standards LDAP

- III-A. Les fichiers LDIF

- III-A-1. Introduction aux fichiers LDIF

- III-A-2. Syntaxe

- III-A-3. Liste des opérations

- III-A-3-a. Ajout d'une entrée

- III-A-3-b. Suppression d'une entrée

- III-A-3-c. Ajout de valeurs à un attribut

- III-A-3-d. Suppression de valeurs à un attribut

- III-A-3-e. Remplacer les valeurs d'un attribut

- III-A-3-f. Modification du DN et/ou du RDN

- III-B. Filtre de recherche

- III-B-1. Présentation générale

- III-B-2. Les opérations élémentaires

- III-B-3. Exemples de filtres simples

- III-B-4. Les filtres étendus

- III-B-4-a. Changement de règle de comparaison dans un filtre

- III-C. url LDAP

- III-C-1. Présentation

- III-C-2. Syntaxe

- III-C-3. Exemples

- IV. Introduction à la suite OpenLDAP

- IV-A. Présentation de la suite OpenLDAP

- IV-A-1. Historique

- IV-A-2. Contenu de la suite

- IV-A-3. RFC supportées

- IV-A-3-a. Les RFC obligatoires

- IV-A-3-b. Les RFC non obligatoires

- IV-A-4. Les RFC non supportées

- IV-A-5. La licence

- IV-B. Points forts/Points faibles

- IV-B-1. Points forts

- IV-B-2. Points faibles

- V. Configuration des serveurs OpenLDAP

- V-A. Le serveur slapd

- V-A-1. Présentation du serveur slapd

- V-A-2. Configuration du serveur slapd

- V-B. Détail du fichier de configuration

- V-B-1. Structure générale

- V-B-2. Directives générales

- V-B-3. Directives sur la sécurité

- V-B-4. Directives sur les schémas

- V-B-5. Gestion des ressources

- V-B-6. Directives des sections backend

- V-B-7. Directives d'une section database

- V-B-8. Directives de réplication

- V-C. Sécurisation des serveurs OpenLDAP

- V-C-1. Utiliser un utilisateur sans privilèges pour faire tourner openldap

- V-C-2. Crypter les communications

- V-C-3. Choisir un hashage fort pour les mots de passe

- VI. Fonctionnement des permissions dans OpenLDAP

- VI-A. Description de la syntaxe

- VI-A-1. Description générale

- VI-A-2. Description de la cible

- VI-A-2-a. Syntaxe

- VI-A-2-b. Le DN

- VI-A-2-c. Les attributs

- VI-A-3. Description du sujet

- VI-A-3-a. La syntaxe

- VI-A-3-b. Désignation par catégorie du sujet

- VI-A-3-c. Désignation directe ou indirecte du sujet

- VI-A-3-d. Désignation par un groupe du sujet

- VI-A-3-e. Désignation par les connexions réseau du sujet

- VI-A-3-f. Désignation par les ensembles du sujet

- VI-A-4. Description de l'action

- VI-A-5. Description des contrôles

- VI-B. Cas pratiques

- VI-B-1. Conseils généraux

- VI-B-1-a. Le piège des surchaînes

- VI-B-2. Permission pour la création d'enfants

- VI-B-3. Restriction pour la création d'enfants

- VII. Conception des schémas LDAP

- VII-A. Modèle des données

- VII-B. Les attributs

- VII-B-1. Description des attributs

- VII-B-2. Exemples

- VII-B-2-a. Exemples de syntaxes définies dans la [rfc2252]

- VII-B-3. Exemples et descriptions de règles de comparaison définies dans les [rfc2252]

- VII-B-4. Exemples d'attributs définis dans la [rfc2256]

- VII-C. Les classes

- VII-C-1. Description

- VII-C-2. Exemples

- VII-D. Présentation des OID

- VII-D-1. Présentation des OID

- VII-D-2. Exemples

- VII-D-2-a. Exemples d'OID

- VII-D-2-b. Exemple de hiérarchie

- VII-E. Syntaxe

- VII-E-1. Syntaxe de la définition d'un attribut

- VII-E-2. Syntaxe de la définition d'un objet

- VII-F. L'intérêt de créer ses propres schémas

- VIII. Déploiement d'une architecture LDAP

- VIII-A. Phase de cadrage

- VIII-B. Phase de conception

- VIII-B-1. Choix des données et Identification des acteurs

- VIII-B-1-a. Déterminer les données de l'annuaire

- VIII-B-1-b. Cas d'utilisation

- VIII-B-2. Élaboration du schéma

- VIII-C. Sécurisation

- VIII-D. Développement de l'arbre informationnel

- VIII-D-1. La structure de l'arbre informationnel

- VIII-D-2. Le nommage des données

- VIII-D-2-a. Choix du suffixe

- VIII-D-2-b. Nommage des entrées

- VIII-E. Topologie du service

- VIII-E-1. Conception

- VIII-E-1-a. Objectifs

- VIII-E-1-b. Recueil des informations

- VIII-E-1-c. Les décisions techniques

- VIII-E-2. Utilisation de referral

- VIII-E-3. La réplication

- VIII-F. Vue d'ensemble

- IX. Configuration d'applications externes sur LDAP

- IX-A. Authentification

- IX-A-1. Introduction

- IX-A-2. Apache

- IX-A-2-a. Module auth_ldap

- IX-B. Messagerie

- Bibliographie

- Définition des annuaires

- Documents généraliste sur les annuaires

- Note

I - Présentation des annuaires

Ce chapitre donnera une définition des annuaires électronique et leurs domaines d'utilisation avec un historique. La norme X500 sera également présentée.

I-A - Définition

Selon la définition du Petit Robert, un annuaire est un [Recueil publié annuellement et qui contient des renseignements variables d'une année à l'autre]. Nous pouvons définir un annuaire électronique comme une base de données optimisée pour les opérations de lecture, et supportant des opérations de recherche et de navigation avancées.
Néanmoins l'essentiel de la documentation technique sur les annuaires électroniques s'appuie implicitement d'avantage sur la définition d'un annuaire donnée par la norme X500, ou par la norme LDAP, que sur la définition que nous venons de donner.
L'utilisation des annuaires présente un certain nombre d'avantages que nous allons citer dans les sections suivantes. Ces avantages proviendront pour la plupart de la définition X500 des annuaires.

I-A-1 - Gestion dynamique de l'annuaire

Mise à jour en temps réel. L'annuaire électronique est sans cesse mis à jour en fonction des entrées et des sorties des personnels d'une entreprise. Il est par exemple possible de lier l'annuaire électronique au logiciel de gestion des ressources humaines.
Coûts de mise à jour. Les coûts de mise à jour sont très faibles, car cela se fait soit de façon automatique soit par l'utilisateur lui-même ! Ceci est à comparer avec la réimpression d'un annuaire papier.

I-A-2 - Flexibilité

Un annuaire électronique peut contenir des informations sur différentes familles d'objets, pas seulement sur des personnes. Par exemple on peut trouver dans un annuaire : des entités constituant l'entreprise (département, filiale, etc.) ; n'importe quelle ressource de l'entreprise (bâtiment, matériel informatique, etc.) ; tout type d'information qui doit être partagée, et peu modifiée.
Un annuaire électronique n'est jamais figé. La structure de l'information contenue dans l'annuaire peut ainsi être modifiée facilement, à la volée, sans nécessiter de reconstruire l'annuaire : il est possible d'ajouter des nouveaux champs (de nouveaux attributs en terminologie annuaire) en fonction des besoins ; il est également possible d'ajouter des nouvelles familles d'objets.

I-A-3 - La recherche

Plusieurs types de recherches sont possibles. Il y a la recherche exacte sur le nom d'une personne par exemple. Il est également possible de faire une recherche phonétique sur une syllabe, ou bien encore, une recherche sur une chaîne de caractères : par exemple la recherche sur la chaîne « du » renverra Dupont, Durand, mais aussi Perdu…

I-A-4 - Gestion de la sécurité

La diffusion de l'information contenue dans un annuaire est facilement contrôlable. Tout d'abord les utilisateurs doivent s'authentifier avant d'accéder à l'information. Ceci est un avantage certain qui différencie les annuaires électroniques sur leurs équivalents papier.
Mais un annuaire électronique permet un contrôle bien plus fin que la seule authentification. Ils permettent une centralisation et un contrôle total de l'accès à l'information.
L'annuaire électronique pourra, par exemple, contrôler finement l'information délivrée en fonction du profil de l'utilisateur authentifié. Il sera ainsi possible de n'afficher que certains attributs, ou biens de rendre accessible uniquement certaines branches/certains objets de l'annuaire. Cela permet une granularité forte dans la gestion de l'accès à l'information, à comparer avec le principe traditionnel de liste rouge, qui ne peut gérer que deux groupes, les autorisés et les interdits.
En plus du profil utilisateur, et de l'information cible, il sera aussi possible de considérer les types de connexion (crypté ou pas) et d'authentification utilisés, ou bien d'où a lieu la consultation (réseau interne ou externe).

I-B - Comparaison avec d'autres systèmes

I-B-1 - Les caractéristiques propres d'un annuaire électronique

Nous avons défini un annuaire comme étant « «une base de données optimisée pour les opérations de lecture, et supportant des opérations de recherche et de navigation avancées» ». Un annuaire électronique possède cependant d'autres caractéristiques essentielles que nous allons citer.
Un annuaire électronique peut ainsi être caractérisé par le fait que l'information y est stockée de manière structurée et hiérarchisée. Il existe une hiérarchie aussi bien dans l'information stockée, que dans la modélisation des données. On trouve dans cette modélisation beaucoup des concepts de la programmation orientée objet, comme des notions de classes, d'objets, d'attributs, et d'héritage.
L'autre caractéristique des annuaires électroniques est l'existence d'un protocole de communication réseau. Les annuaires électroniques sont conçus pour pouvoir communiquer entre eux, et communiquer avec des clients.
Les annuaires électroniques sont aussi prévus pour être distribués et répliqués à grande échelle. Ceci explique la nécessité de ces protocoles de communication.
En revanche la spécification d'une manière de stockage n'intervient pas dans la définition d'un annuaire. Seul compte la modélisation des données et leur transport sur le réseau.

I-B-2 - Comparaison avec les bases de données

Il est important de souligner les différences entre base de données relationnelle et annuaires. Un annuaire électronique n'a pas pour vocation de stocker uniquement des informations sur des personnes. Il peut être utilisé comme base dans de nombreux types d'applications. C'est donc en connaissant ces différences, qu'il sera possible de choisir le bon type de stockage pour chaque type d'application.
La première différence est qu'un annuaire électronique est conçu pour être consulté, bien plus que mis à jour. Le rapport lecture sur écriture est donc plus élevé dans les annuaires électroniques que dans les bases de données relationnelles.
L'autre différence est la grande facilité d'extension des annuaires. L'ajout d'attributs, l'équivalent des champs dans les bases de données relationnelles, est très aisé à réaliser. Il ne nécessite pas, par exemple, de reconstruction de la base. Un autre élément de flexibilité des annuaires par rapport aux bases de données, est l'héritage multiple. Une entrée d'un annuaire peut être deux objets différents, alors qu'un objet dans une base de données n'appartient qu'à une seule table.
La contrepartie de cette facilité est l'absence de transactions et de procédures stockées. Il faudra donc faire attention lors de l'exécution d'opérations complexes, et gérer du côté applicatif les erreurs. Comme autre type de restriction, il n'existe pas dans les annuaires de notions de cohérence. Ainsi la notion de clé étrangère n'existe pas. S'il est possible de modéliser un attribut en lui imposant d'être un lien vers une entrée de l'annuaire, il est impossible de contrôler si le nœud pointé appartient à une branche précise ou s'il appartient à une certaine classe d'objet (1).
Une différence plus mineure concerne le type de recherches que l'on peut effectuer sur des bases de données et des annuaires. Si les annuaires permettent dans un certain sens d'effectuer des recherches assez évoluées (recherches approximatives ou phonétiques), ils ne possèdent pas l'équivalent de l'instruction SQL joint pour fusionner des informations de plusieurs sources.
Mais les bases de données n'offrent pas les facilités de déploiement et de réplication que l'on a avec les annuaires. Il n'existe pas non plus de protocole universel permettant à un client quelconque de contacter un serveur quelconque, comme c'est le cas pour la norme LDAP ou la norme X500 avant elle. Chaque base de données relationnelle a son propre protocole réseau, qu'elle ne partage pas avec les autres bases.

I-B-3 - Comparaison avec d'autres systèmes de stockage

I-B-3-a - Système de fichiers

Un système de fichiers est aussi un système d'informations hiérarchisées, les répertoires formant une hiérarchie, espace de nommage homogène. Néanmoins les systèmes de fichiers ne permettent pas une gestion fine des droits. De plus ils peuvent contenir des informations très volumineuses, alors qu'un annuaire ne contient majoritairement que des informations peu importantes en taille, de l'ordre du mot, cette information n'est pas du tout structurée. Ainsi l'analogie entre un système de fichiers et un annuaire bute sur l'absence de modélisation de l'information en classe et en attribut.

I-B-3-b - Serveur Web

Les serveurs web sont optimisés eux aussi pour un rapport lecture sur écriture élevé, à l'instar des annuaires électroniques. De plus un serveur web est accédé depuis le réseau, via un protocole universel, partagé entre client et serveur. Néanmoins l'information d'un serveur web n'est elle non plus pas assez structurée pour pouvoir comparer ces serveurs à des serveurs annuaires.

I-B-3-c - Serveur DNS

Les serveurs DNS sont très similaires aux annuaires électroniques. Il s'agit en effet d'un système d'information hiérarchisé et répliqué, possédant des fonctionnalités de recherche avancée. La différence fondamentale avec les annuaires concerne l'information stockée qui est très figée, puisque normalisée dans des RFC. Contrairement aux annuaires il n'est pas possible de faire évoluer l'information contenue dans un serveur DNS.

I-C - Domaines d'utilisation

I-C-1 - Recherche

Les annuaires peuvent être utilisés dans toute application informatique nécessitant une information hiérarchisée et répliquée, et des fonctionnalités de recherche. Néanmoins le type d'information stockée doit être limité. Pour l'essentiel il doit s'agir de chaînes de caractères. Et si l'on doit stocker des attributs binaires, il est préférable que leur taille soit du même ordre de grandeur, pour éviter des problèmes de performance.

I-C-2 - Gestion

Un annuaire peut contenir tout type d'objets qu'une organisation est amenée à gérer: les personnes internes (ses salariés ou ses membres, etc.), les personnes externes (les contacts, les fournisseurs, etc.), son parc informatique (les postes clients, les serveurs, les imprimantes, etc.), ses entités géographiques ou administratives, etc. Un annuaire électronique permet de centraliser toutes ces informations dans une même base, et d'unifier leur gestion. Il permet aussi de créer des liens entre ces informations (tel membre appartient à telle structure administrative et travaille dans tel bâtiment).

I-C-3 - Autres domaines d'utilisation

I-C-3-a - Applications légères de base de données

En fait, un annuaire peut aussi servir comme une base de données allégée pour de petites applications. En effet les annuaires électroniques offrent beaucoup plus de souplesse que les traditionnelles bases de données relationnelles. Certaines applications ne nécessitent pas toutes la rigidité de ces bases de données.

I-C-3-b - Application de clé publique

Les applications PKI nécessitent de distribuer des clés, de les garder à jour, de les révoquer. Avec un annuaire, à la structure hiérarchisée, ces tâches sont grandement facilitées.

I-D - Historique et Norme X500

I-D-1 - Historique, avant la norme

Les premiers annuaires électroniques sont apparus avec les premiers ordinateurs. Ils avaient des tâches ciblées : authentification, contrôle des accès, information de type contacts.
Néanmoins il n'existait aucune unification ni standard. Chaque système possédait sa propre méthode pour gérer ses utilisateurs. Unix possédait déjà son fameux /etc/passwd. Les mainframes avaient Michigan Terminal System (MTS) (2).
À partir du milieu des années 70, l'utilisation des réseaux commence à se généraliser. Les systèmes deviennent distribués et les besoins sont ceux d'une authentification sur une base distante et commune. De plus, la multiplication des LAN fait apparaître de nouveaux types de services, que l'on apparente à des annuaires: Les serveurs DNS et le protocole Whois.
On assiste à partir de la fin des années 80 et dans les années 90 à une multiplication des annuaires spécifiques. Il y a tout d'abord les annuaires inclus dans des logiciels ou des suites logiciels (mail et groupware): Lotus Notes, Novell Groupwise Directory, Microsoft Exchange Directory, Sendmail UNIX et son /etc/aliases. Il y a aussi les Annuaires Internets comme Yahoo, ou Bigfoot.
C'est aussi à la fin des années 90 qu'apparaissent des Network operating system. Il s'agit d'applications fournissant des services à des clients et des serveurs à travers un réseau. Ces services permettent le partage de ressources comme des fichiers ou des imprimantes. Ils incluent évidemment des annuaires électroniques (Novell NDS, MS Active Directory).

I-D-2 - La norme

I-D-2-a - Apparition de la norme

Suite à l'apparition dans les années 80 d'annuaires généraux et multiusages, non limités à une application, ni à un système spécifique, la nécessité de standardiser les annuaires électroniques s'est fait sentir. Deux organismes se sont mis à travailler en parallèle sur ce projet de standardisation : Le CCITT (International Telegraph and Telephone Consultative Committee) devenu ITU (International Telecommunications Unions) depuis; et l'ISO (International Organization for Standardization). Les deux projets ont finalement fusionné pour donner naissance à la norme annuaire X500. La première version de la norme en 1988. La deuxième version de 1993.

I-D-2-b - Description

L'objectif de la norme était de pouvoir être utilisée par tout type d'applications. Elle devait être un standard ouvert indépendant de tout système et de tout fabricant.
Techniquement, elle devait fournir de nombreuses possibilités de recherches. Les annuaires devaient pouvoir être distribués à très grande échelle. L'un des buts du CCITT consistait en la création d'un service de pages blanches à l'échelle mondiale. La norme X500 devait donc être capable de faire dialoguer et cohabiter tous les annuaires pour constituer des services pages blanches et pages jaunes mondiaux.

La norme X500 est constituée de plusieurs standards:

X500

Vue d'ensemble des concepts, des modèles et des services

X501

Modèles associés aux annuaires X500

X509

Procédures d'identification et d'authentification

X511

Définition des services (recherche, création, suppression)

X518

Description du fonctionnement distribué

X519

Protocoles de communication entre serveurs, et entre serveurs et clients clients/serveurs

X520

Attributs des annuaires X500 prédéfinis

X521

Classes d'objets des annuaires X500 prédéfinies

X525

Description de la réplication sur les serveurs

Les standards X520 et X519 définissent un langage commun minimum pour l'échange d'informations. Ils seront repris pour partie dans la norme LDAP.

La norme X500 a introduit un certain nombre de termes techniques:

Directory User Agent (DUA)

Poste ou logiciel client accédant à un annuaire

Directory Access Protocol (DAP)

Protocole de communication entre un client et un serveur annuaire

Directory System Agent (DSA)

Un serveur annuaire. Ce terme est encore utilisé dans la norme LDAP

Directory System Protocol (DSP)

Protocole de communication entre deux serveurs. Proche du DAP.

Directory Information Shadowing Protocol

Protocole pour la réplication entre DSA maître et DSA miroir

I-D-2-c - La réalité de la norme X500

La mise en place de la norme X500 apparaît comme un modèle de réussite dans la création d'un standard réalisé par des acteurs divers. En effet le critère d'indépendance vis-à-vis des éditeurs et le critère d'interopérabilité ont été respectés.
Mais rapidement, cette norme a été jugée trop riche et trop complexe à mettre en œuvre. Des problèmes de performance sont constatés à cause de la modélisation OSI des protocoles réseau. Il apparaît que la norme a été décidée et imposée sans tenir compte de la réalité et des besoins du terrain : le déploiement des annuaires X500 a été réalisé selon une démarche inverse au déploiement réussi d'Internet. Aussi, seuls les grands organismes publics ont déployé de tels annuaires.
La norme LDAP s'est nourrie de tous ces constats afin de ne pas connaître le sort de la norme X500.

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

III - Présentation de quelques standards LDAP

Dans le chapitre précédent, nous avons vu que la norme LDAP est une agglomération de différentes RFC, de différents standards. Dans ce chapitre quelques-uns de ces standards vont être présentés.

III-A - Les fichiers LDIF

III-A-1 - Introduction aux fichiers LDIF

LDIF est un format de fichier, spécifié dans la [rfc2849]. Les fichiers de type LDIF sont utilisés d'une part pour décrire des objets d'un annuaire LDAP, et d'autre part pour décrire un ensemble d'opérations à effectuer sur le contenu d'un annuaire. L'utilisation descriptive permet, par exemple, de créer les premières entrées d'un annuaire, ou bien d'avoir une sauvegarde d'un annuaire sous la forme d'un fichier.

Le format LDIF a été développé par l'Université du Michigan, dans ses implémentations d'annuaire LDAP. La première utilisation a été celle de fichiers descriptifs, puis le format a évolué pour pouvoir décrire des modifications apportées à un annuaire.

III-A-2 - Syntaxe

La syntaxe d'une entrée dans un fichier LDIF est la suivante :

dn: <distinguished name>
<attrdesc>: <attrvalue>
<attrdesc>: <attrvalue>
<attrdesc>:: <base64-encoded-value>
<attrdesc>:< <URL>

Soit en premier le DN de l'entrée décrite, ou bien de l'entrée sur laquelle nous allons effectuer des opérations, suivi d'une liste d'attributs et de leurs valeurs, les attributs pouvant décrire une opération en fonction du type de fichier LDIF.

Les attributs dont la valeur contient des accents doivent être encodés en UTF-8. Les attributs contenant des caractères spéciaux doivent être encodés en base 64. Les attributs peuvent être sur plusieurs lignes, à condition que les lignes supplémentaires commencent par un blanc. Les attributs dont la valeur est localisée dans un fichier sont introduits par la :< ou lieu de :. Les espaces entre les noms d'attributs et leur valeur sont optionnels, mais utiles à la lisibilité du fichier.

Le DN doit être encodé en base 64, lorsqu'il commence par une espace, un <, un : , un retour ligne ou un retour chariot. De même pour les attributs qui se terminent avec une espace.

Un fichier LDIF peut commencer par un numéro de version, qui doit être 1: version: 1. Les commentaires commencent par #. Les différentes entrées sont séparées par une ligne blanche, qui peut être un CR LF ou LF. Il ne peut y avoir plus deux lignes blanches consécutives.

Il est possible de rajouter des options à un attribut. L'intitulé de l'option se rajoute au nom de l'attribut, avec un ;. Il est possible de mettre plusieurs options à la suite. Si un attribut a une valeur vide, il peut être représenté, la valeur dans le fichier LDIF restant vide.

Plusieurs opérations sur les attributs (ci-après changetype: add, delete ou modidy) peuvent s'enchaîner, en les séparant par une ligne contenant un -.

III-A-3 - Liste des opérations

III-A-3-a - Ajout d'une entrée

dn: <distinguished name>
changetype: add
objectclass: top
objectclass: <objectclassvalue>
<attrdesc>: <attrvalue>
<attrdesc>: <attrvalue>

Il existe certaines commandes d'administration qui permettent d'insérer dans un annuaire des objets décrits dans un fichier LDIF, sans qu'il soit nécessaire que ce fichier LDIF contienne la commande d'insertion ci-dessus.

III-A-3-b - Suppression d'une entrée

dn: <distinguished name>
changetype: delete

Ce n'est pas la peine de mettre des attributs supplémentaires. L'objet ne peut être effacé que s'il n'a pas de descendants.

III-A-3-c - Ajout de valeurs à un attribut

dn: <distinguished name>
changetype: modify
add: <attribut>
<attribut>: <attrvalue1>
<attribut>: <attrvalue2>

On peut ainsi donner à l'attribut autant de valeurs que l'on souhaite. Les attributs précédents de l'objet ne sont pas effacés.

III-A-3-d - Suppression de valeurs à un attribut

Si l'on souhaite effacer uniquement certaines valeurs, il faut passer en paramètres ces valeurs. L'opération a la syntaxe suivante :

dn: <distinguished name>
changetype: modify
delete: attribut
<attribut>: <première valeur à effacer>
<attribut>: <seconde valeur à effacer>

Si l'on souhaite effacer toutes les valeurs d'un attribut d'un objet, il ne faut passer en paramètres aucune valeur de l'attribut. La syntaxe a ainsi la forme suivante :

dn: <distinguished name>
changetype: modify
delete: attribut

III-A-3-e - Remplacer les valeurs d'un attribut

Similaire aux deux cas précédents, les paramètres contiennent cette fois les valeurs qui remplacent les valeurs précédentes :

dn: <distinguished name>
changetype: modify
replace: attribut
<attribut>: <nouvelle valeur 1>
<attribut>: <nouvelle valeur 2>

III-A-3-f - Modification du DN et/ou du RDN

Les syntaxes pour modifier le DN d'une entrée, soit modifier sa position dans l'arbre, ou pour modifier son RDN, soit modifier son identifiant, sont similaires. La modification d'un DN s'écrit :

dn: <distinguished name>
changetype: moddn
newrdn: <nouveau relative distinguished name>
deleteoldrdn: <1 ou 0>
newsuperior: <nouveau parent>

deleteoldrdn indique si l'on souhaite ou non conserver l'ancienne entrée. Ce type d'opération ne marche que sur les serveurs LDAP respectant la version 3 de la norme.

La modification d'un RDN s'écrit :

dn: <distinguished name>
changetype: modrdn
newrdn: <nouveau relative distinguished name>
deleteoldrdn: <1 ou 0>

III-B - Filtre de recherche

III-B-1 - Présentation générale

Un filtre LDAP est comparable à une requête SQL. C'est une chaîne de caractères destinée à être exécutée pour récupérer des entrées d'un annuaire LDAP. Plus précisément elle ne définit que la partie WHERE d'une requête SQL: un filtre définit sur quels objets et sur quels attributs doit se faire la recherche.

Un filtre LDAP est donc constitué d'un ensemble d'opérations, portant sur des attributs, combinées avec les opérateurs booléens classiques: ET, OU et NON.

Une opération élémentaire de recherche s'écrit sous la forme : attribut OPERATEUR valeur La forme générale d'un filtre est une combinaison : (operator(search operation)(search operation)…)).

La syntaxe complète des filtres LDAP est décrite dans le document [rfc2254], qui fait partie de l'ensemble des RFC définissant la norme LDAP.

III-B-2 - Les opérations élémentaires

Une opération élémentaire est composée d'un attribut, d'un opérateur de comparaison et d'une valeur. Pour effectuer des filtres sur le type des objets, sur leur classe, il suffit d'utiliser leur objectclass comme un attribut. Au besoin, il est possible d'utiliser l'OID de l'attribut plutôt que son nom.

Les opérateurs de recherche sont les suivants :

Égalité

: =

Approximation

~=

Supérieur ou égal

>=

Inférieur ou égal

<=

S'il n'existe pas d'opérateur : « différent de », « strictement inférieur », ou « strictement supérieur », il est possible de les obtenir à l'aide des opérateurs autorisés, en utilisant un opérateur booléen « NON ».

La valeur accepte le caractère '*' afin de permet des recherches sur des parties de chaînes. Ce même caractère, seul, permet de tester la présence d'un attribut. Ce caractère n'est valide qu'avec l'opération d'égalité.

Une opération doit obligatoirement se trouver entre deux parenthèses. Les valeurs qui sont dans la partie droite d'une opération élémentaire ne sont pas entre quotes, mais certains caractères doivent être échappés :

Le caractère

Sa valeur ASCII

Le caractère dans un filtre

*

0x2a

\2a

(

0x28

\28

)

0x29

\29

\

0x5c

\5c

NULL (caractère vide)

0x00

\00

Les opérateurs booléens sont les suivants :

L'opérateur NON

!

L'opérateur ET

&

L'opérateur OU

|

Un opérateur booléen s'applique à toutes les opérations qui suivent jusqu'à l'opérateur suivant.

III-B-3 - Exemples de filtres simples

Toutes les personnes ayant leur numéro de téléphone renseigné dans la base :

(&(objectclass=person)(telephoneNumber=*))

Toutes les personnes dont le nom commence par 'A' et n'habitant pas Paris :

(&(objectclass=person)(cn=A*)(!(l=Paris)))

Toutes les personnes dont le nom ressemble à Febvre (Faivre, Fèvre, Lefebvre…) :

(&(objectclass=person)(cn~=febvre))
(&(objectclass=person)(cn=*f*vre))

III-B-4 - Les filtres étendus

En plus des attributs constituant une entrée d'un annuaire, il est possible, grâce aux filtres étendus, de considérer les éléments du DN comme faisant partie aussi de l'entrée elle-même, lors de la recherche. La syntaxe est la suivante :

attribut:dn:=value

Par exemple le filtre (ou:dn:=users) récupérera non seulement toutes les entrées qui ont un attribut ou qui a pour valeur users, mais aussi toutes les entrées dont le DN contient un attribut ou avec la valeur users.

L'autre possibilité offerte par les filtres étendus est de modifier la règle de comparaison sur un attribut. La syntaxe est la suivante :

attribut:oid-matching-rule:=value

Par exemple, si un attribut a une règle de comparaison par défaut qui est insensible à la case, mais que l'on veut faire une recherche avec une valeur précise, qui tienne compte de la case, il faut modifier la règle de comparaison par défaut.

III-B-4-a - Changement de règle de comparaison dans un filtre

Dans cet exemple, on rend l'opération d'égalité sensible à la case

(cn:2.5.13.5:=Mickey)

Les filtres étendus permettent aussi de spécifier une règle de comparaison, sans spécifier d'attribut. La recherche s'effectue alors sur tous les attributs qui acceptent cette règle. On peut aussi étendre cette recherche au DN. Les syntaxes sont les suivantes:

:oid-matching-rule:=value
:dn:oid-matching-rule:=value

Tous les filtres ne marchent qu'avec l'opérateur d'égalité, et celui-ci s'écrit :=, lieu de = dans le cas de filtres simples.

Il n'est pas permis non plus d'utiliser le caractère * pour faire des recherches sur des sous-chaînes avec les filtres étendus.

III-C - url LDAP

III-C-1 - Présentation

Les URL LDAP sont une notation pour identifier, localiser, des entrées d'un annuaire, résultat d'une recherche. Elles représentent un moyen simple pour pointer sur un annuaire, ou bien seulement une partie de l'annuaire, tels une branche ou des objets disséminés. Elles sont utilisées par des clients web, dans des fichiers de configuration, ou encore dans des entrées de l'annuaire. Elles ont l'avantage de ne nécessiter aucune notion de programmation.

La syntaxe URL de LDAP est décrite dans la [rfc2255] qui est une mise à jour de la [rfc1959], datée de 1996. La nouvelle RFC intègre la notion d'extension.

III-C-2 - Syntaxe

La syntaxe d'une url est la suivante :

ldap[s]://<hostname>:<port>/<base_dn>?<attributes>?<scope>?<filter>?<extensions>

avec les paramètres suivants :

hostname

Adresse du serveur. L'adresse peut être absente, le client est supposé connaître un serveur LDAP à contacter, en fonction du contexte.

port

Port TCP de la connexion. Par défaut il s'agit du port 389. Il ne peut y avoir de port s'il n'y a pas d'adresse.

base_dn

DN de l'entrée qui est le point de départ de la recherche.

attributes

Les attributs que l'on veut récupérer, séparés par des virgules. Si la valeur n'est pas remplie, ou si elle est remplie avec une *, tous les attributs d'usage userApplication doivent être retournés.

scope

La profondeur de la recherche dans l'arbre : base, one ou sub.

filter

Le filtre de recherche, tel que nous venons de le définir. Le filtre par défaut est (objectClass=*).

extensions

Les extensions sont un moyen pour pouvoir ajouter des fonctionnalités aux url LDAP tout en gardant la même syntaxe. On peut mettre inclure plusieurs extensions dans une URL, en les séparant par des virgules. Les extensions ont le format suivant : type=value. La partie =value est optionnelle. Elles peuvent être préfixées par un ! pour signaler une extension critique. Une extension critique signifie que le client et le serveur doivent supporter tous les deux l'extension, sinon une erreur sera levée.

La [rfc2255] définit une extension bindname, dont la valeur est le DN utilisé par le client pour se connecter au serveur. Le client a la charge de demander à l'utilisateur de rentrer le mot de passe associé si nécessaire.

Tous les caractères non autorisés ou spéciaux dans les url (voir section 2.2 de [rfc1738]) ainsi que le caractère '?' lorsqu'il est présent dans un DN, un filtre ou une extension, doivent être échappé avec la méthode décrite dans la [rfc1738]. Cette méthode consiste à écrire le caractère avec '%' suivi des deux chiffres hexadécimaux, formant sa valeur hexadécimale.

III-C-3 - Exemples

Lecture de toutes les personnes du service vente :

ldap://ldap.netscape.com/ou=Sales,o=Netscape,c=US?cn,tel,mail?scope=sub?(objetclass=person)

Lecture des objets personnes d'un annuaire :

ldap://localhost:389/??sub?objectclass=person

Recherche de Valery Febvre :

ldap://ldap.easter-eggs.fr/cn=Valery Febvre,ou=Moyens Informatiques,dc=easter-eggs,dc=fr

Recherche approximative d'une personne :

ldap://ldap.easter-eggs.fr/o=easter-eggs,dc=fr?mail,uid,sub?(sn=Febvre)

IV - Introduction à la suite OpenLDAP

Ce chapitre présente la suite logicielle OpenLDAP. Nous verrons l'historique du projet, le détail des outils fournis par cette suite et enfin nous aborderons les points forts et les points faibles du projet.

IV-A - Présentation de la suite OpenLDAP

IV-A-1 - Historique

La suite Openldap est dérivée du logiciel University of Michigan LDAP version 3.3, c'est-à-dire du premier serveur LDAP indépendant. La dernière version du serveur de l'Université du Michigan date d'avril 96[5]. Le premier serveur Openldap est sorti en août 1998[6]. La suite Openldap a totalement remplacé le logiciel de l'Université du Michigan qui n'est plus supporté et qui continue d'être distribué pour des raisons historiques seulement.

Les améliorations apportées par la suite sont nombreuses: support de la version 3 de la norme LDAP, ajout de nombreux backend, plus de plates-formes supportées, options de sécurité plus avancées, et d'inévitables corrections de bugs. Actuellement Openldap fonctionne sur de nombreuses plates-formes, dont de nombreux Unix libres (Darwin, FreeBSD, GNU/Linux, NetBSD, OpenBSD) et commerciaux (HP-UX, IBM AIX, SGI IRIX, Solaris), ainsi que sur d'autres plates-formes, comme BeOS, Apple MacOS X, IBM zOS, et Microsoft Windows 2000.

La version 2.0 de la suite, sortie en août 2000, est la première à supporter la version 3 de la norme LDAP. Chaque version suivante, les 2.1 et la 2.2, ajoutent des extensions LDAP supplémentaires à la suite. À ce jour (début 2004) la version stable d'Openldap est la version 2.1. La version 2.2 est encore en phase de stabilisation.

Le copyright du logiciel est détenu par la fondation OpenLDAP. Son développement est sponsorisé par l'Internet Software Consortium, qui sponsorise aussi des outils comme dhcp, bind et inn, qui sont respectivement un serveur dhcp, un serveur DNS, un serveur de news. L'autre sponsor est net boolean, une société de service spécialisée dans les annuaires électroniques, et dans le logiciel libre.

IV-A-2 - Contenu de la suite

La suite Openldap est composée des éléments suivants :

Slapd

Le serveur d'annuaire LDAP. Slapd signifie Stand-alone LDAP Daemon

Slurpd

Serveur de réplication. Slurpd signifie Standalone LDAP Update Replication Daemon

Un kit de développement

Ce kit contient des librairies LDAP réutilisées dans de nombreux projets, et permet de développer des applications LDAP, en C, C++ ou en Tk

Des utilitaires clients

Il s'agit d'applications utilisables en ligne de commande permettant d'interroger un annuaire LDAP

Des contributions

Ces contributions sont actuellement des classes java, développées par Novell, et un pont JDBC-LDAP, développé par Octet String

IV-A-3 - RFC supportées

IV-A-3-a - Les RFC obligatoires

La suite Openldap respecte la [rfc3377] qui est en fait la meta RFC définissant la norme LDAP version 3. En se conformant à cette norme, Openldap respecte intégralement la norme LDAP version 3.

- [rfc2251]

- [rfc2252]

- [rfc2253]

- [rfc2254]

- [rfc2255]

- [rfc2256]

- [rfc2829]

- [rfc2830]

IV-A-3-b - Les RFC non obligatoires

Il existe un certain nombre de RFC qui ajoutent des fonctionnalités au protocole LDAP sans pour autant faire partie de la norme. Openldap implémente plusieurs de ces extensions. Voici une liste de ces extensions supportées, avec une description pour certaines d'entre elles :

[rfc2596]

Cette RFC propose de rajouter une option langage aux attributs. Ainsi la valeur d'un attribut pourra être associée à une langue

[rfc2596bis]

Il s'agit d'une extension à la RFC précédente, qui n'est pas devenue une RFC. Cette extension traite des intervalles de langue.

[rfc2247]

définit un mécanisme qui permet de déduire le suffixe d'un annuaire LDAP à partir de son nom de domaine

[rfc3088]

décrit l'utilisation du service DNS pour localiser le serveur annuaire d'un domaine

[rfc3062]

Cette RFC décrit un mécanisme pour modifier le mot de passe d'un utilisateur, même lorsque celui-ci n'est pas authentifié auprès de l'annuaire, mais avec un autre procédé SASL

[rfc3296]

Cette RFC propose un moyen de gérer les referrals. Nous explicitons son contenu dans une autre partie

Matched Values Control

Cette extension permet de limiter les attributs récupérés, lors d'une recherche, aux valeurs qui correspondent à un filtre supplémentaire à celui de la recherche

[rfc2696]

Cette RFC décrit un contrôle qui permet à un client de recevoir les réponses à une recherche par paquets au lieu de les recevoir en un seul bloc. Ce contrôle est implémenté depuis la version 2.2 d'Openldap

IV-A-4 - Les RFC non supportées

Openldap n'implémente pas toutes les extensions optionnelles LDAP. En particulier les extensions suivantes ne sont pas respectées :

DIT Structure Rules

Openldap ne permet pas de spécifier des règles dans l'arbre informationnel, pour imposer par exemple qu'une branche ne contienne que des objets d'une classe donnée. Cette possibilité était présente dans la norme X500

Name Forms

Il s'agit de la possibilité d'imposer à des objets d'une classe donnée, ou dans une branche, quel attribut doit être unique et doit être utilisé comme RDN. Cette possibilité est aussi issue du monde X500

Modification de schéma via LDAP

Il n'est pas possible, avec le serveur slapd d'Openldap de modifier le schéma, directement via le protocole LDAP

[rfc2589]

Cette RFC propose un ensemble d'extension et d'objet spécifique pour permettre à un annuaire de gérer des objets à courte durée de vie. L'objectif est de pouvoir gérer avec un annuaire des informations du type: «est-ce que l'utilisateur est en ligne?»

[rfc2649]

Cette RFC propose un contrôle pour signer des opérations effectuées sur un annuaire, et de créer ensuite un journal pour chaque entrée contenant les modifications effectuées et une signature digitale de l'opération

[rfc2891]

Cette RFC décrit un contrôle permettant à un client de demander au serveur de trier les résultats d'une recherche, suivant un attribut donné et éventuellement une règle de comparaison donnée

IV-A-5 - La licence

Openldap est un logiciel libre, au send de la Free Software Foundation. Cela signifie qu'il respecte les quatre libertés fondamentales d'un logiciel libre: liberté d'exécution, liberté d'étude, liberté de modification et liberté de redistribution.

En revanche ce n'est pas un logiciel copyleft. C'est-à-dire qu'il n'impose pas sa licence d'utilisation aux logiciels qui dérivent de lui. Il peut donc être privatisé. Ce qui ne l'empêche pas d'être compatible avec la licence GPL. Le code d'Openldap peut donc être intégré dans un logiciel sous GPL.

IV-B - Points forts/Points faibles

IV-B-1 - Points forts

Parmi les atouts d'Openldap on distingue facilement ses atouts techniques :

- De nombreux backends. Ils permettent au serveur slapd d'être utilisé à de nombreux usages, (comme un proxy ou un meta annuaire par exemple).

- Des options de sécurité avancées. Le serveur slapd est compatible avec les protocoles SSL et SASL.

- De nombreuses extensions implémentées. Chaque nouvelle version amène son lot de nouveautés et d'extensions supplémentaires implémentées.

L'autre grand atout d'Openldap qu'il ne faut pas négliger c'est sa qualité de logiciel libre. Évidemment son coût s'en trouve réduit, puisqu'il n'y a aucun coût de licence, ni à l'achat, ni à l'exploitation, et quelle que soit la quantité de données gérées. Le seul coût est donc celui de son déploiement et de sa maintenance. En tant que logiciel libre, ses bugs sont corrigés très rapidement, en particulier les bugs de sécurité.

Mais le principal avantage de ce genre de logiciel reste l'indépendance qu'il assure vis-à-vis d'un fournisseur ou d'un prestataire, la liberté de le modifier (ou de le faire modifier) pour l'adapter à ses propres besoins, sans avoir à en référer à personne.

IV-B-2 - Points faibles

Les principaux reproches que l'on faire à Openldap sont d'ordre technique. L'obligation de redémarrer le serveur à chaque changement de configuration est assez pénible. En effet le fichier de configuration n'est lu qu'au démarrage, et il contient les règles d'accès et le schéma. Ce qui nécessite l'arrêt puis le redémarrage après chaque modification d'une règle ou du schéma. Ceci n'est au fond pas très gênant dans la mesure où schéma et règle ne devraient pas être modifiés très souvent, et qu'un annuaire qui doit être toujours accessible devrait être répliqué.

L'autre faiblesse, qui peut se révéler plus gênante, concerne les RFC optionnelles non implémentées, et dont certaines organisations ne peuvent pas se passer.

Enfin, le dernier petit reproche concerne la documentation. La documentation en ligne n'est pas la plus complète. Pour avoir accès à toutes les directives de configuration, il faut télécharger le logiciel pour consulter les pages de manuels. Éventuellement, certaines pages de la FAQ peuvent se révéler d'un grand secours.

V - Configuration des serveurs OpenLDAP

Dans ce chapitre nous étudierons comment configurer les serveurs de la suite logicielle Openldap.

V-A - Le serveur slapd

V-A-1 - Présentation du serveur slapd

Slapd est le serveur LDAP de la suite logicielle Openldap. Il répond donc aux requêtes des clients LDAP, quels qu'ils soient, et quelle que soit la librairie LDAP sur laquelle ils sont construits.

Un serveur slapd est configuré pour n'écouter qu'un seul port, à la différence d'autres serveurs comme Apache. Néanmoins un même serveur slapd permet de répondre aux requêtes de plusieurs annuaires, c'est-à-dire d'annuaires qui ont des suffixes différents.

Mais dans ce cas les annuaires servis par une même instance de slapd vont partager un certain nombre de caractéristiques (permissions, index, etc.), ce qui n'est pas toujours souhaitable. Donc si l'on veut qu'une même machine serve plusieurs annuaires il est parfois nécessaire de faire tourner plusieurs instances du serveur slapd, chacun écoutant un port différent et chacun ayant son propre fichier de configuration slapd.conf.

V-A-2 - Configuration du serveur slapd

La configuration d'un serveur slapd consiste tout d'abord à définir son identité. L'identité d'un serveur est donnée par le port que le serveur va écouter, et par les annuaires qu'il va servir, chaque annuaire étant défini par un suffixe.

La définition du schéma des données servies par un serveur, et les permissions contrôlant l'accès à ces données font partie des autres informations de configuration d'un serveur slapd.

S'il l'on voit l'intérêt de partager des schémas, des définitions d'objets, entre plusieurs annuaires, le partage de permission entre ces mêmes annuaires peut se révéler être beaucoup plus gênant.

La manière dont sont stockées les données d'un serveur slapd fait aussi partie des informations de configuration. Le stockage des données est défini par un backend. De la même façon qu'une même instance de serveur slapd peut servir plusieurs annuaires, une même instance de serveur slapd peut avoir plusieurs backends, dans lesquels elle va stocker ses différents annuaires.

Un fichier de configuration d'un serveur slapd est logiquement divisé en trois sections :

- Configuration globale

- Spécifique à un backend

- Spécifique à un annuaire

V-B - Détail du fichier de configuration

V-B-1 - Structure générale

La structure d'un fichier de configuration est la suivante :

# global configuration directives
<global config directives>

# first backend definition
backend <typeA>
<backend-specific directives>

# first database definition & config directives of the first backend
database <typeA>
<database-specific directives>

# second database definition & config directives of the first backend
database <typeA>
<database-specific directives>

# second backend definition
backend <typeB>
<backend-specific directives>

# first database definition & config directives of the second backend
database <typeB>
<database-specific directives>

# second database definition & config directives of the second backend
database <typeB>
<database-specific directives>

On distingue les trois sections décrites précédemment.

Il est possible d'inclure d'autre fichier dans un fichier de configuration :

include <nom de fichier>

Cette directive permet d'inclure un fichier externe dans le fichier de configuration, à l'endroit où elle se trouve. Le fichier inclus fera partie intégrante du fichier de configuration, c'est-à-dire qu'il devra respecter la même syntaxe.

Les fichiers sont très utiles pour séparer la définition du schéma de l'annuaire, ou les permissions, du reste du fichier de configuration.

Il est possible d'inclure à nouveau un fichier dans un fichier déjà inclus. Néanmoins aucune vérification de boucle n'est faite. Il faut donc se méfier des boules infinies.

V-B-2 - Directives générales

loglevel <entier>

Cette directive est un entier qui indique le niveau de débogage du serveur. Sa valeur indique le type d'informations qui vont être transmises au système (dans syslogd). La valeur de la directive est une combinaison additive de valeurs de base, dont les plus utiles sont les suivantes (la liste complète est dans le manuel d'OpenLdap)

-1

Permet d'affichage toutes les valeurs de débogage, ce qui peut très vite se montrer illisible

0

Aucune valeur de débogage

32

Affiche le processus de recherche d'un filtre

64

Affiche le processus de parsage du fichier de configuration

128

Affiche le calcul des permissions de chaque opération. Cette valeur est évidemment très utilisée lorsqu'on met en place les permissions pour valider le bon déroulement des accès, en lecture comme en écriture, aux objets de la base

256

Affiche le résultat de chaque opération (succès, échec, permission refusée, etc.)

referral <URI>

Cette directive donne le referral qui sera retourné aux clients lorsque le serveur ne peut pas répondre à une requête qui lui est soumise. Cela arrive lorsqu'une requête s'exécute à partir d'un nœud qui n'est pas dans les suffixes gérés par le serveur.

Sur un annuaire en production, il est préférable de ne pas laisser un niveau de log trop élevé. Certains niveaux de log trop bavards, comme le 128, peuvent en certaines circonstances ralentir l'annuaire à cause d'écritures trop fréquentes et trop importantes dans le fichier syslog.

V-B-3 - Directives sur la sécurité

defaultaccess  { none | compare | search | read | write }

Cette directive donne l'accès accordé par défaut aux clients lorsqu'aucune clause de permission n'est présente dans le reste du fichier de configuration, ou bien lorsqu'aucune de ces clauses ne correspond.

password-hash { SSHA | SHA | SMD5 | MD5 | CRYPT }

Cette directive indique le hashage utilisé pour le stockage des mots de passe dans l'annuaire. Par défaut le hashage utilisé est SSHA.

access to "clause d'accès"

Cette directive inclut une clause d'accès. Un chapitre lui est dédié

V-B-4 - Directives sur les schémas

schemacheck { On | Off }

Cette directive indique si le serveur slapd devra vérifier si les objets de l'annuaire respectent ou pas le schéma, lors d'une insertion ou d'une modification.
Il n'y a généralement aucune raison de désactiver la vérification du schéma en dehors de la phase de développement de l'annuaire, lorsque des composants ne sont pas encore finis.

attributetype <RFC2252 Attribute Type Description>,  objectclass <RFC2252 Object Class Description>

Ces deux directives permettent de définir respectivement des attributs et des classes d'objets. Avant de définir ses propres attributs et ses propres objets, il faut inclure les schémas standards. De plus les attributs doivent être définis avant les objets. La syntaxe et l'usage de ces directives seront étudiés dans un autre chapitre.

V-B-5 - Gestion des ressources

Nous allons voir dans cette section les directives qui permettent de gérer les ressources utilisées par un serveur slapd.

idletimeout

Cette directive prend pour valeur un entier qui indique le nombre de secondes qu'attendra un serveur avant de fermer de force la connexion à un client inoccupé. La valeur par défaut, 0, permet de désactiver cette option.

sizelimit

Cette directive prend pour valeur un entier qui spécifie le nombre maximum d'entrées retournées par une recherche dans l'annuaire. La valeur par défaut est 500.

timelimit

Cette directive prend pour valeur un entier qui sera la durée maximale, en secondes, que le serveur passera à répondre à une requête. Si une demande n'est pas terminée pendant ce temps, une erreur de type « exceeded timelimit » sera envoyée au client. La valeur par défaut est 3600 (une heure).

V-B-6 - Directives des sections backend

backend <backend type>

Cette directive ouvre une section dédiée à un backend particulier. Elle définit le type de backend. Les valeurs possibles sont les suivantes :

bdb

Backend base de données transactionnelle Berkeley

ldbm

Backend basé sur des fichiers de format DBM, ou GDBM, le plus facile à installer

dnssrv

Ce backend retourne des referrals en se basant sur le champ SRV des enregistrements DNS

ldap

Backend proxy, qui transmet les requêtes entrantes à un autre LDAP serveur. Un server proxy permet de mutualiser entre les différents clients les connexions à un serveur distant

meta

Backend similaire au backend ldap, mais offrant des possibilités supplémentaires pour présenter aux clients un ensemble de serveur LDAP comme étant un seul serveur LDAP grâce à des mécanismes de traduction du nom des objets

monitor

Le backend monitor n'est pas vraiment un backend. Il permet d'accéder à des informations sur le serveur

passwd

Backend qui s'appuie sur le fichier /etc/passwd. Il n'est utilisé qu'à des fins de démonstration

perl, shell

Ces deux backends exécutent chaque commande ldap, soit par l'intermédiaire d'un objet perl, soit par un programme externe quelconque

sql

Backend qui s'appuie sur une base de données SQL, de type ODBC. Ce backend nécessite beaucoup de configuration pour transformer les requêtes ldap en requêtes SQ

La plupart des backends nécessitent leurs propres directives pour être configuré correctement. Nous y reviendrons plus tard

V-B-7 - Directives d'une section database

Une section database commence dans le fichier de configuration par une directive database, dont la valeur est celle du backend auquel appartient la base de données.

suffix DN

Indique le nœud que la base de données va gérer.

lastmod on | off

Indique si la base de données doit enregistrer les modifications effectuées dans des attributs dédiés. Ces attributs sont les suivants: modifiersName, modifyTimestamp, creatorsName, and createTimestamp. Par défaut la valeur on. Pour certains backend il est nécessaire qu'elle soit à off.

readonly on | off

Cette option met la base en lecture seule.

rootdn <DN>

Utilisateur dont les accès ne seront pas soumis aux clauses d'accès.

rootpw <mot de passe>

Le mot de passe de l'utilisateur rootdn. Ce mot de passe peut être stocké sous forme hashé.

V-B-8 - Directives de réplication

Les directives suivantes permettent de contrôler comment s'effectue la réplication d'un annuaire. Toutes ces directives sont spécifiques à une database.

replica host <hostname>[:<port>] [bindmethod={ simple | kerberos | sasl }]
replogfile <filename>
updatedn <DN>

V-C - Sécurisation des serveurs OpenLDAP

Dans ce chapitre nous étudierons comment sécuriser les serveurs de la suite logicielle OpenLDAP.

V-C-1 - Utiliser un utilisateur sans privilèges pour faire tourner openldap

Dans le cas où une faille existerait dans le daemon slapd, il est souhaitable d'éviter que cette faille potentielle conduise à un accès avec des droits superutilisateurs (root). Pour ce faire il est possible de faire fonctionner le daemon slapd sous une identité autre que root.

Voici comment mettre en place une telle configuration:

1. arrêter slapd s'il est en fonctionnement

/etc/init.d/slapd stop

2. créer un groupe et un utilisateur dédié

groupadd ldap
useradd -s /bin/false -d /var/lib/ldap -g ldap ldap

3. créer un sous-répertoire pour placer le fichier de pid

mkdir -p /var/run/slapd

4. modifier en conséquence les directives pidfile et argsfile dans /etc/ldap/slapd.conf

pidfile /var/run/slapd/slapd.pid
argsfile /var/run/slapd/slapd.args

5. appliquer les droits nécessaires sur les répertoires utilisés par slapd

# Sur le répertoire de configuration:
chown -R ldap:ldap /etc/ldap
# Sur le répertoire de stockage:
chown -R ldap:ldap /var/lib/ldap
# Sur le répertoire de "fonctionnement":
chown ldap:ldap /var/run/slapd

6. relancer slapd avec les options appropriées et/ou modifier le script de démarrage

/usr/sbin/slapd -u ldap -g ldap

7. sous Debian GNU/Linux 3.0 (openldap 2.0.23), on peut modifier le script de démarrage /etc/init.d/slapd en ajoutant ces options à la ligne suivante

start-stop-daemon --start --quiet --pidfile "$pf" --exec /usr/sbin/slapd
start-stop-daemon --start --quiet --pidfile "$pf" --exec /usr/sbin/slapd -- -u ldap -g ldap

8. Sous Debian GNU/Linux testing ou unstable (openldap 2.1.23/2.1.25) il suffit de mettre le nom de l'utilisateur et du groupe dans le fichier /etc/default/slapd (variables SLAPD_USER et SLAPD_GROUP).

V-C-2 - Crypter les communications

Afin d'assurer la confidentialité des informations véhiculées par le protocole ldap, il peut être utile de mettre en place le système de cryptage ssl.

V-C-3 - Choisir un hashage fort pour les mots de passe

Une attaque pouvant être effectuée sur la base ldap elle même (fichiers db… suivant le backend choisi), il convient de stocker les mots de passe (les données à priori les plus sensibles) avec un cryptage fort et irréversible. Openldap support en standard les formats suivants (du plus sécurisé au moins sécurisé) :

- md5

- sha

- des

- clear

VI - Fonctionnement des permissions dans OpenLDAP

Dans ce chapitre nous nous attarderons sur le fonctionnement des permissions qui permettent de contrôler l'accès aux données des serveurs de la suite logicielle Openldap.

VI-A - Description de la syntaxe

VI-A-1 - Description générale

Les permissions d'accès sont fournies au serveur slapd sous la forme d'une liste de clauses. La syntaxe de ces clauses est la suivante :

<clause d'accès> ::= access to <objet> [ by <sujet> <action> <contrôle> ]+

La définition de chacun de ces quatre composants est la suivante :

objet

L'objet, ou bien la cible, désigne une entrée, un ensemble d'entrées ou un attribut de l'annuaire

sujet

Décrit la ou les personnes à qui la clause d'accès donne les droits. Il s'agit d'un ensemble de DN.

action

Désigne le type d'accès est concédé: lecture, écriture, etc.

contrôle

Indique le comportement du serveur après l'accès à la clause

Les informations les plus pertinentes sur la gestion des contrôles d'accès d'Openldap se trouvent dans la page manuel de slapd.access, et dans la FAQ d'Openldap.

VI-A-2 - Description de la cible

VI-A-2-a - Syntaxe

La syntaxe de la cible est la suivante :

<objet> ::= * | [dn[.<dnstyle>]=<dnspec>] [filter=<ldapfilter>] [attrs=<attrlist>]

La cible peut donc être *, ce qui désigne toutes les entrées de l'annuaire. Elle peut sinon être désignée par son DN, par un filtre ou être une liste d'attributs. Il est possible de combiner toutes ces trois dernières cibles ensemble. Cela permet par exemple de cibler tous les attributs des entrées répondant à un filtre, dans une branche, ciblée par le DN.

VI-A-2-b - Le DN

La désignation du DN peut être donnée de cinq façons différentes :

- De façon exacte. Il s'agit du comportement par défaut à partir de la version 2.2 de slapd. Il n'y a pas de dnstyle à fournir. Avec les versions précédentes, il est obligatoire de mettre un dnstyle ayant la valeur base ou bien exact qui est synonyme.

- Désignation d'une sous branche. Si l'on veut cibler toutes les entrées sous une entrée précise, dnstyle doit contenir la valeur subtree ou sub synonyme du précédent.

- Désignation d'un seul niveau. Si l'on ne veut cibler que les entrées immédiatement sous une entrée précise, dnstyle doit contenir la valeur one ou onelevel synonyme du précédent à partir de la version 2.2.

- Désignation des enfants. Si l'on ne veut cibler que les enfants d'une entrée précise, en excluant l'entrée elle-même, dnstyle doit contenir alors la valeur children.

- Désignation par expression régulière. Il est possible de cibler des entrées par une expression régulière sur leur DN. dnstyle doit contenir alors la valeur regex. Il s'agit de la valeur par défaut sous Openldap 2.1.

VI-A-2-c - Les attributs

attrlist doit contenir une liste d'attributs, séparés par des virgules. Il existe deux attributs particuliers qui peuvent être inclus: entry et children. Le premier permet de cibler l'entrée elle-même, le second ses enfants uniquement. Il est possible aussi de mettre des objectclass, ce qui est équivalent à mettre tous les attributs de l'objectclass en question.

L'accès à des entrées en tant que tel est nécessaire pour des opérations de création, d'effacement ou de renommage de l'entrée, mais aussi pour l'accès en écriture. Nous détaillerons ces cas dans des études de cas pratiques ci-après.

VI-A-3 - Description du sujet

VI-A-3-a - La syntaxe

La définition complète de la clause sujet est la suivante :

*
anonymous
users
self

dn[.<dnstyle>[,<modifier>]]=<pattern>
dnattr=<attrname>
group[/<objectclass>[/<attrname>]]
[.<style>]=<pattern>
peername[.<style>]=<pattern>
sockname[.<style>]=<pattern>
domain[.<domainstyle>[,<modifier>]]=<pattern>
sockurl[.<style>]=<pattern>
set[.<style>]=<pattern>

ssf=<n>
transport_ssf=<n>
tls_ssf=<n>
sasl_ssf=<n>

aci=<attrname>

Nous allons étudier qu'une partie de cette syntaxe, la plus significative et la plus utile.

VI-A-3-b - Désignation par catégorie du sujet

Le serveur slapd distingue quatre catégories différentes (mais non disjointes) d'utilisateurs, à qui il est possible de donner accès dans une clause, via les syntaxes suivantes dédiées au sujet :

*

Désigne n'importe quel utilisateur, qu'il soit identifié ou pas.

anonymous

Désigne un utilisateur non identifié.

users

Désigne un utilisateur identifié.

self

Désigne l'objet, c'est-à-dire l'utilisateur dont le DN est la cible.

VI-A-3-c - Désignation directe ou indirecte du sujet

La désignation directe du sujet se fait avec la syntaxe suivante :

dn[.<dnstyle>[,<modifier>]]=<pattern>

pattern est le DN de l'utilisateur qui sera sujet. Il est possible d'y associer un dnstyle, exactement comme dans la désignation de la cible. Dans le cas où ce dnstyle a pour valeur regex, il est possible de faire apparaître dans le pattern des sous-chaînes de substitution, de la forme $i (où i est un chiffre entre 1 et 9). Chaque chaîne $i sera remplacée par la ième sous chaîne substituée de l'expression régulière de l'objet. Depuis la version 2.2 d'Openldap il existe un nouveau dnstyle qui est expand, qui permet d'utiliser ces chaînes de substitution de la cible, sans que le reste du pattern soit considéré comme une expression régulière.

Il existe une autre façon plus dynamique encore de désigner le sujet. Il est possible en effet de désigner le DN du sujet comme étant la valeur d'un attribut de la cible. La syntaxe suivante permet cela :

dnattr=<attrname>

attrname contient alors l'attribut dont la valeur désigne le sujet. Un exemple classique d'utilisation de cette syntaxe est la clause qui donne accès en écriture à un objet de type groupe au propriétaire du groupe. Le propriétaire étant un attribut de l'objet groupe.

VI-A-3-d - Désignation par un groupe du sujet

Il est possible de définir des objets de type groupe dans un annuaire. Ces objets possèdent un attribut, multivalué, contenant les DN des personnes appartenant au groupe. Dans les schémas fournis avec Openldap il existe deux classes de groupe: groupOfNames et groupOfUniqueNames, dont les attributs désignant les membres sont respectivement member et uniqueMember. Il est fort utile de savoir écrire des permissions concernant les membres d'un groupe. C'est ce que nous allons étudier maintenant.

La syntaxe pour que le sujet d'une clause soit les membres d'un groupe est la suivante :

group[/<objectclass>[/<attrname>]] [.<style>]=<pattern>

pattern est le nom du groupe. Par défaut les groupes doivent être de classe groupofnames, mais il est possible de changer cette classe en précisant l'objectclass. De même que l'attribut par défaut contenant les DN sera member mais il est possible de le modifier en précisant l'attrname.

Il est possible de préciser un style, qui peut être base, exact (synonyme de base) ou regex. Dans ce dernier cas, il n'est pas possible d'utiliser des expressions régulières dans le pattern mais seulement des chaînes de substitutions.

VI-A-3-e - Désignation par les connexions réseau du sujet

Jusqu'à présent la désignation du sujet s'effectue à partir du contenu de l'annuaire. Dans cette partie nous allons désigner le sujet à partir d'informations concernant son accès physique au réseau.

Les syntaxes pour désigner ainsi le sujet sont les suivantes :

peername[.<style>]=<pattern>
sockname[.<style>]=<pattern>
domain[.<domainstyle>[,<modifier>]]=<pattern>
sockurl[.<style>]=<pattern>

Les définitions de ces clauses sont les suivantes :

peername

Désigne l'extrémité distante de la connexion entre le serveur et le client. pattern est de la forme ip-address:port

sockname

Désigne l'extrémité locale de la connexion entre le serveur et le client. pattern est de la même forme que celle décrite ci-dessus

domain

Désigne le nom de la machine distante d'où est lancée la requête. Ce nom est récupéré par recherche DNS inversée, à condition que cette recherche, désactivée par défaut, soit activée dans le fichier de configuration de slapd. Les clauses désignant un sujet à l'aide du domaine sont déconseillées, parce qu'il est très facile de falsifier son domaine. Il est possible d'utiliser un domainstyle avec la valeur subtree pour faire accepter des surdomaines

sockurl

Désigne l'url contactée

style peut être base (ou son synonyme exact) ou bien regex pour pouvoir faire des substitutions, tout comme avec les groupes.

VI-A-3-f - Désignation par les ensembles du sujet

Les ensembles sont l'un des moyens les plus pratiques, mais des moins connus pour préciser le sujet. Ils permettent de déterminer le sujet par rapport à la valeur de ses attributs, et éventuellement par rapport aussi à la valeur des attributs de l'objet.

La syntaxe est la suivante :

<set> :=        <base>
| "(" <set> ")"
| <set> <conj> <set>
| <set> "/" <attribute> "*"
| <set> "/" <attribute>
<base> :=       "this"
| "user"
| "[" <any text> "]"
<conj> :=       "&" | "|"
<attribute>> :=  any attribute name

Cette syntaxe définit des intersections (via le symbole &) et des réunions (via le symbole |) d'ensembles. Chaque ensemble est une ou plusieurs chaînes de caractères, qui peuvent être interprétées comme des DN lorsqu'elles sont suivies d'un /, dans une syntaxe de la forme <ensemble>/ attribut .

Dans ce cas un nouvel ensemble est construit, par la réunion des valeurs des attributs, pour chaque objet désigné par son DN dans l'ensemble initial. Il est possible de récupérer récursivement les valeurs de l'attribut par l'opérateur *.

Les valeurs des ensembles sont définies soit de façon absolues, par une chaîne fournie entre crochets ([ et ]), soit relativement à l'objet, désigné par this, soit à l'utilisateur, désigné par user.

L'accès est obtenu lorsque l'ensemble n'est pas vide.

Tous les utilisateurs dont une valeur de l'attribut description est python :

user/description & [python]

Tous les utilisateurs dont une valeur de l'attribut description est identique à une valeur de l'attribution description de la cible

user/description & this/description

Tous les utilisateurs membres d'un groupe

[cn=dev,dc=ee,dc=fr]/uniquemember & user

Tous les utilisateurs membres d'un groupe, ce groupe pouvant lui-même contenir d'autres groupes

[cn=dev,dc=ee,dc=fr]/uniquemember*  & user

Tous les utilisateurs qui sont membres du groupe dont la valeur est contenue dans la cible

this/allowedgroups/uniquemember & user

Tous les utilisateurs qui sont membres du groupe dont la valeur est contenue dans la cible, ou bien, récursivement dans un groupe de ce groupe

this/allowedgroups/uniquemember* & user

Ces exemples montrent qu'il est possible d'utiliser la syntaxe des ensembles pour désigner des groupes. Ils montrent aussi que cette syntaxe est beaucoup plus forte que celle des groupes, puisqu'elle permet de faire des groupes récursifs.

VI-A-4 - Description de l'action

Après avoir spécifier sur quel objet portait la clause de sécurité, puis à qui elle donnait accès, il faut ensuite préciser sur quel est type d'accès, d'action, la permission est à accorder. Il existe deux méthodes pour définir l'action. La première consiste à fournir des types d'accès par groupe, les groupes ayant une relation d'inclusion entre eux. La deuxième méthode consiste à faire des accès élémentaires.

La syntaxe pour fournir une action est la suivante :

<access> ::= [self]{<level>|<priv>}
<level> ::= none | auth | compare | search | read | write
<priv> ::= {=|+|-}{w|r|s|c|x}+

La syntaxe level implémente la première méthode citée. Il existe six niveaux de permissions, de l'accès nul (none), le plus bas, à l'accès en écriture (write), le plus élevé. Chaque niveau incluant les niveaux inférieurs. Le deuxième niveau, auth permettant l'authentification.

À moins d'être dans le cas d'un annuaire en lecture seule pour tout le monde, la moindre des choses dans la mise en place d'un annuaire consiste à autoriser les utilisateurs à s'identifier. Pour cela, il est obligatoire d'avoir parmi les clauses d'accès une clause similaire à la suivante.

access to attribute=userPassword
by anonymous auth
by self write
by * none break

La deuxième méthode pour désigner l'action consiste donc à donner, ou à retirer des accès élémentaires. La syntaxe priv permet cela. Les accès élémentaires sont définis par une des lettres x, c, s r ou w, ces lettres désignant respectivement l'accès en authentification, comparaison, recherche, lecture et écriture. Pour ajouter un accès élémentaire, il faut préfixer l'accès d'un +. Pour retirer il faut préfixer l'accès de -. Pour imposer un accès fixe, et ne pas tenir compte de ce qui a déjà été accordé, il faut préfixer d'un =.

En préfixant chacune de ces deux syntaxes d'un self, l'accès ne concernera que si l'utilisateur est désigné dans la cible. Un exemple d'utilisation de cette syntaxe est l'accès selfwrite accordé sur un objet de type groupe et qui permet à un utilisateur de ne modifier que la valeur attribut contenant son DN, pour se retirer du groupe par exemple.

VI-A-5 - Description des contrôles

Les contrôles précisent le comportement que doit avoir le serveur slapd après avoir atteint une clause d'accès. Le comportement par défaut est de s'arrêter d'accorder les permissions obtenues lorsque la clause a été atteinte. Ceci est équivalent à écrire stop à la fin de la clause.
Les autres possibilités pour un contrôle sont break et continue. continue indique au serveur qu'il doit continuer à chercher d'autre sujet (et action), pour le même objet. break indique qu'il doit rechercher une autre cible.
Par défaut, chaque groupe de clauses pour un objet donné se termine implicitement par * none stop. Le serveur s'arrête donc et ne donne aucun droit.

VI-B - Cas pratiques

VI-B-1 - Conseils généraux

Les expressions régulières doivent être utilisées uniquement quand cela est nécessaire. Quand on veut mettre en objet un sous arbre, on préférera utiliser le dnstyle, one, sub ou children en fonction du besoin.
Par ailleurs, pour éviter toute ambiguïté, il est préférable de toujours préciser les style et dnstyle plutôt que de s'appuyer sur les valeurs par défaut. Si vous connaissez par cœur toutes les style et dnstyle implicite, ce n'est pas forcément le cas de la personne qui relira le fichier de configuration après vous.
Le composant d'expression régulière (.)* est à éviter, parce qu'il peut correspondre à beaucoup trop de choses, y compris une chaîne vide. On lui préférera le composante (.)+, qui correspond à une chaîne d'au moins un caractère. On peut aussi parfois utiliser le composant [^,]+ qui correspond à une chaîne d'un au moins un caractère et ne contenant pas de virgule, ce qui permet d'isoler un niveau dans un DN.
De même l'on pensera à encadrer les expressions régulières d'un ^ et d'un $. Le premier correspond à un début de chaîne, le second à une fin de chaîne. Cela permet d'être certain que l'expression régulière ne répond pas à une surchaîne.

VI-B-1-a - Le piège des surchaînes

L'expression régulière

cn=[^,]+,ou=admin,dc=ee,dc=fr

répondra positivement au DN

cn=niakniak,ou=admin,dc=ee,dc=fr,cn=cracker,ou=users,dc=ee,dc=fr

Pour éviter ce détournement, il faut utiliser l'expression régulière suivante :

^cn=[^,]+,ou=admin,dc=ee,dc=fr$

, ou encore

^cn=([:alnum:]+),ou=admin,dc=ee,dc=fr$

À la fin du parcours de toutes les clauses, slapd affecte une permission par défaut. Cette permission par défaut est définie dans le fichier de configuration du serveur. Or la clause qui permet de définir ces permissions par défaut est devenue dépréciée dans la version 2.1. Cela signifie qu'elle sera supprimée des prochaines versions du logiciel. Il faut donc commencer à s'en passer et remplacer son usage par une clause de permission finale.

VI-B-2 - Permission pour la création d'enfants

La clause :

access to dn.children="ou=contacts,dc=ee,dc=fr"
by dn="cn=intreenet,ou=apps-accounts,dc=ee,dc=fr" write

n'autorise pas la création d'enfants sous le nœud ou=contacts,dc=ee,dc=fr. Cette clause permet l'accès en écriture aux nœuds enfants, mais pour pouvoir créer des enfants, il faut rajouter une clause permettant de modifier aussi l'entrée ou=contacts,dc=ee,dc=fr

La clause :

access to dn="ou=contacts,dc=ee,dc=fr" attrs=children
by dn="cn=intreenet,ou=apps-accounts,dc=ee,dc=fr" write

donne bien l'autorisation voulue, le droit d'écriture sur l'entrée ou=contacts,dc=ee,dc=fr, pour créer des enfants sous le nœud.

Les deux clauses sont donc nécessaires.

VI-B-3 - Restriction pour la création d'enfants

Nous souhaitons maintenant permettre à un utilisateur donné (en réalité à une application) de créer, modifier et supprimer, mais uniquement des utilisateurs d'un type particulier (l'objectclass est fixé). Il faut modifier notre première clause pour y ajouter le filtre :

access to dn.children="ou=contacts,dc=ee,dc=fr"
filter=(objectclass=eeintreenetobject)
by dn="cn=intreenet,ou=apps-accounts,dc=ee,dc=fr" write
by users read
by * break

VII - Conception des schémas LDAP

Dans ce chapitre nous allons étudier comment écrire un schéma LDAP, c'est-à-dire comment créer de nouveaux objets et de nouveaux attributs lorsque cela est nécessaire. Nous commencerons par présenter le modèle des données de la norme LDAP.

VII-A - Modèle des données

Chaque entrée de l'annuaire est constituée d'un ensemble d'attributs, chaque attribut ayant une ou plusieurs valeurs.
Le schéma d'un annuaire définit l'ensemble des classes et attributs que celui-ci peut contenir. Chaque entrée de l'annuaire appartient à une ou plusieurs classes d'objet, et ne peut contenir que des attributs de cette classe.
Chaque classe d'objets est définie par une liste d'attributs - de propriétés - obligatoires et une liste d'attributs facultatifs. À chaque attribut sont associés notamment un nom et une syntaxe, mais aussi une description, et d'autres informations que nous allons étudier en détail.

VII-B - Les attributs

VII-B-1 - Description des attributs

Un attribut est caractérisé par les informations suivantes :

- Un nom : Un identifiant sous forme de chaîne de caractères. Les noms d'attributs sont toujours insensibles à la case. Un attribut peut avoir plusieurs noms. C'est le cas de l'attribut givenName qui s'appelle aussi gn.

- Un Object Identifier (OID) : Un identifiant numérique. Voir la section dédiée.

- Une description : La description d'un attribut fait partie du schéma à part entière.

- Une syntaxe et des règles de comparaison : La syntaxe indiquera quel type d'information l'attribut peut contenir. Les règles de comparaison indiqueront comme effectuer des recherches sur les valeurs de l'attribut. La [rfc2252] fournit un ensemble de syntaxes et de règles de comparaison, que les serveurs LDAP doivent savoir gérer.

- Sa valuation : S'il est mono ou multivalué

- Un indicateur d'usage : Il existe quatre indicateurs d'usages possibles (userApplication, directoryOperation, distributedOperation, dsaOperation). Les trois derniers types d'attributs sont dit Operational. Cela signifie qu'ils ne sont pas modifiables par l'utilisateur, ni accessibles, sauf certains qui peuvent être lus, comme par exemple modifytimestamp.

- Un format ou une limite de taille

- Il existe des relations d'héritage entre attributs. Lorsqu'on définit un attribut, il faut donc aussi définir l'attribut dont il descend, même si cela n'est pas obligatoire.

Ainsi les attributs sn (nom de famille), gn (prénom) dérivent de l'attribut name. L'aspect pratique de l'héritage entre attributs est qu'il est possible d'effectuer des recherches sur plusieurs attributs en même temps. En effectuant une recherche sur l'attribut name, on fera aussi une recherche sur ses sous-types.

VII-B-2 - Exemples

VII-B-2-a - Exemples de syntaxes définies dans la [rfc2252]

OID

Nom

Description

1.3.6.1.4.1.1466.115.121.1.7

Boolean

Booléen

1.3.6.1.4.1.1466.115.121.1.12

DN

Un DN

1.3.6.1.4.1.1466.115.121.1.15

Directory String

Une chaîne de caractères, encodée en UTF-8

1.3.6.1.4.1.1466.115.121.1.26

IA5String

Une chaîne de caractères ASCII

1.3.6.1.4.1.1466.115.121.1.27

INTEGER

Un entier

VII-B-3 - Exemples et descriptions de règles de comparaison définies dans les [rfc2252]

OID

Nom

Description

Syntaxe

2.5.13.0

objectIdentifierMatch

Comparaison d'égalité entre deux OID.

1.3.6.1.4.1.1466.115.121.1.38

2.5.13.1

distinguishedNameMatch

Comparaison d'égalité entre deux DN.

1.3.6.1.4.1.1466.115.121.1.12

2.5.13.2

caseIgnoreMatch

Retourne vrai si les chaînes ont la même taille et sont identiques, à la case près.

1.3.6.1.4.1.1466.115.121.1.15

2.5.13.3

caseIgnoreOrderingMatch

Règle d'inégalité, retourne vrai si la valeur de l'attribut comparé apparaît est avant la valeur passée en paramètre, une fois les deux chaînes converties en majuscules.

1.3.6.1.4.1.1466.115.121.1.15

2.5.13.4

caseIgnoreSubstringsMatch

Règle d'inclusion, insensible à la case, comme les deux règles précédentes.

1.3.6.1.4.1.1466.115.121.1.58

2.5.13.8

numericStringMatch

Règle identique à la règle caseIgnoreMatch sauf que les espaces sont ignorés pendant la comparaison.

1.3.6.1.4.1.1466.115.121.1.36

2.5.13.10

numericStringSubstringsMatch

Règle identique à la règle caseIgnoreSubstringsMatch sauf que les espaces sont ignorés pendant la comparaison.

1.3.6.1.4.1.1466.115.121.1.58

2.5.13.23

uniqueMemberMatch

Retourne vrai si la valeur soumise et la valeur de l'attribut comparé sont des DN identiques; ou bien si le DN de l'attribut contient un composant uid, celui-ci peut être absent du DN de la valeur soumise, ou bien s'il est présent il doit être égal.

1.3.6.1.4.1.1466.115.121.1.34

VII-B-4 - Exemples d'attributs définis dans la [rfc2256]

Nom

Description

sn

Nom de famille, dérive de l'attribut name

telephoneNumber

Numéro de téléphone

member

Membre d'un groupe. Cet attribut contient un DN, donc une référence vers un nœud de l'annuaire.

VII-C - Les classes

VII-C-1 - Description

Chaque entrée de l'annuaire appartient à une ou plusieurs classes. Les classes modélisent ainsi les objets réels ou abstraits décrits dans un annuaire. Des exemples de classes sont : personne, bâtiment, application.

Une classe est constituée de :

- Un nom : Un identifiant sous forme de chaîne de caractères. Exactement comme les noms de classes sont insensibles à la case. Une classe peut elle aussi avoir plusieurs noms.

- Un Object Identifier (OID) : Un identifiant numérique. Voir la section dédiée.

- Une description : La description de la classe fait partie du schéma.

- Un type

Il existe trois types de classes :

- Les classes structurelles : C'est une classe classique qui peut être instanciée.

- Les classes auxiliaires : Ce sont des classes permettant de rajouter des informations complémentaires à des objets structurels. Des exemples de classes auxiliaires sont: mailRecipient, labelURIObject. Ces classes contiennent un ensemble d'attributs, généralement facultatifs. Les classes auxiliaires sont similaires aux interfaces en java.

- Les classes abstraites : Les classes abstraites ne peuvent pas être instanciées, mais seulement dérivées.

Il n'est pas possible de faire de l'héritage multiple entre classes: une classe dérive toujours d'une seule classe. Néanmoins une entrée de l'annuaire peut être constituée de plusieurs classes, à condition qu'elle ne soit constituée que d'une seule classe structurelle, et de zéro, une ou plusieurs classes auxiliaires.

L'ensemble des classes d'objet forme une hiérarchie, dont la classe Top est au sommet.

VII-C-2 - Exemples

Exemples d'objet standards issus de la [rfc2256] :

OID

Nom

Supérieur

Type

Attributs obligatoires

Attributs facultatifs

Description

2.5.6.0

top

Aucun

ABSTRACT

Aucun

Aucun

Classe parente de toutes les classes

2.5.6.6

person

top

STRUCTURAL

sn, cn

userPassword, telephoneNumber, seeAlso, descriptio

Classe de base modélisant une personne

2.5.6.9

groupOfNames

top

STRUCTURAL

member, cn

businessCategory, seeAlso, owner, ou, o, description

Groupes d'utilisateurs

VII-D - Présentation des OID

VII-D-1 - Présentation des OID

Les OID sont des identifiants universels, représentés sous la forme d'une suite d'entiers. Ils sont organisés sous forme hiérarchique. Ainsi seul l'organisme 1.2.3 peut dire quelle est la signification de l'OID 1.2.3.4. Ils ont été définis dans une recommandation de l'International Telecommunication Union. L'IETF a proposé de représenter la suite d'entiers constituant les OID séparés par des points.
L'objectif des OID est d'assurer l'interopérabilité entre différents logiciels. Les OID sont utilisés dans le monde LDAP, mais aussi dans d'autres domaines, par exemple les logiciels SNMP pour identifier des ressources. Il est possible d'obtenir un OID, et par conséquent toute une branche, auprès de l'IANA.
Dans le monde LDAP les objets, les attributs, les syntaxes et les règles de comparaison sont référencés par un objet OID. La [rfc2256] normalise un certain nombre de ces objets.

VII-D-2 - Exemples

VII-D-2-a - Exemples d'OID

OID

Description

0

branche de l'International Telecommunication Union

1

branche ISO

2

branche commune entre l'International Telecommunication Union et ISO

2.5

fait référence au service X500

2.5.4

définition des types d'attributs

2.5.6

définition des classes d'objets

1.3.6.1

the Internet OID

1.3.6.1.4.1

IANA-assigned company OIDs, used for private MIBs

1.3.6.1.4.1.4203

OpenLDAP

1.3.6.1.4.1.10650

Easter-eggs

Supposons qu'un organisme ait le OID 1.1. L'exemple suivant montre une façon d'ordonner les OID qu'il créera pour ses propres besoins

VII-D-2-b - Exemple de hiérarchie

OID

Description

1.1

OID de l'organisme

1.1.1

Branches des identifiants SNMP

1.1.2

Branches des identifiants LDAP

1.1.2.1

Branches des attributs LDAP

1.1.2.1.1

Identifiant du premier attribut LDAP

1.1.2.2

Branche des classes d'objets LDAP

1.1.2.2.1

Identifiant du premier objet LDAP

VII-E - Syntaxe

VII-E-1 - Syntaxe de la définition d'un attribut

AttributeTypeDescription = "(" whsp
numericoid whsp              ; AttributeType identifier
[ "NAME" qdescrs ]             ; name used in AttributeType
[ "DESC" qdstring ]            ; description
[ "OBSOLETE" whsp ]
[ "SUP" woid ]                 ; derived from this other
; AttributeType
[ "EQUALITY" woid              ; Matching Rule name
[ "ORDERING" woid              ; Matching Rule name
[ "SUBSTR" woid ]              ; Matching Rule name
[ "SYNTAX" whsp noidlen whsp ] ;
[ "SINGLE-VALUE" whsp ]        ; default multi-valued
[ "COLLECTIVE" whsp ]          ; default not collective
[ "NO-USER-MODIFICATION" whsp ]; default user modifiable
[ "USAGE" whsp AttributeUsage ]; default userApplications
whsp ")"

Cette syntaxe est extraite de la [rfc2252]. whsp est un blanc. Le nom de l'attribut doit être entre parenthèses et entre simples quotes. Des espaces sont obligatoires entre les parenthèses et le nom entre quotes, et entre les différents noms, s'il y en a plusieurs. La syntaxe de la description est identique, excepté qu'il ne peut y avoir qu'une seule description.

woid signifie OID. noidlen signifie que la syntaxe d'un attribut est aussi un OID qui peut être complété par une taille maximale, contenue entre {}.

AttributeUsage est l'une des quatre valeurs présentées ci-dessus: userApplications directoryOperation distributedOperation dSAOperation.

La [rfc2252] permet à un attribut d'être collectif, c'est-à-dire partagé entre plusieurs entrées. C'est un héritage de la norme X500. Néanmoins la norme LDAP n'a pas fourni d'indication sur l'implémentation de ces attributs. Ils ne sont donc pas utilisés actuellement. Une RFC récente, de décembre 2003, fournit plus d'informations. Il s'agit de la [rfc3671].

Exemples de déclarations d'attributs :

attributetype ( 2.5.4.4 NAME ( 'sn' 'surname' )
DESC 'RFC2256: last (family) name(s) for which the entity is known by'
SUP name )

attributetype ( 2.5.4.20 NAME 'telephoneNumber'
DESC 'RFC2256: Telephone Number'
EQUALITY telephoneNumberMatch
SUBSTR telephoneNumberSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.50{32} )

( 2.5.4.31 NAME 'member' SUP distinguishedName )

VII-E-2 - Syntaxe de la définition d'un objet

ObjectClassDescription = "(" whsp
numericoid whsp      ; ObjectClass identifier
[ "NAME" qdescrs ]
[ "DESC" qdstring ]
[ "OBSOLETE" whsp ]
[ "SUP" oids ]       ; Superior ObjectClasses
[ ( "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" ) whsp ]
; default structural
[ "MUST" oids ]      ; AttributeTypes
[ "MAY" oids ]       ; AttributeTypes
whsp ")"

Cette déclaration de la syntaxe d'un objet est en tout point similaire à celle d'un attribut.

Exemples de déclarations d'attributs :

( 2.5.6.0 NAME 'top' ABSTRACT MUST objectClass )

( 2.5.6.3 NAME 'locality' SUP top STRUCTURAL
MAY ( street $ seeAlso $ searchGuide $ st $ l $ description ) )

( 2.5.6.6 NAME 'person' SUP top STRUCTURAL MUST ( sn $ cn )
MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )

( 2.5.6.9 NAME 'groupOfNames' SUP top STRUCTURAL MUST ( member $ cn )
MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description ) )

VII-F - L'intérêt de créer ses propres schémas

Bien qu'il existe de nombreux objets et attributs normalisés, ceux-ci ne sont pas toujours adaptés au besoin d'une organisation. Généralement chaque organisation possède des informations à stocker dans l'annuaire qui lui sont spécifiques.
Sachant que les objets standards sont impossible à modifier, il reste la possibilité de créer ses propres attributs et ses propres objets. Cela nécessite la démarche administrative consistant à récupérer un identifiant auprès de l'IANA.

VIII - Déploiement d'une architecture LDAP

Après avoir vu comment écrire un schéma, nous allons étudier le processus de mise en œuvre d'un annuaire LDAP.

VIII-A - Phase de cadrage

La première phase du processus de mise en œuvre d'un annuaire est la phase de cadrage. C'est pendant cette phase que doivent être désignés tous les objectifs qui sont assignés à l'annuaire.

Quel que soit le type d'organisation dans laquelle un annuaire est déployé, celui-ci a toujours un impact important. Le service informatique est bien sûr le premier à être concerné, mais il est loin d'être le seul. Il est donc important que l'organisation désigne un responsable annuaire, qui sera l'interlocuteur unique entre le prestataire qui met en œuvre l'annuaire, mais aussi entre les utilisateurs finaux et le service informatique.

L'annuaire est amené à devenir le point central de l'architecture informatique de l'organisation. Toute application nécessitant une authentification des utilisateurs devrait s'appuyer sur un annuaire. C'est là sa première vocation et sa première utilisation. Mais il est aussi possible de l'utiliser pour stocker des informations supplémentaires sur les personnes, et peut ainsi être la base de données d'une application de type « pages blanches ». On voit bien alors qu'il peut servir pour gérer presque n'importe quel type de données, et dans beaucoup d'applications.

Il est donc primordial, pendant la phase de cadrage, de se donner des priorités parmi toutes ces possibilités d'utilisation d'un annuaire. Il faut, d'une part, choisir quelles seront les premières applications qui appuieront leur authentification sur l'annuaire. Il faut aussi, d'autre part, déterminer quelles sont les premières applications qui utiliseront les données de l'annuaire en tant que telles.

L'important à cette étape est de rester modeste et pragmatique. Avoir une ou deux applications s'appuyant sur l'annuaire est un bon début, qui permet de démarrer simplement, sans faire la révolution dans tout le système informatique. Avoir une application de type pages blanches et un serveur mail dont l'authentification et les paramètres de messagerie sont basés sur l'annuaire est un bon début. Ce n'est pas la peine d'y ajouter tout de suite une liaison avec le logiciel de paie et la gestion des permissions du serveur de fichiers.

L'autre paramètre à intégrer dans cette phase concerne les utilisateurs. Dans le cas de la mise en œuvre d'une application pages blanches, ou bien d'une autre application nouvelle entièrement basée sur l'annuaire, ils doivent être intégrés au plus tôt dans la définition des besoins. En effet, au-delà des données techniques, l'utilisateur final sera le plus compétent pour dire quelles sont les données qui devront être intégrées à l'annuaire.

VIII-B - Phase de conception

VIII-B-1 - Choix des données et Identification des acteurs

VIII-B-1-a - Déterminer les données de l'annuaire

Après la phase de cadrage, la première étape de la phase de conception consiste à énumérer les données présentes dans l'annuaire. Il s'agit d'énumérer de manière exhaustive d'une part toutes les classes d'objets amenées à peupler l'annuaire, et d'autres parts, pour chaque classe, quelles sont ses propriétés gérées par l'annuaire.

Pour chaque type de données, en procédant par classes d'objets puis par propriétés si nécessaire, il faut alors déterminer les informations suivantes :

- Quelles sont les personnes ou les applications manipulant cette donnée? On se contentera dans un premier temps d'une réponse sommaire, sachant qu'une réponse plus complète - par type d'action - sera donnée par la suite.

- Quelle est la ou les sources actuelles de cette donnée ? Est-elle déjà sous forme numérique ou pas encore ? Est-ce une donnée statique ou dynamique ? Est-elle calculée ?

- Quel est le type de cette donnée (chaîne de caractères, entier, data, etc)? Quel est son format : la chaîne est-elle encodée en utf8 ou unicode? Quel format de date est utilisé ? Sa taille ?

- Quelle est la pérennité de la donnée ? Sa fréquence de mise à jour ? Cette mise à jour est-elle automatique ou manuelle ?

VIII-B-1-b - Cas d'utilisation

Une fois les données de l'annuaire bien définies, il faut détailler leur utilisation. Pour y parvenir de façon convenable, il est utile d'employer la même méthode que lorsqu'on décrit des cas d'utilisation, en eXtrem Programming et en modélisation UML.

Bien que les cas d'utilisation soient centrés sur les utilisateurs, il faudra, dans notre travail, énumérer aussi les actions des applications externes à l'annuaire, mais qui l'utilisent.

Pour chaque donnée contenue dans l'annuaire, il faut donc noter qui effectue les actions suivantes :

- Recherche. Une recherche s'effectue sur certains attributs. Pour chaque objet, dans chaque cas d'utilisation, il faudra donc noter les attributs sur lesquels la recherche s'effectue.

- Lecture. Là encore il faut tenir compte des attributs. Les cas d'utilisation devront contenir l'information «de quel attribut a besoin de lire telle personne sur tel objet.»

- Création. Lors du processus de création des objets dans l'annuaire, il faudra valider que la personne, ou l'application, qui crée un objet, a bien connaissance de toute l'information nécessaire. Il peut arriver que cela ne soit pas le cas. Par exemple, une personne du département ressources humaines ne pourra pas d'elle-même assigner un login à un utilisateur dans l'annuaire. Il faut prévoir un mécanisme, en dehors de l'annuaire, qui lui fournit cette information qui se peut se révéler nécessaire dans certains cas.

- Modification. Dans l'écriture des cas d'utilisation comprenant des modifications, il est nécessaire de noter quels attributs sont modifiés, et de quel type de modifications il s'agit: ajout d'une valeur, retrait d'une valeur, modification de toutes les valeurs, etc.

- Suppression.

LDAP ne contient pas l'équivalent de clé étrangère pour contrôler la cohérence des données de l'annuaire.

Les cas d'utilisation peuvent dans un premier temps être effectués sur les classes, sur les catégories d'objets présents dans l'annuaire. Il sera parfois nécessaire de descendre à un niveau de précision inférieure et d'écrire les cas d'utilisation par attribut, ou par groupes d'attributs.

Il sera aussi utile noter la fréquence de chaque cas d'utilisation.

VIII-B-2 - Élaboration du schéma

Cette étape s'appuie essentiellement sur l'étape précédente du choix des données contenues dans l'annuaire. Elle consiste à écrire un schéma qui modélise ces données.

Écrire un schéma c'est essentiellement définir :

- les attributs

- les classes

- la hiérarchie entre ces classes

des objets qui constitueront l'annuaire.

De la liste des données, il faut extraire les informations élémentaires, sous la forme d'une liste d'attributs, et d'une liste de classes, celles-ci étant définies en regroupant les attributs. Notre méthode consistera à définir et modéliser les attributs, indépendamment des classes, les attributs étant partagés entre classes; puis à constituer les classes d'objet en agrégeant les attributs adéquats.
Entre la définition des classes et celle des attributs, il peut y avoir une démarche itérative. Ainsi certaines informations élémentaires changeront de statut au cours de la modélisation. Par exemple la catégorie d'une personne pourra être une classe, plutôt qu'un attribut, parce que l'appartenance d'une personne à une catégorie implique la présence obligatoire d'autres attributs.
Lors de la définition des attributs comme celles des classes, il faut penser à utiliser la relation d'héritage, lorsque des caractéristiques sont partagées et qu'il existe des liens de spécialisations, entre attributs ou entre classes.

En reprenant ce qui a été écrit précédemment, définir un attribut consiste à définir :

- son nom;

- s'il est standard, issu d'une RFC, public, déjà créé et publié, ou encore spécifique, spécialement créé;

- son attribut père, s'il dérive d'un autre attribut

- sa syntaxe: est-ce une chaîne de caractères ? Un pointeur vers une autre entrée de l'annuaire ? Etc.

- s'il est mono ou multivalué;

- par quelle(s) classe(s) il est utilisé;

- sa fréquence d'utilisation

Il peut arriver que l'on ait distingué des attributs contenant exactement le même type d'information parce qu'ils étaient attributs de classes différentes. Cette différenciation n'a pas lieu d'être. Au contraire, il est plus logique d'avoir un même attribut utilisé par plusieurs classes.

De façon similaire, la définition des classes d'objets consiste à préciser :

- son nom;

- si elle est standard, issue d'une RFC, publique, ou spécifique;

- sa classe mère, si elle dérive d'une autre classe;

- la liste des attributs obligatoires;

- la liste des attributs facultatifs;

VIII-C - Sécurisation

Bien qu'étant primordial, ce chapitre sera assez court. En effet, la sécurisation de l'annuaire s'appuie sur les éléments cités précédemment, et sur des éléments à venir.
Tout d'abord, les cas d'utilisation, par classe puis par attribut, permettent de définir les droits d'accès à la granularité nécessaire.
Il s'agit donc ensuite d'écrire les règles d'accès, en s'appuyant sur la syntaxe présentée au chapitre Fonctionnement des permissions dans OpenLDAP.
La topologie du service influence aussi la sécurité.

VIII-D - Développement de l'arbre informationnel

Comme on l'a vu aux deux premiers chapitres, les données d'un annuaire sont organisées sous forme hiérarchique, en arbre. Concevoir l'arbre informationnel d'un annuaire c'est spécifier la forme de cet arbre, son organisation, comment les données vont y être nommées. L'objectif à cette étape est donc d'organiser les données pour leur :

- Consultation

- Mise à jour

- Duplication

- Répartition

VIII-D-1 - La structure de l'arbre informationnel

Un arbre est caractérisé par son branchage plus ou moins fort. Un arbre a un branchage faible lorsque les entrées feuilles (sans descendant) sont très regroupées, au lieu d'être dispersées sous d'autres entrées. On dit aussi qu'il est plat.

Arbre plat

Arbre à branchage fort

Les arbres plats ont pour principal avantage que les recherches s'effectuent rapidement, parce que le serveur n'a pas à parcourir toutes les branches, et à faire une recherche par branche. Par ailleurs les arbres plats présentent beaucoup d'inconvénients :

- Les collusions de RDN peuvent se produire fréquemment;

- La mise en place de referral n'est pas possible (Le mécanisme de referral peut alors être remplacé par la mise en place d'un méta annuaire. Néanmoins un méta annuaire est beaucoup plus lourd à mettre en place.)

Sur ces points les arbres à fort branchage sont bien plus efficaces. Ils facilitent aussi la délégation. L'inconvénient des arbres à fort branchage apparaît essentiellement lorsque la structure de l'arbre reflète la structure de l'organisation, et que cette structure est amenée à être modifiée. Dans ce cas, les entrées de l'arbre vont elles aussi être amenées à changer de place et de DN, ce qui peut provoquer des problèmes de cohérences.

Il y a donc un certain équilibre à atteindre entre les deux types d'arbres. Les éléments à prendre en compte sont les suivants (4) :

- Le nombre d'entrées prévu et son évolution ?

- La nature (type d'objet) des entrées actuelles et futures ?

- Vaut-il mieux centraliser les données ou les distribuer ?

- Seront-elles administrées de manière centrale ou faudra-t-il déléguer une partie de la gestion ?

- La duplication est-elle prévue ?

- Quelles applications utiliseront l'annuaire et imposent-elles des contraintes particulières ?

- Quelles permissions seront mises en place?

VIII-D-2 - Le nommage des données

VIII-D-2-a - Choix du suffixe

Contrairement aux annuaires X500 les annuaires LDAP n'ont à vocation à s'insérer dans un annuaire universel. Dès lors, contrairement à leurs ancêtres, chaque annuaire peut avoir la racine qu'il veut. Il n'existe pas d'obligation à respecter. La norme X500 imposer aux annuaires d'entreprises parisiennes d'avoir un suffixe de la forme l=paris,o=fr.

Dans la norme LDAP chaque annuaire fait ce qu'il lui plaît, et peut prendre comme racine, comme suffixe, ce qu'il veut. Le suffixe est devenu l'identifiant d'un annuaire.

Il existe néanmoins une RFC, la [rfc2377] qui apporte un peu de cohérence dans le choix des suffixes. Elle permet de construire un suffixe à partir d'un nom de domaine, et en utilisant l'attribut dc. Cette RFC propose tout simplement de transformer tous les éléments d'un nom de domaine en valeur de l'attribut dc. Ainsi l'annuaire l'entreprise dont le nom de domaine est easter-eggs.com sera dc=Easter-eggs, dc=com.

VIII-D-2-b - Nommage des entrées

Le nommage des entrées consiste à choisir un attribut, qui sera utilisé pour nommer les entrées. Il s'agit donc de choisir le RDN de chaque branche. Cet attribut doit permettre de désigner sans ambiguïté une entrée. C'est-à-dire que sa valeur doit être unique dans chaque branche. Le deuxième élément à prendre en compte est sa stabilité. Il est préférable en effet qu'une entrée ne change guère d'identité. Cela est d'autant plus vrai dans le cas des entrées possédant des descendants.

VIII-E - Topologie du service

Définir la topologie du service consiste à définir la répartition géographique de l'annuaire. Un annuaire LDAP peut en effet être déployé sur des machines physiques différentes. Cette étape a but de concevoir cette répartition.

VIII-E-1 - Conception

VIII-E-1-a - Objectifs

Disposer des serveurs annuaires sur des plusieurs machines permet de répondre à un besoin en qualité de service. S'ils sont bien répartis et bien configurés, plusieurs serveurs seront plus performants et plus fiables qu'un seul serveur. La répartition de l'annuaire sur plusieurs machines peut aussi faciliter sa gestion.
La norme LDAP définit deux mécanismes permettant une répartition géographique des serveurs. Le premier est le mécanisme de referral qui permet de déléguer une branche d'un annuaire à un autre annuaire, localisé sur une machine distante. Le deuxième est le mécanisme de réplication.
La mise en place des deux mécanismes dépend très fortement de la structure de l'arbre informationnel. Le processus de conception de la topologie du service peut donc être itératif avec la conception de l'arbre informationnelle.

VIII-E-1-b - Recueil des informations

La première étape consiste à faire l'inventaire des sites géographiques qui devront se connecter à l'annuaire. Pour chaque site il est nécessaire ensuite de dessiner son schéma réseau pour identifier les différents réseaux, les différents routeurs et surtout par quelle machine passe les flux sortants. Les liaisons entre sites devront aussi être répertoriées et leurs caractéristiques (débit, réseau privé ou public) devront être notées. Cette étape est donc l'identification des contraintes réseau.
Pour chaque site, il faut ensuite évaluer le nombre d'utilisateurs et en déduire le nombre de requêtes qu'ils génèrent et le type de requêtes (interrogations, mises à jour, création, etc.). Cette étape réutilise donc les cas d'utilisation déjà produits précédemment.
La troisième information à noter sur les requêtes, outre leur nombre et leur type, est l'information concernée par la requête. Par exemple, est-ce qu'il s'agit de l'identité des utilisateurs, des attributs de messagerie, ou bien de leur numéro de téléphone.

VIII-E-1-c - Les décisions techniques

Nous avons alors à notre disposition :

- la topologie du réseau;

- les flux générés par certaines parties du réseau vers l'annuaire, ces flux étant eux même composés de flux de recherche, de lecture, d'écriture, etc.;

- l'arbre informationnel, qui contient l'information recherchée, lue ou modifiée par ces flux.

À partir de toutes ces informations, nous devons définir la topologie du service LDAP, soit répondre aux deux questions suivantes :

- L'information doit-elle être répartie sur un ou plusieurs serveurs ? Et comment?

- Quelle redondance ?

La répartition du contenu de l'annuaire entre plusieurs serveurs n'est possible que si l'arbre informationnel le permet. Il y a donc une démarche itérative entre la définition de la topologie et le choix de l'espace de nommage.

Les deux sections suivantes donnent d'avantage d'information sur le service referral, et sur la réplication.

VIII-E-2 - Utilisation de referral

Le mécanisme de referral est un mécanisme de redirection qui permet à un serveur annuaire de déléguer une partie de ses branches à un autre serveur. Dans le protocole LDAP décrit dans [rfc2251] le serveur peut toujours répondre à une opération quelconque par un referral.

La [rfc2251] décrit en particulier uniquement comment un serveur doit répondre à une recherche dont les entrées retournées sont réparties sur plusieurs autres annuaires. La réponse du serveur doit alors contenir les entrées gérées par lui-même, et une ou plusieurs références, des url que le client doit exécuter pour terminer sa recherche.

Les RFC de la version 3 de la norme ne définissent pas davantage comment un serveur a connaissance des branches qu'il doit déléguer. La [rfc3296] est une proposition pour remplir cette lacune. Openldap s'appuie dessus.

Cette RFC introduit une classe d'objets, la classe referral, possédant pour seul attribut ref. Cette classe représente une référence inférieure dans l'annuaire, c'est-à-dire une branche déléguée à un autre serveur. L'attribut ref contient une url LDAP. Néanmoins elle ne doit pas contenir de profondeur, de filtre ou d'attribut. Son usage est distributedOperation.

À chaque fois qu'un client tente d'accéder à une entrée située une entrée de type referral, ou bien sous une de ces entrées, l'annuaire renvoie donc en referral les valeurs de l'attribut ref de l'entrée referral. Il est néanmoins possible d'ajouter le contrôle ManageDsaIT aux opérations, pour pouvoir modifier les entrées elle même.

Openldap utilise aussi un default referral. Ce referral est renvoyé par défaut à toute les requêtes effectuées sur le serveur et dont le base_dn n'est sous aucun suffixe du serveur.

Le chaînage, mécanisme par lequel le serveur contacte lui même un autre serveur et envoie sa réponse au client, n'est pas mis en place dans Openldap et n'est guère déployé ailleurs pour des raisons de sécurité. Néanmoins les mécanismes de meta annuaire permettent ce type de configuration.

VIII-E-3 - La réplication

Alors que le mécanisme de referral permet de répartir l'information d'un annuaire entre plusieurs serveurs, la réplication permet quant à elle de dupliquer cette information sur plusieurs serveurs.

Les mécanisme, referral et réplication, ont des points communs et des différences. Leur point commun est qu'ils impliquent tous deux une répartition géographique des serveurs. En cela ils permettent d'intervenir sur la qualité de service de l'annuaire. Mais les moyens mis en œuvre diffèrent.

La réplication introduit de la redondance. Cette redondance permet :

- Tolérance aux pannes. Si un serveur ne répond plus, il sera possible pour le client de contacter un autre serveur contenant l'information.

- Équilibrage de charge. Les clients LDAP seront configurés pour contacter le serveur annuaire le plus proche d'eux.

- Gestion locale des données. Le mécanisme de réplication permet à chaque entité géographique de gérer elles-mêmes les données qui dépendent d'elle, et de les partager en lecture aux entités.

VIII-F - Vue d'ensemble

Phase

Aspects fonctionnels

Aspects techniques

Phase I

Cadrage

- se limiter à une ou deux applications

- trouver un maître d'ouvrage (un sponsor du projet, un groupe d'utilisateurs)

- établir des priorités dans les usages possibles de l'annuaire

Il n'y a pas d'aspect fonctionnel à cette étape

Phase II

Choix des données et Identification des acteurs

- Écriture des cas d'utilisation à la UML

- Rester dans le cadre défini en phase I

Écriture du schéma

- Utilisation de la phase II fonctionnelle

- Peut être itératif avec la phase III technique

Phase III

Définition des droits d'accès
Utilisation des cas d'utilisation

Écriture des clauses d'accès
Nécessite une vision de l'arbre informationnel

Phase IV

Conception de l'arborescence
Prise en compte d'un aspect géographique supplémentaire par rapport aux cas d'utilisation

Topologie du service

- Le service referral

- Duplication des données

IX - Configuration d'applications externes sur LDAP

Dans ce chapitre nous allons voir comment configurer un certain nombre d'applications pour qu'elles s'appuient sur un annuaire LDAP.

IX-A - Authentification

IX-A-1 - Introduction

La première utilisation d'un annuaire LDAP concerne généralement l'authentification. Cela signifie que l'annuaire sera utilisé par des applications diverses pour valider qu'un utilisateur qui s'identifie, par exemple, par un couple (login, mot de passe) est bien un utilisateur admis à utiliser l'application.

L'annuaire permet donc dans un premier temps de centraliser toutes ces données de connexions, les couples (login, mot de passe). Le principal problème posé par la configuration d'applications externes consiste à convertir l'identifiant fourni à l'application par l'utilisateur, avec un DN. En effet, comme nous l'avons écrit précédemment, pour se connecter à un annuaire il faut s'identifier auprès de cet annuaire en tant qu'une entrée de l'annuaire.

Nous allons donner quelques exemples de configurations d'applications, et voir quels sont les procédés mis en œuvre par les applications pour déduire, à partir d'un login, un DN.

IX-A-2 - Apache

IX-A-2-a - Module auth_ldap

Ce module permet de protéger l'accès à certaines pages web, en demandant à l'utilisateur de s'authentifier auprès d'un annuaire. Il fonctionne en deux temps. Tout d'abord, à partir du login fourni par l'utilisateur il va rechercher dans l'annuaire un DN. Ensuite il va regarder si ce DN possède les droits nécessaires pour se connecter.

Comme tout module apache, sa configuration est donnée sous la forme de directive, qui peuvent être insérées soit dans le fichier de configuration globale d'apache: httpd.conf, soit dans des fichiers locaux .htaccess situés dans l'arborescence du site que l'on souhaite protéger.

IX-B - Messagerie

Bibliographie

Définition des annuaires

- Overview and History of Directory Services. Disponible en ligne

- Understanding X.500 - The Directory. http://www.isi.salford.ac.uk/staff/dwc/Version.Web/Contents.htm

- Guidelines for the Evaluation of X.500 Directory Products. http://snad.ncsl.nist.gov/snad-staff/tebbutt/x5eg/tableofcontents2_1.html

- Introduction to LDAP. Peter Gietz. http://www.ceenet.org/workshops/lectures2001/Peter Gietz/CEENET2001-LDAPl/index.htm

Documents généraliste sur les annuaires

- Directory Services for Linux in comparison with Novell NDS and Microsoft Active Directory. Norbert Klasen. http://www.daasi.de/staff/norbert/thesis/html/thesis.html

Note

Ce document est une copie du livre en ligne LDAP Book de Michaël Parienti Maire (mparienti@easter-eggs.com) soumis à la licence Creative Commons Attribution-ShareAlike Licence. Le document original est disponible ici : http://ldapbook.labs.libre-entreprise.org/book/html/.
Ce document a été passé au gabarit par Hugo Etiévant.

(1)Openldap peut dans certains cas simuler ce type de contrôle grâce à des permissions

(2)Voir Michigan Terminal System: Summary.

(3)L'erreur retournée est notAllowedOnRDN.

(4)L'essentiel de cette liste provient du tutoriel de Laurent Mirtain, Christian Claveleira et Claude Gross.