Δημιουργία καταλόγου διευθύνσεων WEB PHP + LDAP

Έτυχε μια (σχετικά) μεγάλη καμπάνια να είχε πολλά απομακρυσμένα γραφεία με αξιοπρεπή αριθμό χρηστών. Όλα τα γραφεία συνδέονται σε ένα δίκτυο με έναν κοινό τομέα, κάθε γραφείο ορίστηκε στην υπηρεσία καταλόγου Active Directory (εφεξής AD) ως Οργανωτική Μονάδα (OU), στην οποία είχαν ήδη δημιουργηθεί χρήστες.

Ήταν απαραίτητο να δοθεί στους χρήστες η ευκαιρία να αποκτήσουν γρήγορα και αβίαστα τα στοιχεία επικοινωνίας του απαιτούμενου υπαλλήλου από την AD και οι διαχειριστές συστήματος να απελευθερωθούν από τη ρουτίνα επεξεργασίας ενός αρχείου κειμένου που έπαιζε το ρόλο ενός βιβλίου διευθύνσεων.

Δεν υπήρχαν έτοιμες κατάλληλες επιλογές για την επίλυση του προβλήματος, οπότε έπρεπε να κάνω τα πάντα με τα χέρια και το κεφάλι μου.

Ας ξεκινήσουμε με το γεγονός ότι πρώτα πρέπει να αποφασίσετε τι θα χρησιμοποιήσετε, είναι απλό - ο τελικός κατάλογος θα πρέπει να είναι διαθέσιμος σε όλους τους χρήστες του τομέα μέσω ενός προγράμματος περιήγησης. Το πρώτο πράγμα που μας έρχεται στο μυαλό είναι η PHP σε συνδυασμό με το ldap και θα τα χρησιμοποιήσουμε. Θεωρώ ότι το μεγάλο πλεονέκτημα της χρήσης της PHP είναι η σχετική απλότητά της - οποιοσδήποτε διαχειριστής συστήματος με έστω και λίγη κατανόηση θα μπορεί να κάνει τις απαραίτητες αλλαγές στον κώδικα, αν χρειαστεί, χωρίς ιδιαίτερη πίεση.

Λοιπόν, ας ξεκινήσουμε. Αρχικά, ας ορίσουμε τις παραμέτρους για τη σύνδεση στον τομέα:

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

Το επόμενο σημείο είναι να καθορίσουμε σε ποιο OU θα αναζητήσουμε χρήστες. Θα το κάνουμε αυτό παρεμποδίζοντας τιμές από $_GET['place']. Για παράδειγμα, εάν ο χρήστης μεταβεί στη διεύθυνση διακομιστής/index.php?place=πρώτα, μετά τη μεταβλητή $τόπος θα εκχωρηθεί μια τιμή πρώτα.

$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";

Μεταβλητή $doscript απαιτείται για την αποθήκευση της τιμής - είτε έχουμε ορίσει το OU στο οποίο θα αναζητήσουμε χρήστες είτε όχι. Εάν δεν υπάρχουν αντιστοιχίσεις που αναφέρονται στο "switch-case", τότε $doscript=false, το κύριο μέρος του σεναρίου δεν θα εκτελεστεί και θα εμφανιστεί η αρχική σελίδα "main_table.html" (θα σας πω για στο τέλος).

Εάν έχουμε ορίσει ένα OU, τότε προχωράμε σε περαιτέρω ενέργειες: αρχίζουμε να σχεδιάζουμε μια σελίδα καταλόγου για τον χρήστη:

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

Περιλαμβάνουμε στυλ για πιο ευχάριστη εμφάνιση (ναι, θα μπορούσαν να συμπεριληφθούν ως αρχείο css, αλλά ορισμένες εκδόσεις του IE δεν θέλουν να δέχονται στυλ που ορίζονται με αυτόν τον τρόπο, επομένως πρέπει να τα γράψετε απευθείας στο σενάριο):

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

Τελειώσαμε με τα στυλ, τώρα γράφουμε τον τίτλο της καρτέλας και σχεδιάζουμε έναν βολικό σύνδεσμο για να επιστρέψουμε στην κύρια σελίδα:

<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>
";

Ορίζουμε φίλτρα αναζήτησης κατά AD και λαμβάνουμε δεδομένα σχετικά με το 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

Στη συνέχεια σχεδιάζουμε το επάνω μέρος της σελίδας:

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>";

Στη συνέχεια, λαμβάνουμε και επεξεργαζόμαστε δεδομένα χρήστη σε βρόχο, ενώ για να κρύψουμε ορισμένους λογαριασμούς (για παράδειγμα, υπηρεσίας), απλώς εισάγουμε "απόκρυψη" στο πεδίο "δωμάτιο" στα στοιχεία χρήστη στο AD, τέτοιοι χρήστες δεν θα εμφανίζεται στον κατάλογο:

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, то отображаем прочерк

Παρεμπιπτόντως, εάν πρέπει να λάβετε την τιμή ενός άλλου χαρακτηριστικού, τότε θυμηθείτε (αυτό είναι σημαντικό):
στο αίτημα περνάμε το όνομα του χαρακτηριστικού πεζά γράμματα, διαφορετικά δεν θα λειτουργήσει.

Και εισάγετε τα ληφθέντα δεδομένα στον πίνακα:

    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>";

Στη συνέχεια, κλείνουμε τη σύνδεση ldap ή εμφανίζουμε ένα μήνυμα σχετικά με την αδυναμία σύνδεσης στον διακομιστή:

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

Το αρχείο "main_table.html" από μέσα είναι μια απλή σελίδα html με συνδέσμους και μοιάζει κάπως έτσι:

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

Εάν ο κωδικός μου βοηθήσει κάποιον, θα χαρώ να τον χρησιμοποιήσει!

Μπορείτε επίσης να το επεξεργαστείτε ελεύθερα όπως θέλετε (βελτιώστε/χειρότερα) και να το διανείμετε με οποιοδήποτε μέσο.

Спасибо за внимание!

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο