Friday, October 1, 2010

Use PHP to perform an LDAP Bind to Windows Active Directory for User Authentication

This example shows some basic LDAP bind lookups on a Windows 2003 active directory server.

The sequence is:

  • Connect 
  • Bind using privileged user 
  • search for 'dn' of supplied credentials
  • re-bind using this dn and password of supplied credentials
  • unbind

The per-requisite is that php_ldap modules are loaded and compiled.  These are fairly standard now days.  In fedora it was just a matter of executing:

# yum install php-ldap

Anyway:  Here is the example.  It's farily well commented so should be a simple matter to make work in your own environment.

// example.php
// David Latham @ 2010
// This code cannot be executed on the same server as AD is installed on!!!
// Active Directory has an Organizational Unit of "_Test_Users" with 3 users loaded
// into it.
// user1 | User One
// user2 | User Two
// ldapbind | ldap bind
// execute with php -q example.php

// credentials to test
// user='user2'; //Use this one to test binding without an email address.

// AD server details
$ldap_server = "";
$dn = "OU=_Test_Users,DC=example,DC=local";

// Connect
$ad = ldap_connect($ldap_server); //Must be a real active directory server
//(WIN2003 used in this example)

// Set some variables
ldap_set_option($ad, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ad, LDAP_OPT_REFERRALS, 0);

// Bind to the ldap directory.
// Here we are binding using a fixed user who has privileges to bind to the
// active directory. This user also has a fixed password. It can not change
// otherwise this script will break.

$bd = @ldap_bind($ad,"ldap user","pa$$word")
or die("Couldn't bind to AD!");

// Search the directory for a distinguished name (dn) using the supplied
// credentials.
// If $user is an email address then use 'mail' otherwise use 'sAMAccountName'

if( strpos($user, '@') > 0 ) {
} else {
echo "Searching AD using ...".$field."\n";

$result = @ldap_search($ad, $dn, "(".$field."=".$user.")", array('dn'));

// Create result set
$entries = @ldap_get_entries($ad, $result);

// Show an array of result

// If we have a result then we should 're-bind' using the destinguished name found
// in the search.
if ( $entries[0] ) {
if(@ldap_bind($ad, $entries[0]['dn'], $pass)) {
// If bind was successful then show some data. This is user
// authentication success.
echo "found: ".$entries[0]['dn'];
} else {
// Bind failed so this would equate to user authentication failure.
echo "Failed to bind.";
} else {
// Failure to search would indicate a problem with your $dn variable.
echo "failed to search";

//never forget to unbind!


the result might look something like this:

[dave@fedora php-ldap]$ php -q example.php
Searching AD using ...mail
[count] => 1
[0] => Array
[count] => 0
[dn] => CN=user2,OU=_Test_Users,DC=example,DC=local

found: CN=user2,OU=_Test_Users,DC=example,DC=local

Have fun authenticating your users against your work active directory. You will:

  • Please your security manager

  • Avoid the headache of managing passwords password compliance

  • Write safer applications in terms of locking them down

  • Feel good about yourself

Post a Comment