It so happened that a (relatively) large company had many remote offices, each with a considerable number of users. All offices are connected in a single network with a common domain, and each office was defined in Active Directory (hereinafter referred to as AD) as an Organization Unit (OU), where users were already created.
It was necessary to allow users to quickly and effortlessly obtain contact details for the required employee from AD, while freeing system administrators from the routine of editing a text file that acted as an address book.
There were no ready-made suitable options for solving the task at hand, so everything had to be done manually and thoughtfully.
Let’s start by determining what to use; it’s simple — the final directory should be accessible to all domain users via a browser. The first thing that comes to mind is PHP in conjunction with LDAP, which we will use. I consider the relative simplicity of PHP a big advantage — any system administrator with even a little understanding can make necessary changes to the code without too much hassle.
So, let’s begin. First, we need to set the connection parameters to the domain:
$srv ="SERVER";
$srv_domain ="DOMAIN.COM";
$srv_login ="USERNAME@".$srv_domain;
$srv_password ="PASSWORD";
Next, we need to determine which OU we will search for users in. We will do this by intercepting values from $_GET[‘place’]. For example, if the user navigates to the address first, then the variable $place will be assigned the value 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;
// additional conditions can be added here.
default:
$doscript=false;
break;
}
if (!$doscript) include "main_table.html";
The variable $doscript is needed to store the value — whether we have determined the OU in which we will search for users or not. If there were no matches found in the "switch-case", then $doscript=false, and the main part of the script will not execute, but the start page "main_table.html" will be displayed (I will explain about it at the very end).
If we have determined the OU, then we proceed to further actions: we start designing the directory page for the user:
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/ '>
We enable styles for a more pleasant appearance (yes, they could have been connected as a CSS file; however, some versions of IE do not recognize styles defined this way, so we have to write them directly in the script):
*{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;}
The styles are done; now we write the tab title and create a convenient link to return to the homepage:
<title>Address book 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>Home</p></a>
</td></tr></table>
";
We define the search filters for AD and retrieve data about OU:
$filter ="(&(objectcategory=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"; // all users except disabled ones.
$filter2 ="(objectCategory=OrganizationalUnit)"; // to get information about 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 place
Next, we format the top part of the page:
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"> No. </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 Data </td><td>";
echo "<div class='transition-rotate'><a href="mailto:"" . $placemail .">" . $PlaceMail ." </a></div>";
echo "</td><td width='150'> " . $PlacePhone ." </td><td> - </td></tr>";
Then we loop through and process user data, while to hide some (for example, service accounts), we simply write "hide" in the "room" field in the user's properties in AD, such users will not be displayed in the directory:
for ($i=0; $i<$info["count"];$i++) {
$UserHide = $info[$i]["physicaldeliveryofficename"][0];
if ($UserHide != 'hide') {
$UserName = $info[$i]["cn"][0]; //User name
$UserPosition = $info[$i]["title"][0]; //Position
$UserMail = $info[$i]["mail"][0]; //mail
if (!$UserMail)) $UserMail = "-"; //if there is no mailbox data in AD, display a dash
$UserIpPhone = $info[$i]["ipphone"][0]; //ip phone
if (!$UserIpPhone) $UserIpPhone = "-"; //if there is no phone data in AD, display a dash
$UserMobile = $info[$i]["mobile"][0]; //mobile
if (!$UserMobile) $UserMobile = "-"; //if there is no mobile data in AD, display a dash
By the way, if you need to get the value of another attribute, remember (this is important):
we pass the attribute name in the request in lowercase letters, otherwise it won't work.
And we insert the retrieved data into the table:
echo "<tr>
<td>". $n+=1 ."</td>
<td> ". $UserName ."<br> <div class='smalltext'>". $UserPosition ."</div></td><td>"; // User name and position
if ($UserMail !='-') echo "<div class='transition-rotate'><a href="mailto:'$UserMail'">$UserMail </a></div>"; // if user has an email, create a link to send an email
else echo "-"; // if no email, display a dash.
echo "<td> ". $UserIpPhone ." </td>
<td> ". $UserMobile ." </td></tr>";
}
}
echo "</table>";
Then we close the LDAP connection, or display a message about the inability to connect to the server:
ldap_close($ds);
}
else echo "<h4>Unable to connect to the LDAP server</h4>";
echo '<br><br><br></body></html>';}
The file "main_table.html" internally represents a simple HTML page with links, and looks something like this:
<head>
<link rel="shortcut icon" href="ico.png"/>
<meta charset="windows-1251"/>
<title>Address book of «YourMegaCompanyName»</title>
</head>
<body style='background-color:#ffffff;'>
<center><a href="index.php"><img border="none" src="logo.png"/></a></center>
<center><b>Locations 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>
If my code helps someone — I will be happy, feel free to use it!
You can also freely edit it as you wish (improve/worsen) and distribute it by any means.
Thank you for your attention!
Source: habr.com
