diff --git a/include/class_ldap.inc b/include/class_ldap.inc
index 8d4d06aef576e62556a9818eb963a9dfb0db83dc..0e1e909b5282c3e4e6ae12e96847863947321076 100644 (file)
--- a/include/class_ldap.inc
+++ b/include/class_ldap.inc
/*****************************************************************************
newldap.inc - version 1.0
Copyright (C) 2003 Alejandro Escanero Blanco <alex@ofmin.com>
- Copyright (C) 2004 Cajus Pollmeier <pollmeier@gonicus.de>
+ Copyright (C) 2004-2006 Cajus Pollmeier <pollmeier@gonicus.de>
Based in code of ldap.inc of
Copyright (C) 1998 Eric Kilfoil <eric@ipass.net>
define("UNKNOWN_TOKEN_IN_LDIF_FILE",-10002);
define("NO_FILE_UPLOADED",10003);
define("INSERT_OK",10000);
-define("COLON_OVERRIDE", TRUE);
+define("SPECIALS_OVERRIDE", TRUE);
class LDAP{
var $hostname = "";
var $follow_referral = FALSE;
var $referrals= array();
+ var $max_ldap_query_time = 0; // 0, empty or negative values will disable this check
function LDAP($binddn,$bindpw, $hostname, $follow_referral= FALSE, $tls= FALSE)
{
+ global $config;
$this->follow_referral= $follow_referral;
$this->tls=$tls;
$this->binddn=$this->convert($binddn);
$this->bindpw=$bindpw;
$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'];
+ $this->max_ldap_query_time = (float)($str);
+ }
+
$this->connect();
}
+ /* 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
+ \22 => TO
+ \" => TO
+ \+ => PL
+ ( => OB
+ ) => CB
+ / => SL */
function convert($dn)
{
- if (COLON_OVERRIDE == TRUE){
- $res= preg_replace("/\\\\,/", '###GOSAREPLACED###', $dn);
- $res= preg_replace("/\\\\2C/", '###GOSAREPLACED###', $res);
- #if ($dn != $res){
- # echo "Conversation from '$dn' to '$res'<br>";
- #}
- return ($res);
+ if (SPECIALS_OVERRIDE == TRUE){
+ $tmp= preg_replace(array("/\\\\,/", "/\\\\2C/", "/\(/", "/\)/", "/\//", "/\\\\22/", '/\\\\"/', "/\\\\3D/", "/\\\\2B/", '/\\\\+/'),
+ array("\001CO", "\001CO", "\001OB", "\001CB", "\001SL", "\001TO", "\001TO", "\001GL", "\001PL", "\001PL"),
+ $dn);
+ return (preg_replace('/,\s+/', ',', $tmp));
} else {
return ($dn);
}
}
+ /* Function to fix all problematic characters inside a DN by replacing \001XX
+ codes to their original values. See "convert" for mor information.
+ ',' characters are always expanded to \, (not \2C), since all tested LDAP
+ servers seem to take it the correct way. */
function fix($dn)
{
- if (COLON_OVERRIDE == TRUE){
- $res= preg_replace("/###GOSAREPLACED###/", '\,', $dn);
- #if ($dn != $res){
- # echo "Fix from '$dn' to '$res'<br>";
- #}
- return ($res);
+ if (SPECIALS_OVERRIDE == TRUE){
+ return (preg_replace(array("/\001CO/", "/\001OB/", "/\001CB/", "/\001SL/", "/\001TO/", "/\001PL/", "/\001GL/"),
+ array("\,", "(", ")", "/", '\"', "\+", "="),
+ $dn));
} else {
return ($dn);
}
}
+ /* Function to fix problematic characters in DN's that are used for search
+ requests. I.e. member=.... */
+ function prepare4filter($dn)
+ {
+ return normalizeLdap(preg_replace('/\\\\/', '\\\\\\', @LDAP::fix($dn)));
+ }
+
+
function connect()
{
$this->hascon=false;
if ($basedn=="")
$basedn = $this->basedn;
else
- $basedn = $this-convert($this->basedn);
+ $basedn = $this->convert($this->basedn);
return(ereg_replace("[^,]*[,]*[ ]*(.*)", "\\1", $basedn));
}
function search($filter, $attrs= array())
{
- $start = microtime();
-
if($this->hascon){
if ($this->reconnect) $this->connect();
+
+ $start = microtime();
+
$this->clearResult();
$this->sr = @ldap_search($this->cid, $this->fix($this->basedn), $filter, $attrs);
$this->error = @ldap_error($this->cid);
$this->resetResult();
$this->hasres=true;
-
- /* Time management */
- $r = split(" ",$start);
- $ms = $r[0];
- $s= $r[1];
-
- $re = split(" ",microtime());
- $mse = $re[0];
- $se= $re[1];
-
- $add = 0;
- if(($mse -$ms)<0){
- $se --;
- $add = 1;
- }
- $secs = ($se -$s);
- $msecs = (int)(($add+($mse -$ms))*1000);
- $time = $secs +($msecs/1000);
- if($time > .2){
- $Sattrs = "";
- foreach($attrs as $att){
- $Sattrs .= " ".$att;
+
+ /* Check if query took longer as specified in max_ldap_query_time */
+ if($this->max_ldap_query_time){
+ $diff = get_MicroTimeDiff($start,microtime());
+ if($diff > $this->max_ldap_query_time){
+ print_red(sprintf(_("The LDAP server is slow (%.2fs for the last query). This may be responsible for performance breakdowns."),$diff)) ;
}
- print_red(sprintf(_("Ldap search took about %s seconds, used filter '%s' with following attributes '%s '. Please check for performance improvements."),$time,htmlentities($filter),$Sattrs));
}
+
+ $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";
$basedn = $this->basedn;
else
$basedn= $this->convert($basedn);
+
+ $start = microtime();
+
$this->sr = @ldap_list($this->cid, $this->fix($basedn), $filter,$attrs);
$this->error = @ldap_error($this->cid);
$this->resetResult();
$this->hasres=true;
+
+ /* Check if query took longer as specified in max_ldap_query_time */
+ if($this->max_ldap_query_time){
+ $diff = get_MicroTimeDiff($start,microtime());
+ if($diff > $this->max_ldap_query_time){
+ print_red(sprintf(_("The ldapserver is answering very slow (%.2f), this may be responsible for performance breakdowns."),$diff)) ;
+ }
+ }
+
+ $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";
}
}
- function cat($dn)
+ function cat($dn,$attrs= array("*"))
{
if($this->hascon){
if ($this->reconnect) $this->connect();
+ $start = microtime();
$this->clearResult();
$filter = "(objectclass=*)";
- $this->sr = @ldap_read($this->cid, $this->fix($dn), $filter);
+ $this->sr = @ldap_read($this->cid, $this->fix($dn), $filter,$attrs);
$this->error = @ldap_error($this->cid);
$this->resetResult();
$this->hasres=true;
+ $this->log("LDAP operation: time=".get_MicroTimeDiff($start,microtime())." operation=cat('".$this->fix($dn)."')");
return($this->sr);
}else{
$this->error = "Could not connect to LDAP server";
function fetch()
{
+ $att= array();
if($this->hascon){
if($this->hasres){
if ($this->start == 0)
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)){
$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";
{
if($this->hascon){
if ($this->reconnect) $this->connect();
+ $start= microtime();
$r = @ldap_delete($this->cid, $this->fix($deletedn));
$this->error = @ldap_error($this->cid);
+ $this->log("LDAP operation: time=".get_MicroTimeDiff($start,microtime())." operation=delete('".$this->fix($deletedn)."')");
return($r ? $r : 0);
}else{
$this->error = "Could not connect to LDAP server";
}
/* Copy given attributes and sub-dns with attributes to destination dn
-
*/
- function copy_FAI_resource_recursive($sourcedn,$destinationdn,$type="branch",$is_first = false)
+ function copy_FAI_resource_recursive($sourcedn,$destinationdn,$destinationName,$type="branch",$is_first = true,$depth=0)
{
error_reporting(E_ALL);
+
+ if($is_first){
+ echo "<h2>".sprintf(_("Creating copy of %s"),"<i>".@LDAP::fix($sourcedn)."</i>")."</h2>";
+ }else{
+ if(preg_match("/^ou=/",$sourcedn)){
+ echo "<h3>"._("Processing")." <i>".@LDAP::fix($destinationdn)."</i></h3>";
+ }else{
+ $tmp = split(",",$sourcedn);
+
+ echo " <b>"._("Object").":</b> ";
+
+ $deststr = @LDAP::fix($destinationdn);
+ if(strlen($deststr) > 96){
+ $deststr = substr($deststr,0,96)."...";
+ }
+
+ echo $deststr."<br>";
+ }
+ }
+
+ flush();
+
if($this->hascon){
if ($this->reconnect) $this->connect();
/* Save base dn */
$basedn= $this->basedn;
$delarray= array();
-
+
/* Check if destination entry already exists */
- if($this->count($this->fetch($this->cat($destinationdn)))){
+ $this->cat($destinationdn);
+
+ if($this->count()){
return;
}else{
+
+ $this->clearResult();
- /* Get source entrie */
+ /* Get source entry */
$this->cd($basedn);
- $attr = $this->fetch($this->cat($sourcedn));
+ $this->cat($sourcedn);
+ $attr = $this->fetch();
+ /* Error while fetching object / attribute abort*/
+ if((!$attr) || (count($attr)) ==0) {
+ echo _("Error while fetching source dn - aborted!");
+ return;
+ }
+
/* check if this is a department */
if(in_array("organizationalUnit",$attr['objectClass'])){
$attr['dn'] = $this->convert($destinationdn);
/* If is first entry, append FAIbranch to department entry */
if($is_first){
- $attr= $this->fetch($this->cat($destinationdn));
+ $this->cat($destinationdn);
+ $attr= $this->fetch();
/* Filter unneeded informations */
foreach($attr as $key => $value){
if(is_numeric($key)) unset($attr[$key]);
- if(isset($attr[$key]['count'])){
- if(($attr[$key]['count']==1)&&($key!="objectClass")){
- $attr[$key] = $attr[$key][0];
- }
- }
-
if(isset($attr[$key]['count'])){
if(is_array($attr[$key])){
unset($attr[$key]['count']);
}
}
}
+
unset($attr['count']);
unset($attr['dn']);
/* Add this entry */
$this->modify($attr);
}
-
}else{
- /* If this is no department */
+
+ /* If this is no department */
foreach($attr as $key => $value){
- if(is_numeric($key)) unset($attr[$key]);
- if(isset($attr[$key]['count'])){
- if(($attr[$key]['count']==1)&&($key!="objectClass")){
- $attr[$key] = $attr[$key][0];
+ if(in_array($key ,array("FAItemplateFile","FAIscript", "gotoLogonScript", "gosaApplicationIcon"))){
+ $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)){
+ $attr[$key] = $tmp;
}
}
+
+ if(is_numeric($key)) unset($attr[$key]);
if(isset($attr[$key]['count'])){
if(is_array($attr[$key])){
unset($attr[$key]['count']);
}
unset($attr['count']);
unset($attr['dn']);
-
- if($type=="branch"){
- $attr['FAIstate'] ="branch";
- }elseif($type=="freeze"){
- $attr['FAIstate'] ="freeze";
- }else{
- print_red(_("Unknown FAIstate %s"),$type);
+
+ if(!in_array("gosaApplication" , $attr['objectClass'])){
+ if($type=="branch"){
+ $attr['FAIstate'] ="branch";
+ }elseif($type=="freeze"){
+ $attr['FAIstate'] ="freeze";
+ }else{
+ print_red(_("Unknown FAIstate %s"),$type);
+ }
+ }elseif(in_array("gosaApplication",$attr['objectClass'])){
+ if(!in_array("FAIobject",$attr['objectClass'])){
+ $attr['objectClass'][] = "FAIobject";
+ }
+ $attr['FAIstate'] = $type;
}
-
+
+ /* Replace FAIdebianRelease with new release name */
+ if(in_array("FAIpackageList" , $attr['objectClass'])){
+ $attr['FAIdebianRelease'] = $destinationName;
+ if($type=="branch"){
+ $attr['FAIstate'] ="branch";
+ }elseif($type=="freeze"){
+ $attr['FAIstate'] ="freeze";
+ }else{
+ print_red(_("Unknown FAIstate %s"),$type);
+ }
+ }
+
/* Add entry */
$this->cd($destinationdn);
- $a = $this->fetch($this->cat($destinationdn));
+ $this->cat($destinationdn);
+ $a = $this->fetch();
if(!count($a)){
$this->add($attr);
}
if($this->error != "Success"){
- /* Some error occured */
+ /* Some error occurred */
print "---------------------------------------------";
print $this->get_error()."<br>";
print $sourcedn."<br>";
}
}
+ echo "<script language=\"javascript\" type=\"text/javascript\">scrollDown2();</script>" ;
+
$this->ls ("(objectClass=*)",$sourcedn);
while ($this->fetch()){
$deldn= $this->getDN();
asort ($delarray);
reset ($delarray);
+ $depth ++;
foreach($delarray as $dn => $bla){
if($dn != $destinationdn){
$this->cd($basedn);
$item = $this->fetch($this->cat($dn));
if(!in_array("FAIbranch",$item['objectClass'])){
- $this->copy_FAI_resource_recursive($dn,str_replace($sourcedn,$destinationdn,$dn),$type);
+ $this->copy_FAI_resource_recursive($dn,str_replace($sourcedn,$destinationdn,$dn),$destinationName,$type,false,$depth);
}
}
}
}
+ if($is_first){
+ echo "<p class='seperator'> </p>";
+ }
+
}
function modify($attrs)
{
+ if(count($attrs) == 0){
+ return (0);
+ }
if($this->hascon){
if ($this->reconnect) $this->connect();
+ $start= microtime();
$r = @ldap_modify($this->cid, $this->fix($this->basedn), $attrs);
$this->error = @ldap_error($this->cid);
+ $this->log("LDAP operation: time=".get_MicroTimeDiff($start,microtime())." operation=modify('$this->basedn')");
return($r ? $r : 0);
}else{
$this->error = "Could not connect to LDAP server";
{
if($this->hascon){
if ($this->reconnect) $this->connect();
+ $start= microtime();
$r = @ldap_add($this->cid, $this->fix($this->basedn), $attrs);
$this->error = @ldap_error($this->cid);
+ $this->log("LDAP operation: time=".get_MicroTimeDiff($start,microtime())." operation=add('$this->basedn')");
return($r ? $r : 0);
}else{
$this->error = "Could not connect to LDAP server";
}
}
+
function create_missing_trees($target)
+ {
+ global $config;
+
+ $real_path= substr($target, 0, strlen($target) - strlen($this->basedn) -1 );
+
+ 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){
+ if ($part != "dummy"){
+ $cdn= "$part,$cdn";
+ }
+
+ /* Ignore referrals */
+ $found= false;
+ foreach($this->referrals as $ref){
+ $base= preg_replace('!^[^:]+://[^/]+/([^?]+).*$!', '\\1', $ref['URL']);
+ if ($base == $cdn){
+ $found= true;
+ break;
+ }
+ }
+ if ($found){
+ continue;
+ }
+
+ $this->cat ($cdn);
+ $attrs= $this->fetch();
+
+ /* Create missing entry? */
+ if (count ($attrs)){
+ /* Catch the tag - if present */
+ if (isset($attrs['gosaUnitTag'][0])){
+ $tag= $attrs['gosaUnitTag'][0];
+ }
+
+ } else {
+ $type= preg_replace('/^([^=]+)=.*$/', '\\1', $cdn);
+ $param= preg_replace('/^[^=]+=([^,]+),.*$/', '\\1', $cdn);
+
+ $na= array();
+
+ /* 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'];
+ }
+ }
+ }
+
+ /* 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");
+ $na["gosaUnitTag"]= $tag;
+ } 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 create_missing_trees_old($target)
{
/* Ignore create_missing trees if the base equals target */
if ($target == $this->basedn){
return;
}
- $l= array_reverse(explode(",", preg_replace("/,".$this->basedn."/", "", $target)));
+
+ $real_path= substr($target, 0, strlen($target) - strlen($this->basedn) -1 );
+ $tmp = ldap_explode_dn($real_path,0);
+ if(!$tmp){
+ print_red(sprintf(_("The referral url '%s' is missing the ldap base. It should look like this 'ldap://server:port/base'."),$this->fix($this->basedn)));
+ return;
+ }
+
+ $l= array_reverse($tmp);
+ unset($l['count']);
$cdn= $this->basedn;
+ $tag= "";
+
foreach ($l as $part){
$cdn= "$part,$cdn";
$attrs= $this->fetch();
/* Create missing entry? */
- if (!count ($attrs)){
+ if (count ($attrs)){
+
+ /* Catch the tag - if present */
+ if (isset($attrs['gosaUnitTag'][0])){
+ $tag= $attrs['gosaUnitTag'][0];
+ }
+
+ } else {
$type= preg_replace('/^([^=]+)=.*$/', '\\1', $cdn);
$param= preg_replace('/^[^=]+=([^,]+),.*$/', '\\1', $cdn);
$na= array();
switch ($type){
case 'ou':
- $na["objectClass"]= "organizationalUnit";
+ if ($tag != ""){
+ $na["objectClass"]= array("organizationalUnit", "gosaAdministrativeUnitTag");
+ $na["gosaUnitTag"]= $tag;
+ } else {
+ $na["objectClass"]= "organizationalUnit";
+ }
$na["ou"]= $param;
break;
case 'dc':
- $na["objectClass"]= array("dcObject", "top", "locality");
+ if ($tag != ""){
+ $na["objectClass"]= array("dcObject", "top", "locality", "gosaAdministrativeUnitTag");
+ $na["gosaUnitTag"]= $tag;
+ } else {
+ $na["objectClass"]= array("dcObject", "top", "locality");
+ }
$na["dc"]= $param;
break;
default:
if ($this->error == 'Success'){
return $this->error;
} else {
- $error= $this->error." (".$this->get_additional_error().")";
+ $adderror= $this->get_additional_error();
+ if ($adderror != ""){
+ $error= $this->error." (".$this->get_additional_error().", ".sprintf(_("while operating on '%s' using LDAP server '%s'"), $this->basedn, $this->hostname).")";
+ } else {
+ $error= $this->error." (".sprintf(_("while operating on LDAP server %s"), $this->hostname).")";
+ }
return $error;
}
}
@@ -868,7 +1146,7 @@ function gen_xls ($dn, $filter= "(objectClass=*)", $attributes= array('*'), $rec
$ndn = split("#", $lineone[0]);
$line = $ndn[1];
- $dnn = split (":",$line);
+ $dnn = split (":",$line,2);
$current_line = $ndn[0];
$dn = $dnn[0];
$value = $dnn[1];
@@ -937,7 +1215,7 @@ function gen_xls ($dn, $filter= "(objectClass=*)", $attributes= array('*'), $rec
}
/* 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 */
@@ -1009,6 +1287,178 @@ function gen_xls ($dn, $filter= "(objectClass=*)", $attributes= array('*'), $rec
}
}
+
+ function get_objectclasses_old()
+ {
+ $objectclasses = array();
+
+ # Get base to look for schema
+ $sr = @ldap_read ($this->cid, NULL, "objectClass=*", array("subschemaSubentry"));
+ $attr = @ldap_get_entries($this->cid,$sr);
+
+ if (!isset($attr[0]['subschemasubentry'][0])){
+ $this->error = @ldap_error($this->cid);
+ gosa_log($this->get_error());
+ return array();
+ }
+
+ # Get list of objectclasses
+ $nb= $attr[0]['subschemasubentry'][0];
+ $objectclasses= array();
+ $sr= ldap_read ($this->cid, $nb, "objectClass=*", array("objectclasses"));
+ $attrs= ldap_get_entries($this->cid,$sr);
+ if (!isset($attrs[0])){
+ return array();
+ }
+ foreach ($attrs[0]['objectclasses'] as $val){
+ $name= preg_replace("/^.* NAME\s+\(*\s*'([^']+)'\s*\)*.*$/", '\\1', $val);
+ if ($name != $val){
+ $objectclasses[$name]= $val;
+ }
+ }
+
+ return $objectclasses;
+ }
+
+
+ function get_objectclasses()
+ {
+ global $config;
+ $objectclasses = array();
+
+ 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"));
+ 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 and fill array */
+ $nb= $attr[0]['subschemasubentry'][0];
+ $objectclasses= array();
+ $sr= ldap_read ($this->cid, $nb, "objectClass=*", array("objectclasses"));
+ $attrs= ldap_get_entries($this->cid,$sr);
+ if (!isset($attrs[0])){
+ return array();
+ }
+ foreach ($attrs[0]['objectclasses'] as $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 <zeph@purotesto.it> */
+ 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']);
+ }
}