index c01428d42f2047bd6a24f022599bd885ec7f9e59..29f82e7fcd4e460a4c7f41dc04c0aa81695cb9b6 100644 (file)
class LDAP{
var $hascon =false;
- var $hasres =false;
var $reconnect=false;
var $tls = false;
- var $basedn ="";
var $cid;
+ var $hasres = array();
+ var $sr = array();
+ var $re = array();
+ var $basedn ="";
+ var $start = array(); // 0 if we are fetching the first entry, otherwise 1
var $error = ""; // Any error messages to be returned can be put here
- var $start = 0; // 0 if we are fetching the first entry, otherwise 1
+ var $srp = 0;
var $objectClasses = array(); // Information read from slapd.oc.conf
var $binddn = "";
var $bindpw = "";
var $referrals= array();
var $max_ldap_query_time = 0; // 0, empty or negative values will disable this check
- var $re = NULL;
-
function LDAP($binddn,$bindpw, $hostname, $follow_referral= FALSE, $tls= FALSE)
{
global $config;
$this->hostname=$hostname;
/* Check if MAX_LDAP_QUERY_TIME is defined */
- if(isset($config->data['MAIN']['MAX_LDAP_QUERY_TIME'])){
- $str = $config->data['MAIN']['MAX_LDAP_QUERY_TIME'];
+ if(is_object($config) && $config->get_cfg_value("ldapMaxQueryTime") != ""){
+ $str = $config->get_cfg_value("ldapMaxQueryTime");
$this->max_ldap_query_time = (float)($str);
}
}
+ function getSearchResource()
+ {
+ $this->sr[$this->srp]= NULL;
+ $this->start[$this->srp]= 0;
+ $this->hasres[$this->srp]= false;
+ return $this->srp++;
+ }
+
+
/* Function to replace all problematic characters inside a DN by \001XX, where
\001 is decoded to chr(1) [ctrl+a]. It is not impossible, but very unlikely
that this character is inside a DN.
-
+
Currently used codes:
- , => CO
- \2C => CO
- ( => OB
- ) => CB
- / => SL */
+ , => CO
+ \2C => CO
+ ( => OB
+ ) => CB
+ / => SL */
static function convert($dn)
{
if (SPECIALS_OVERRIDE == TRUE){
$tmp= preg_replace(array("/\\\\,/", "/\\\\2C/", "/\(/", "/\)/", "/\//"),
- array("\001CO", "\001CO", "\001OB", "\001CB", "\001SL"),
- $dn);
+ array("\001CO", "\001CO", "\001OB", "\001CB", "\001SL"),
+ $dn);
return (preg_replace('/,\s+/', ',', $tmp));
} else {
return ($dn);
{
if (SPECIALS_OVERRIDE == TRUE){
return (preg_replace(array("/\001CO/", "/\001OB/", "/\001CB/", "/\001SL/"),
- array("\,", "(", ")", "/"),
- $dn));
+ array("\,", "(", ")", "/"),
+ $dn));
} else {
return ($dn);
}
}
-
/* Function to fix problematic characters in DN's that are used for search
requests. I.e. member=.... */
static function prepare4filter($dn)
{
- return normalizeLdap(preg_replace('/\\\\/', '\\\\\\', LDAP::fix($dn)));
+ $fixed= normalizeLdap(str_replace('\\\\', '\\\\\\', LDAP::fix($dn)));
+ return str_replace('\\,', '\\\\,', $fixed);
}
function rebind($ldap, $referral)
{
$credentials= $this->get_credentials($referral);
- if (@ldap_bind($ldap, LDAP::fix($credentials['ADMIN']), $credentials['PASSWORD'])) {
+ if (@ldap_bind($ldap, LDAP::fix($credentials['ADMINDN']), $credentials['ADMINPASSWORD'])) {
$this->error = "Success";
$this->hascon=true;
$this->reconnect= true;
return (0);
} else {
- $this->error = "Could not bind to " . $credentials['ADMIN'];
+ $this->error = "Could not bind to " . $credentials['ADMINDN'];
return NULL;
}
}
function cd($dir)
{
- if ($dir == "..")
+ if ($dir == ".."){
$this->basedn = $this->getParentDir();
- else
+ } else {
$this->basedn = LDAP::convert($dir);
+ }
}
function getParentDir($basedn = "")
{
- if ($basedn=="")
+ if ($basedn==""){
$basedn = $this->basedn;
- else
+ } else {
$basedn = LDAP::convert($this->basedn);
+ }
return(ereg_replace("[^,]*[,]*[ ]*(.*)", "\\1", $basedn));
}
- function search($filter, $attrs= array())
+ function search($srp, $filter, $attrs= array())
{
if($this->hascon){
if ($this->reconnect) $this->connect();
$start = microtime();
- $this->clearResult();
- $this->sr = @ldap_search($this->cid, LDAP::fix($this->basedn), $filter, $attrs);
+ $this->clearResult($srp);
+ $this->sr[$srp] = @ldap_search($this->cid, LDAP::fix($this->basedn), $filter, $attrs);
$this->error = @ldap_error($this->cid);
- $this->resetResult();
- $this->hasres=true;
+ $this->resetResult($srp);
+ $this->hasres[$srp]=true;
/* Check if query took longer as specified in max_ldap_query_time */
if($this->max_ldap_query_time){
}
$this->log("LDAP operation: time=".get_MicroTimeDiff($start,microtime())." operation=search('".LDAP::fix($this->basedn)."', '$filter')");
- return($this->sr);
+ return($this->sr[$srp]);
}else{
$this->error = "Could not connect to LDAP server";
return("");
}
}
- function ls($filter = "(objectclass=*)", $basedn = "",$attrs = array("*"))
+ function ls($srp, $filter = "(objectclass=*)", $basedn = "",$attrs = array("*"))
{
if($this->hascon){
if ($this->reconnect) $this->connect();
- $this->clearResult();
+ $this->clearResult($srp);
if ($basedn == "")
$basedn = $this->basedn;
else
$basedn= LDAP::convert($basedn);
$start = microtime();
- $this->sr = @ldap_list($this->cid, LDAP::fix($basedn), $filter,$attrs);
+ $this->sr[$srp] = @ldap_list($this->cid, LDAP::fix($basedn), $filter,$attrs);
$this->error = @ldap_error($this->cid);
- $this->resetResult();
- $this->hasres=true;
+ $this->resetResult($srp);
+ $this->hasres[$srp]=true;
/* Check if query took longer as specified in max_ldap_query_time */
if($this->max_ldap_query_time){
$this->log("LDAP operation: time=".get_MicroTimeDiff($start,microtime())." operation=ls('".LDAP::fix($basedn)."', '$filter')");
- return($this->sr);
+ return($this->sr[$srp]);
}else{
$this->error = "Could not connect to LDAP server";
return("");
}
}
- function cat($dn,$attrs= array("*"))
+ function cat($srp, $dn,$attrs= array("*"))
{
if($this->hascon){
if ($this->reconnect) $this->connect();
- $this->clearResult();
+ $this->clearResult($srp);
$filter = "(objectclass=*)";
- $this->sr = @ldap_read($this->cid, LDAP::fix($dn), $filter,$attrs);
+ $this->sr[$srp] = @ldap_read($this->cid, LDAP::fix($dn), $filter,$attrs);
$this->error = @ldap_error($this->cid);
- $this->resetResult();
- $this->hasres=true;
- return($this->sr);
+ $this->resetResult($srp);
+ $this->hasres[$srp]=true;
+ return($this->sr[$srp]);
}else{
$this->error = "Could not connect to LDAP server";
return("");
}
}
+ function object_match_filter($dn,$filter)
+ {
+ if($this->hascon){
+ if ($this->reconnect) $this->connect();
+ $res = @ldap_read($this->cid, LDAP::fix($dn), $filter, array("objectClass"));
+ $rv = @ldap_count_entries($this->cid, $res);
+ return($rv);
+ }else{
+ $this->error = "Could not connect to LDAP server";
+ return(FALSE);
+ }
+ }
+
function set_size_limit($size)
{
/* Ignore zero settings */
}
}
- function fetch()
+ function fetch($srp)
{
$att= array();
if($this->hascon){
- if($this->hasres){
- if ($this->start == 0)
+ if($this->hasres[$srp]){
+ if ($this->start[$srp] == 0)
{
- if ($this->sr){
- $this->start = 1;
- $this->re= @ldap_first_entry($this->cid, $this->sr);
+ if ($this->sr[$srp]){
+ $this->start[$srp] = 1;
+ $this->re[$srp]= @ldap_first_entry($this->cid, $this->sr[$srp]);
} else {
return array();
}
} else {
- $this->re= @ldap_next_entry($this->cid, $this->re);
+ $this->re[$srp]= @ldap_next_entry($this->cid, $this->re[$srp]);
}
- if ($this->re)
+ if ($this->re[$srp])
{
- $att= @ldap_get_attributes($this->cid, $this->re);
- $att['dn']= trim(LDAP::convert(@ldap_get_dn($this->cid, $this->re)));
+ $att= @ldap_get_attributes($this->cid, $this->re[$srp]);
+ $att['dn']= trim(LDAP::convert(@ldap_get_dn($this->cid, $this->re[$srp])));
}
$this->error = @ldap_error($this->cid);
if (!isset($att)){
}
return($att);
}else{
- $this->error = "Perform a Fetch with no Search";
+ $this->error = "Perform a fetch with no search";
return("");
}
}else{
}
}
- function resetResult()
+ function resetResult($srp)
{
- $this->start = 0;
+ $this->start[$srp] = 0;
}
- function clearResult()
+ function clearResult($srp)
{
- if($this->hasres){
- $this->hasres = false;
- @ldap_free_result($this->sr);
+ if($this->hasres[$srp]){
+ $this->hasres[$srp] = false;
+ @ldap_free_result($this->sr[$srp]);
}
}
- function getDN()
+ function getDN($srp)
{
if($this->hascon){
- if($this->hasres){
+ if($this->hasres[$srp]){
- if(!$this->re)
+ if(!$this->re[$srp])
{
$this->error = "Perform a Fetch with no valid Result";
}
else
{
- $rv = @ldap_get_dn($this->cid, $this->re);
+ $rv = @ldap_get_dn($this->cid, $this->re[$srp]);
$this->error = @ldap_error($this->cid);
return(trim(LDAP::convert($rv)));
}
}
- function count()
+ function count($srp)
{
if($this->hascon){
- if($this->hasres){
- $rv = @ldap_count_entries($this->cid, $this->sr);
+ if($this->hasres[$srp]){
+ $rv = @ldap_count_entries($this->cid, $this->sr[$srp]);
$this->error = @ldap_error($this->cid);
return($rv);
}else{
}
}
+
+ /*! \brief Move the given Ldap entry from $source to $dest
+ @param String $source The source dn.
+ @param String $dest The destination dn.
+ @return Boolean TRUE on success else FALSE.
+ */
+ function rename_dn($source,$dest)
+ {
+ /* Check if source and destination are the same entry */
+ if(strtolower($source) == strtolower($dest)){
+ trigger_error("Source and destination can't be the same entry.");
+ $this->error = "Source and destination can't be the same entry.";
+ return(FALSE);
+ }
+
+ /* Check if destination entry exists */
+ if($this->dn_exists($dest)){
+ trigger_error("Destination '$dest' already exists.");
+ $this->error = "Destination '$dest' already exists.";
+ return(FALSE);
+ }
+
+ /* Extract the name and the parent part out ouf source dn.
+ e.g. cn=herbert,ou=department,dc=...
+ parent => ou=department,dc=...
+ dest_rdn => cn=herbert
+ */
+ $parent = preg_replace("/^[^,]+,/","", $dest);
+ $dest_rdn = preg_replace("/,.*$/","",$dest);
+
+ if($this->hascon){
+ if ($this->reconnect) $this->connect();
+ $r= ldap_rename($this->cid,@LDAP::fix($source), @LDAP::fix($dest_rdn),@LDAP::fix($parent),TRUE);
+ $this->error = ldap_error($this->cid);
+
+ /* Check if destination dn exists, if not the
+ server may not support this operation */
+ $r &= is_resource($this->dn_exists($dest));
+ return($r);
+ }else{
+ $this->error = "Could not connect to LDAP server";
+ return(FALSE);
+ }
+ }
+
+
/**
* Function rmdir_recursive
*
* GiveBack: True on sucessfull , 0 in error, and "" when we don't get a ldap conection
*
*/
-
- function rmdir_recursive($deletedn)
+ function rmdir_recursive($srp, $deletedn)
{
if($this->hascon){
if ($this->reconnect) $this->connect();
$delarray= array();
/* Get sorted list of dn's to delete */
- $this->ls ("(objectClass=*)",$deletedn);
- while ($this->fetch()){
- $deldn= $this->getDN();
+ $this->ls ($srp, "(objectClass=*)",$deletedn);
+ while ($this->fetch($srp)){
+ $deldn= $this->getDN($srp);
$delarray[$deldn]= strlen($deldn);
}
arsort ($delarray);
/* Really Delete ALL dn's in subtree */
foreach ($delarray as $key => $value){
- $this->rmdir_recursive($key);
+ $this->rmdir_recursive($srp, $key);
}
/* Finally Delete own Node */
}
}
- function create_missing_trees($target)
+ function create_missing_trees($srp, $target)
{
global $config;
/* Ignore referrals */
$found= false;
foreach($this->referrals as $ref){
- $base= preg_replace('!^[^:]+://[^/]+/([^?]+).*$!', '\\1', $ref['URL']);
+ $base= preg_replace('!^[^:]+://[^/]+/([^?]+).*$!', '\\1', $ref['URI']);
if ($base == $cdn){
$found= true;
break;
continue;
}
- $this->cat ($cdn);
- $attrs= $this->fetch();
+ $this->cat ($srp, $cdn);
+ $attrs= $this->fetch($srp);
/* Create missing entry? */
if (count ($attrs)){
} else {
$type= preg_replace('/^([^=]+)=.*$/', '\\1', $cdn);
- $param= preg_replace('/^[^=]+=([^,]+),.*$/', '\\1', $cdn);
+ $param= preg_replace('/^[^=]+=([^,]+).*$/', '\\1', $cdn);
$na= array();
/* Bail out, if we've nothing to do... */
if ($ocname == ""){
- msg_dialog::display(_("Internal error"), sprintf(_("Cannot automatically create subtrees with RDN '%s': no object class found"),$type), FATAL_ERROR_DIALOG);
+ msg_dialog::display(_("Internal error"), sprintf(_("Cannot automatically create subtrees with RDN '%s': no object class found!"),$type), FATAL_ERROR_DIALOG);
exit();
}
$this->cd($cdn);
$this->add($na);
- show_ldap_error($this->get_error(), sprintf(_("Creating subtree '%s' failed."),$cdn));
- if (!preg_match('/success/i', $this->error)){
+ if (!$this->success()){
+
+ print_a(array($cdn,$na));
+
+ msg_dialog::display(_("LDAP error"), msgPool::ldaperror($this->get_error(), $cdn, LDAP_ADD, get_class()));
return FALSE;
}
}
}
- function recursive_remove()
+ function recursive_remove($srp)
{
$delarray= array();
/* Get sorted list of dn's to delete */
- $this->search ("(objectClass=*)");
- while ($this->fetch()){
- $deldn= $this->getDN();
+ $this->search ($srp, "(objectClass=*)");
+ while ($this->fetch($srp)){
+ $deldn= $this->getDN($srp);
$delarray[$deldn]= strlen($deldn);
}
arsort ($delarray);
}
}
+
function get_attribute($dn, $name,$r_array=0)
{
$data= "";
}
}
}
- if($r_array==0)
- return ($data);
- else
- return ($info);
-
-
+ if($r_array==0) {
+ return ($data);
+ } else {
+ return ($info);
+ }
}
return ($error);
}
+
+ function success()
+ {
+ return (preg_match('/Success/i', $this->error));
+ }
+
+
function get_error()
{
if ($this->error == 'Success'){
if (isset($referrals[$server])){
return ($referrals[$server]);
} else {
- $ret['ADMIN']= LDAP::fix($this->binddn);
- $ret['PASSWORD']= $this->bindpw;
+ $ret['ADMINDN']= LDAP::fix($this->binddn);
+ $ret['ADMINPASSWORD']= $this->bindpw;
}
return ($ret);
}
- function gen_ldif ($dn, $filter= "(objectClass=*)", $attributes= array('*'), $recursive= TRUE)
+ function gen_ldif ($srp, $dn, $filter= "(objectClass=*)", $attributes= array('*'), $recursive= TRUE)
{
$display= "";
if ($recursive){
$this->cd($dn);
- $this->ls($filter,$dn, array('dn','objectClass'));
+ $this->ls($srp, $filter,$dn, array('dn','objectClass'));
$deps = array();
$display .= $this->gen_one_entry($dn)."\n";
- while ($attrs= $this->fetch()){
+ while ($attrs= $this->fetch($srp)){
$deps[] = $attrs['dn'];
}
foreach($deps as $dn){
- $display .= $this->gen_ldif($dn, $filter,$attributes,$recursive);
+ $display .= $this->gen_ldif($srp, $dn, $filter,$attributes,$recursive);
}
} else {
$display.= $this->gen_one_entry($dn);
}
- function gen_xls ($dn, $filter= "(objectClass=*)", $attributes= array('*'), $recursive= TRUE,$r_array=0)
+ function gen_xls ($srp, $dn, $filter= "(objectClass=*)", $attributes= array('*'), $recursive= TRUE,$r_array=0)
{
$display= array();
$this->cd($dn);
- $this->search("$filter");
+ $this->search($srp, "$filter");
$i=0;
- while ($attrs= $this->fetch()){
+ while ($attrs= $this->fetch($srp)){
$j=0;
foreach ($attributes as $at){
if JustMofify id false the destination dn will be overwritten by the new ldif.
*/
- function import_complete_ldif($str_attr,&$error,$JustModify,$DeleteOldEntries)
+ function import_complete_ldif($srp, $str_attr,$error,$JustModify,$DeleteOldEntries)
{
if($this->reconnect) $this->connect();
}
/* If we can't Import, return with a file error */
- if(!$this->import_single_entry($single,$usemodify,$usermdir) ) {
+ if(!$this->import_single_entry($srp, $single,$usemodify,$usermdir) ) {
$error= sprintf(_("Error while importing dn: '%s', please check your LDIF from line %s on!"), $line,
$current_line);
return UNKNOWN_TOKEN_IN_LDIF_FILE; }
if $modify is true; All variables that are not touched by the new ldif will be kept.
if $modify is false; The new ldif overwrites the old entry, and all untouched attributes get lost.
*/
- function import_single_entry($str_attr,$modify,$delete)
+ function import_single_entry($srp, $str_attr,$modify,$delete)
{
global $config;
/* Delete existing entry */
if($delete){
- $this->rmdir_recursive($data['dn']);
+ $this->rmdir_recursive($srp, $data['dn']);
}
/* Create missing trees */
$this->cd ($this->basedn);
$this->cd($config->current['BASE']);
- $this->create_missing_trees(preg_replace("/^[^,]+,/","",$data['dn']));
+ $this->create_missing_trees($srp, preg_replace("/^[^,]+,/","",$data['dn']));
$this->cd($data['dn']);
$dn = $data['dn'];
if(!$modify){
- $this->cat($dn);
- if($this->count()){
+ $this->cat($srp, $dn);
+ if($this->count($srp)){
/* The destination entry exists, overwrite it with the new entry */
- $attrs = $this->fetch();
+ $attrs = $this->fetch($srp);
foreach($attrs as $name => $value ){
if(!is_numeric($name)){
if(in_array($name,array("dn","count"))) continue;
$ret = $this->modify($data);
}
}
- show_ldap_error($this->get_error(), sprintf(_("Ldap import with dn '%s' failed."),$dn));
+
+ if (!$this->success()){
+ msg_dialog::display(_("LDAP error"), msgPool::ldaperror($this->get_error(), $dn, "", get_class()));
+ }
+
return($ret);
}
}
- function get_objectclasses()
+ function get_objectclasses( $force_reload = FALSE)
{
$objectclasses = array();
global $config;
/* Only read schema if it is allowed */
if(isset($config) && preg_match("/config/i",get_class($config))){
- if(!isset($config->data['MAIN']['SCHEMA_CHECK']) || !preg_match("/true/i",$config->data['MAIN']['SCHEMA_CHECK'])){
+ if ($config->get_cfg_value("schemaCheck") != "true"){
return($objectclasses);
}
}
/* Return the cached results. */
- if(class_available('session') && session::is_set("LDAP_CACHE::get_objectclasses")){
- $objectclasses = session::get("LDAP_CACHE::get_objectclasses");
+ if(class_available('session') && session::global_is_set("LDAP_CACHE::get_objectclasses") && !$force_reload){
+ $objectclasses = session::global_get("LDAP_CACHE::get_objectclasses");
return($objectclasses);
}
# Get base to look for schema
- $sr = @ldap_read ($this->cid, NULL, "objectClass=*", array("subschemaSubentry"));
- if(!$sr){
- $sr = @ldap_read ($this->cid, "", "objectClass=*", array("subschemaSubentry"));
- }
-
+ $sr = @ldap_read ($this->cid, "", "objectClass=*", array("subschemaSubentry"));
$attr = @ldap_get_entries($this->cid,$sr);
if (!isset($attr[0]['subschemasubentry'][0])){
return array();
}
if(class_available("session")){
- session::set("LDAP_CACHE::get_objectclasses",$objectclasses);
+ session::global_set("LDAP_CACHE::get_objectclasses",$objectclasses);
}
+
return $objectclasses;
}
function log($string)
{
- if (session::is_set('config')){
- $cfg = session::get('config');
+ if (session::global_is_set('config')){
+ $cfg = session::global_get('config');
if (isset($cfg->current['LDAPSTATS']) && preg_match('/true/i', $cfg->current['LDAPSTATS'])){
syslog (LOG_INFO, $string);
}