Creando un directorio de enderezos WEB PHP + LDAP

Aconteceu que unha campaña (relativamente) grande tiña moitas oficinas remotas cun número decente de usuarios. Todas as oficinas están conectadas nunha rede cun dominio común, cada oficina estaba definida en Active Directory (en diante AD) como unha Unidade de Organización (OU), na que xa estaban creados os usuarios.

Era necesario dar aos usuarios a oportunidade de obter de forma rápida e sen esforzo a información de contacto do empregado requirido de AD e liberar aos administradores do sistema da rutina de editar un ficheiro de texto que desempeñaba o papel dunha axenda de enderezos.

Non había opcións axeitadas preparadas para resolver o problema, polo que tiven que facer todo coas miñas propias mans e cabeza.

Comecemos co feito de que primeiro debes decidir que usar, é sinxelo: o directorio final debería estar dispoñible para todos os usuarios do dominio a través dun navegador. O primeiro que se nos ocorre é PHP en conxunto con ldap, e imos usalos. Considero que a gran vantaxe de usar PHP é a súa relativa sinxeleza: calquera administrador do sistema, aínda que teña un pouco de comprensión, poderá facer os cambios necesarios no código, se é necesario, sen esforzarse especialmente.

Entón, imos comezar. Primeiro, imos establecer os parámetros para conectarse ao dominio:

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

O seguinte punto é determinar en que OU buscaremos usuarios. Farémolo interceptando valores de $_GET['lugar']. Por exemplo, se o usuario vai ao enderezo server/index.php?place=primeiro, entón a variable $lugar asignaráselle un valor primeiro.

$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 é necesario para almacenar o valor, se temos definido a OU na que buscaremos usuarios ou non. Se non hai coincidencias listadas no "switch-case", entón $doscript=false, a parte principal do script non se executará e aparecerá a páxina de inicio "main_table.html" (falarei sobre ao final).

Se definimos unha OU, procedemos a outras accións: comezamos a debuxar unha páxina de directorio para o usuario:

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

Incluímos estilos para unha aparencia máis agradable (si, poderían incluírse como ficheiro css, pero algunhas versións de IE non queren aceptar estilos definidos deste xeito, polo que tes que escribilos directamente no script):

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

Rematamos cos estilos, agora escribimos o título da pestana e trazamos unha ligazón conveniente para volver á páxina principal:

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

Definimos filtros de busca por AD e obtemos datos sobre a 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

A continuación deseñamos a parte superior da páxina:

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

A continuación, recibimos e procesamos os datos do usuario nun bucle, mentres que para ocultar algunhas contas (por exemplo, de servizo), simplemente introducimos "ocultar" no campo "sala" nos detalles do usuario en AD, tales usuarios non serán aparece no directorio:

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

Por certo, se precisas obter o valor doutro atributo, recorda (isto é importante):
na solicitude pasamos o nome do atributo minúscula letras, se non, non funcionará.

E insira os datos recibidos na táboa:

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

A continuación, pechamos a conexión ldap ou mostramos unha mensaxe sobre a imposibilidade de conectarse ao servidor:

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

O ficheiro "main_table.html" do interior é unha páxina html sinxela con ligazóns e ten un aspecto así:

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

Se o meu código axuda a alguén, estarei feliz, úsao!

Tamén podes editalo libremente como queiras (mellorar/peorar) e distribuílo por calquera medio.

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

Fonte: www.habr.com

Engadir un comentario