X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=include%2Fclass_ldap.inc;h=17ae13ff4071b267c4f606dbe63bf5e69bfc1197;hb=b21c0ebad0d51dba8d8fec81c117b1250bf48323;hp=fafa96c9765c561a0869b822dcf482b61050ac70;hpb=1023c4f367b8d2e9ff45ccae274013e28fe1a0cc;p=gosa.git diff --git a/include/class_ldap.inc b/include/class_ldap.inc index fafa96c97..17ae13ff4 100644 --- a/include/class_ldap.inc +++ b/include/class_ldap.inc @@ -1,7 +1,7 @@ + Copyright (C) 2003 Alejandro Escanero Blanco Copyright (C) 2004-2006 Cajus Pollmeier Based in code of ldap.inc of @@ -95,18 +95,18 @@ class LDAP{ { $this->hascon=false; $this->reconnect=false; - if ($this->cid= ldap_connect($this->hostname)) { - ldap_set_option($this->cid, LDAP_OPT_PROTOCOL_VERSION, 3); + if ($this->cid= @ldap_connect($this->hostname)) { + @ldap_set_option($this->cid, LDAP_OPT_PROTOCOL_VERSION, 3); if (function_exists("ldap_set_rebind_proc") && $this->follow_referral) { - ldap_set_option($this->cid, LDAP_OPT_REFERRALS, 1); - ldap_set_rebind_proc($this->cid, array(&$this, "rebind")); + @ldap_set_option($this->cid, LDAP_OPT_REFERRALS, 1); + @ldap_set_rebind_proc($this->cid, array(&$this, "rebind")); } if (function_exists("ldap_start_tls") && $this->tls){ - ldap_start_tls($this->cid); + @ldap_start_tls($this->cid); } $this->error = "No Error"; - if ($bid = ldap_bind($this->cid, $this->fix($this->binddn), $this->bindpw)) { + if ($bid = @ldap_bind($this->cid, $this->fix($this->binddn), $this->bindpw)) { $this->error = "Success"; $this->hascon=true; } else { @@ -126,7 +126,7 @@ class LDAP{ function rebind($ldap, $referral) { $credentials= $this->get_credentials($referral); - if (ldap_bind($ldap, $this->fix($credentials['ADMIN']), $credentials['PASSWORD'])) { + if (@ldap_bind($ldap, $this->fix($credentials['ADMIN']), $credentials['PASSWORD'])) { $this->error = "Success"; $this->hascon=true; $this->reconnect= true; @@ -140,21 +140,21 @@ class LDAP{ function reconnect() { if ($this->reconnect){ - ldap_unbind($this->cid); + @ldap_unbind($this->cid); $this->cid = NULL; } } function unbind() { - ldap_unbind($this->cid); + @ldap_unbind($this->cid); $this->cid = NULL; } function disconnect() { if($this->hascon){ - ldap_close($this->cid); + @ldap_close($this->cid); $this->hascon=false; } } @@ -184,8 +184,8 @@ class LDAP{ $start = microtime(); $this->clearResult(); - $this->sr = ldap_search($this->cid, $this->fix($this->basedn), $filter, $attrs); - $this->error = ldap_error($this->cid); + $this->sr = @ldap_search($this->cid, $this->fix($this->basedn), $filter, $attrs); + $this->error = @ldap_error($this->cid); $this->resetResult(); $this->hasres=true; @@ -217,8 +217,8 @@ class LDAP{ $start = microtime(); - $this->sr = ldap_list($this->cid, $this->fix($basedn), $filter,$attrs); - $this->error = ldap_error($this->cid); + $this->sr = @ldap_list($this->cid, $this->fix($basedn), $filter,$attrs); + $this->error = @ldap_error($this->cid); $this->resetResult(); $this->hasres=true; @@ -245,8 +245,8 @@ class LDAP{ if ($this->reconnect) $this->connect(); $this->clearResult(); $filter = "(objectclass=*)"; - $this->sr = ldap_read($this->cid, $this->fix($dn), $filter,$attrs); - $this->error = ldap_error($this->cid); + $this->sr = @ldap_read($this->cid, $this->fix($dn), $filter,$attrs); + $this->error = @ldap_error($this->cid); $this->resetResult(); $this->hasres=true; return($this->sr); @@ -260,10 +260,10 @@ class LDAP{ { /* Ignore zero settings */ if ($size == 0){ - ldap_set_option($this->cid, LDAP_OPT_SIZELIMIT, 10000000); + @ldap_set_option($this->cid, LDAP_OPT_SIZELIMIT, 10000000); } if($this->hascon){ - ldap_set_option($this->cid, LDAP_OPT_SIZELIMIT, $size); + @ldap_set_option($this->cid, LDAP_OPT_SIZELIMIT, $size); } else { $this->error = "Could not connect to LDAP server"; } @@ -277,16 +277,16 @@ class LDAP{ if ($this->start == 0) { $this->start = 1; - $this->re= ldap_first_entry($this->cid, $this->sr); + $this->re= @ldap_first_entry($this->cid, $this->sr); } else { - $this->re= ldap_next_entry($this->cid, $this->re); + $this->re= @ldap_next_entry($this->cid, $this->re); } if ($this->re) { - $att= ldap_get_attributes($this->cid, $this->re); - $att['dn']= trim($this->convert(ldap_get_dn($this->cid, $this->re))); + $att= @ldap_get_attributes($this->cid, $this->re); + $att['dn']= trim($this->convert(@ldap_get_dn($this->cid, $this->re))); } - $this->error = ldap_error($this->cid); + $this->error = @ldap_error($this->cid); if (!isset($att)){ $att= array(); } @@ -310,7 +310,7 @@ class LDAP{ { if($this->hasres){ $this->hasres = false; - ldap_free_result($this->sr); + @ldap_free_result($this->sr); } } @@ -325,9 +325,9 @@ class LDAP{ } else { - $rv = ldap_get_dn($this->cid, $this->re); + $rv = @ldap_get_dn($this->cid, $this->re); - $this->error = ldap_error($this->cid); + $this->error = @ldap_error($this->cid); return(trim($this->convert($rv))); } }else{ @@ -344,8 +344,8 @@ class LDAP{ { if($this->hascon){ if($this->hasres){ - $rv = ldap_count_entries($this->cid, $this->sr); - $this->error = ldap_error($this->cid); + $rv = @ldap_count_entries($this->cid, $this->sr); + $this->error = @ldap_error($this->cid); return($rv); }else{ $this->error = "Perform a Fetch with no Search"; @@ -364,8 +364,8 @@ class LDAP{ if ($dn == "") $dn = $this->basedn; - $r = ldap_mod_del($this->cid, $this->fix($dn), $attrs); - $this->error = ldap_error($this->cid); + $r = @ldap_mod_del($this->cid, $this->fix($dn), $attrs); + $this->error = @ldap_error($this->cid); return($r); }else{ $this->error = "Could not connect to LDAP server"; @@ -380,8 +380,8 @@ class LDAP{ if ($dn == "") $dn = $this->basedn; - $r = ldap_mod_replace($this->cid, $this->fix($dn), $attrs); - $this->error = ldap_error($this->cid); + $r = @ldap_mod_replace($this->cid, $this->fix($dn), $attrs); + $this->error = @ldap_error($this->cid); return($r); }else{ $this->error = "Could not connect to LDAP server"; @@ -393,8 +393,8 @@ class LDAP{ { if($this->hascon){ if ($this->reconnect) $this->connect(); - $r = ldap_delete($this->cid, $this->fix($deletedn)); - $this->error = ldap_error($this->cid); + $r = @ldap_delete($this->cid, $this->fix($deletedn)); + $this->error = @ldap_error($this->cid); return($r ? $r : 0); }else{ $this->error = "Could not connect to LDAP server"; @@ -432,8 +432,8 @@ class LDAP{ } /* Finally Delete own Node */ - $r = ldap_delete($this->cid, $this->fix($deletedn)); - $this->error = ldap_error($this->cid); + $r = @ldap_delete($this->cid, $this->fix($deletedn)); + $this->error = @ldap_error($this->cid); return($r ? $r : 0); }else{ $this->error = "Could not connect to LDAP server"; @@ -445,19 +445,19 @@ class LDAP{ */ function copy_FAI_resource_recursive($sourcedn,$destinationdn,$destinationName,$type="branch",$is_first = true,$depth=0) { - error_reporting(E_ALL); + error_reporting(E_ALL | E_STRICT); if($is_first){ - echo "

".sprintf(_("Creating copy of %s"),"".LDAP::fix($sourcedn)."")."

"; + echo "

".sprintf(_("Creating copy of %s"),"".@LDAP::fix($sourcedn)."")."

"; }else{ if(preg_match("/^ou=/",$sourcedn)){ - echo "

"._("Processing")." ".LDAP::fix($destinationdn)."

"; + echo "

"._("Processing")." ".@LDAP::fix($destinationdn)."

"; }else{ $tmp = split(",",$sourcedn); echo " "._("Object").": "; - $deststr = LDAP::fix($destinationdn); + $deststr = @LDAP::fix($destinationdn); if(strlen($deststr) > 96){ $deststr = substr($deststr,0,96)."..."; } @@ -533,7 +533,7 @@ class LDAP{ if(in_array($key ,array("FAItemplateFile","FAIscript", "gotoLogonScript", "gosaApplicationIcon","gotoMimeIcon"))){ $sr= ldap_read($this->cid, $this->fix($sourcedn), "$key=*", array($key)); $ei= ldap_first_entry($this->cid, $sr); - if ($tmp= ldap_get_values_len($this->cid, $ei,$key)){ + if ($tmp= @ldap_get_values_len($this->cid, $ei,$key)){ $attr[$key] = $tmp; } } @@ -573,7 +573,7 @@ class LDAP{ } if($this->error != "Success"){ - /* Some error occured */ + /* Some error occurred */ print "---------------------------------------------"; print $this->get_error()."
"; print $sourcedn."
"; @@ -618,8 +618,8 @@ class LDAP{ } if($this->hascon){ if ($this->reconnect) $this->connect(); - $r = ldap_modify($this->cid, $this->fix($this->basedn), $attrs); - $this->error = ldap_error($this->cid); + $r = @ldap_modify($this->cid, $this->fix($this->basedn), $attrs); + $this->error = @ldap_error($this->cid); return($r ? $r : 0); }else{ $this->error = "Could not connect to LDAP server"; @@ -631,8 +631,8 @@ class LDAP{ { if($this->hascon){ if ($this->reconnect) $this->connect(); - $r = ldap_add($this->cid, $this->fix($this->basedn), $attrs); - $this->error = ldap_error($this->cid); + $r = @ldap_add($this->cid, $this->fix($this->basedn), $attrs); + $this->error = @ldap_error($this->cid); return($r ? $r : 0); }else{ $this->error = "Could not connect to LDAP server"; @@ -642,19 +642,26 @@ class LDAP{ function create_missing_trees($target) { - /* Ignore create_missing trees if the base equals target */ - if ($target == $this->basedn){ - return; - } + global $config; $real_path= substr($target, 0, strlen($target) - strlen($this->basedn) -1 ); - $l= array_reverse(gosa_ldap_explode_dn($real_path)); + + if ($target == $this->basedn){ + $l= array("dummy"); + } else { + $l= array_reverse(gosa_ldap_explode_dn($real_path)); + } unset($l['count']); $cdn= $this->basedn; $tag= ""; + /* Load schema if available... */ + $classes= $this->get_objectclasses(); + foreach ($l as $part){ - $cdn= "$part,$cdn"; + if ($part != "dummy"){ + $cdn= "$part,$cdn"; + } /* Ignore referrals */ $found= false; @@ -685,36 +692,98 @@ class LDAP{ $param= preg_replace('/^[^=]+=([^,]+),.*$/', '\\1', $cdn); $na= array(); - switch ($type){ - case 'ou': - if ($tag != ""){ - $na["objectClass"]= array("organizationalUnit", "gosaAdministrativeUnitTag"); - $na["gosaUnitTag"]= $tag; - } else { - $na["objectClass"]= "organizationalUnit"; - } - $na["ou"]= $param; - break; - case 'dc': - if ($tag != ""){ - $na["objectClass"]= array("dcObject", "top", "locality", "gosaAdministrativeUnitTag"); - $na["gosaUnitTag"]= $tag; - } else { - $na["objectClass"]= array("dcObject", "top", "locality"); + + /* Automatic or traditional? */ + if(count($classes)){ + + /* Get name of first matching objectClass */ + $ocname= ""; + foreach($classes as $class){ + if (isset($class['MUST']) && $class['MUST'] == "$type"){ + + /* Look for first classes that is structural... */ + if (isset($class['STRUCTURAL'])){ + $ocname= $class['NAME']; + break; + } + + /* Look for classes that are auxiliary... */ + if (isset($class['AUXILIARY'])){ + $ocname= $class['NAME']; + } } - $na["dc"]= $param; - break; - default: - print_red(sprintf(_("Autocreation of type '%s' is currently not supported. Please report to the GOsa team."), $type)); + } + + /* Bail out, if we've nothing to do... */ + if ($ocname == ""){ + print_red(sprintf(_("Autocreation of subtree failed. No objectClass found for attribute '%s'."), $type)); echo $_SESSION['errors']; exit; + } + + /* Assemble_entry */ + if ($tag != ""){ + $na['objectClass']= array($ocname, "gosaAdministrativeUnitTag"); + } else { + $na['objectClass']= array($ocname); + } + if (isset($classes[$ocname]['AUXILIARY'])){ + $na['objectClass'][]= $classes[$ocname]['SUP']; + } + if ($type == "dc"){ + /* This is bad actually, but - tell me a better way? */ + $na['objectClass'][]= 'locality'; + } + $na[$type]= $param; + if (is_array($classes[$ocname]['MUST'])){ + foreach($classes[$ocname]['MUST'] as $attr){ + $na[$attr]= "filled"; + } + } + + } else { + + /* Use alternative add... */ + switch ($type){ + case 'ou': + if ($tag != ""){ + $na["objectClass"]= array("organizationalUnit", "gosaAdministrativeUnitTag"); + $na["gosaUnitTag"]= $tag; + } else { + $na["objectClass"]= "organizationalUnit"; + } + $na["ou"]= $param; + break; + case 'dc': + if ($tag != ""){ + $na["objectClass"]= array("dcObject", "top", "locality", "gosaAdministrativeUnitTag"); + $na["gosaUnitTag"]= $tag; + } else { + $na["objectClass"]= array("dcObject", "top", "locality"); + } + $na["dc"]= $param; + break; + default: + print_red(sprintf(_("Autocreation of type '%s' is currently not supported. Please report to the GOsa team."), $type)); + echo $_SESSION['errors']; + 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)){ + return FALSE; + } } } + + return TRUE; } + function recursive_remove() { $delarray= array(); @@ -738,13 +807,13 @@ class LDAP{ { $data= ""; if ($this->reconnect) $this->connect(); - $sr= ldap_read($this->cid, $this->fix($dn), "objectClass=*", array("$name")); + $sr= @ldap_read($this->cid, $this->fix($dn), "objectClass=*", array("$name")); /* fill data from LDAP */ if ($sr) { - $ei= ldap_first_entry($this->cid, $sr); + $ei= @ldap_first_entry($this->cid, $sr); if ($ei) { - if ($info= ldap_get_values_len($this->cid, $ei, "$name")){ + if ($info= @ldap_get_values_len($this->cid, $ei, "$name")){ $data= $info[0]; } @@ -763,7 +832,7 @@ class LDAP{ function get_additional_error() { $error= ""; - ldap_get_option ($this->cid, LDAP_OPT_ERROR_STRING, $error); + @ldap_get_option ($this->cid, LDAP_OPT_ERROR_STRING, $error); return ($error); } @@ -788,7 +857,7 @@ class LDAP{ $url= preg_replace('!\?\?.*$!', '', $url); $server= preg_replace('!^([^:]+://[^/]+)/.*$!', '\\1', $url); - if ($referrals == NULL){ + if ($referrals === NULL){ $referrals= $this->referrals; } @@ -859,10 +928,10 @@ class LDAP{ } /* Searching Ldap Tree */ - $sr= ldap_read($this->cid, $this->fix($dn), $filter, $name); + $sr= @ldap_read($this->cid, $this->fix($dn), $filter, $name); /* Get the first entry */ - $entry= ldap_first_entry($this->cid, $sr); + $entry= @ldap_first_entry($this->cid, $sr); /* Get all attributes related to that Objekt */ $atts = array(); @@ -874,14 +943,14 @@ class LDAP{ /* Reset index */ $i = 1 ; $identifier = array(); - $attribute= ldap_first_attribute($this->cid,$entry,$identifier); + $attribute= @ldap_first_attribute($this->cid,$entry,$identifier); while ($attribute) { $i++; $atts[$i]['name'] = $attribute; - $atts[$i]['value'] = ldap_get_values_len($this->cid, $entry, "$attribute"); + $atts[$i]['value'] = @ldap_get_values_len($this->cid, $entry, "$attribute"); /* Next one */ - $attribute= ldap_next_attribute($this->cid,$entry,$identifier); + $attribute= @ldap_next_attribute($this->cid,$entry,$identifier); } foreach($atts as $at) @@ -889,7 +958,7 @@ class LDAP{ for ($i= 0; $i<$at['value']['count']; $i++){ /* Check if we must encode the data */ - if(!preg_match('/^[a-z0-9+#.=, \/ -]+$/i', $at['value'][$i])) { + if(!preg_match('/^[a-z0-9+@#.=, \/ -]+$/i', $at['value'][$i])) { $ret .= $at['name'].":: ".base64_encode($at['value'][$i])."\n"; } else { $ret .= $at['name'].": ".$at['value'][$i]."\n"; @@ -903,7 +972,7 @@ class LDAP{ function dn_exists($dn) { - return ldap_list($this->cid, $this->fix($dn), "(objectClass=*)", array("objectClass")); + return @ldap_list($this->cid, $this->fix($dn), "(objectClass=*)", array("objectClass")); } @@ -1043,6 +1112,13 @@ class LDAP{ */ function import_single_entry($str_attr,$modify,$delete) { + global $config; + + if(!$config){ + trigger_error("Can't import ldif, can't read config object."); + } + + if($this->reconnect) $this->connect(); $ret = false; @@ -1120,7 +1196,8 @@ class LDAP{ /* Create missing trees */ $this->cd ($this->basedn); - $this->create_missing_trees($data['dn']); + $this->cd($config->current['BASE']); + $this->create_missing_trees(preg_replace("/^[^,]+,/","",$data['dn'])); $this->cd($data['dn']); $dn = $data['dn']; @@ -1184,16 +1261,28 @@ class LDAP{ function get_objectclasses() { - $objectclasses = array(); - + $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'])){ + return($objectclasses); + } + } + # Get base to look for schema - $sr = ldap_read ($this->cid, NULL, "objectClass=*", array("subschemaSubentry")); - $attr = ldap_get_entries($this->cid,$sr); + $sr = @ldap_read ($this->cid, NULL, "objectClass=*", array("subschemaSubentry")); + if(!$sr){ + $sr = @ldap_read ($this->cid, "", "objectClass=*", array("subschemaSubentry")); + } + + $attr = @ldap_get_entries($this->cid,$sr); if (!isset($attr[0]['subschemasubentry'][0])){ return array(); } - # Get list of objectclasses + /* Get list of objectclasses and fill array */ $nb= $attr[0]['subschemasubentry'][0]; $objectclasses= array(); $sr= ldap_read ($this->cid, $nb, "objectClass=*", array("objectclasses")); @@ -1202,15 +1291,74 @@ class LDAP{ return array(); } foreach ($attrs[0]['objectclasses'] as $val){ - $name= preg_replace("/^.* NAME\s+\(*\s*'([^']+)'\s*\)*.*$/", '\\1', $val); - if ($name != $val){ - $objectclasses[$name]= $val; - } + if (preg_match('/^[0-9]+$/', $val)){ + continue; + } + $name= "OID"; + $pattern= split(' ', $val); + $ocname= preg_replace("/^.* NAME\s+\(*\s*'([^']+)'\s*\)*.*$/", '\\1', $val); + $objectclasses[$ocname]= array(); + + foreach($pattern as $chunk){ + switch($chunk){ + + case '(': + $value= ""; + break; + + case ')': if ($name != ""){ + $objectclasses[$ocname][$name]= $this->value2container($value); + } + $name= ""; + $value= ""; + break; + + case 'NAME': + case 'DESC': + case 'SUP': + case 'STRUCTURAL': + case 'ABSTRACT': + case 'AUXILIARY': + case 'MUST': + case 'MAY': + if ($name != ""){ + $objectclasses[$ocname][$name]= $this->value2container($value); + } + $name= $chunk; + $value= ""; + break; + + default: $value.= $chunk." "; + } + } + } - return $objectclasses; } + + function value2container($value) + { + /* Set emtpy values to "true" only */ + if (preg_match('/^\s*$/', $value)){ + return true; + } + + /* Remove ' and " if needed */ + $value= preg_replace('/^[\'"]/', '', $value); + $value= preg_replace('/[\'"] *$/', '', $value); + + /* Convert to array if $ is inside... */ + if (preg_match('/\$/', $value)){ + $container= preg_split('/\s*\$\s*/', $value); + } else { + $container= chop($value); + } + + return ($container); + } + + function log($string) { if (isset($_SESSION['config'])){ @@ -1221,7 +1369,7 @@ class LDAP{ } } - /* added by Guido Serra aka Zeph */ + /* added by Guido Serra aka Zeph */ function getCn($dn){ $simple= split(",", $dn); @@ -1234,6 +1382,7 @@ class LDAP{ } } + function get_naming_contexts($server, $admin= "", $password= "") { /* Build LDAP connection */ @@ -1245,13 +1394,43 @@ class LDAP{ $r= ldap_bind ($ds, $admin, $password); /* Get base to look for naming contexts */ - $sr = ldap_read ($ds, "", "objectClass=*", array("namingContexts")); - $attr= ldap_get_entries($ds,$sr); - + $sr = @ldap_read ($ds, "", "objectClass=*", array("+")); + $attr= @ldap_get_entries($ds,$sr); + return ($attr[0]['namingcontexts']); } + function get_root_dse($server, $admin= "", $password= "") + { + /* Build LDAP connection */ + $ds= ldap_connect ($server); + if (!$ds) { + die ("Can't bind to LDAP. No check possible!"); + } + ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); + $r= ldap_bind ($ds, $admin, $password); + + /* Get base to look for naming contexts */ + $sr = @ldap_read ($ds, "", "objectClass=*", array("+")); + $attr= @ldap_get_entries($ds,$sr); + + /* Return empty array, if nothing was set */ + if (!isset($attr[0])){ + return array(); + } + + /* Rework array... */ + $result= array(); + for ($i= 0; $i<$attr[0]['count']; $i++){ + $result[$attr[0][$i]]= $attr[0][$attr[0][$i]]; + unset($result[$attr[0][$i]]['count']); + } + + return ($result); + } + + } // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler: