PHP - Administration d'un annuaire LDAP

Décembre 2016

Introduction à LDAP

PHP permet la connexion et l'envoi de requêtes sur un annuaire LDAP, c'est-à-dire un serveur permettant de stocker des informations de manière hiérarchique.

Pour plus d'informations sur les fonctions LDAP de PHP, reportez-vous à l'article consacré à ce sujet




Avant de commencer, il faut installer le module LDAP pour le langage PHP. Ce module ajoute un certain nombre de fonctions qui débutent par « ldap_ » et qui permettent d'interfacer le serveur. En effet, par défaut, PHP n'est pas livré avec le support LDAP. Si vous n'installez pas le module et que vous tentez d'utiliser les commandes concernant LDAP, vous obtiendrez le message d'erreur suivant :

Fatal error: Call to unsupported or undefined function ldap_connect() in
rpm -ivh /home/httpd/html/ldap/consulte.php on line x


Il est possible de se procurer ces bibliothèques sur le serveur de l'Université du Michigan (ldap-3.3 package) ou chez Netscape (Netscape Directory SDK).

Dans le cadre de cet article, on se propose d'écrire un interface d'administration
pour un annuaire. On va prévoir les actions de base, c'est à dire : ajouter, modifier
et supprimer des éléments de notre annuaire LDAP. Naturellement chacun à une action précise. Il y aura donc une page principale qui affichera les personnes contenues dans l'annuaire et qui proposera les différentes actions associées aux objets.


Dans chaque module, on va avoir besoin d'un certain nombre de variables qui caractérisent le serveur LDAP. On va donc créer un fichier de configuration externe qui sera chargé au démarrage de chaque module. De cette façon, lorsque vous voulez installer votre application sur une autre plate-forme, vous ne devez modifier que ce fichier de configuration.

De plus, on va prévoir la possibilité de modifier le modèle d'affichage,
c'est à dire l'apparence de votre interface. On utilisera donc deux fichiers :

  • header.php : qui définira le haut de page de notre interface
  • footer.php : qui définira le bas de page de notre interface

Sécurisation de l'interface

On supposera que l'ensemble des pages PHP créées dans ce tutorial se trouvent
sous le répertoires ldap_admin/.


Nous allons donc protéger le répertoire ldap_admin/ qui contiendra les pages d'administration de notre annuaire. Chaque utilisateur qui voudra accéder à ces pages devra s'authentifier. Nous utilisons la méthode des fichiers .htaccess.


On va ainsi définir que seul l'utilisateur ldap_admin peut accéder à l'interface d'administration du forum. On va dans un premier temps créer le fichier des utilisateurs.


Placez-vous dans le répertoire ldap_admin et exécuter la commande suivante pour créer ce fichier (pour les utilisateurs de Linux) :

htpasswd -c ldap_admin.passwd ldap_admin





Remarque : le nom de ce fichier n'a aucune importance. L'option -c correspond à la création du fichier.

On va alors avoir à rentrer un mot de passe pour l'utilisateur: ldap_admin autorisé à accéder au répertoire protégé.

New password: 


On confirme.

Re-type new password: 


Une fois que le fichier des utilisateurs est généré, on va créer le fichier .htaccess qui sera stocké dans le répertoire à protéger, ici ldap_admin/.

On protège aussi le fichier de configuration :

<Files config_LDAP.inc.php>

Order Deny,Allow
Deny From All
</Files>

AuthUserFile /home/httpd/html/services/ldap_admin/ldap_admin.passwd
AuthName "Acces Restreint"
AuthType Basic
<Limit GET POST>

require valid-user
</Limit>


La sécurisation de notre interface est maintenant terminée.

Fichier de configuration

Commençons par commenter le fichier de configuration nommé config_LDAP.inc.php :

<?
// Fichier de configuration pour l'interface PHP pour administrer
// notre annuaire LDAP
$server = "localhost";

$port = "389";

$racine = "o=commentcamarche, c=fr";

$rootdn = "cn=ldap_admin, o=commentcamarche, c=fr";

$rootpw = "secret";

?>


On définit donc cinq variables pour caractériser le serveur LDAP :
le nom du serveur, le port (389 par défaut), la racine supérieure de l'arborescence,
la chaîne de connexion pour l'administrateur ainsi que son mot de passe.
Le fichier de configuration sera automatiquement appelé par le fichier header.php
qui définit le haut de notre interface.

L'interface PHP/LDAP

Détaillons maintenant le fichier admin.php qui est la page principale de notre interface :


[Image:http://static.commentcamarche.net/www.commentcamarche.net/pictures/php-images-interface1.png|interface pour administrer un serveur LDAP avec PHP]

Cette page liste les personnes saisies dans l'annuaire et propose soit de les modifier soit de les supprimer. Elle propose aussi un lien en bas de page pour ajouter une nouvelle
personne.


Du point du vue du code source, elle ne comporte aucune grosse complexité.

  • En début de programme, le fichier header.php, qui décrit le haut de page de l'interface, est chargé. Ce même fichier charge automatiquement le fichier de configuration.
  • Le fichier footer.php, utilisé pour le bas de page est chargé à la fin.


La connexion au serveur LDAP est réalisée grâce à la fonction ldap_connect.

Ensuite, la fonction ldap_search permet de rechercher tous les objets de
type person et de les afficher avec une boucle de type « for » sous la forme
d'un tableau en ajoutant deux liens qui correspondent respectivement à la modification et
à la suppression.

Pour la modification, la page modifie.php est appelée. On lui passe en paramètre la valeur de cn contenue dans l'annuaire, qui correspond au nom concaténé au prénom.

La même chose est réalisée pour le lien concernant la suppression sauf que la page supprime.php est appelée.

Le paramètre cn est encodé avec la fonction urlencode() de façon à transformer cette chaîne de caractère en une chaîne compatible avec le format des URL. Ainsi les espaces seront par exemple remplacés par des « + ».

<?
// affichage du haut de la page contenu dans le fichier header.php
require("header.php");

echo "Les personnes suivantes sont inscrites dans l'annuaire :<p>";

// connexion au serveur LDAP : ds est égal à 1 si la connexion est OK
$ds=ldap_connect($server);

if ($ds==1)
{
// on recherche les objet de type person à partir de la racine
// de notre serveur LDAP, ici : o=commentcamarche, c=fr
$sr=ldap_search($ds, $racine, "objectclass=person");

$info = ldap_get_entries($ds, $sr);

echo "<table border=1>";

echo "<tr>
<th>Nom et prénom</th>
<th>Adresse e-Mail </th>
<th>Téléphone</th>
</tr>";

// on affiche sous forme d'un tableau les personnes enregistrées
// dans l'annuaire avec un lien pour modifier et un lien pour supprimer
for ($i=0;$i<$info["count"];$i++)
{
$mynom = $info[$i]["cn"][0];

$myemail = $info[$i]["mail"][0];

$mytel = $info[$i]["telephonenumber"][0];

echo" <tr><th>$mynom</th><th>

<A HREF=mailto:$myemail>$myemail</a></th><th>$mytel</th>";

$mynom=urlencode($mynom);

echo" <th><a href=\"modifie.php?cn=$mynom\">

Modifier</a></th>";

echo" <th><a href=\"supprime.php?cn=$mynom\">

Supprimer</a></th></tr>";

}
echo"</table>";

echo "<center>< br><a href=\"ajoute.php\">Ajouter une
nouvelle personne dans l'annuaire</a></center>";

}
// on ferme la connexion au serveur LDAP
ldap_close($ds);

// on affiche le bas de page défini dans le fichier footer.php
require("footer.php");

?>

Ajout d'une entrée à LDAP

Continuons avec la page ajoute.php qui est utilisée pour ajouter de nouvelles personnes dans notre annuaire : Sur la copie d'écran, vous pouvez constater sur le haut et bas de page est exactement le même que sur notre page principale (dû à l'utilisation des fichiers header.php et footer.php). La page est constituée d'un formulaire avec des champs obligatoires. Vous retrouvez les boutons standards pour valider ou annuler votre nouvelle saisie. Pour essayer de garder toute la fonction « ajouter » dans la même page
(formulaire et enregistrement), on introduit une variable go qui détermine si la page est appellée pour la première fois ou si elle est rappellée après la validation du formulaire.

Cette variable est en fait un champ caché du formulaire (<INPUT type="hidden" name="go" value="1">).


[Image:http://static.commentcamarche.net/www.commentcamarche.net/pictures/php-images-interface2.png|Interface d\'ajout dans l\'annuaire LDAP]



Si la variable go est égale à 1 et que les champs nom, prénom et mail ne sont pas vides, on peut alors enregistrer la nouvelle personne dans l'annuaire.

Pour ce faire, on se connecte au serveur et on s'authentifie avec le super-utilisateur,
ici ldap_admin (fonction ldap_bind()).

Ensuite on doit préparer nos informations avant de les inscrire dans l'annuaire : on construit le champ cn en concaténant le nom et le prénom. On précise bien que c'est un objet de type person que l'on veut ajouter et on lance l'enregistrement avec la fonction ldap_add().


Sinon, on affiche le formulaire de saisie avec un message d'erreur si l'on a validé le formulaire sans avoir rempli les champs obligatoires.

<?
// on affiche le haut de la page contenu dans le fichier header.php
require("header.php");

if (($go==1) and ($nom!="") and ($prenom!="") and ($mail!=""))
{
$ds=ldap_connect($server);

if ($ds==1)
{
// on s'authentifie en tant que super-utilisateur, ici, ldap_admin
$r=ldap_bind($ds,$rootdn,$rootpw);

// préparation des données
$info["cn"]=$nom." ".$prenom;

$info["mail"]=$mail;

$info["telephonenumber"]=$tel;

$info["objectclass"]="person";

// ajout dans l'annuaire
$r=ldap_add($ds,"cn=$nom $prenom,$racine",$info);

// fermeture de la connexion
ldap_close($ds);

$go==0;

$nom=="";

$prenom="";

$mail="";

$tel="";

echo "L'enregistrement a réussi !!!\n";

echo "<P><A HREF=\"ajoute.php\">Ajouter
une nouvelle personne</A>\n";

echo "<P><A HREF=\"admin.php\">Retourner
à la page d'administration</A>\n";

}
} else {
if ($go==1)
{
$mes="ERREUR ! Vous devez obligatoirement remplir les champs en gras";

echo "<FONT COLOR=FF0000>$mes</FONT>\n";

}
echo "<FORM ACTION=\"ajoute.php\" METHOD=POST>\n";

echo "<TABLE BORDER=0>\n";

echo quot;<TR><TD> <B>Nom</B></TD>\n";

echo "<TD><INPUT TYPE=\"text\" NAME=\"nom\"
value=\"$nom\" SIZE=30 maxlength=80><BR></TD></TR>\n";

echo "<TR><TD> <B>Prénom</B></TD>\n";

echo "<TD><INPUT TYPE=\"text\" NAME=\"prenom\"
value=\"$prenom\" SIZE=30 maxlength=80><BR></TD></TR>\n";

echo "<TR><TD> <B>E-Mail</B></TD>\n";

echo "<TD><INPUT TYPE=\"text\" NAME=\"mail\"
value=\"$mail\" SIZE=40 maxlength=80><BR></TD></TR>\n";

echo "<TR><TD> Téléphone</TD>\n";

echo "<TD><INPUT TYPE=\"text\" NAME=\"tel\"
value=\"$tel\" SIZE=40 maxlength=255><BR></TD></TR>\n";

echo "</TABLE>\n";

echo "<INPUT type=\"hidden\" name=\"go\" value=\"1\"><BR><BR>\n";

echo "<INPUT type=\"submit\" value=\"Valider\">\n";

echo "<INPUT type=\"reset\" value=\"Annuler\">\n";

echo "</FORM>\n";

echo "<BR>Les champs en <B>gras</B> sont obligatoires.\n";

}
// on affiche le bas de la page contenu dans le fichier footer.php
require("footer.php");

?>

Modification d'une entrée de l'annuaire LDAP

Regardons maintenant le source (plus long mais pas plus complexe !) de la page modifie.php.
Le nom et le prénom étant concaténé dans le champ cn de l'annuaire,
il sera impossible de faire une modification sur le nom ou sur le prénom.


[Image:http://static.commentcamarche.net/www.commentcamarche.net/pictures/php-images-interface3.png|Interface d\'ajout dans l\'annuaire LDAP]



Pour modifier une personne, il faut d'abord la supprimer (avec ldap_delete()) puis la réenregistrer avec les nouvelles valeurs.

Le champ mail est bien sûr toujours obligatoire. On utilise le même principe pour centraliser sur la même page le formulaire de modification et le l'enregistrement des modifications (variable go).

<?
// on affiche le haut de la page contenu dans le fichier header.php
require("header.php");

$cn=urldecode($cn);

if (($go==1) and ($mail!=""))
{
// connexion au serveur
$ds=ldap_connect($server);

if ($ds==1)
{
// on s'authentifie en tant que super-utilisateur, ici, ldap_admin
$r=ldap_bind($ds,$rootdn,$rootpw);

// Suppression de l'ancien enregistrement
$r=ldap_delete($ds,"cn=$cn,$racine");

// Préparation des données
$info["cn"]=$cn;

$info["mail"]=$mail;

$info["telephonenumber"]=$tel;

$info["objectclass"]="person";

// Ajout dans l'annuaire
$r=ldap_add($ds,"cn=$cn,$racine",$info);

// fermeture de la connexion à l'annuaire LDAP
ldap_close($ds);

$go==0;

$nom=="";

$prenom="";

$mail="";

$tel="";

echo "La modification a réussi !!!\n";

echo "<P><A HREF=\"admin.php\">Retourner
à la page d'administration</A>\n";

}
} else {
if ($go==1)
{
$mes="ERREUR ! Vous devez obligatoirement remplir le champ mail";

echo "<FONT COLOR=FF0000>$mes</FONT>\n";

}
// connexion au serveur
$ds=ldap_connect($server);

if ($ds)
{
$recherche="cn=$cn";

$champs = array("cn", "telephonenumber", "mail");

// recherche les informations de la personne que l'on veut modifier
$sr=ldap_search($ds, $racine, $recherche, $champs);

$num= ldap_get_entries($ds,$sr);

if ($num["count"]>0)
{
$mynom = $num[0]["cn"][0];

$myemail = $num[0]["mail"][0];

$mytel = $num[0]["telephonenumber"][0];

echo "<FORM ACTION=\"modifie.php\" METHOD=POST>\n";

echo "<TABLE BORDER=0>\n";

echo "<TR><TD> <B>Modification de l'utilisateur : $cn</B></TD>\n";

echo "<TR><TD> <B>E-Mail</B></TD>\n";

echo "<TD><INPUT TYPE=\"text\" NAME=\"mail\" value=\"$myemail\"
SIZE=40 maxlength=80><BR></TD></TR>\n";

echo "<TR><TD> Téléphone</TD>\n";

echo "<TD><INPUT TYPE=\"text\" NAME=\"tel\" value=\"$mytel\"
SIZE=40 maxlength=255><BR></TD></TR>\n";

echo "</TABLE>\n";

echo "<INPUT type=\"hidden\" name=\"cn\" value=\"$cn\"><BR><BR>\n";

echo "<INPUT type=\"hidden\" name=\"go\" value=\"1\"><BR><BR>\n";

echo "<INPUT type=\"submit\" value=\"Modifier\">\n";

echo "<INPUT type=\"reset\" value=\"Annuler\">\n";

echo "</FORM>\n";

echo "<BR>Le champ <B>mail</B> est obligatoire.\n";

} else {
echo "Erreur ! La recherche n'a pas aboutie";

}
} else {
echo "Erreur ! Problème à la connexion avec le serveur LDAP";

}
}
require("footer.php");

?>

Suppression d'une entrée de l'annuaire LDAP

On termine enfin avec la page supprime.php qui, avant de supprimer, va demander
une confirmation.


[Image:http://static.commentcamarche.net/www.commentcamarche.net/pictures/php-images-interface4.png|suppression d\'une entrée de l\'annuaire LDAP avec PHP]



Si on confirme, on rappelle la page supprime.php avec le paramètre go=1.

Ici, on est obligé de préciser go=1 dans l'URL car seules les variables contenues dans les formulaires sont automatiquement passées d'une page à l'autre.

La suppression ne peut s'effectuer qu'avec le super-utilisateur ldap_admin (fonction ldap_bind()).

<?
// on affiche le haut de la page contenu dans le fichier header.php
require("header.php");

$cn=urldecode($cn);

if ($go==0) {
echo "Etes-vous sur de vouloir supprimer l'utilisateur $cn<br>\n";

$cn=urlencode($cn);

echo "<A HREF=\"supprime.php?go=1&cn=$cn\">oui</A><BR>\n";

echo "<A HREF=\"admin.php\">non</A><BR>\n";

}
else {
$cn=urldecode($cn);

// connexion au serveur LDAP
$ds=ldap_connect($server);

if ($ds==1) {
// on s'authentifie en tant que super-utilisateur, ici, ldap_admin
$r=ldap_bind($ds,$rootdn,$rootpw);

// Suppression de l'ancien enregistrement
$r=ldap_delete($ds,"cn=$cn,$racine");

echo "La suppression a réussi !!!\n";

echo "<P><A HREF=\"admin.php\">Retourner
à la page d'administration</A>\n";

}
}

// on affiche le bas de la page contenu dans le fichier footer.php
require("footer.php");

?>

Modification d'une entrée de l'annuaire LDAP

Vous voilà prêt à administrer votre annuaire... ou à construire votre propre interface d'administration. Pour un souci de simplicité, seules les fonctionnalités de base ont été implémentées.

Une page pour rechercher une personne pourrait aussi être écrite.

La présentation de l'interface est sommaire mais assez pratique : toutefois, pour la page admin.php, il serait envisageable d'ajouter un alphabet qui lorsque l'on clique sur une lettre, déclenche l'affichage des personnes dont le nom commence par la lettre sélectionnée.

De même, vous pouvez modifier aussi la structure de l'annuaire.
Par exemple, vous pouvez ajouter des propriétés à votre objet person : un champ

photo qui pourrait contenir le chemin d'accès complet à une photo d'identité stockée
sur votre serveur...


Les sources sont commentés de façon à vous aider à concevoir de nouveaux programmes en PHP.


Article écrit par Michel Maudet et Jean-François Pillou


A voir également :

Ce document intitulé «  PHP - Administration d'un annuaire LDAP  » issu de CommentCaMarche (www.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.