Création d'un annuaire WEB en PHP + LDAP

Il se trouve que dans une grande entreprise (relativement) il y avait de nombreux bureaux distants, où se trouvaient un nombre considérable d'utilisateurs. Tous les bureaux sont connectés en un réseau avec un domaine commun, chaque bureau étant défini dans Active Directory (ci-après AD) comme une Unité Organisationnelle (OU), où les utilisateurs étaient déjà créés.

Il était nécessaire de donner aux utilisateurs la possibilité d'obtenir rapidement et sans effort les coordonnées de l’employé requis à partir de l'AD, tout en libérant les administrateurs système de la routine consistant à éditer un fichier texte qui servait de carnet d'adresses.

Aucun option adéquate pour résoudre la tâche posée n'a été trouvée, il a donc fallu tout faire par soi-même.

Commençons par le fait qu'il faut d'abord décider de ce que nous allons utiliser, c'est simple — l'annuaire final doit être accessible à tous les utilisateurs du domaine via un navigateur. La première chose qui vient à l'esprit est PHP associé à ldap, que nous allons utiliser. Un grand avantage de l'utilisation de PHP, selon moi, est sa relative simplicité — tout administrateur système comprenant un peu pourra, si nécessaire, apporter les modifications nécessaires au code sans trop de difficulté.

Donc, commençons. Pour commencer, définissons les paramètres de connexion au domaine :

$srv = "SERVER";
$srv_domain = "DOMAIN.COM";
$srv_login = "USERNAME@" . $srv_domain;
$srv_password = "PASSWORD";

L'étape suivante consiste à définir dans quel OU nous allons chercher des utilisateurs. Nous allons le faire en interceptant les valeurs de $_GET[‘place’]. Par exemple, si l'utilisateur accède à l'adresse server/index.php?place=first, alors la variable $place recevra la valeur first.

$place = (@$_GET['place']);
$doscript = true;
switch($place) {
case "first":
	$dn = "OU=ou1,OU=DOMAIN,dc=DOMAIN,dc=COM";
	break;
case "second":
	$dn = "OU=ou2,OU=DOMAIN,dc=DOMAIN,dc=COM";
	break;
	// ici, vous pouvez ajouter d'autres conditions.
default:
	$doscript = false;
	break;
}
if (!$doscript) include "main_table.html";

Variable $doscript est nécessaire pour stocker la valeur — avons-nous défini l'OU dans lequel nous allons chercher des utilisateurs ou non. Si aucune correspondance n'est trouvée dans les « switch-case », alors $doscript = false, la partie principale du script ne sera pas exécutée et la page de démarrage « main_table.html » sera affichée (j'en parlerai à la fin).

Si nous avons défini l'OU, nous passons alors à l'étape suivante : nous commençons à dessiner à l'utilisateur la page de l'annuaire :

else if ($doscript) {
{echo "
<!DOCTYPE html> 
<html xmlns='http://www.w3.org/1999/xhtml'>
<head>
<link rel='shortcut icon' href='ico.png'>
<meta charset='windows-1251/ '>

Nous activons les styles pour un aspect plus agréable (oui, ils auraient pu être intégrés en tant que fichier CSS, mais certaines versions d'IE n'acceptent pas les styles spécifiés de cette manière, c'est pourquoi nous devons les écrire directement dans le script) :

*{text-align: center; font-family:tahoma; font-size:14px;}
	a{text-decoration: none; color: #000;}
	a:hover{text-decoration: underline; color: #0059FF;}
	#bold{text-decoration: none; font-weight: 600;font-size:20px;}
	#table,tr,td{border-style:solid;border-width:1px;	border-collapse:collapse;padding:5px; height:22px;border-color:#7d7d7d;}
	
	/* Lignes impaires */#table tbody tr:nth-child(odd){background: #fff;}
	/* Lignes paires */   #table tbody tr:nth-child(even){background: #F7F7F7;}	
	#noborder{border-width: 0 px; border-style: none;}	
	#sp30px{text-indent: 30px;text-align: justify;}
	#smallsize{font-family:tahoma; text-indent: 5px; text-align:left; font-size:12px;}
	#top {background: #ffffff;
		text-align: center;
		left:0;
		top:0px;
		table-layout: fixed;
		border-style:solid;
		border-width:0px;
		border-collapse:collapse;
		padding:0px;
		height:22px;
		border: 0px;
		z-index: 99999;
		display:block;
		width:80px;
		opacity: 0.6;
		filter: alpha(Opacity=60);
		height:100%;
		position:fixed;}
	#top:hover{background: #afafaf;opacity: 100;filter: alpha(Opacity=100);text-decoration: none;color: #000000;}
	.smalltext{padding-top: 1px;
		padding-bottom: 1px;
		text-align: bottom;
		font-family:tahoma;
		color: #a0a0a0;
		line-height: 7px;
		font-size: 10px;}
	.smalltext:hover{color: #0000ff;}		
	.transition-rotate {position: relative;
		z-index: 2;
		margin: 0 auto;
		padding: 5px;
		text-align: center;
		max-width: 500px;
		cursor: pointer;
		transition: 0.1s linear;}
	.transition-rotate:hover {-webkit-transform: rotate(-2deg);	transform: rotate(-2deg);}
	#lineheight{
		text-align: left;
		line-height: 1px;
		text-decoration: none;
		font-weight: 600;
		font-size:20px;}

Les styles sont terminés, nous allons maintenant définir le titre de l'onglet et créer un lien de retour pratique vers la page d'accueil :

<title>Carnet d'adresses de «YourMegaCompanyName»</title>	
</head>
<body style='background-color:#ffffff;'>";
}
echo "
<table id='top'><tr><td id='top'>
<a href='index.php?place=main' id='top' >
<br><br><br>
<img src='back_to_main.png' alt='' border='0' width='75' height='60'/>
<p>Retour à l'accueil</p></a>
</td></tr></table>
";

Définissons les filtres de recherche par AD, et obtenons les données sur l'OU :

$filter ="(&(objectcategory=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"; // tous les utilisateurs, sauf ceux désactivés.
$filter2 ="(objectCategory=OrganizationalUnit)"; // pour obtenir des informations sur l'OU
$ds=ldap_connect($srv);   
if ($ds) { 
    $r=ldap_bind($ds,$srv_login,$srv_password);;     
	ldap_set_option($ds,LDAP_OPT_REFERRALS, 0);
	ldap_set_option($ds,LDAP_OPT_PROTOCOL_VERSION,3);
	$sr=ldap_search($ds,$dn ,$filter );   
    ldap_sort($ds,$sr, "givenname");
    $info = ldap_get_entries($ds, $sr); 
    $sr2=ldap_search($ds,$dn ,$filter2 );   
    $placeinfo = ldap_get_entries($ds, $sr2); 
$PlaceName = $placeinfo[0]["l"][0];  			// nom du lieu
$PlaceAddres = $placeinfo[0]["street"][0];		// adresse du lieu
$PlaceMail = $placeinfo[0]["description"][0]; 	// mail du lieu
$PlacePhone = $placeinfo[0]["st"][0]; 		// téléphone du lieu

Nous allons ensuite formater la partie supérieure de la page :

écouter"<table align='center' height = '80'>
	<td id='noborder' ><div id='lineheight'>". $PlaceName ."</div></td></tr>
	<tr><td id='noborder' >". $PlaceAddres ."</td></tr>
    </table>
<table align='center' id='table'>
	<tr><td width='35' bgcolor = "#f0f0e4">  N° </td>
	<td width='300' bgcolor = "#f0f0e4"> Nom </td>
	<td width='250' bgcolor = "#f0f0e4"> E-mail </td>
	<td width='60' bgcolor = "#f0f0e4"> Téléphone </td>
	<td width='150' bgcolor = "#f0f0e4"> Mobile </td></tr>
	<tr><td></td><td> Données OU </td><td>";
écouter "<div class='transition-rotate'><a href="mailto:"" . $placemail .">" . $PlaceMail ." </a></div>";
écouter "</td><td width='150'> " . $PlacePhone ." </td><td> - </td></tr>";

Ensuite, nous récupérons et traitons les données des utilisateurs dans une boucle, tout en cachant certains (comme les comptes de service) en inscrivant simplement « hide » dans le champ « salle » des attributs de l'utilisateur dans AD, ces utilisateurs ne s'afficheront pas dans l'annuaire :

for ($i=0; $i<$info["count"];$i++) { 
$UserHide = $info[$i]["physicaldeliveryofficename"][0];
if ($UserHide != 'hide') {
$UserName = $info[$i]["cn"][0];                //Nom d'utilisateur
$UserPosition = $info[$i]["title"][0]; 		//Poste
$UserMail = $info[$i]["mail"][0];			//mail
if (!$UserMail) $UserMail = "-";                  //si aucune donnée sur la boîte dans AD, afficher un tiret
$UserIpPhone = $info[$i]["ipphone"][0];		//ip téléphone
	if (!$UserIpPhone) $UserIpPhone = "-";    //si aucune donnée sur la boîte dans AD, afficher un tiret
$UserMobile = $info[$i]["mobile"][0];		//mobile
	if (!$UserMobile) $UserMobile = "-";     //si aucune donnée sur la boîte dans AD, afficher un tiret

Au fait, si vous devez obtenir la valeur d'un autre attribut, rappelez-vous (c'est important) :
dans la requête, nous transmettons le nom de l'attribut en minuscules lettres, sinon cela ne fonctionnera pas.

Et nous insérons les données obtenues dans le tableau :

    echo "<tr>
	<td>". $n+=1 ."</td>
	<td> ". $UserName ."<br> <div class='smalltext'>". $UserPosition ."</div></td><td>"; 	// Nom d'utilisateur et poste 
	if ($UserMail !='-') echo "<div class='transition-rotate'><a href="mailto:'$UserMail'">$UserMail  </a></div>";    // si l'utilisateur a un e-mail, créez un lien pour envoyer un message
	else echo "-"; // si non, mettez un tiret.
 	echo "<td> ". $UserIpPhone ." </td>
 	<td> ". $UserMobile ." </td></tr>";
	}
}
echo "</table>";

Ensuite, nous fermons la connexion LDAP, ou affichons un message indiquant qu'il est impossible de se connecter au serveur :

ldap_close($ds);
} 
else echo "<h4>Impossible de se connecter au serveur LDAP</h4>"; 
echo '<br><br><br></body></html>';}

Le fichier « main_table.html » est en fait une simple page html contenant des liens, et ressemble à ceci :

<head>
<link rel="shortcut icon" href="ico.png"/>
<meta charset="windows-1251"/>
<title>Carnet d'adresses de «YourMegaCompanyName»</title>
</head>
<body style='background-color:#ffffff;'>
<center><a href="index.php"><img border="none" src="logo.png"/></a></center>
<center><b>Lieux et bureaux</b></center>
<br>
<table border="0" width="450" bgcolor="#dddddd" align="center" valign="middle" cellspacing="0">

<tr id="space"><td></td></tr>
<tr><td align="left" id="abz"><a href="index.php?place=ou1">OU1</a></td></tr>
<tr id="space"><td></td></tr>
<tr><td align="left" id="abz"><a href="index.php?place=ou2">OU2</a></td></tr>

</table></body></html>

Si mon code peut aider quelqu'un, je serai ravi, n'hésitez pas à l'utiliser !

Vous pouvez également le modifier à votre convenance (améliorer/empirer) et le distribuer par tous les moyens.

Merci de votre attention !

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster