Modèle de stockage des informations
L’unité de base de l’information stockée dans un annuaire s’appelle une entrée ; celle-ci contient des informations sur un type d’objet particulier qui peut être une personne, un serveur, une fonction ou bien même une organisation d’entreprise, etc. Les entrées sont ainsi composées d’une collection d’attributs qui contiennent les informations décrivant l’objet. Chaque attribut est constitué d’un type de syntaxe et d’une ou plusieurs valeurs. Le type de syntaxe spécifie en fait le type de valeurs pouvant être stockées par l’attribut. Par exemple, une entrée contenant des informations sur un objet Personne peut avoir un attribut nommé Numéro de Téléphone dont le type de syntaxe autorisera l’utilisation de caractères numériques, mais aussi de caractères spéciaux tels que des tirets (-) ou des signes plus (+) et également des espaces. Mais comme une personne peut détenir plusieurs numéros de téléphone, il convient également de définir pour cet attribut la possibilité de posséder plusieurs valeurs différentes.
La relation entre une entrée de l’annuaire et ses attributs et leurs valeurs est illustrée par la figure 2-1 :
¬
Figure 2-1 : Modèle de stockage de l’information
1. Les attributs
En plus de définir quelles données peuvent être stockées en tant que valeur d’un attribut, un type de syntaxe de l’attribut définit également la manière dont ces valeurs se comportent pendant les opérations de recherche ou de comparaison soumises aux informations de l’annuaire.
Ainsi, la syntaxe de l’attribut Numéro de Téléphone de notre exemple précédent contiendra une information supplémentaire afin de spécifier que les espaces, les signes plus (+) et les tirets (-) seront ignorés lors d’une opération de recherche ou de comparaison sur ce type d’attribut. Par exemple, si une recherche dans l’annuaire de type : trouver l’entrée (ou les entrées) de l’annuaire qui possède(nt) la valeur 0665452312 pour l’attribut Numéro de Téléphone .
Alors l’opération de recherche retournera comme valeurs correctes : 06-65-XX-XX-12, 06 65 XX XX 12 ou bien même + 0665XXXX12. Ce fonctionnement est donc très appréciable, car il permet de ne pratiquement pas manquer une entrée de l’annuaire pour l’opération de recherche effectuée.
Certaines des syntaxes définies pour LDAP sont listées dans le tableau de la figure 2-2 :
Syntaxe	Description	
bin	Information binaire (autorise seulement les chiffres 1 et 0).	
ces	Pour ’Case exact string’. La valeur recherchée doit être exactement la même et surtout les majuscules/minuscules.	
cis	Pour ’Case ignore string’. La valeur recherchée doit être exactement la même, mais sans considérer les majuscules/minuscules.	
tel	Numéro de téléphone. Les chiffres sont traités comme du texte et tous les espaces et les tirets sont ignorés.	
dn	Nom distinctif.	
Generalized Time	Année, mois, jour et temps sont représentés dans une même chaîne sans espace.	
PostalAddress	Adresse avec des lignes séparées par des caractères "$".	
Figure 2-2
Le tableau de la figure 2-3 présente quelques-uns des attributs les plus couramment utilisés. Certains attributs ont des noms d’alias qui peuvent être utilisés partout où le nom d’attribut complet est utilisé. Par exemple, cn peut être utilisé lorsque vous faites référence à l’attribut commonName.
Attribut, Alias	Syntaxe	Description	Exemple	
commonName, cn	cis	Nom complet	michel dupont	
surname, sn	cis	Nom de la personne	dupont	
telephoneNumber	tel	Numéro de téléphone	06-65-45-23-12	
organizationalUnit Name, ou

owner	cis

 
dn	Nom d’un service ou d’une entité de l’entreprise
DN du propriétaire de l’entrée	DBA

 
cn=michel
dupont,o= entreprise,c=fr	
organization,
ou 
jpegPhoto	cis
 
bin	Nom de l’entreprise
Photo au format JPEG	entreprise
 
La photo de michel dupont	
Figure 2-3
Des contraintes peuvent être associées à des types d’attributs pour limiter le nombre de valeurs pouvant être stockées dans l’attribut ou limiter la taille totale d’une valeur. Par exemple, un attribut qui contient une photo peut être limité à une taille de 50 Ko pour empêcher l’utilisation de quantités déraisonnables d’espace de stockage, ou bien encore un attribut stockant un numéro de sécurité sociale pourrait être limité à la possession d’une seule valeur.
2. Les classes d’objets et les schémas
Les schémas définissent tous les types d’objets pouvant être stockés dans l’annuaire : une personne, un serveur, etc., au travers d’attributs caractérisant les différents types d’objets et également leurs caractères facultatifs ou non.
Par exemple, pour créer une entrée de l’annuaire contenant des informations sur une personne de l’entreprise, l’annuaire devra au préalable charger le schéma contenant tous les attributs caractérisant l’objet nommé person. Dans ce schéma se trouvent plusieurs attributs parmi lesquels certains seront obligatoires (ex. surname qui donne le nom de la personne) alors que d’autres seront facultatifs (ex. description qui permet de renseigner diverses informations). Ce fonctionnement permet ainsi de s’assurer que tous les attributs nécessaires lors de la création d’une entrée pour un type d’objet donné sont bien tous présents. Les attributs facultatifs peuvent être quant à eux configurés à tout moment.
Cependant, les schémas permettent également d’organiser les attributs qu’ils contiennent par type objet à l’aide d’un attribut particulier appelé « classe d’objet » (en anglais objectclass).
Cela s’apparente tout simplement à de la programmation orientée objet. Ainsi, lors de la création d’une entrée de type person, il suffit de renseigner l’attribut objectclass avec la valeur person qui aura pour effet d’apporter les attributs (obligatoires et facultatifs) nécessaires à la création de cette entrée.
¬
Figure 2-4 : Application de plusieurs classes d’objets à une entrée
Ces classes d’objets sont également conçues dans un modèle hiérarchique ou de sous-classification avec héritage des attributs provenant des parents. Cela a pour conséquence d’apporter de nouveaux attributs à une classe d’objet non pas directement, mais par l’intermédiaire d’une sous-classe. Une entrée peut contenir plusieurs classes d’objets ce qui sous-entend que l’attribut objectclass est multivaleurs.
Par exemple, supposons qu’un objet appelé person soit défini et comprend entre autres l’attribut surname. Alors une classe d’objet organisationPerson pourrait être définie comme une sous-classe de la classe d’objet person et hériterait donc des attributs de la classe d’objet person, en plus de ceux définis dans sa propre classe comme l’attribut title (intitulé de la fonction de la personne) ou bien officenumber (pour le numéro de bureau). La classe d’objet person serait donc classée au-dessus de la classe d’objet organizationPerson. Une classe d’objet spéciale, appelée top, n’a pas de supérieur hiérarchique et se situe donc au sommet du modèle hiérarchique des classes d’objets. Ainsi, il est impossible d’utiliser une classe d’objet sans sa classe d’objet supérieure.
La classe d’objet spéciale extensibleObject permet à n’importe quel attribut d’être stocké dans une entrée, plus pratique à l’usage que de définir une nouvelle classe d’objet pour ajouter un attribut spécial à quelques entrées, mais aussi ouvrir cet objet pour pouvoir contenir tout (ce qui pourrait ne pas être une bonne chose dans un système structuré).
Il existe trois types de classe : abstraite, structurelle et auxiliaire.
	•	Une classe d’objet dite abstraite est utilisée comme modèle pour créer d’autres classes d’objets, mais qu’il n’est pas possible d’instancier : c’est-à-dire qu’une entrée d’annuaire ne peut donc pas être créée seulement à partir de celle-ci. Il faudra pour cela y ajouter une classe d’objet de type structurel héritière de celle-ci également. Il existe cependant une classe abstraite de base, baptisée "top", qui est la mère de toutes les classes abstraites et dont toutes les classes structurelles héritent directement ou indirectement.
	•	Une classe d’objet dite structurelle est quant à elle nécessaire et caractérise réellement la nature de l’entrée. Il est possible d’ajouter plusieurs classes d’objet de type structurel si et seulement si celles-ci sont des sous-classes (ex. inetOrgPerson est une sous-classe de organizationalPerson qui est une sous-classe de person). Autrement, vous recevrez une erreur de type objectclass violation.
	•	Une classe d’objet dite auxiliaire permet de compléter les caractéristiques de l’entrée (et donc de la classe d’objet structurelle) en rajoutant des informations complémentaires par l’intermédiaire d’attributs facultatifs.
Le tableau de la figure 2-5 énumère quelques classes d’objets communément utilisées avec leurs attributs obligatoires :
Classe d’objet	Description	Attributs obligatoires	
InetOrgPerson	Décrit une personne de l’entreprise	commonName (cn)
surname (sn)
objectClass	
organizationalUnit	Nomme un service ou une entité de l’entreprise	ou
objectclass	
organization	Nomme une entreprise	ou
objectClass	
Figure 2-5
Bien que chaque serveur d’annuaire puisse définir son propre schéma, il convient dans un souci d’interopérabilité entre les différents serveurs LDAP d’utiliser des schémas communs et donc standardisés (voir RFC 2252).
Il existe des cas où un nouveau schéma sera nécessaire sur un serveur particulier ou dans une organisation. Dans LDAP version 3, un serveur doit renvoyer des informations sur lui-même, y compris le schéma qu’il utilise. Un programme peut donc interroger un serveur d’annuaire pour déterminer le contenu du schéma. Cette information est stockée sur le DN spécial de longueur zéro.
Les classes d’objets LDAP définissent des ensembles d’attributs standards répertoriés par groupe d’attributs obligatoires et par groupe d’attributs facultatifs. Différentes classes d’objets peuvent contenir éventuellement les mêmes attributs, et il est courant dans les annuaires LDAP d’utiliser plusieurs classes d’objets pour définir une entrée de l’annuaire. La plupart des classes d’objets sont définies dans un ordre hiérarchique, où une classe d’objet est héritée d’une autre classe d’objet de niveau supérieur. Considérons un objet LDAP qui est défini avec les classes d’objets suivantes :
objectclass: top 
objectclass: person 
objectclass: organizationalPerson 
objectclass: inetOrgPerson 
objectclass: eDominoAccount
L’ordre indiqué ci-dessus reflète la relation hiérarchique entre ces classes d’objets, mais pas nécessairement. La classe d’objet top est évidemment au sommet de la hiérarchie. La plupart des autres classes d’objets qui ne sont pas destinées à être subordonnées à une autre classe devraient être supérieures à top. Tous les annuaires LDAP n’attendent pas qu’un enregistrement d’utilisateur ait la classe d’objet la plus élevée, tandis que d’autres l’exigent pour utiliser des listes de contrôle d’accès (ACL) sur l’objet. La classe person, subordonnée à la classe top, exige que les attributs cn (nom commun) et sn (nom) soient renseignés et permettent de saisir plusieurs autres attributs facultatifs. Un niveau en dessous se trouve la classe organizationPerson qui hérite donc des attributs de la classe person. De même que la classe inetOrgPerson avec la classe organizationalPerson. En revanche, bien qu’à l’affichage de l’entrée la classe eDominoAccount se situe sous la classe organizationalPerson, cela ne signifie pas qu’elle soit subordonnée à celle-ci. Il ne faut donc pas se fier à l’affichage, mais directement à la valeur de l’attribut objectclass. L’exemple ci-dessous montre le détail des classes d’objets : top, person, organizationalPerson et inetOrgPerson :
objectclass: top 
objectclasses=( 2.5.6.0 NAME ’top’ DESC ’Standard ObjectClass’ 
ABSTRACT MUST ( objectClass ) ) 
 
objectclass: person 
objectclasses=( 2.5.6.6 NAME ’person’ DESC ’Defines entries that 
generically represent people.’ SUP ’top’ STRUCTURAL MUST ( cn $ sn ) 
MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) ) 
 
objectclass: organizationalPerson 
objectclasses=( 2.5.6.7 NAME ’organizationalPerson’ DESC ’Defines 
entries for people employed by or associated with an  
organization.’ SUP ’person’ STRUCTURAL MAY ( title $ x121Address  
$ registeredAddress $ destinationIndicator $  
preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $ 
internationalISDNNumber $  facsimileTelephoneNumber $ street $ 
postalAddress $ postalCode $ postOfficeBox $  
physicalDeliveryOfficeName $ ou $ st $ l ) ) 
 
objectclass: inetOrgPerson 
objectclasses=( 2.16.840.1.113730.3.2.2 NAME ’inetOrgPerson’ DESC 
’Defines entries representing people in an organizations  
enterprise network.’ SUP ’organizationalPerson’ STRUCTURAL MAY ( 
audio $ businessCategory $ carLicense $ departmentNumber $  
employeeNumber $ employeeType $ givenName $ homePhone $  
homePostalAddress $ initials $ jpegPhoto $ labeledURI $ mail $  
manager $ mobile $ pager $ photo $ preferredLanguage $ roomNumber 
$ secretary $ uid $ userCertificate $ userSMIMECertificate $ 
x500UniqueIdentifier $ displayName $ o $ userPKCS12 ) )
Notez que chaque classe d’objet commence par une chaîne de nombres délimités par des décimales. Ce numéro est appelé OID (identificateur d’objet), suivi du nom de la classe d’objet (NAME) puis d’une brève description (DESC). Si elle est subordonnée à une autre classe d’objet, la classe d’objet supérieure (SUP) est répertoriée. Enfin, la définition de la classe d’objet spécifie quels attributs sont obligatoires (MUST) et quels sont ceux qui sont facultatifs (MAY).
L’OID est une chaîne numérique utilisée pour identifier un objet de façon unique et ainsi définir une normalisation des objets de l’annuaire pour permettre une interopérabilité entre les services d’annuaire. Les OID sont organisés sous forme hiérarchique et administrés par l’Organisation Internationale de Normalisation (ISO - site web http://www.iso.ch/) et par l’Union Internationale des Télécommunications (UIT - site web http://www.itu.ch/). L’ISO et l’UIT délèguent la gestion des OID aux organisations en leur attribuant des numéros OID. Les organisations peuvent alors assigner des OID à des objets ou déléguer d’autres organisations à d’autres organisations. Les OID sont associés à des objets dans des protocoles et des structures de données définies à l’aide de la Notation de synthèse abstraite (ASN.1).
Si vous disposez d’un répertoire LDAP dérivé du code LDAP originel de l’Université de Michigan, alors les définitions de classe d’objet devraient être contenues dans les fichiers se terminant par « .oc ».
La classe d’objet consiste donc à définir les attributs ou les types d’éléments de données contenus dans ce type d’objet. Certains exemples d’attributs typiques sont cn (nom commun), sn (nom de famille), mail, uid et userPassword. Tout comme les classes d’objets sont définies avec des OID uniques, chaque attribut possède également un numéro OID unique. Les attributs LDAP V3 suivent une notation similaire (ASN.1) aux classes d’objets. L’exemple suivant montre certaines définitions d’attributs :
attribute: name 
attributetypes=( 2.5.4.41 NAME ’name’ DESC ’The name attribute 
type is the attribute supertype from which string attribute types 
typically used for naming may be formed. It is unlikely that  
values of this type itself will occur in an entry.’ EQUALITY 
1.3.6.1.4.1.1466.109.114.2 SUBSTR 2.5.13.4 SYNTAX 
1.3.6.1.4.1.1466.115.121.1.15 USAGE userApplications )  
 
attribute: sn 
attributetypes=( 2.5.4.4 NAME ( ’sn’ ’surName’ ) DESC ’This is  
the X.500 surname attribute, which contains the family name of a 
person.’ SUP 2.5.4.41 EQUALITY 2.5.13.2 ORDERING 2.5.13.3 SUBSTR 
2.5.13.4 USAGE userApplications ) 
 
attribute: mail 
attributetypes=( 0.9.2342.19200300.100.1.3 NAME ( ’mail’ 
’rfc822mailbox’ ) DESC ’Identifies a users primary email address 
(the email address retrieved and displayed by white-pages lookup 
applications).’ EQUALITY 2.5.13.2 SYNTAX 
1.3.6.1.4.1.1466.115.121.1.15 USAGE userApplication)