Создаём WEB адресный справочник PHP + LDAP

от автора

Так случилось, что у (относительно) большой кампании было много отдалённых офисов, в которых находилось приличное количество пользователей. Все офисы соединены в одну сеть с общим доменом, каждый офис был определён в Active Directory (далее по тексту AD) как Organization Unit (OU), в котором уже заводились пользователи.

Необходимо было дать пользователям возможность быстро и без особенных усилий получать контактные данные необходимого сотрудника из AD, а системных администраторов освободить от рутины редактирования текстового файла, который играл роль адресной книги.

Готовых подходящих вариантов для решения поставленной задачи не нашлось, поэтому пришлось делать всё своими руками и головой.

Начнём с того, что для начала нужно определиться что использовать, это просто — итоговый справочник должен быть доступен всем пользователям домена посредством браузера. Первое, что приходит на ум это PHP в связке с ldap, их и будем использовать. Большим плюсом использования PHP я считаю его относительную простоту — любой хоть немного понимающий системный администратор сможет внести, при необходимости, нужные правки в код, не особенно напрягаясь.

Итак, начнём. для начала зададим параметры подключения к домену:

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

Следующим пунктом нужно определить в каком OU будем искать пользователей. Делать это будем перехватывая значения из $_GET[‘place’]. Например, если пользователь переходит по адресу server/index.php?place=first, то переменной $place будет присвоено значение 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; 	//здесь можно добавить ещё условий. 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>"; 

Далее получаем в цикле и обрабатываем данные пользователей, при этом, чтобы скрыть некоторые (например служебные) учётные записи, просто прописываем «hide» в поле «комната» в реквизитах пользователя в 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> 

Если кому-либо поможет мой код — я буду рад, пользуйтесь!

Также можете свободно редактировать его как вам угодно (улучшать/ухудшать) и распространять любыми методами.

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

ссылка на оригинал статьи https://habr.com/ru/post/490690/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *