[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: compare uidNumber in LDAP



Here is my php script. It is adaptable and it spins like a top
excepting the script level race condition that seems to be common to all of these scripts. Not much of a problem though. Wonder why there isn't a way to lock anything using php-ldap? Hmmm... I could actually fix this also by adding yet another attribute to the proxyuser. Then I could use that attribute as a semaphore for the uidNumber! :-) Since the operations themselves are atomic, this should work. ummm... oh. ARRGH! No it wont. You would still have to retrieve and lock as an atomic action for this to work. Drat! :-/


Anyway not bad for someone who didn't know php on Monday, eh? :-)

Adam, thanks for your help.  I appreciate it.

Jim C.
<?php
// basic sequence with LDAP is connect, bind, search, interpret search
// result, close connection
$machine=trim($argv[1]);
define(LDAPSERVER,"localhost");
define(PROXYDN,"cn=proxyuser,dc=microverse,dc=net");
define(ROOTDN,"cn=root,dc=microverse,dc=net");
define(ROOTPW,"[deleted for security]");
define(LDAPBASE,"dc=microverse,dc=net");
define(MINUID, 500);
define(MACHINEGROUP,"421");
define(NUMRETRIES, 4);

function getnewuid ($ds) {

	$booleantest=FALSE;
	
	//We get a number of retries equal to NUMRTRIES
	for($idx=0; $idx < NUMRETRIES && !$booleantest ;$idx=$idx+1 )
		{

		$entries=ldap_get_entries($ds, ldap_search($ds, PROXYDN ,"cn=*"));
		/*
		If another such script starts and finishes it's ldap_mod_replace before 
		we get ours started right here at this point, then we have a race condition
		at the script level.  This is why I've tried to condense this part as 
		much as possible.
		*/

		if($entries[0]["uidnumber"][0] < MINUID )
			$change_entry["uidnumber"] = MINUID;
			else
			$change_entry["uidnumber"] = $entries[0]["uidnumber"][0] + 1;
			
		//This, at least, is atomic.
		$booleantest=ldap_mod_replace($ds, PROXYDN, $change_entry);
		
		}

	if($booleantest)
		return $change_entry["uidnumber"];
		else 
		die("Timeout error! Unable to set uidNumber in PROXYDN.  To many users being added from other sources?\n");
		
	
	
	}//end of function getnewuid ($ds)


//echo "LDAP query test\n";
//echo "Connecting ...\n";
$ds=ldap_connect(LDAPSERVER);  // must be a valid LDAP server!
//echo "connect result is ".$ds."\n";

if ($ds) {
//echo "Binding ...";    

$r=ldap_bind($ds,ROOTDN,ROOTPW);     

//echo "Bind result is ".$r."\n";

} else die( "Unable to connect to LDAP server!\n");


$dn = "uid=$machine\$,ou=Computers,dc=microverse,dc=net";
$new_object["objectClass"][0] = "top";
$new_object["objectClass"][1] = "account";
$new_object["objectClass"][2] = "posixAccount";
$new_object["uidNumber"][0] = getnewuid($ds);
$new_object["uid"][0] = $machine;
$new_object["cn"][0] = $machine;
$new_object["gidNumber"][0] = MACHINEGROUP;
$new_object["homeDirectory"][0] = "/dev/null";
$new_object["loginShell"][0] = "/bin/false";
$new_object["gecos"][0] = "Machine Account";
$new_object["description"][0] = "Machine Account";

if(!ldap_add($ds, $dn, $new_object))
	{
	ldap_close($ds);
	die("Error! Could not add new user. Most likely someone already has that userid.\n");
	}

//echo "\nClosing connection\n";
ldap_close($ds);

?>