Dernière modification 5 août 2026
Si on rentre dans les détails, le
protocole LDAP est du type client serveur, le serveur
contient la base de données, et le client consulte la base de
données, le protocole fournit les bases pour cette communication
entre la client et le serveur (normalisée par l'IETF par la
RFC2251), et les commandes nécessaires au client pour rechercher,
créer, modifier ou effacer des données. LDAP est bien
entendu sécurisé pour le transfert et l'accès aux des données,
avec des outils de cryptage comme SSL et d'authentification.
Par ailleurs LDAP fournit des outils pour que les serveurs
LDAP puissent communiquer entre eux, on a ainsi la
possibilité de créer des serveurs miroirs qui pourront se
synchroniser, ou de relier simplement les serveurs entre eux, les
serveurs redirigeant automatiquement les requêtes qui ne les
concernent pas.
Les exemples d'applications de LDAP
sont nombreux:
- bases de données d'employés,
- bases de données de produits,
- bases de données pour certaines applications, exemple :
* toutes les infos
contenant les utilisateurs de votre réseau (mot de passe, shell,
homedirectory, ...) peuvent être dans la base, on a ainsi beaucoup
plus de possibilités qu'un simple fichier /etc/passwd,
l'authentification peut donc utiliser LDAP plutôt que passwd
ou shadow ou encore NIS. Vos utilisateurs pourront
ainsi changer leur mot de passe et certains de leurs attributs à
partir d'une interface web.
* les préférences
d'applications ou d'environnement (netscape, environnement
graphique KDE, ...) sont sauvegardés dans la base, ainsi
l'utilisateur peut passer d'une machine à une autre et retrouver
ses préférences.
Cette page est une introduction à LDAP elle ne couvre pas certains aspects comme les liens avec d'autres bases (duplication, miroir, ...), la sécurité (access control, SSL, ...). Elle n'a seulement pour but de mettre en place un serveur LDAP simplement configuré pour que vous puissiez faire vos "premières armes" dans le domaine. Pour plus d'info reportez vous à l'excellente page de Laurent Mirtain .
Pour utiliser une base LDAP à partir de script PHP, voir ma page Apache .
Le principe est donc le même qu'en C++, on retrouve une structure arborescente, avec à la racine la classe top, toutes les autres classes d'objet dérivent de cette classe générique, chaque classe hérite des propriétés d'une classe père et possède des attributs supplémentaires par rapport à ce dernier.
objectclass ( 2.5.6.6 NAME 'person'
DESC 'RFC2256: a
person'
SUP top STRUCTURAL
MUST ( sn $ cn )
MAY ( userPassword $
telephoneNumber $ seeAlso $ description ) )
MUST correspond au attributs obligatoires et MAY à
ceux facultatifs
objectClass est le nom de la classe qui descend elle même
de la classe top
sn correspond à surname (nom)
cn correspond à common name (prénom nom)
Je vous laisse deviner la signification des autres attributs.
On voit qu'il est nécessaire de fournir les attributs sn (surname) et cn (common name), sont facultatifs le mot de passe (userPassword), le numéro de téléphone (telephoneNumber ), les liens (seeAlso) et la description.
Les attributs sont définis dans le même fichier, la syntaxe est la suivante pour telephoneNumber par exemple :
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} )
Je vous présenterai la syntaxe plus tard, on peut dans un premier temps se limiter aux attributs disponibles. Pour créer une classe d'objet breizhPerson dérivant de person, disposant de l'attribut obligatoire title en plus et des arguments facultatifs ou (groupe de travail) et l (localisation). On tapera dans le fichier core.schema juste après la définition de la classe person
objectclass ( 2.5.6.6.2 NAME 'breizhPerson' SUP person
STRUCTURAL
MUST ( title )
MAY ( ou $ l ) )
# $OpenLDAP: pkg/ldap/servers/slapd/slapd.conf,v 1.8.8.6
2001/04/20 23:32:43 kurt Exp $
#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
# Modified by Christian Zoffoli
<czoffoli@linux-mandrake.com>
# Version 0.2
include /usr/share/openldap/schema/core.schema
include
/usr/share/openldap/schema/cosine.schema
include
/usr/share/openldap/schema/corba.schema
include
/usr/share/openldap/schema/inetorgperson.schema
include /usr/share/openldap/schema/java.schema
include
/usr/share/openldap/schema/krb5-kdc.schema
include /usr/share/openldap/schema/kerberosobject.schema
include /usr/share/openldap/schema/misc.schema
include /usr/share/openldap/schema/nis.schema
include
/usr/share/openldap/schema/openldap.schema
include /usr/share/openldap/schema/autofs.schema
include /usr/share/openldap/schema/samba.schema
include /usr/share/openldap/schema/kolab.schema
include /usr/share/openldap/schema/evolutionperson.schema
include /usr/share/openldap/schema/calendar.schema
include /usr/share/openldap/schema/sudo.schema
include /usr/share/openldap/schema/dnszone.schema
include /usr/share/openldap/schema/dhcp.schema
include /etc/openldap/schema/local.schema
# Define global ACLs to disable default read access and provide
default
# behaviour for samba/pam use
include /etc/openldap/slapd.access.conf
# Do not enable referrals until AFTER you have a working
directory
# service AND an understanding of referrals.
#referral ldap://root.openldap.org
pidfile /run/ldap/slapd.pid
argsfile /run/ldap/slapd.args
modulepath /usr/lib64/openldap
# database backend modules available:
moduleload back_mdb.la
# To allow TLS-enabled connections, create
/etc/ssl/openldap/ldap.pem
# and uncomment the following lines.
#TLSRandFile
/dev/random
#TLSCipherSuite
HIGH:MEDIUM:+SSLv2
TLSCertificateFile
/etc/pki/tls/certs/ldap.pem
TLSCertificateKeyFile /etc/pki/tls/private/ldap.pem
#TLSCACertificatePath /etc/ssl/openldap/
#TLSCACertificateFile /etc/ssl/cacert.pem
TLSCACertificateFile
/etc/pki/tls/certs/ldap.pem
#TLSVerifyClient never # ([never]|allow|try|demand)
# logging
#loglevel 256
#######################################################################
# database definitions
#######################################################################
database mdb
suffix "dc=kervao,dc=fr"
rootdn
"cn=Manager,dc=kervao,dc=fr"
# Cleartext passwords, especially for the rootdn, should
# be avoided. See slappasswd(8) and slapd.conf(5) for
details.
# Use of strong authentication encouraged.
rootpw secret
# The database directory MUST exist prior to running slapd AND
# should only be accessable by the slapd/tools. Mode 700
recommended, répertoire où se trouve la base de donnée
directory /var/lib/ldap
# Tuning settings, please see the man page for slapd-bdb for
more information
# as well as the DB_CONFIG file in the database directory
# commented entries are at their defaults
# In-memory cache size in entries
#cachesize 1000
# Checkpoint the bdb database after 256kb of writes or 5 minutes
have passed
# since the last checkpoint
checkpoint 256 5
# Indices to maintain
index objectClass
eq
# persion-type searches
index
cn,mail,surname,givenname
eq,subinitial
# nss_ldap exact searches:
index
uidNumber,gidNumber,memberuid,member,uniqueMember
eq
# username completion via nss_ldap needs uid indexed sub:
index
uid
eq,subinitial
# samba:
index
sambaSID,sambaDomainName,displayName
eq
# autofs:
#index
nisMapName
eq
# bind sdb_ldap:
#index
zoneName,relativeDomainName
eq
# sudo
#index
sudoUser
eq
# syncprov
#index
entryCSN,entryUUID
eq
# Replicas running syncrepl as non-rootdn need unrestricted
size/time limits:
limits group="cn=Replicator,ou=Group,dc=example,dc=com"
size=unlimited
time=unlimited
# Basic ACL (deprecated in favour of ACLs in
/etc/openldap/slapd.access.conf)
access to attrs=userPassword
by self write
by anonymous
auth
by
dn="cn=Manager,dc=kervao,dc=fr" write
by * none
#
access to *
by
dn="cn=Manager,dc=kervao,dc=fr" write
by * read
La base LDAP a été créée par défaut sous /var/lib/ldap
Le fichier ldap.conf peut être vide dans un premier temps voire inexistant.
Le mot de passe de l'administrateur est secret en clair, si ça ne vous convient pas et que vous voulez le crypter, il faudra taper
slappasswd
on saisit son mot de passe
New password:
Re-enter new password:
et voilà le résultat
{SSHA}vNCYRQthN6u3OqcTAJ4lt/9vIhjsFmI
A la place de
rootpw secret
Dans slapd.conf, vous mettrez donc:
rootpw {SSHA}vNCYRQthN6u3OqcTAJ4lt/9vIhjsFmI
After=syslog.target
[Service]
Type=forking
PIDFile=/run/ldap/slapd.pid
Environment="SLAPDURLLIST=ldap:/// ldapi:///" "LDAP_USER=ldap"
"LDAP_GROUP=ldap" "SLAPDSYSLOGLOCALUSER=local4"
"SLAPDSYSLOGLEVEL=0"
EnvironmentFile=/etc/sysconfig/slapd
ExecStartPre=/usr/share/openldap/scripts/ldap-config check
ExecStart=/usr/sbin/slapd -u ${LDAP_USER} -g ${LDAP_GROUP} -h
${SLAPDURLLIST} -l ${SLAPDSYSLOGLOCALUSER} -s
${SLAPDSYSLOGLEVEL}
[Install]
WantedBy=multi-user.target
Sur ma Mageia 10 j'ai supprimé l'invocation de l'appel au script ldap-config
qui fait du zèle et empêche le lancement de slapd vous
pouvez toujours vérifier la validité de votre fichier de
configuration en tant slaptest
maintenant pour que le service soit lancé à chaque boot de la
machine il faudra taper
systemctl enable slapd.service
voilà le résultat
Created symlink from /etc/systemd/system/multi-user.target.wants/slapd.service to /usr/lib/systemd/system/slapd.service.
pour le lancer il suffit maintenant de taper
systemctl start slapd.service
et pour connaître son état
systemctl status slapd.service
voilà le résultat
● slapd.service -
OpenLDAP Server Daemon
Loaded: loaded
(/usr/lib/systemd/system/slapd.service; disabled; vendor preset:
disabled)
Active: active (running) since Sat
2022-07-16 11:24:49 CEST; 2h 13min ago
Process: 3267
ExecStartPre=/usr/share/openldap/scripts/ldap-config check
(code=exited, status=0/SUCCESS)
Process: 3302 ExecStart=/usr/sbin/slapd -u
${LDAP_USER} -g ${LDAP_GROUP} -h ${SLAPDURLLIST} -l
${SLAPDSYSLOGLOCALUSER} -s ${SLAPDSYSLOGLEVEL} (code=exited,
status=0/SUCCESS)
Main PID: 3303 (slapd)
Tasks: 3 (limit: 9283)
Memory: 3.1M
CPU: 57ms
CGroup: /system.slice/slapd.service
└─3303 /usr/sbin/slapd -u ldap -g ldap -h ldap:/// ldapi:/// -l
local4 -s 0
juil. 16 11:24:48 serveur-slapd.kervao.fr systemd[1]: Starting
OpenLDAP Server Daemon...
juil. 16 11:24:48 serveur-slapd.kervao.fr su[3274]: (to ldap)
root on none
juil. 16 11:24:49 serveur-slapd.kervao.fr su[3274]:
pam_unix(su:session): session opened for user ldap by (uid=0)
juil. 16 11:24:49 serveur-slapd.kervao.fr su[3274]:
pam_unix(su:session): session closed for user ldap
juil. 16 11:24:49 serveur-slapd.kervao.fr ldap-config[3267]:
Vérification de la configuration file
/etc/openldap/slapd.conf : [ OK ]
juil. 16 11:24:49 serveur-slapd.kervao.fr systemd[1]: Started
OpenLDAP Server Daemon.
ça nous évitera
une erreur du genre
slapd[5803]: main: TLS
init def ctx failed: -1
maintenant on va
modifier le fichier /etc/openldap/slapd.conf on
rajoute les lignes suivantes
TLSCACertificateFile /etc/pki/CA/cacert.pem
TLSCertificateFile
/etc/pki/CA/private/cakey.pem
TLSCertificateKeyFile /etc/pki/CA/cacert.pem/etc/pki/tls/certs/). Il doit avoir
les droits 644
chmod 644 ldapcrt.pem
On édite le fichier
/etc/openldap/ldapd.conf et on
modifie ainsi
# SSL/TSL
configuration. With CA-signed certs, TLS_REQCERT
should be
# "demand", with the CA certificate accessible
#TLS_REQCERT
([demand],never,allow,try)
# We ship with allow by default as some LDAP clients
(e.g. evolution) have
# no interactive SSL configuration
TLS_REQCERT allow
# CA Certificate locations
# Use the default self-signed cert generated by
openldap-server postinstall
# by default
TLS_CACERT
/etc/pki/tls/certs/ldap.pem
La syntaxe du format LDIF est la suivante:
dn: description du distinguished name
objetclass: classe d'objet d'origine
...
objetclass: classe d'objet dérivée
type attribut: valeur
...
On va par exemple utiliser la classe breizPerson définie
plus haut pour décrire une nouvelle personne Veronique Hoarau
qu'on va rajouter dans l'annuaire. Elle appartient au service (organizationalUnit)
staff, ce même service appartenant à l'organisation kervao.fr
Soit le fichier entree.ldif
dn: dc=kervao, dc=fr
objectClass: dcObject
objectClass: organization
dc: kervao
o: kervao.fr
dn: ou=staff, dc=kervao, dc=fr
objectclass: organizationalUnit
ou: staff
dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
objectclass: person
objectclass: breizhPerson
cn: Veronique Hoarau
sn: Hoarau
title: madame
dc=fr
|
dc=kervao
|
------------------------------------------------------------------------------------------------------------
|
|
|
|
ou=staff
ou=informatique
ou=production
ou=achat
|
------------------------------------------------------------------
|
|-b 'dc=kervao, dc=fr' '(objectclass=*)'
cn=Veronique
Hoarau
cn=Olivier
Hoarau
Au niveau de la définition de la personne:
objetclass: person définit la classe père de la classe breizPerson,
objetclass: breizPerson classe décrivant la
personne,
cn et sn sont des attributs à renseigner
obligatoirement,
title est un attribut obligatoire
On rajoutera l'enregistrement en utilisant la syntaxe suivante (en tant que simple utilisateur):
ldapadd -x -D "description du dn de l'administrateur" -W -f nom-du-fichier-ldif
Exemple concret:
ldapadd -x -D "cn=Manager, dc=kervao, dc=fr" -W
-f entree.ldif
Enter LDAP Password: secret
adding new entry "dc=kervao, dc=fr"
adding new entry "ou=staff, dc=kervao, dc=fr"
adding new entry "cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr"
Pour rajouter par la suite un autre enregistement dans le groupe staff, il sera plus nécessaire de rajouter la définition du groupe et de l'organisation. Soit le fichier entree.ldif
dn: cn=Olivier Hoarau, ou=staff, dc=kervao, dc=fr
objectclass: person
objectclass: breizhPerson
cn: Olivier Hoarau
sn: Hoarau
title: monsieur
On tape ensuite la commande:
ldapadd -x -D "cn=Manager, dc=kervao, dc=fr" -W -f
entree.ldif
Enter LDAP Password:
adding new entry "cn=Olivier Hoarau, ou=staff, dc=kervao,
dc=fr"
ldapsearch -x -b 'dc=kervao, dc=fr' '(objectclass=*)'
Voilà le résultat
# extended LDIF
#
# LDAPv3
# base <dc=kervao, dc=fr> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# kervao.fr
dn: dc=kervao,dc=fr
objectClass: dcObject
objectClass: organization
dc: kervao
o: kervao.fr
# staff, kervao.fr
dn: ou=staff,dc=kervao,dc=fr
objectClass: organizationalUnit
ou: staff
# Veronique Hoarau, staff, kervao.fr
dn: cn=Veronique Hoarau,ou=staff,dc=kervao,dc=fr
objectClass: person
objectClass: breizhPerson
cn: Veronique Hoarau
sn: Hoarau
title: madame
# Olivier Hoarau, staff, kervao.fr
dn: cn=Olivier Hoarau,ou=staff,dc=kervao,dc=fr
objectClass: person
objectClass: breizhPerson
cn: Olivier Hoarau
sn: Hoarau
title: monsieur
# search result
search: 2
result: 0 Success
# numResponses: 5
# numEntries: 4
dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
add: l
title: bureau36
On tape ensuite
ldapmodify -x -D "cn=Manager, dc=kervao, dc=fr" -W -f
modif.ldif
Enter LDAP Password:secret
modifying entry "cn=Veronique Hoarau, ou=staff, dc=kervao,
dc=fr"
dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
changetype: modify
replace: title
title: mademoiselle
On tape ensuite
ldapmodify -x -D "cn=Manager, dc=kervao, dc=fr" -W -f
modif.ldif
Enter LDAP Password:secret
modifying entry "cn=Veronique Hoarau, ou=staff, dc=kervao,
dc=fr"
dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
delete: l
On tape ensuite
ldapmodify -x -D "cn=Manager, dc=kervao, dc=fr" -W -f
modif.ldif
Enter LDAP Password:secret
modifying entry cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
dn: cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
changetype: delete
On tape ensuite:
ldapmodify -x -D "cn=Manager, dc=kervao, dc=fr" -W -f
modif.ldif
Enter LDAP Password:secret
deleting entry cn=Veronique Hoarau, ou=staff, dc=kervao, dc=fr
ATTENTION Vous ne pouvez pas supprimer un attribut obligatoire comme title pour la classe breizhPerson.
Le principe est d'exporter une base sur le serveur A pour la réimporter sur le serveur B. Pour exporter une base sur le serveur A on tapera
slapcat > base.ldif
Maintenant on revient sur le serveur B sur lequel on aura récupéré le fichier base.ldif, on stoppera tout d'abord slapd en tapant
systemctl stop slapd
puis pour importer
slapadd -l base.ldif
voilà le résultat
62d2baf8 /etc/openldap/slapd.conf: line 185: rootdn is always
granted unlimited privileges.
62d2baf8 /etc/openldap/slapd.conf: line 189: rootdn is always
granted unlimited privileges.
_#################### 100.00% eta none
elapsed
none fast!
Closing DB...
Attention si la base contient déjà des éléments préexistants en doublon, ça fera une erreur dans ce genre
62d2b3b7 /etc/openldap/slapd.conf: line 185: rootdn is always
granted unlimited privileges.
62d2b3b7 /etc/openldap/slapd.conf: line 189: rootdn is always
granted unlimited privileges.
_#
8.38% eta 27s
elapsed
02s spd 155.6 /s 62d2b3b9 mdb_id2entry_put: mdb_put
failed: MDB_KEYEXIST: Key/data pair already exists(-30799)
"dc=kervao,dc=fr"
62d2b3b9 => mdb_tool_entry_put: id2entry_add failed:
err=-30799
62d2b3b9 => mdb_tool_entry_put: txn_aborted! MDB_KEYEXIST:
Key/data pair already exists (-30799)
slapadd: could not add entry dn="dc=kervao,dc=fr" (line=1):
txn_aborted! MDB_KEYEXIST: Key/data pair already exists (-30799)
.#
8.38% eta 27s
elapsed
02s spd 0.0 /s
Closing DB..
Dans ce cas il faudra faire le ménage dans la base de donnée en la supprimant tout simplement
rm -f /var/lib/ldap/*
on relance slapd pour créer une base minimale
systemctl start slapd
puis on le recoupe pour taper
slapadd -l base.ldif
on relance ensuite slapd
systemctl start slapd
Il suffit de rajouter l'option -Z pour passer en connexion chiffrée, avec le mode debug en plus (-d 1), on doit obtenir ce genre de message
TLS trace: SSL_connect:before SSL initialization
TLS trace: SSL_connect:SSLv3/TLS write client hello
TLS trace: SSL_connect:SSLv3/TLS write client hello
TLS trace: SSL_connect:SSLv3/TLS read server hello
TLS trace: SSL_connect:TLSv1.3 read encrypted extensions
TLS certificate verification: depth: 0, err: 0, subject:
/CN=serveur-slapd.kervao.fr/OU=default ldap cert for
serveur-slapd.kervao.fr/emailAddress=root@serveur-slapd.kervao.fr,
issuer: /CN=serveur-slapd.kervao.fr/OU=default ldap cert for
serveur-slapd.kervao.fr/emailAddress=root@serveur-slapd.kervao.fr
TLS trace: SSL_connect:SSLv3/TLS read server certificate
TLS trace: SSL_connect:TLSv1.3 read server certificate verify
TLS trace: SSL_connect:SSLv3/TLS read finished
TLS trace: SSL_connect:SSLv3/TLS write change cipher spec
TLS trace: SSL_connect:SSLv3/TLS write finished
ldap_sasl_bind
ldap_send_initial_request
ldap_send_server_request
(...)
TLS trace: SSL_connect:SSL negotiation finished successfully
TLS trace: SSL_connect:SSL negotiation finished successfully
TLS trace: SSL_connect:SSLv3/TLS read server session ticket
TLS trace: SSL_connect:SSL negotiation finished successfully
TLS trace: SSL_connect:SSL negotiation finished successfully
TLS trace: SSL_connect:SSLv3/TLS read server session ticket
(...)
ldap_free_connection 1 1
ldap_send_unbind
ber_flush2: 7 bytes to sd 3
TLS trace: SSL3 alert write:warning:close notify
ldap_free_connection: actually freed
il y a une erreur avec le certificat qui est auto signé mais comme on a mis TLS_REQCERT allow dans le fichier ldap.conf ce n'est pas bloquant. Côté serveur cela donne cela
juil. 16 14:26:32
serveur-slapd.kervao.fr slapd[5289]: conn=1001 fd=11 ACCEPT from
IP=127.0.0.1:37634 (IP=0.0.0.0:389)
juil. 16 14:26:32 serveur-slapd.kervao.fr slapd[5289]: conn=1001
op=0 EXT oid=1.3.6.1.4.1.1466.20037
juil. 16 14:26:32 serveur-slapd.kervao.fr slapd[5289]: conn=1001
op=0 STARTTLS
juil. 16 14:26:32 serveur-slapd.kervao.fr slapd[5289]: conn=1001
op=0 RESULT oid= err=0 text=
juil. 16 14:26:32 serveur-slapd.kervao.fr slapd[5289]: conn=1001
fd=11 TLS established tls_ssf=256 ssf=256
juil. 16 14:26:32 serveur-slapd.kervao.fr slapd[5289]: conn=1001
op=1 BIND dn="" method=128
juil. 16 14:26:32 serveur-slapd.kervao.fr slapd[5289]: conn=1001
op=1 RESULT tag=97 err=0 text=
juil. 16 14:26:32 serveur-slapd.kervao.fr slapd[5289]: conn=1001
op=2 SRCH base="dc=kervao,dc=fr" scope=2 deref=0
filter="(objectClass=*)"
juil. 16 14:26:32 serveur-slapd.kervao.fr slapd[5289]: conn=1001
op=2 SEARCH RESULT tag=101 err=0 nentries=4 text=
juil. 16 14:26:32 serveur-slapd.kervao.fr slapd[5289]: conn=1001
op=3 UNBIND
juil. 16 14:26:32 serveur-slapd.kervao.fr slapd[5289]: conn=1001
fd=11 closed
| [Retour page d'accueil FUNIX] |