PHP/LDAP problems

Permabanned
Joined
17 Mar 2004
Posts
1,486
Location
Edinburgh
Hi,

Since my work upgraded their DCs from 2000 to 2003 I've found that a web site I wrote which queries Active Directory via LDAP and PHP has stopped working. Adding in some debugging comments I am now getting the following:

LDAP query test
Locating Active Directory Server
Connecting to an.LDAP.server on port 389...
connect result is Resource id #25
Binding ...
Bind result is 1
Searching for (cn=<*USERNAME*>) ...
<br />
<b>Warning</b>: ldap_search(): Search: Can't contact LDAP server in <b>/foo/bar.php</b> on line <b>63</b><br />
Search result is
Can't contact LDAP server

Now from the above, its finding an LDAP server fine, connecting to it, binding to it but for some reason it can't connect when searching. Any ideas? I can post code snippets if required.

Sorry feel like a newb having to actually ask a computer-related question :(

editted to hide our server names :)
 
Code:
<?php
// basic sequence with LDAP is connect, bind, search, interpret search
// result, close connection

function fatal($errno) {
    die(ldap_err2str($errno));
}


echo "Locating Active Directory Server\n";
require_once('Net/DNS.php');
$resolver = new Net_DNS_Resolver();
//$resolver->debug = 1;
$response = $resolver->query('_ldap._tcp.ed.ac.uk', 'SRV', 'IN');
if ($response) {
  if ($resolver->debug) {
    foreach ($response->answer as $rr) {
      //$rr->display();
      print_r($rr);
    }
  }
  $ldap_server = $response->answer[0]->target;
  $ldap_port = $response->answer[0]->port;
} else {
  die("Cannot resolve ('_ldap._tcp.ed.ac.uk', 'SRV', 'IN')");
}

This is a bit of code that uses some DNS resolving code written in PHP. I assume this is working fine as it does resolve valid domain controllers with which to perform LDAP lookups on.

Code:
echo "Connecting to $ldap_server on port $ldap_port...\n";
$ds=@ldap_connect($ldap_server, $ldap_port);  // must be a valid LDAP server!
if (@ldap_errno($ds)) fatal(@ldap_errno($ds));
echo "connect result is " . $ds . "\n";

This is the code which performs a connection to the LDAP server. $ldap_port is 389 generally and this code always returns "Resource id #25".

Code:
$username = getenv('php_ldap_user');
$password = getenv('php_ldap_password');
// functional account taken from .htaccess-specified environment variables

if ($ds) {
   echo "Binding ...\n";
   $r=@ldap_bind($ds, $username, $password);
   echo "Bind result is " . $r . "\n";
   if (@ldap_errno($ds)) fatal(@ldap_errno($ds));

This is where it binds to LDAP using a service account created in AD which has rights to search LDAP.


Code:
 $base = "dc=ed,dc=ac,dc=uk";
   if (!isset($_SERVER['REMOTE_USER'])) {
	$username = "scitest1";
   } else {
       $username = $_SERVER['REMOTE_USER'];
   }

   //$filter = "(&(cn=$username)(objectClass=organizationalPerson))";
   $onlyattrs = array("givenName","sn","targetAddress",
		"homeDirectory");

   $filter = "(cn=$username)";
   //echo "Searching for $filter ...\n";

This is where the user whose details are being looked up is passed by their web session.


Code:
$sr=ldap_search($ds, $base, $filter); // , $onlyattrs); 
   echo "Search result is " . $sr . "\n";
   if (@ldap_errno($ds)) fatal(@ldap_errno($ds));

This is where it breaks down, and I don't know why as it is syntactically correct and was working fine until the upgrade from 2000 to 2003
 
Last edited:
Fixed it! Had to add the following parameters for it to work in 2003:

Code:
// Fix for 2003 AD
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);

If you put this in right after you have successfully connected using ldap_connect() and before you specify the user account to bind, e.g.

Code:
//echo "Connecting to $ldap_server on port $ldap_port...\n";
$ds=@ldap_connect($ldap_server, $ldap_port);  // must be a valid LDAP server!
if (@ldap_errno($ds)) fatal(@ldap_errno($ds));
//echo "connect result is " . $ds . "\n";

// Fix for 2003 AD
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);

$username = getenv('php_ldap_user');
$password = getenv('php_ldap_password');
// functional account taken from .htaccess-specified environment variables

if ($ds) {
  // echo "Binding ...\n";
   $r=@ldap_bind($ds, $username, $password);
  // echo "Bind result is " . $r . "\n";
   if (@ldap_errno($ds)) fatal(@ldap_errno($ds));
 
Back
Top Bottom