Erstellen eines WEB-Adressenverzeichnisses PHP + LDAP

Es stellte sich heraus, dass eine (relativ) große Firma viele entfernte Büros hatte, in denen eine beträchtliche Anzahl von Nutzern arbeitete. Alle Büros sind in ein Netzwerk mit einer gemeinsamen Domäne verbunden, und jedes Büro wurde im Active Directory (im Folgenden AD) als Organisationseinheit (OU) definiert, in der bereits Benutzer angelegt wurden.

Es war notwendig, den Benutzern zu ermöglichen, schnell und ohne großen Aufwand die Kontaktdaten des benötigten Mitarbeiters aus dem AD zu erhalten, während die Systemadministratoren von der Routine des Bearbeitens einer Textdatei, die als Adressbuch diente, entlastet werden sollten.

Es gab keine passenden Lösungen für die gestellte Aufgabe, daher mussten wir alles selbst in die Hand nehmen und nach eigenem Kopf gestalten.

Zunächst müssen wir festlegen, was wir verwenden wollen – das ist einfach: Das endgültige Verzeichnis muss allen Domänenbenutzern über einen Browser zugänglich sein. Das erste, was mir in den Sinn kommt, ist PHP in Verbindung mit LDAP, die werden wir verwenden. Ein großer Vorteil von PHP ist seine relative Einfachheit – jeder Systemadministrator, der ein wenig versteht, kann bei Bedarf erforderliche Anpassungen im Code vornehmen, ohne sich besonders anstrengen zu müssen.

Also, fangen wir an. Zuerst legen wir die Verbindungsparameter zur Domäne fest:

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

Als nächstes müssen wir festlegen, in welcher OU wir nach Benutzern suchen werden. Wir werden dies tun, indem wir die Werte aus $_GET['place'] abfangen. Zum Beispiel, wenn der Benutzer die Adresse aufruft server/index.php?place=first, dann wird der Variable $place der Wert zugewiesen 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;
	// hier können weitere Bedingungen hinzugefügt werden.
default:
	$doscript=false; 
	break;
}
if (!$doscript) include "main_table.html";

Variable $doscript dient dazu, den Wert zu speichern – ob wir die OU, in der wir nach Benutzern suchen werden, bestimmt haben oder nicht. Wenn keine Übereinstimmungen gefunden wurden, die in „switch-case“ aufgeführt sind, wird $doscript=false, der Hauptteil des Skripts wird nicht ausgeführt und die Startseite „main_table.html“ wird angezeigt (ich werde sie ganz am Ende erläutern).

Wenn wir jedoch die OU bestimmt haben, gehen wir zu den nächsten Schritten über: Wir beginnen damit, dem Benutzer die Verzeichnissseite darzustellen:

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

Aktivieren wir die Stile für ein ansprechenderes Aussehen (ja, man hätte sie als CSS-Datei einbinden können, aber einige IE-Versionen möchten Stile, die auf diese Weise festgelegt sind, nicht akzeptieren, weshalb wir sie direkt in das Skript schreiben müssen):

*{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;}
	
	/* Ungerade Zeilen */#table tbody tr:nth-child(odd){background: #fff;}
	/* Gerade Zeilen */   #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;}

Die Stile sind festgelegt, jetzt schreiben wir den Titel des Tabs und erstellen einen praktischen Link zurück zur Startseite:

<title>Adressbuch von «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>Zur Startseite</p></a>
</td></tr></table>
";

Definieren wir die Suchfilter nach AD und erhalten die Daten über OU:

$filter ="(&(objectcategory=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"; // alle Benutzer, außer die Deaktivierten.
$filter2 ="(objectCategory=OrganizationalUnit)"; // für das Abrufen von Informationen über 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 des Ortes
$PlaceAddres = $placeinfo[0]["street"][0];		// Adresse des Ortes
$PlaceMail = $placeinfo[0]["description"][0]; 	// E-Mail des Ortes
$PlacePhone = $placeinfo[0]["st"][0]; 		// Telefon des Ortes

Nun gestalten wir den oberen Teil 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">  Nr. </td>
	<td width='300' bgcolor = "#f0f0e4"> Name </td>
	<td width='250' bgcolor = "#f0f0e4"> E-Mail </td>
	<td width='60' bgcolor = "#f0f0e4"> Telefon </td>
	<td width='150' bgcolor = "#f0f0e4"> Mobil </td></tr>
	<tr><td></td><td> OU-Daten </td><td>";
echo "<div class='transition-rotate'><a href="mailto:"" . $placemail .">" . $PlaceMail ." </a></div>";
echo "</td><td width='150'> " . $PlacePhone ." </td><td> - </td></tr>";

Jetzt holen wir in einer Schleife die Benutzerdaten und verarbeiten diese, wobei wir einige (z. B. Verwaltungs-) Konten ausblenden, indem wir einfach "hide" im Feld "Raum" in den Benutzerdaten in AD angeben; solche Benutzer werden im Verzeichnis nicht angezeigt:

for ($i=0; $i<$info["count"];$i++) { 
$UserHide = $info[$i]["physicaldeliveryofficename"][0];
if ($UserHide != 'hide') {
$UserName = $info[$i]["cn"][0];                \/\/Benutzername
$UserPosition = $info[$i]["title"][0]; 		\/\/ Position
$UserMail = $info[$i]["mail"][0];			\/\/Mail
if (!$UserMail)) $UserMail = "-";                  \/\/wenn keine Mailboxdaten in AD vorhanden sind, zeigen wir einen Strich an
$UserIpPhone = $info[$i]["ipphone"][0];		\/\/IP-Telefon
	if (!$UserIpPhone) $UserIpPhone = "-";    \/\/wenn keine Mailboxdaten in AD vorhanden sind, zeigen wir einen Strich an
$UserMobile = $info[$i]["mobile"][0];		\/\/Mobil
	if (!$UserMobile) $UserMobile = "-";     \/\/wenn keine Mailboxdaten in AD vorhanden sind, zeigen wir einen Strich an

Übrigens, wenn Sie den Wert eines anderen Attributs erhalten möchten, denken Sie daran (das ist wichtig):
im Anfrage übergeben wir den Namen des Attributs kleinen Buchstaben, sonst funktioniert es nicht.

Und wir fügen die erhaltenen Daten in die Tabelle ein:

    echo "<tr>
	<td>". $n+=1 ."</td>
	<td> ". $UserName ."<br> <div class='smalltext'>". $UserPosition ."</div></td><td>"; // Benutzername und Position 
	if ($UserMail !='-') echo "<div class='transition-rotate'><a href="mailto:'$UserMail'">$UserMail  </a></div>";    // wenn der Benutzer eine E-Mail hat, erstellen wir einen Link zum Versenden einer Nachricht
	else echo "-"; // wenn keine E-Mail vorhanden ist, setzen wir einen Strich.
 	echo "<td> ". $UserIpPhone ." </td>
 	<td> ". $UserMobile ." </td></tr>";
	}
}
echo "</table>";

Dann schließen wir die LDAP-Verbindung oder geben eine Nachricht über die Unmöglichkeit der Verbindung zum Server aus:

ldap_close($ds); 
} 
else echo "<h4>Verbindung zum LDAP-Server konnte nicht hergestellt werden</h4>"; 
echo '<br><br><br></body></html>';}

Die Datei „main_table.html“ stellt eine einfache HTML-Seite mit Links dar und sieht ungefähr so aus:

<head>
<link rel="shortcut icon" href="ico.png"/>
<meta charset="windows-1251"/>
<title>Adressbuch von «YourMegaCompanyName»</title>
</head>
<body style='background-color:#ffffff;'>
<center><a href="index.php"><img border="none" src="logo.png"/></a></center>
<center><b>Standorte und Büros</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 jemandem mein Code helfen kann – ich würde mich freuen, nutzen Sie ihn!

Sie können ihn auch ganz nach Ihren Wünschen bearbeiten (verbessern / verschlechtern) und nach Belieben verbreiten.

Vielen Dank für Ihre Aufmerksamkeit!

Quelle: habr.com

60GB SSD 8Gb DDR4