Erstellen eines WEB-Adressverzeichnisses PHP + LDAP

So kam es, dass es bei einer (relativ) großen Kampagne viele Außenstellen mit einer ordentlichen Anzahl an Benutzern gab. Alle Büros sind in einem Netzwerk mit einer gemeinsamen Domäne verbunden, jedes Büro wurde im Active Directory (im Folgenden AD genannt) als Organisationseinheit (OU) definiert, in der bereits Benutzer angelegt wurden.

Es war notwendig, Benutzern die Möglichkeit zu geben, schnell und mühelos die Kontaktinformationen des gewünschten Mitarbeiters von AD zu erhalten, und Systemadministratoren von der Routine der Bearbeitung einer Textdatei zu befreien, die die Rolle eines Adressbuchs spielte.

Für die Lösung des Problems gab es keine vorgefertigten passenden Möglichkeiten, also musste ich alles mit meinen eigenen Händen und meinem Kopf machen.

Beginnen wir mit der Tatsache, dass Sie zunächst entscheiden müssen, was Sie verwenden möchten. Das ist ganz einfach: Das endgültige Verzeichnis sollte für alle Benutzer der Domain über einen Browser verfügbar sein. Das erste, was mir in den Sinn kommt, ist PHP in Verbindung mit LDAP, und wir werden sie verwenden. Den großen Vorteil der Verwendung von PHP sehe ich in der relativen Einfachheit – jeder Systemadministrator mit auch nur ein wenig Verständnis kann bei Bedarf ohne große Anstrengung die notwendigen Änderungen am Code vornehmen.

Also, fangen wir an. Legen wir zunächst die Parameter für die Verbindung zur Domäne fest:

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

Der nächste Punkt besteht darin, zu bestimmen, in welcher OU wir nach Benutzern suchen. Wir werden dies tun, indem wir Werte von $_GET['place'] abfangen. Zum Beispiel, wenn der Benutzer die Adresse aufruft server/index.php?place=zuerst, dann die Variable $Platz wird der Wert zugewiesen zuerst.

$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;
	//здесь можно добавить ещё условий.
default:
	$doscript=false; 
	break;
}
if (!$doscript) include "main_table.html";

Variable $doscript wird benötigt, um den Wert zu speichern – unabhängig davon, ob wir die Organisationseinheit definiert haben, in der wir nach Benutzern suchen werden oder nicht. Wenn im „switch-case“ keine Übereinstimmungen aufgeführt sind, dann ist $doscript=false, der Hauptteil des Skripts wird nicht ausgeführt und die Startseite „main_table.html“ wird angezeigt (ich werde es Ihnen sagen). es ganz am Ende).

Wenn wir eine OU definiert haben, fahren wir mit weiteren Aktionen fort: Wir beginnen mit dem Zeichnen einer Verzeichnisseite für den Benutzer:

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/ '>

Wir integrieren Stile für ein angenehmeres Erscheinungsbild (ja, sie könnten als CSS-Datei eingebunden werden, aber einige IE-Versionen möchten auf diese Weise festgelegte Stile nicht akzeptieren, daher müssen Sie sie direkt in das Skript schreiben):

<style>
	*{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;}
	/* Нечетные строки */#table tbody tr:nth-child(odd){background: #fff;}
	/* Четные строки */   #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;}
</style>

Wir sind mit den Stilen fertig, jetzt schreiben wir den Titel der Registerkarte und zeichnen einen praktischen Link, um zur Hauptseite zurückzukehren:

<title>Adressbook of «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>На главную</p></a>
</td></tr></table>
";

Wir definieren Suchfilter nach AD und erhalten Daten über die OU:

$filter ="(&(objectcategory=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"; //все пользователи, кроме отключенных.
$filter2 ="(objectCategory=OrganizationalUnit)"; // для получения информации о 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];  			// name of place
$PlaceAddres = $placeinfo[0]["street"][0];		// address of place
$PlaceMail = $placeinfo[0]["description"][0]; 	// mail of place
$PlacePhone = $placeinfo[0]["st"][0]; 		// phone of plase

Als nächstes gestalten wir den oberen Rand der Seite:

echo"<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>  № </td>
	<td width='300' bgcolor = #f0f0e4> Name </td>
	<td width='250' bgcolor = #f0f0e4> E-mail </td>
	<td width='60' bgcolor = #f0f0e4> Phone </td>
	<td width='150' bgcolor = #f0f0e4> Mobile </td></tr>
	<tr><td></td><td> Данные OU </td><td>";
echo "<div class='transition-rotate'><a href=mailto:" . $PlaceMail .">" . $PlaceMail ." </a></div>";
echo "</td><td width='150'> " . $PlacePhone ." </td><td> - </td></tr>";

Als nächstes empfangen und verarbeiten wir Benutzerdaten in einer Schleife. Um einige (z. B. Dienst-)Konten auszublenden, geben wir einfach „Ausblenden“ in das Feld „Raum“ in den Benutzerdetails in AD ein. Solche Benutzer werden nicht angezeigt im Verzeichnis angezeigt:

for ($i=0; $i<$info["count"];$i++) { 
$UserHide = $info[$i]["physicaldeliveryofficename"][0];
if ($UserHide != 'hide') {
$UserName = $info[$i]["cn"][0];                //Имя пользователя
$UserPosition = $info[$i]["title"][0]; 		// Должность
$UserMail = $info[$i]["mail"][0];			//mail
if (!$UserMail)) $UserMail = "-";                  //если нет данных о ящике в AD, то отображаем прочерк
$UserIpPhone = $info[$i]["ipphone"][0];		//ip phone
	if (!$UserIpPhone) $UserIpPhone = "-";    //если нет данных о ящике в AD, то отображаем прочерк
$UserMobile = $info[$i]["mobile"][0];		//mobile
	if (!$UserMobile) $UserMobile = "-";     //если нет данных о ящике в AD, то отображаем прочерк

Wenn Sie übrigens den Wert eines anderen Attributs benötigen, denken Sie daran (das ist wichtig):
In der Anfrage übergeben wir den Attributnamen Kleinbuchstaben Buchstaben, sonst funktioniert es nicht.

Und fügen Sie die empfangenen Daten in die Tabelle ein:

    echo "<tr>
	<td>". $n+=1 ."</td>
	<td> ". $UserName ."<br> <div class='smalltext'>". $UserPosition ."</div></td><td>"; //	Имя пользователя и должность 
	if ($UserMail !='-') echo "<div class='transition-rotate'><a href=mailto:'$UserMail'>$UserMail  </a></div>";    // если у пользователя есть e-mail создаём ссылку на отправку письма
	else echo "-"; //если нет e-mail - ставим прочерк.
 	echo "<td> ". $UserIpPhone ." </td>
 	<td> ". $UserMobile ." </td></tr>";
	}
}
echo "</table>";

Als nächstes schließen wir die LDAP-Verbindung oder zeigen eine Meldung an, dass keine Verbindung zum Server möglich ist:

ldap_close($ds); 
} 
else echo "<h4>Unable to connect to LDAP server</h4>"; 
echo '<br><br><br></body></html>';}

Die Datei „main_table.html“ ist von innen eine einfache HTML-Seite mit Links und sieht in etwa so aus:

<head>
<link rel="shortcut icon" href="ico.png"/>
<meta charset="windows-1251"/>
<title>Adressbook of «YourMegaCompanyName»</title>
</head>
<body style='background-color:#ffffff;'>
<center><a href=index.php><IMG border="none" src="logo.png"/></a></center>
<center><b>Places and offices</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>

Wenn mein Code jemandem hilft, würde ich mich freuen, ihn zu verwenden!

Sie können es auch nach Belieben bearbeiten (verbessern/schlechter) und auf beliebige Weise verbreiten.

Danke!

Source: habr.com

Kommentar hinzufügen