PHP + LDAP WEB дарек каталогун түзүү

Ошентип, (салыштырмалуу) чоң кампаниянын колдонуучуларынын татыктуу саны бар көптөгөн алыскы кеңселери болгон. Бардык кеңселер жалпы домен менен бир тармакка туташтырылган, ар бир кеңсе Active Directoryде (мындан ары - AD) колдонуучулар мурунтан эле түзүлгөн Уюштуруу бөлүмү (UU) катары аныкталган.

Колдонуучуларга ADдан керектүү кызматкердин байланыш маалыматын тез жана кыйынчылыксыз алуу мүмкүнчүлүгүн берүү керек болчу, ал эми системалык администраторлорго дарек китебинин ролун аткарган тексттик файлды редакциялоонун тартибинен бекер.

Маселени чечүү үчүн эч кандай даяр ылайыктуу варианттар жок болчу, ошондуктан мен баарын өз колум жана башым менен жасоого туура келди.

Келгиле, адегенде сиз эмнени колдонууну чечишиңиз керек экендиги менен баштайлы, бул жөнөкөй - акыркы каталог браузер аркылуу домендин бардык колдонуучуларына жеткиликтүү болушу керек. Эң биринчи ойго келген нерсе - РНР ldap менен бирдикте, биз аларды колдонобуз. Мен РНРди колдонуунун чоң артыкчылыгы анын салыштырмалуу жөнөкөйлүгү деп эсептейм – бир аз түшүнүгү бар ар бир системалык администратор, керек болсо, өзгөчө чыңалуусуз эле кодго керектүү өзгөртүүлөрдү киргизе алат.

Ошентип, баштайлы. Биринчиден, доменге туташуу үчүн параметрлерди орнотобуз:

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

Кийинки нерсе - колдонуучуларды кайсы OUден издей турганыбызды аныктоо. Биз муну $_GET['place'] маанисинен кармап туруу менен жасайбыз. Мисалы, колдонуучу дарекке барса server/index.php?place=биринчи, андан кийин өзгөрмө $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";

Variable $doscript маанини сактоо үчүн керек - биз колдонуучуларды издей турган OU аныктадыкпы же жокпу. Эгерде “которуу-касасында” тизмеленген дал келүүлөр жок болсо, анда $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>

Эгерде менин коду кимдир-бирөөгө жардам берсе, мен кубанычтамын, колдонуңуз!

Ошондой эле сиз каалагандай эркин түзөтө аласыз (жакшыртуу/жаман) жана каалаган ыкма менен тарата аласыз.

Конул бурганын учун рахмат!

Source: www.habr.com

Комментарий кошуу