3

I've written a little monitoring script in PHP, which should monitor a virtual directory and it's active directories. Everything works fine but when the virtual directory service freezes is my ldap_connect() not able to connect but also doesn't get an error back. So my whole script stands still. I think that the ldap_connect function gets a timeout back (like when you try to ping an IP and it's not reachable).

That's my connect command:

$connection = ldap_connect($hostname, $port) or die("Could not connect to {$hostname});

And I haven't found something in the manual for ldap_connect() (manual) about a timelimit parameter in which you could define how long the function should try to connect until it aborts.

How ever I wasn't quite able to come up with a solution with try and catch or something like this. I also didn't wanted to use the set_time_limit() function because my script needs to be run until the end.

I appreciate every help :) Thanks and greetings Tim

TehQuila
  • 628
  • 1
  • 8
  • 19

4 Answers4

5

http://www.php.net/manual/en/function.ldap-set-option.php

particular the following options :-

LDAP_OPT_NETWORK_TIMEOUT
LDAP_OPT_TIMELIMIT
ajreal
  • 46,720
  • 11
  • 89
  • 119
  • but is the exception also thrown when ldap_connect() ends in a timeout? I didn't see anything in the exception handling manual where it says that a timeout or something like that throws an exception. So i thought it wouldn't. – TehQuila Dec 07 '11 at 12:52
  • I've debugged a little more and found out that my ldap_bind() function is running into a timeout. I've tried your idea with ldap_set_option() (with LDAP_OPT_NETWORK_TIMEOUT and LDAP_OPT_TIMELIMIT) but somehow it still times out... I even tried it before and after my bind call... but maybe I did something wrong I didn't find any examples with these two options... – TehQuila Dec 07 '11 at 16:01
  • I think the set timeout can only be set when the connection established, whilst in your case, you always unable to connect, this become sort of deadlock, need to revise again – ajreal Dec 07 '11 at 16:05
  • Well i checked again and the connection is established (with ldap_connect) and I found out, that the LDAP_OPT_NETWORK_TIMEOUT option didn't work because of my php version... I've to check wether I can update it... but thank you very much for the help :) – TehQuila Dec 07 '11 at 18:05
  • i did the update and tested it once again with the option NETWORK_TIMEOUT and it worked perfectly (running into a php error which says that he couldn't bind that ldap_server) thank you very much – TehQuila Dec 14 '11 at 14:05
  • ldap_connect does not make the connection and has no timeout related to it. You're thinking of ldap_bind which is when the connection is established. Try commenting out line 2 here with an unavailable LDAP server and you'll see: $ldap = ldap_connect('server.string.com'); $test = ldap_bind($ldap, 'uid=ldap_user,cn=users,cn=accounts,dc=test,dc=test', 'userpw'); – akahunahi Jan 23 '15 at 04:27
0

If you don't want your PHP program to wait XXX seconds before giving up in a case when one of your corporate DC's have failed,
and since ldap_connect() does not have a mechanism to timeout on a user specified time,

this is my workaround which shows excellent practical results.

function serviceping($host, $port=389, $timeout=1)
{
   $op = fsockopen($host, $port, $errno, $errstr, $timeout);
   if (!$op) return 0; //DC is N/A
   else {
      fclose($op); //explicitly close open socket connection
      return 1; //DC is up & running, we can safely connect with ldap_connect
   }
}

// ##### STATIC DC LIST, if your DNS round robin is not setup
//$dclist = array('10.111.222.111', '10.111.222.100', '10.111.222.200');

// ##### DYNAMIC DC LIST, reverse DNS lookup sorted by round-robin result
$dclist = gethostbynamel('domain.name');

foreach ($dclist as $k => $dc) if (serviceping($dc) == true) break; else $dc = 0;
//after this loop, either there will be at least one DC which is available at present, or $dc would return bool false while the next line stops program from further execution

if (!$dc) exit("NO DOMAIN CONTROLLERS AVAILABLE AT PRESENT, PLEASE TRY AGAIN LATER!"); //user being notified


//now, ldap_connect would certainly connect succesfully to DC tested previously and no timeout will occur
$ldapconn = ldap_connect($dc) or die("DC N/A, PLEASE TRY AGAIN LATER.");

Also with this approach, you get a real nice fail over functionality.

Take for an example a company with a dozen of DC-a distributed along distant places.

This way your PHP program will always have high availability if at least one DC is active at present.

  • This is cool, but if the server never responds on the host and port then the connection hangs and we never hear back. This could happen, for example, if the server is under DoS. – Charlie Schliesser Oct 08 '14 at 20:03
  • 2
    ldap_connect doesn't actually connect to ldap it just prepares the connection. The timeout is an ini setting and it happens when calling another ldap method, typically ldap_bind() – akahunahi Jan 23 '15 at 04:22
0

http://www.php.net/manual/en/function.ldap-set-option.php

try set LDAP_OPT_REFERRALS in 0

Paawaaa
  • 9
  • 1
-1

You'll need to use an API that supports time-outs. Connection time-outs are not supported in a native fashion by LDAP (the protocol). The timelimit is a client-requested parameter that refers to how long the directory will spend processing a search request, and is not the same as a "connect time-out".

Terry Gardner
  • 10,957
  • 2
  • 28
  • 38