X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;ds=sidebyside;f=include%2Fclass_ldap.inc;h=126aabbad27a562be5207cd82998a291f78e8399;hb=fc44dae33071cec905b366610a5468809b09977b;hp=494b1da9bdad8f4f10098dd5d68d2a7479fee269;hpb=ab934d9be3708301031548a94528fb9479fd5d7c;p=gosa.git diff --git a/include/class_ldap.inc b/include/class_ldap.inc index 494b1da9b..126aabbad 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 @@ -197,6 +197,7 @@ class LDAP{ } } + $this->log("LDAP operation: time=".get_MicroTimeDiff($start,microtime())." operation=search('".$this->fix($this->basedn)."', '$filter')"); return($this->sr); }else{ $this->error = "Could not connect to LDAP server"; @@ -229,6 +230,8 @@ class LDAP{ } } + $this->log("LDAP operation: time=".get_MicroTimeDiff($start,microtime())." operation=ls('".$this->fix($basedn)."', '$filter')"); + return($this->sr); }else{ $this->error = "Could not connect to LDAP server"; @@ -281,7 +284,7 @@ class LDAP{ if ($this->re) { $att= @ldap_get_attributes($this->cid, $this->re); - $att['dn']= $this->convert(@ldap_get_dn($this->cid, $this->re)); + $att['dn']= trim($this->convert(@ldap_get_dn($this->cid, $this->re))); } $this->error = @ldap_error($this->cid); if (!isset($att)){ @@ -325,7 +328,7 @@ class LDAP{ $rv = @ldap_get_dn($this->cid, $this->re); $this->error = @ldap_error($this->cid); - return($this->convert($rv)); + return(trim($this->convert($rv))); } }else{ $this->error = "Perform a Fetch with no Search"; @@ -527,7 +530,7 @@ class LDAP{ /* If this is no department */ foreach($attr as $key => $value){ - if(in_array($key ,array("FAItemplateFile","FAIscript", "gotoLogonScript", "gosaApplicationIcon"))){ + 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)){ @@ -545,7 +548,8 @@ class LDAP{ unset($attr['count']); unset($attr['dn']); - if(!in_array("gosaApplication" , $attr['objectClass'])){ + if((!in_array("gosaApplication" , $attr['objectClass'])) && (!in_array("gotoMimeType", $attr['objectClass']))){ + $attr['FAIdebianRelease'] = $destinationName; if($type=="branch"){ $attr['FAIstate'] ="branch"; }elseif($type=="freeze"){ @@ -580,6 +584,8 @@ class LDAP{ } } + echo "" ; + $this->ls ("(objectClass=*)",$sourcedn); while ($this->fetch()){ $deldn= $this->getDN(); @@ -636,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(ldap_explode_dn($real_path,0)); + + 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; @@ -679,36 +692,97 @@ 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(); @@ -823,7 +897,7 @@ class LDAP{ function gen_xls ($dn, $filter= "(objectClass=*)", $attributes= array('*'), $recursive= TRUE,$r_array=0) { - $display= ""; + $display= array(); $this->cd($dn); $this->search("$filter"); @@ -902,7 +976,14 @@ class LDAP{ - function import_complete_ldif($str_attr,&$error,$overwrite,$cleanup) + /* This funktion imports ldifs + + If DeleteOldEntries is true, the destination entry will be deleted first. + If JustModify is true the destination entry will only be touched by the attributes specified in the ldif. + if JustMofify id false the destination dn will be overwritten by the new ldif. + */ + + function import_complete_ldif($str_attr,&$error,$JustModify,$DeleteOldEntries) { if($this->reconnect) $this->connect(); @@ -914,8 +995,21 @@ class LDAP{ $cnt = 0; $current_line = 0; + /* FIX ldif */ + $last = ""; + $tmp = ""; + $i = 0; + foreach($entries as $entry){ + if(preg_match("/^ /",$entry)){ + $tmp[$i] .= trim($entry); + }else{ + $i ++; + $tmp[$i] = trim($entry); + } + } + /* Every single line ... */ - foreach($entries as $entry) { + foreach($tmp as $entry) { $current_line ++; /* Removing Spaces to .. @@ -965,7 +1059,7 @@ class LDAP{ $ndn = split("#", $lineone[0]); $line = base64_decode($ndn[1]); - $dnn = split (":",$line); + $dnn = split (":",$line,2); $current_line = $ndn[0]; $dn = $dnn[0]; $value = $dnn[1]; @@ -982,18 +1076,18 @@ class LDAP{ /* Delete before insert */ $usermdir= false; - /* The dn address already exists! */ - if (($this->dn_exists($value))&&((!$overwrite)&&(!$cleanup))) { + /* The dn address already exists, Don't delete destination entry, overwrite it */ + if (($this->dn_exists($value))&&((!$JustModify)&&(!$DeleteOldEntries))) { - $error= sprintf(_("The dn: '%s' (from line %s) already exists in the LDAP database."), $line, $current_line); - return ALREADY_EXISTING_ENTRY; + $usermdir = $usemodify = false; - } elseif(($this->dn_exists($value))&&($cleanup)){ + /* Delete old entry first, then add new */ + } elseif(($this->dn_exists($value))&&($DeleteOldEntries)){ /* Delete first, then add */ $usermdir = true; - } elseif(($this->dn_exists($value))&&($overwrite)) { + } elseif(($this->dn_exists($value))&&($JustModify)) { /* Modify instead of Add */ $usemodify = true; @@ -1010,7 +1104,11 @@ class LDAP{ } - /* Imports a single entry */ + /* Imports a single entry + If $delete is true; The old entry will be deleted if it exists. + 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) { if($this->reconnect) $this->connect(); @@ -1034,9 +1132,17 @@ class LDAP{ } /* Split the line into attribute and value */ - $attr = split(":", $row); + $attr = split(":", $row,2); $attr[0]= trim($attr[0]); /* attribute */ - $attr[1]= trim($attr[1]); /* value */ + $attr[1]= $attr[1]; /* value */ + + /* Check :: was used to indicate base64_encoded strings */ + if($attr[1][0] == ":"){ + $attr[1]=trim(preg_replace("/^:/","",$attr[1])); + $attr[1]=base64_decode($attr[1]); + } + + $attr[1] = trim($attr[1]); /* Check for attributes that are used more than once */ if(!isset($data[$attr[0]])) { @@ -1061,6 +1167,17 @@ class LDAP{ /* If dn is an index of data, we should try to insert the data */ if(isset($data['dn'])) { + + /* Fix dn */ + $tmp = gosa_ldap_explode_dn($data['dn']); + unset($tmp['count']); + $newdn =""; + foreach($tmp as $tm){ + $newdn.= trim($tm).","; + } + $newdn = preg_replace("/,$/","",$newdn); + $data['dn'] = $newdn; + /* Creating Entry */ $this->cd($data['dn']); @@ -1068,19 +1185,45 @@ class LDAP{ if($delete){ $this->rmdir_recursive($data['dn']); } - + /* Create missing trees */ + $this->cd ($this->basedn); $this->create_missing_trees($data['dn']); + $this->cd($data['dn']); + + $dn = $data['dn']; unset($data['dn']); - /* If entry exists use modify */ if(!$modify){ - $ret = $this->add($data); + + $this->cat($dn); + if($this->count()){ + + /* The destination entry exists, overwrite it with the new entry */ + $attrs = $this->fetch(); + foreach($attrs as $name => $value ){ + if(!is_numeric($name)){ + if(in_array($name,array("dn","count"))) continue; + if(!isset($data[$name])){ + $data[$name] = array(); + } + } + } + $ret = $this->modify($data); + + }else{ + + /* The destination entry doesn't exists, create it */ + $ret = $this->add($data); + } + } else { + + /* Keep all vars that aren't touched by this ldif */ $ret = $this->modify($data); } } - show_ldap_error($this->get_error(),_("Ldap import failed")); + show_ldap_error($this->get_error(), sprintf(_("Ldap import with dn '%s' failed."),$dn)); return($ret); } @@ -1109,16 +1252,20 @@ class LDAP{ function get_objectclasses() { - $objectclasses = array(); + $objectclasses = array(); # 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")); + } + $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")); @@ -1127,15 +1274,146 @@ 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'])){ + $cfg= $_SESSION['config']; + if (isset($cfg->current['LDAPSTATS']) && preg_match('/true/i', $cfg->current['LDAPSTATS'])){ + syslog (LOG_INFO, $string); + } + } + } + + /* added by Guido Serra aka Zeph */ + function getCn($dn){ + $simple= split(",", $dn); + + foreach($simple as $piece) { + $partial= split("=", $piece); + + if($partial[0] == "cn"){ + return $partial[1]; + } + } + } + + + function get_naming_contexts($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 ($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: