LDAP

1. Qu'est-ce que c'est ?

C'est une base de donnée, ainsi que le protocole pour y accéder (avec tout ce que l'on veut comme cryptographie), optimisée en lecture : on va très souvent y rechercher des informations, mais très rarement les modifier.

LDAP est principalement utilisé comme annuaire, ie, stocke nom, coordonnées, fonctions des différents employées/clients d'une entreprise.

2. À quoi ça sert ?

Pour l'instant, à presque rien : on peut chercher les coordonnées de quelqu'un, c'est tout.
  http://ldap.math.cnrs.fr/
À l'avenir, on pourrait l'utiliser aux fins suivantes :

Remplacement de /etc/passwd (chaque enregistrement contiendrait donc le nom du shell, du répertoire racine et le numéro de chaque utilisateur), à l'aide de PAM.

(Il doit y avoir d'autres applications, non ?)

3. Structure de la base de données

Une base de données LDAP est un peu comme une arborescence de fichiers sous UNIX, avec quelques différences : Exemple :
  dn: cn=Vincent Zoonekynd, dc=math, dc=cnrs, dc=fr
signifie « dans le répertoire dc=fr, il y a un répertoire dc=cnrs, contenant un répertoire dc=math, contenant un enregistrement cn=Vincent Zoonekynd ».

Dans cet exemple, la racine pourrait être dc=fr ou dc=cnrs, dc=fr ou encore dc=math, dc=cnrs, dc=fr.

La raison pour laquelle il faut préciser la racine est que l'on tente, avec LDAP, d'obtenir un annuaire mondial, distribué. Il faut donc que chaque racine soit unique au monde. Mais comme il n'y a pas trop de standardisation des entrées, c'est pour l'instant utopique.

4. Type des données

Chaque entrée a un type particulier, qui précise quels sont les différents champs obligatoires ou facultatifs (et quel est leur type : chaine de caractères, nombres, date, etc.).

Le type a lui-même une structure arborescente. Tous les types descendent du type « top » : cela signifie en particulier qu'ils ont une entrée « dn » et « objectclass ». Chaque sous-type rajoute des champs supplémentaires. Voici un exemple.

  objectClass: top
  objectClass: person
  objectClass: organizationalPerson
  objectClass: inetOrgPerson
Si ce type n'est pas suffisant pour nous, il suffit de rajouter un sous-type contenant les champs dont on a besoin (numéro d'utilisateur, shell de login, etc.).
  objectClass: top
  objectClass: person
  objectClass: organizationalPerson
  objectClass: inetOrgPerson
  objectClass: posixAccount
Cette présentation suggère un héritage simple, mais il peut être multiple.

5. Champs obligatoires et usuels

Les champs ont des noms assez cryptiques (qui ne sont pas sans rappeler les innombrables commandes UNIX à deux lettres). La valeur de chaque champ est codée en UTF-8.

6. Authentification et cryptographie

C'est possible, il suffit de configurer le serveur pour que les communications soient cryptées (SSL, TLS, etc.) et/ou pour que seules les personnes authentifiées puissent accéder à la base.

7. Fichiers de configuration

/etc/openldap/slapd.conf Fichier de configuration du serveur

/etc/openldap/ldap.conf Fichier de configuration des clients, avec en particulier le nom et le port du serveur et le nom de sa racine.

8. LDIF

Quand on construit une base de données LDAP (ou quand différentes bases s'échangent des données), les enregistrements sous mis sous la forme LDIF. Ce n'est pas du XML, ça ressemble à ça :
  dn: cn=Vincent Zoonekynd, dc=math, dc=cnrs, dc=fr
  objectClass: top
  objectClass: person
  objectClass: organizationalPerson
  objectClass: inetOrgPerson
  cn: Vincent Zoonekynd
  sn: Zoonekynd
  givenName: Vincent
  mail: zoonek@math.jussieu.fr
  labeledURI: http://www.math.jussieu.fr/~zoonek
  telephoneNumber: +33 1 44 27 xx xx
  facsimileTelephoneNumber: +33 1 44 27 85 41
  l: Paris 13eme
  postalAddress: Institut de Mathematiques de Jussieu, 175 rue du Chevaleret
  postalCode: 75013 PARIS
  o: Institut de Mathematiques de Jussieu

9. URL

On peut formuler une recherche LDAP à l'aide d'un URL. Par exemple
  ldap://ldap.math.jussieu.fr:389/dc=math, dc=cnrs, dc=fr?email?sub?(objectClass=*)
    
est équivalent à
  ldapsearch -h ldap.math.cnrs.fr -b "dc=math, dc=cnrs, dc=fr" '(objectclass=*)' mail
    

9. ldapsearch

Avant tout chose, il nous faut l'adresse du serveur, son port et le nom de sa racine. Nous prendrons
  server : ldap.math.cnrs.fr
  port : 389
  server root : dc=math, dc=cnrs, dc=fr
La commande suivante demande _tous_ les enregistrements de la base de données (en fait, on demande toutes les entrées avec un attribut objectclass, or cet attribut est obligatoire).
  ldapsearch -h ldap.math.cnrs.fr -b "dc=math, dc=cnrs, dc=fr" '(objectclass=*)'
(Le serveur est configuré pour ne donner que 50 réponses, donc on n'a pas toute la base : cela permet d'éviter le spamming.)

La commande suivante demande juste l'adresse électronique des personnes.

  ldapsearch -h ldap.math.cnrs.fr -b "dc=math, dc=cnrs, dc=fr" '(objectclass=*)' mail
Voici d'autres exemples :
  ldapsearch -h ldap.math.cnrs.fr -b "dc=math, dc=cnrs, dc=fr" 'givenName=Vincent'

  ldapsearch -h ldap.math.cnrs.fr -b "dc=math, dc=cnrs, dc=fr" 'sn=Z*'
Il est possible d'affiner ces recherches avec le « et logique & », le « ou logique | » ou la négation « ! ». La notation est préfixée et il ne faut pas oublier les parenthèses !!!
  ldapsearch -h ldap.math.cnrs.fr -b "dc=math, dc=cnrs, dc=fr" '(&(givenName=Vincent)(sn=Z*))'
Il ne faut pas oublier de parenthèses ! Si on les oublie, il n'y a ni réponse ni message d'erreur :
  ldapsearch -h ldap.math.cnrs.fr -b "dc=math, dc=cnrs, dc=fr" '&(givenName=Vincent)(sn=Z*)'
On peut demander une sortie au format LDIF avec l'option « -L ».

On peut demander à ldapsearch de nous dire exactement ce qu'il fait, avec l'option « -v » (verbose).

Voici la liste des entrées qui ne sont pas de type « inetOrgPerson »

  ldapsearch -h ldap.math.cnrs.fr -b "dc=math, dc=cnrs, dc=fr" '(!(objectClass=inetOrgPerson))'

  dc=math, dc=cnrs, dc=fr
  o=Laboratoires de mathematiques francais
  objectClass=organization
(C'est juste la racine de l'arbre.)

10. kldap

C'est une interface graphique à un serveur LDAP. Il parait que c'est facile à utiliser.

11. Netscape

Il parait qu'on peut utiliser LDAP depuis Netscape (si, si...).

12. Perl

Je n'ai pas testé ce qui suit, je l'ai juste recopié de la page de manuel.
  use Net::LDAPapi;
Se connecter
  $ld = new Net::LDAPapi($hostname,15555);
Dire bind au serveur (ça doir vouloir dire « bonjour »)
  $status = $ld->bind_s;
  # S'il fallait une authentification (pour modifier quelque chose,
  # par exemple) :
  #$status = $ld->bind_s($dn,$password);
  # ou :
  #$status = $ld->bind_s(-dn=>$dn,-password=>$password,-type=>LDAP_AUTH_SIMPLE);
Effectuer une recherche
  @attrs = ("cn","sn");    # Return specific attributes
  @attrs = ();             # Return all attributes

  $status = $ld->search_s("o=Motorola, c=US",
                          LDAP_SCOPE_SUBTREE,
                          "(sn=Donley)",
                          \@attrs,
                          0);
  # On peut aussi effectuer la recherche avec un URL :
  #$status = $ld->url_search_s($my_ldap_url,0);
Regarder les résultats de cette recherche.
  # Prendre la première entrée 
  $entry = $ld->first_entry;

  # regarder son dn (si c'est "", il y a un problème)
  $dn = $ld->get_dn;

  # Premier attribut de cette entrée
  $att = $ld->first_attribute

  # Valeurs de cet attribut (comme il peut y en avoir plusieures, 
  # on récupère une LISTE)
  @valeurs = $ld->get_values($att);

  # Prendre les attributs suivants, un a un, jusqu'à ""
  $att = $ld->next_attribute

  # Prendre l'entrée suivante
  $entry = $ld->next_entry;
S'il y a d'autres recherches, on peut les faire.

Dire unbind au serveur (ça doit vouloir dire « au revoir »).

  $ld->unbind;

13. Comment modifier les données nous concernant ?

Dans un fichier ~/.ldapdata, on peut mettre (je ne sais pas si ça marche) :
  dn: cn=Zoonekynd, o=Maths Jussieu, c=FR
  cn: Zoonekynd
  sn: Vincent
  office: 7C24
  telephoneNumber: 01 44 27 86 59
  mail: zoonek@math.jussieu.fr
  objectclass:person
On ne peut bien évidemment modifier que certaines des données nous concernant. Par exemple, si le fichier /etc/passwd a été remplacé par LDAP, on n'a pas le droit de changer son numéro d'utilisateur (pour mettre 0).
lun avr  9 11:50:16 CEST 2001