PHP and LDAP: How to Manipualte Active Directory

February 13th, 2011 Leave a comment 2 comments
Like the article?
PHP and LDAP (Active Directory)

There is one major question that may be asked to this tutorial’s subject: “Why would I want PHP to access Active Directory? I can use Users and Groups to manage it already.” The answer to this is (though I am sure there are others): Quite often, management wants to delegate some Active Directory (AD) functions to users who don’t or shouldn’t have access to LDAP Users and Groups. As a real-life example, I once worked at a company that wanted their secretary to be able to add users, delete users, and update user passwords and contact info from a nice, user-friendly, web interface. I put together a simple web-based interface using PHP and LDAP, and thus this tutorial was born.

Step 1: Configure PHP with LDAP Support

If PHP doesn’t already have LDAP support enabled, depending on your OS, you’ll need to enable it. On Linux, there are a few different ways to do it – either compile PHP with LDAP support like so (universal across all distros):

./configure --with-ldap [other configuration options]

or install your distro-specific php-ldap package and then add the following line in your php.ini:

extension=mod_ldap.so

and restart Apache.

On Windows, uncomment or add the following line in your php.ini:

extension=php_ldap.dll

and restart Apache/IIS

Step 2: Connect to Your Existing Active Directory

Once your PHP installation has been updated to include LDAP support (or had it in the first place), it’s time to initiate a connection. Pop this into a PHP file:

<?php
   $adconn = ldap_connect("ldap://ldap.example.com");
   ldap_set_option($adconn, LDAP_OPT_PROTOCOL_VERSION, 3);
?>

So in the code above, we’ve created a connection and assigned it to ldap.example.com. Some LDAP installations and functions require an explicit setting of the protocol version; for me, it has become a habit to set it to avoid any errors, and I have done so in the line following the connection.

Step 3: Binding PHP to Active Directory

An anonymous connect is all well and good, but we’ve got to bind to the Active Directory before we can do anything with it. Depending on your security settings, an anonymous bind might suffice for performing searches on the Active Directory; for anything requiring access, however, you’ll need a user with the appropriate permissions. Since users come and go, it might be a good idea to make a user with permissions solely for PHP that interacts with LDAP on an administrative level – in this example, we’ll go with “ldapweb”.

To bind to your Active Directory:

$ldap_bind = ldapbind($adconn, "ldapweb", "password");

So far, still nice and self-explanatory – this line binds against our open Active Directory connection with username “ldapweb” and password “password”).

Despite existing, $ldap_bind won’t be used again – this is a source of common confusion for many first-timers to the PHP LDAP library, myself included. It is a boolean and is only used to check if the ad is bound or not. All queries from now on will query against $adconn, the original LDAP connection.

Step 4: Searching against the Active Directory

Here’s where the real meat of the PHP LDAP library lies! The ldap_search function is incredibly powerful, though it’s also incredibly complex; it’s akin to a SQL query in terms of power and possible options. We are going to use it in a far simpler manner, however – we are going to get a list of usernames from the Active Directory:

$dn = "OU=People,OU=staff,DN=ldap,DN=myawesomesite,DN=com";
$attribute = array("samAccountName");
$result = ldap_search($adconn, $dn, "(cn=*)", $attribute);
$entries = ldap_get_entries($ad, $result);
    
for ($i = 0; $i < $entries["count"]; $i++) {
  echo $entries[$i]["samAccountName"];
  echo "<br></br>";       
}

This isn’t entirely self-explanatory, so let’s run through this line-by-line to figure out what’s going on. When accessing LDAP through PHP, all of the variables come back in the form of an array- this is why we can’t simply use $results straight away. By using ldap_get_entries, we iterate through $results and get back a multidimensional array that contains both the number of the entry in question as well as the Active Directory variable in question (in this case, “samAccountName”). The for loop iterates through each entry and echoes the name as well as an HTML break, giving you a line by line breakdown of every displayname variable in the database.

Step 5: Adding, Modifying, and Deleting Database Entries

I’ll cover all of these in one section because the syntax for them is more or less the same. To add, replace, and remove any entries from the database you use (predictably) ldap_mod_add, ldap_mod_replace, and ldap_delete. Let’s take a look at adding an entry into the database.

$newuser["samAccountName"] = "awesomeman";
$newuser["givenname"] = "awesome";
$newuser["sn"] = "man";
$result = ldap_mod_add($adconn, $dn, $newuser);

That covers ldap_mod_add. ldap_mod_replace uses the exact same syntax, except you have to make the $dn variable specific to what you want to replace. For example, if you wanted to replace those entries in awesomeman instead of adding them, you would do:

$dn = "CN=Awesome Man,OU=People,OU=staff,DN=ldap,DN=myawesomesite,DN=com";
$newuser["samAccountName"] = "awesomeman";
$newuser["givenname"] = "awesome";
$newuser["sn"] = "man";
$result = ldap_mod_replace($adconn, $dn, $newuser);

ldap_delete is even easier, only requiring the specific DN and the $adconn:

$dn = "CN=Awesome Man,OU=People,OU=staff,DN=ldap,DN=myawesomesite,DN=com";
$result = ldap_delete($adconn, $dn);

Step 6: Putting It All Together

In this step, we’re going to write a small function that searches the database for a given username and replaces it with a specified username.

<?php
$adconn = ldap_connect("ldap://ldap.myawesomesite.com");
ldap_set_option($adconn, LDAP_OPT_PROTOCOL_VERSION, 3);
$ldap_bind = ldapbind($adconn, "ldapweb", "password");

function replaceUser($old_username, $new_username) {
  $dn = "CN=$old_username,OU=People,OU=staff,DN=ldap,DN=myawesomesite,DN=com";
  $user["samAccountName"] = $new_username;
  ldap_mod_replace($adconn, $dn, $user);
}

$old_username = $argv[0];
$new_user = $argv[1];
replaceUser($old_username, $new_user);
?>

Step 7: Conclusion

There are, of course, many other powerful uses to the PHP + LDAP combination, but this quick tutorial is designed to give you the quick and dirty of getting PHP to connect and interact with an Active Directory server; you never know when that manager’s going to ask you for a slick, password-changing web front-end for their secretaries. Good luck, and happy coding!

Help us spread the word!
  • Twitter
  • Facebook
  • LinkedIn
  • Pinterest
  • Delicious
  • DZone
  • Reddit
  • Sphinn
  • StumbleUpon
  • Google Plus
  • RSS
  • Email
  • Print
If you liked this article, consider enrolling in one of these related courses:
Don't miss another post! Receive updates via email!

2 comments

  1. PHPGangsta says:

    Nice article, all basic information how to work with LDAP is mentioned. Nowadays you normally use a Framework component for that, so you don’t have to work with this low level functions (like Zend_Ldap).

    Another good explanation with examples can be found here (in german):
    http://www.phpgangsta.de/ldap-authentifizierung-und-andere-abfragen

    And here is an article about using Zend_Ldap:
    http://www.phpgangsta.de/einen-ldap-ad-server-administrieren-mit-zend_ldap

  2. Alvin Lobo says:

    Hey … i am using the same kinda setup as you have explained. Nice article thou.

    I am using Windows Active Directory on 2008 I keep getting this error

    Warning: ldap_mod_replace() [function.ldap-mod-replace]: Modify: Server is unwilling to perform in ……

    Search quite a bit on this. Can any one help

Comment