Code

Just code aligment,.
authorhickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8>
Tue, 21 Sep 2010 06:42:11 +0000 (06:42 +0000)
committerhickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8>
Tue, 21 Sep 2010 06:42:11 +0000 (06:42 +0000)
git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@19775 594d385d-05f5-0310-b6e9-bd551577e9d8

gosa-core/include/class_ldap.inc

index dcd047d6f0dca57d31ce5a18c4a440efeacc64b8..f955eb09a6ab56b5429d0b6fd759330ad6f19351 100644 (file)
@@ -34,1442 +34,1442 @@ class LDAP
     public static $characterMapRegFrom = NULL;
     public static $characterMapRegTo = NULL;
 
-  var $hascon   =false;
-  var $reconnect=false;
-  var $tls      = false;
-  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 $srp      = 0;
-  var $objectClasses = array(); // Information read from slapd.oc.conf
-  var $binddn   = "";
-  var $bindpw   = "";
-  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=LDAP::convert($binddn);
-
-      $this->bindpw=$bindpw;
-      $this->hostname=$hostname;
-
-      /* Check if MAX_LDAP_QUERY_TIME is defined */ 
-      if(is_object($config) && $config->get_cfg_value("core","ldapMaxQueryTime") != ""){
-          $str = $config->get_cfg_value("core","ldapMaxQueryTime");
-          $this->max_ldap_query_time = (float)($str);
-      }
-
-      $this->connect();
-  }
-
-
-  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                                                                  
-     \22 => DQ                                                                  */
-  static function convert($dn)
-  {
-    if (SPECIALS_OVERRIDE == TRUE){
-      $tmp= preg_replace(array("/\\\\,/", "/\\\\2C/", "/\(/", "/\)/", "/\//", "/\\\\22/", '/\\\\"/'),
-          array("\001CO", "\001CO", "\001OB", "\001CB", "\001SL", "\001DQ", "\001DQ"),
-          $dn);
-      return (preg_replace('/,\s+/', ',', $tmp));
-    } else {
-      return ($dn);
+    var $hascon   =false;
+    var $reconnect=false;
+    var $tls      = false;
+    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 $srp      = 0;
+    var $objectClasses = array(); // Information read from slapd.oc.conf
+    var $binddn   = "";
+    var $bindpw   = "";
+    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=LDAP::convert($binddn);
+
+        $this->bindpw=$bindpw;
+        $this->hostname=$hostname;
+
+        /* Check if MAX_LDAP_QUERY_TIME is defined */ 
+        if(is_object($config) && $config->get_cfg_value("core","ldapMaxQueryTime") != ""){
+            $str = $config->get_cfg_value("core","ldapMaxQueryTime");
+            $this->max_ldap_query_time = (float)($str);
+        }
+
+        $this->connect();
     }
-  }
-
-
-  /* \brief     Tests for the special-char handling of the currently used ldap database 
-   *             and updates the LDAP class correspondingly.
-   *            This affects the LDAP::fix function and allows us to write 
-   *             dns containing  , " ( )
-   */
-  static function updateSpecialCharHandling()
-  {
-      // Set a default character handling.
-      LDAP::$characterMapRegFrom = array("/\001CO/", "/\001OB/", "/\001CB/", "/\001SL/", "/\001DQ/");
-      LDAP::$characterMapRegTo = array("\,", "(", ")", "/", '\"');
-
-      if(LDAP::$characterMap == NULL){
-          LDAP::$characterMap = detectLdapSpecialCharHandling();
-
-          // Check if character-detection was successfull, if it wasn't use a fallback.
-          if(LDAP::$characterMap){
-              LDAP::$characterMapRegFrom = array();
-              LDAP::$characterMapRegTo = array();
-              foreach(LDAP::$characterMap as $from => $to){
-                  LDAP::$characterMapRegFrom[] = "/{$from}/";
-                  LDAP::$characterMapRegTo[] = "/{$to}/";
-              }
-          }
-      }
-                
-      $attrs = array(implode(LDAP::$characterMapRegFrom,', '),implode(LDAP::$characterMapRegTo,', '));
-      @DEBUG(DEBUG_LDAP,__LINE__,__FUNCTION__,__FILE__,$attrs,"Detected special-char handling for LDAP actions");
-  }
-
-
-  /* \brief   Function to fix all problematic characters inside a DN by replacing \001XX
-   *           codes to their original values. See "convert" for more information. 
-   *          The ',' characters are always expanded to \, (not \2C), since all tested LDAP
-   *           servers seem to take it the correct way.                                 
-   * @param String  The DN to convert characters in. 
-   * @param String  The converted dn.
-   */
-  static function fix($dn)
-  {
-      if (SPECIALS_OVERRIDE == TRUE){
-        
-          // Update the conversion instruction set.
-          if(LDAP::$characterMap == NULL) LDAP::updateSpecialCharHandling();
-
-          return (preg_replace(LDAP::$characterMapRegFrom,LDAP::$characterMapRegTo,$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)
-  {
-    $fixed= normalizeLdap(str_replace('\\\\', '\\\\\\', LDAP::fix($dn)));
-    return str_replace('\\,', '\\\\,', $fixed);
-  }
-
-
-  function connect()
-  {
-    $this->hascon=false;
-    $this->reconnect=false;
-    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"));
-      }
-      if (function_exists("ldap_start_tls") && $this->tls){
-        @ldap_start_tls($this->cid);
-      }
-
-      $this->error = "No Error";
-      if ($bid = @ldap_bind($this->cid, LDAP::fix($this->binddn), $this->bindpw)) {
-        $this->error = "Success";
-        $this->hascon=true;
-      } else {
-        if ($this->reconnect){
-          if ($this->error != "Success"){
-            $this->error = "Could not rebind to " . $this->binddn;
-          }
+
+
+    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                                                                  
+       \22 => DQ                                                                  */
+    static function convert($dn)
+    {
+        if (SPECIALS_OVERRIDE == TRUE){
+            $tmp= preg_replace(array("/\\\\,/", "/\\\\2C/", "/\(/", "/\)/", "/\//", "/\\\\22/", '/\\\\"/'),
+                    array("\001CO", "\001CO", "\001OB", "\001CB", "\001SL", "\001DQ", "\001DQ"),
+                    $dn);
+            return (preg_replace('/,\s+/', ',', $tmp));
         } else {
-          $this->error = "Could not bind to " . $this->binddn;
+            return ($dn);
         }
-      }
-    } else {
-      $this->error = "Could not connect to LDAP server";
     }
-  }
-
-  function rebind($ldap, $referral)
-  {
-    $credentials= $this->get_credentials($referral);
-    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['ADMINDN'];
-      return NULL;
+
+
+    /* \brief     Tests for the special-char handling of the currently used ldap database 
+     *             and updates the LDAP class correspondingly.
+     *            This affects the LDAP::fix function and allows us to write 
+     *             dns containing  , " ( )
+     */
+    static function updateSpecialCharHandling()
+    {
+        // Set a default character handling.
+        LDAP::$characterMapRegFrom = array("/\001CO/", "/\001OB/", "/\001CB/", "/\001SL/", "/\001DQ/");
+        LDAP::$characterMapRegTo = array("\,", "(", ")", "/", '\"');
+
+        if(LDAP::$characterMap == NULL){
+            LDAP::$characterMap = detectLdapSpecialCharHandling();
+
+            // Check if character-detection was successfull, if it wasn't use a fallback.
+            if(LDAP::$characterMap){
+                LDAP::$characterMapRegFrom = array();
+                LDAP::$characterMapRegTo = array();
+                foreach(LDAP::$characterMap as $from => $to){
+                    LDAP::$characterMapRegFrom[] = "/{$from}/";
+                    LDAP::$characterMapRegTo[] = "/{$to}/";
+                }
+            }
+        }
+
+        $attrs = array(implode(LDAP::$characterMapRegFrom,', '),implode(LDAP::$characterMapRegTo,', '));
+        @DEBUG(DEBUG_LDAP,__LINE__,__FUNCTION__,__FILE__,$attrs,"Detected special-char handling for LDAP actions");
     }
-  }
 
-  function reconnect()
-  {
-    if ($this->reconnect){
-      @ldap_unbind($this->cid);
-      $this->cid = NULL;
+
+    /* \brief   Function to fix all problematic characters inside a DN by replacing \001XX
+     *           codes to their original values. See "convert" for more information. 
+     *          The ',' characters are always expanded to \, (not \2C), since all tested LDAP
+     *           servers seem to take it the correct way.                                 
+     * @param String  The DN to convert characters in. 
+     * @param String  The converted dn.
+     */
+    static function fix($dn)
+    {
+        if (SPECIALS_OVERRIDE == TRUE){
+
+            // Update the conversion instruction set.
+            if(LDAP::$characterMap == NULL) LDAP::updateSpecialCharHandling();
+
+            return (preg_replace(LDAP::$characterMapRegFrom,LDAP::$characterMapRegTo,$dn));
+        } else {
+            return ($dn);
+        }
     }
-  }
-
-  function unbind()
-  {
-    @ldap_unbind($this->cid);
-    $this->cid = NULL;
-  }
-
-  function disconnect()
-  {
-    if($this->hascon){
-      @ldap_close($this->cid);
-      $this->hascon=false;
+
+
+    /* Function to fix problematic characters in DN's that are used for search
+       requests. I.e. member=....                                               */
+    static function prepare4filter($dn)
+    {
+        $fixed= normalizeLdap(str_replace('\\\\', '\\\\\\', LDAP::fix($dn)));
+        return str_replace('\\,', '\\\\,', $fixed);
     }
-  }
-
-  function cd($dir)
-  {
-    if ($dir == ".."){
-      $this->basedn = $this->getParentDir();
-    } else {
-      $this->basedn = LDAP::convert($dir);
+
+
+    function connect()
+    {
+        $this->hascon=false;
+        $this->reconnect=false;
+        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"));
+            }
+            if (function_exists("ldap_start_tls") && $this->tls){
+                @ldap_start_tls($this->cid);
+            }
+
+            $this->error = "No Error";
+            if ($bid = @ldap_bind($this->cid, LDAP::fix($this->binddn), $this->bindpw)) {
+                $this->error = "Success";
+                $this->hascon=true;
+            } else {
+                if ($this->reconnect){
+                    if ($this->error != "Success"){
+                        $this->error = "Could not rebind to " . $this->binddn;
+                    }
+                } else {
+                    $this->error = "Could not bind to " . $this->binddn;
+                }
+            }
+        } else {
+            $this->error = "Could not connect to LDAP server";
+        }
     }
-  }
-
-  function getParentDir($basedn = "")
-  {
-    if ($basedn==""){
-      $basedn = $this->basedn;
-    } else {
-      $basedn = LDAP::convert($basedn);
+
+    function rebind($ldap, $referral)
+    {
+        $credentials= $this->get_credentials($referral);
+        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['ADMINDN'];
+            return NULL;
+        }
     }
-    return(preg_replace("/[^,]*[,]*[ ]*(.*)/", "$1", $basedn));
-  }
-
-  
-  function search($srp, $filter, $attrs= array())
-  {
-    if($this->hascon){
-      if ($this->reconnect) $this->connect();
-
-      $start = microtime(true);
-      $this->clearResult($srp);
-      $this->sr[$srp] = @ldap_search($this->cid, LDAP::fix($this->basedn), $filter, $attrs);
-      $this->error = @ldap_error($this->cid);
-      $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){
-        $diff = microtime(true) - $start;
-        if($diff > $this->max_ldap_query_time){
-          msg_dialog::display(_("Performance warning"), sprintf(_("LDAP performance is poor: last query took %.2fs!"), $diff), WARNING_DIALOG);
-        }
-      }
-
-      $this->log("LDAP operation: time=".(microtime(true)-$start)." operation=search('".LDAP::fix($this->basedn)."', '$filter')");
-
-      // Create statistic table entry 
-      stats::log('ldap', $class = get_class($this), $category = array(),  $action = __FUNCTION__, 
-              $amount = 1, $duration = (microtime(TRUE) - $start));
-      return($this->sr[$srp]);
-    }else{
-      $this->error = "Could not connect to LDAP server";
-      return("");
+
+    function reconnect()
+    {
+        if ($this->reconnect){
+            @ldap_unbind($this->cid);
+            $this->cid = NULL;
+        }
     }
-  }
-
-  function ls($srp, $filter = "(objectclass=*)", $basedn = "",$attrs = array("*"))
-  {
-    if($this->hascon){
-      if ($this->reconnect) $this->connect();
-
-      $this->clearResult($srp);
-      if ($basedn == "")
-        $basedn = $this->basedn;
-      else
-        $basedn= LDAP::convert($basedn);
-  
-      $start = microtime(true);
-      $this->sr[$srp] = @ldap_list($this->cid, LDAP::fix($basedn), $filter,$attrs);
-      $this->error = @ldap_error($this->cid);
-      $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){
-        $diff = microtime(true) - $start;
-        if($diff > $this->max_ldap_query_time){
-          msg_dialog::display(_("Performance warning"), sprintf(_("LDAP performance is poor: last query took %.2fs!"), $diff), WARNING_DIALOG);
-        }
-      }
-
-      $this->log("LDAP operation: time=".(microtime(true) - $start)." operation=ls('".LDAP::fix($basedn)."', '$filter')");
-
-      // Create statistic table entry 
-      stats::log('ldap', $class = get_class($this), $category = array(),  $action = __FUNCTION__, 
-              $amount = 1, $duration = (microtime(TRUE) - $start));
-
-      return($this->sr[$srp]);
-    }else{
-      $this->error = "Could not connect to LDAP server";
-      return("");
+
+    function unbind()
+    {
+        @ldap_unbind($this->cid);
+        $this->cid = NULL;
     }
-  }
-
-  function cat($srp, $dn,$attrs= array("*"), $filter = "(objectclass=*)")
-  {
-    if($this->hascon){
-      if ($this->reconnect) $this->connect();
-
-      $this->clearResult($srp);
-      $this->sr[$srp] = @ldap_read($this->cid, LDAP::fix($dn), $filter,$attrs);
-      $this->error = @ldap_error($this->cid);
-      $this->resetResult($srp);
-      $this->hasres[$srp]=true;
-      return($this->sr[$srp]);
-    }else{
-      $this->error = "Could not connect to LDAP server";
-      return("");
+
+    function disconnect()
+    {
+        if($this->hascon){
+            @ldap_close($this->cid);
+            $this->hascon=false;
+        }
     }
-  }
-
-  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 cd($dir)
+    {
+        if ($dir == ".."){
+            $this->basedn = $this->getParentDir();
+        } else {
+            $this->basedn = LDAP::convert($dir);
+        }
     }
-  }
 
-  function set_size_limit($size)
-  {
-    /* Ignore zero settings */
-    if ($size == 0){
-      @ldap_set_option($this->cid, LDAP_OPT_SIZELIMIT, 10000000);
+    function getParentDir($basedn = "")
+    {
+        if ($basedn==""){
+            $basedn = $this->basedn;
+        } else {
+            $basedn = LDAP::convert($basedn);
+        }
+        return(preg_replace("/[^,]*[,]*[ ]*(.*)/", "$1", $basedn));
     }
-    if($this->hascon){
-      @ldap_set_option($this->cid, LDAP_OPT_SIZELIMIT, $size);
-    } else {
-      $this->error = "Could not connect to LDAP server";
+
+
+    function search($srp, $filter, $attrs= array())
+    {
+        if($this->hascon){
+            if ($this->reconnect) $this->connect();
+
+            $start = microtime(true);
+            $this->clearResult($srp);
+            $this->sr[$srp] = @ldap_search($this->cid, LDAP::fix($this->basedn), $filter, $attrs);
+            $this->error = @ldap_error($this->cid);
+            $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){
+                $diff = microtime(true) - $start;
+                if($diff > $this->max_ldap_query_time){
+                    msg_dialog::display(_("Performance warning"), sprintf(_("LDAP performance is poor: last query took %.2fs!"), $diff), WARNING_DIALOG);
+                }
+            }
+
+            $this->log("LDAP operation: time=".(microtime(true)-$start)." operation=search('".LDAP::fix($this->basedn)."', '$filter')");
+
+            // Create statistic table entry 
+            stats::log('ldap', $class = get_class($this), $category = array(),  $action = __FUNCTION__, 
+                    $amount = 1, $duration = (microtime(TRUE) - $start));
+            return($this->sr[$srp]);
+        }else{
+            $this->error = "Could not connect to LDAP server";
+            return("");
+        }
     }
-  }
-
-  function fetch($srp)
-  {
-    $att= array();
-    if($this->hascon){
-      if($this->hasres[$srp]){
-        if ($this->start[$srp] == 0)
-        {
-          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[$srp]= @ldap_next_entry($this->cid, $this->re[$srp]);
+
+    function ls($srp, $filter = "(objectclass=*)", $basedn = "",$attrs = array("*"))
+    {
+        if($this->hascon){
+            if ($this->reconnect) $this->connect();
+
+            $this->clearResult($srp);
+            if ($basedn == "")
+                $basedn = $this->basedn;
+            else
+                $basedn= LDAP::convert($basedn);
+
+            $start = microtime(true);
+            $this->sr[$srp] = @ldap_list($this->cid, LDAP::fix($basedn), $filter,$attrs);
+            $this->error = @ldap_error($this->cid);
+            $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){
+                $diff = microtime(true) - $start;
+                if($diff > $this->max_ldap_query_time){
+                    msg_dialog::display(_("Performance warning"), sprintf(_("LDAP performance is poor: last query took %.2fs!"), $diff), WARNING_DIALOG);
+                }
+            }
+
+            $this->log("LDAP operation: time=".(microtime(true) - $start)." operation=ls('".LDAP::fix($basedn)."', '$filter')");
+
+            // Create statistic table entry 
+            stats::log('ldap', $class = get_class($this), $category = array(),  $action = __FUNCTION__, 
+                    $amount = 1, $duration = (microtime(TRUE) - $start));
+
+            return($this->sr[$srp]);
+        }else{
+            $this->error = "Could not connect to LDAP server";
+            return("");
         }
-        if ($this->re[$srp])
-        {
-          $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)){
-          $att= array();
-        }
-        return($att);
-      }else{
-        $this->error = "Perform a fetch with no search";
-        return("");
-      }
-    }else{
-      $this->error = "Could not connect to LDAP server";
-      return("");
     }
-  }
-
-  function resetResult($srp)
-  {
-    $this->start[$srp] = 0;
-  }
-
-  function clearResult($srp)
-  {
-    if($this->hasres[$srp]){
-      $this->hasres[$srp] = false;
-      @ldap_free_result($this->sr[$srp]);
+
+    function cat($srp, $dn,$attrs= array("*"), $filter = "(objectclass=*)")
+    {
+        if($this->hascon){
+            if ($this->reconnect) $this->connect();
+
+            $this->clearResult($srp);
+            $this->sr[$srp] = @ldap_read($this->cid, LDAP::fix($dn), $filter,$attrs);
+            $this->error = @ldap_error($this->cid);
+            $this->resetResult($srp);
+            $this->hasres[$srp]=true;
+            return($this->sr[$srp]);
+        }else{
+            $this->error = "Could not connect to LDAP server";
+            return("");
+        }
     }
-  }
-
-  function getDN($srp)
-  {
-    if($this->hascon){
-      if($this->hasres[$srp]){
-
-        if(!$this->re[$srp])
-          {
-          $this->error = "Perform a Fetch with no valid Result";
-          }
-          else
-          {
-          $rv = @ldap_get_dn($this->cid, $this->re[$srp]);
-        
-          $this->error = @ldap_error($this->cid);
-          return(trim(LDAP::convert($rv)));
-           }
-      }else{
-        $this->error = "Perform a Fetch with no Search";
-        return("");
-      }
-    }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 count($srp)
-  {
-    if($this->hascon){
-      if($this->hasres[$srp]){
-        $rv = @ldap_count_entries($this->cid, $this->sr[$srp]);
-        $this->error = @ldap_error($this->cid);
-        return($rv);
-      }else{
-        $this->error = "Perform a Fetch with no Search";
-        return("");
-      }
-    }else{
-      $this->error = "Could not connect to LDAP server";
-      return("");
+
+    function set_size_limit($size)
+    {
+        /* Ignore zero settings */
+        if ($size == 0){
+            @ldap_set_option($this->cid, LDAP_OPT_SIZELIMIT, 10000000);
+        }
+        if($this->hascon){
+            @ldap_set_option($this->cid, LDAP_OPT_SIZELIMIT, $size);
+        } else {
+            $this->error = "Could not connect to LDAP server";
+        }
     }
-  }
-
-  function rm($attrs = "", $dn = "")
-  {
-    if($this->hascon){
-      if ($this->reconnect) $this->connect();
-      if ($dn == "")
-        $dn = $this->basedn;
-
-      $r = ldap_mod_del($this->cid, LDAP::fix($dn), $attrs);
-      $this->error = @ldap_error($this->cid);
-      return($r);
-    }else{
-      $this->error = "Could not connect to LDAP server";
-      return("");
+
+    function fetch($srp)
+    {
+        $att= array();
+        if($this->hascon){
+            if($this->hasres[$srp]){
+                if ($this->start[$srp] == 0)
+                {
+                    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[$srp]= @ldap_next_entry($this->cid, $this->re[$srp]);
+                }
+                if ($this->re[$srp])
+                {
+                    $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)){
+                    $att= array();
+                }
+                return($att);
+            }else{
+                $this->error = "Perform a fetch with no search";
+                return("");
+            }
+        }else{
+            $this->error = "Could not connect to LDAP server";
+            return("");
+        }
     }
-  }
-
-  function mod_add($attrs = "", $dn = "")
-  {
-    if($this->hascon){
-      if ($this->reconnect) $this->connect();
-      if ($dn == "")
-        $dn = $this->basedn;
-
-      $r = @ldap_mod_add($this->cid, LDAP::fix($dn), $attrs);
-      $this->error = @ldap_error($this->cid);
-      return($r);
-    }else{
-      $this->error = "Could not connect to LDAP server";
-      return("");
+
+    function resetResult($srp)
+    {
+        $this->start[$srp] = 0;
     }
-  }
-
-  function rename($attrs, $dn = "")
-  {
-    if($this->hascon){
-      if ($this->reconnect) $this->connect();
-      if ($dn == "")
-        $dn = $this->basedn;
-
-      $r = @ldap_mod_replace($this->cid, LDAP::fix($dn), $attrs);
-      $this->error = @ldap_error($this->cid);
-      return($r);
-    }else{
-      $this->error = "Could not connect to LDAP server";
-      return("");
+
+    function clearResult($srp)
+    {
+        if($this->hasres[$srp]){
+            $this->hasres[$srp] = false;
+            @ldap_free_result($this->sr[$srp]);
+        }
     }
-  }
-
-  function rmdir($deletedn)
-  {
-    if($this->hascon){
-      if ($this->reconnect) $this->connect();
-      $r = @ldap_delete($this->cid, LDAP::fix($deletedn));
-      $this->error = @ldap_error($this->cid);
-      return($r ? $r : 0);
-    }else{
-      $this->error = "Could not connect to LDAP server";
-      return("");
+
+    function getDN($srp)
+    {
+        if($this->hascon){
+            if($this->hasres[$srp]){
+
+                if(!$this->re[$srp])
+                {
+                    $this->error = "Perform a Fetch with no valid Result";
+                }
+                else
+                {
+                    $rv = @ldap_get_dn($this->cid, $this->re[$srp]);
+
+                    $this->error = @ldap_error($this->cid);
+                    return(trim(LDAP::convert($rv)));
+                }
+            }else{
+                $this->error = "Perform a Fetch with no Search";
+                return("");
+            }
+        }else{
+            $this->error = "Could not connect to LDAP server";
+            return("");
+        }
     }
-  }
 
+    function count($srp)
+    {
+        if($this->hascon){
+            if($this->hasres[$srp]){
+                $rv = @ldap_count_entries($this->cid, $this->sr[$srp]);
+                $this->error = @ldap_error($this->cid);
+                return($rv);
+            }else{
+                $this->error = "Perform a Fetch with no Search";
+                return("");
+            }
+        }else{
+            $this->error = "Could not connect to LDAP server";
+            return("");
+        }
+    }
 
-  /*! \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);
+    function rm($attrs = "", $dn = "")
+    {
+        if($this->hascon){
+            if ($this->reconnect) $this->connect();
+            if ($dn == "")
+                $dn = $this->basedn;
+
+            $r = ldap_mod_del($this->cid, LDAP::fix($dn), $attrs);
+            $this->error = @ldap_error($this->cid);
+            return($r);
+        }else{
+            $this->error = "Could not connect to LDAP server";
+            return("");
+        }
     }
 
-    /* Check if destination entry exists */    
-    if($this->dn_exists($dest)){
-      trigger_error("Destination '$dest' already exists.");
-      $this->error = "Destination '$dest' already exists.";
-      return(FALSE);
+    function mod_add($attrs = "", $dn = "")
+    {
+        if($this->hascon){
+            if ($this->reconnect) $this->connect();
+            if ($dn == "")
+                $dn = $this->basedn;
+
+            $r = @ldap_mod_add($this->cid, LDAP::fix($dn), $attrs);
+            $this->error = @ldap_error($this->cid);
+            return($r);
+        }else{
+            $this->error = "Could not connect to LDAP server";
+            return("");
+        }
     }
 
-    /* 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 rename($attrs, $dn = "")
+    {
+        if($this->hascon){
+            if ($this->reconnect) $this->connect();
+            if ($dn == "")
+                $dn = $this->basedn;
+
+            $r = @ldap_mod_replace($this->cid, LDAP::fix($dn), $attrs);
+            $this->error = @ldap_error($this->cid);
+            return($r);
+        }else{
+            $this->error = "Could not connect to LDAP server";
+            return("");
+        }
     }
-  }
-
-
-  /**
-  *  Function rmdir_recursive
-  *
-  *  Description: Based in recursive_remove, adding two thing: full subtree remove, and delete own node.
-  *  Parameters:  The dn to delete
-  *  GiveBack:    True on sucessfull , 0 in error, and "" when we don't get a ldap conection
-  *
-  */
-  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 ($srp, "(objectClass=*)",$deletedn);
-      while ($this->fetch($srp)){
-        $deldn= $this->getDN($srp);
-        $delarray[$deldn]= strlen($deldn);
-      }
-      arsort ($delarray);
-      reset ($delarray);
-
-      /* Really Delete ALL dn's in subtree */
-      foreach ($delarray as $key => $value){
-        $this->rmdir_recursive($srp, $key);
-      }
-      
-      /* Finally Delete own Node */
-      $r = @ldap_delete($this->cid, LDAP::fix($deletedn));
-      $this->error = @ldap_error($this->cid);
-      return($r ? $r : 0);
-    }else{
-      $this->error = "Could not connect to LDAP server";
-      return("");
+
+    function rmdir($deletedn)
+    {
+        if($this->hascon){
+            if ($this->reconnect) $this->connect();
+            $r = @ldap_delete($this->cid, LDAP::fix($deletedn));
+            $this->error = @ldap_error($this->cid);
+            return($r ? $r : 0);
+        }else{
+            $this->error = "Could not connect to LDAP server";
+            return("");
+        }
     }
-  }
 
-  function makeReadableErrors($error,$attrs)
-  { 
-    global $config;
 
-    if($this->success()) return("");
+    /*! \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);
+        }
 
-    $str = "";
-    if(preg_match("/^objectClass: value #([0-9]*) invalid per syntax$/", $this->get_additional_error())){
-      $oc = preg_replace("/^objectClass: value #([0-9]*) invalid per syntax$/","\\1", $this->get_additional_error());
-      if(isset($attrs['objectClass'][$oc])){
-        $str.= " - <b>objectClass: ".$attrs['objectClass'][$oc]."</b>";
-      }
+        /* 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);
+        }
     }
-    if($error == "Undefined attribute type"){
-      $str = " - <b>attribute: ".preg_replace("/:.*$/","",$this->get_additional_error())."</b>";
-    } 
 
-    @DEBUG(DEBUG_LDAP,__LINE__,__FUNCTION__,__FILE__,$attrs,"Erroneous data");
 
-    return($str);
-  }
+    /**
+     *  Function rmdir_recursive
+     *
+     *  Description: Based in recursive_remove, adding two thing: full subtree remove, and delete own node.
+     *  Parameters:  The dn to delete
+     *  GiveBack:    True on sucessfull , 0 in error, and "" when we don't get a ldap conection
+     *
+     */
+    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 ($srp, "(objectClass=*)",$deletedn);
+            while ($this->fetch($srp)){
+                $deldn= $this->getDN($srp);
+                $delarray[$deldn]= strlen($deldn);
+            }
+            arsort ($delarray);
+            reset ($delarray);
+
+            /* Really Delete ALL dn's in subtree */
+            foreach ($delarray as $key => $value){
+                $this->rmdir_recursive($srp, $key);
+            }
 
-  function modify($attrs)
-  {
-    if(count($attrs) == 0){
-      return (0);
+            /* Finally Delete own Node */
+            $r = @ldap_delete($this->cid, LDAP::fix($deletedn));
+            $this->error = @ldap_error($this->cid);
+            return($r ? $r : 0);
+        }else{
+            $this->error = "Could not connect to LDAP server";
+            return("");
+        }
     }
-    if($this->hascon){
-      $start = microtime(TRUE);
-      if ($this->reconnect) $this->connect();
-      $r = @ldap_modify($this->cid, LDAP::fix($this->basedn), $attrs);
-      $this->error = @ldap_error($this->cid);
-      if(!$this->success()){
-        $this->error.= $this->makeReadableErrors($this->error,$attrs);
-      }
-
-      // Create statistic table entry 
-      stats::log('ldap', $class = get_class($this), $category = array(),  $action = __FUNCTION__, 
-              $amount = 1, $duration = (microtime(TRUE) - $start));
-      return($r ? $r : 0);
-    }else{
-      $this->error = "Could not connect to LDAP server";
-      return("");
+
+    function makeReadableErrors($error,$attrs)
+    { 
+        global $config;
+
+        if($this->success()) return("");
+
+        $str = "";
+        if(preg_match("/^objectClass: value #([0-9]*) invalid per syntax$/", $this->get_additional_error())){
+            $oc = preg_replace("/^objectClass: value #([0-9]*) invalid per syntax$/","\\1", $this->get_additional_error());
+            if(isset($attrs['objectClass'][$oc])){
+                $str.= " - <b>objectClass: ".$attrs['objectClass'][$oc]."</b>";
+            }
+        }
+        if($error == "Undefined attribute type"){
+            $str = " - <b>attribute: ".preg_replace("/:.*$/","",$this->get_additional_error())."</b>";
+        } 
+
+        @DEBUG(DEBUG_LDAP,__LINE__,__FUNCTION__,__FILE__,$attrs,"Erroneous data");
+
+        return($str);
     }
-  }
-
-  function add($attrs)
-  {
-    if($this->hascon){
-      $start = microtime(TRUE);
-      if ($this->reconnect) $this->connect();
-      $r = @ldap_add($this->cid, LDAP::fix($this->basedn), $attrs);
-      $this->error = @ldap_error($this->cid);
-      if(!$this->success()){
-        $this->error.= $this->makeReadableErrors($this->error,$attrs);
-      }
-
-      // Create statistic table entry 
-      stats::log('ldap', $class = get_class($this), $category = array(),  $action = __FUNCTION__, 
-              $amount = 1, $duration = (microtime(TRUE) - $start));
-
-      return($r ? $r : 0);
-    }else{
-      $this->error = "Could not connect to LDAP server";
-      return("");
+
+    function modify($attrs)
+    {
+        if(count($attrs) == 0){
+            return (0);
+        }
+        if($this->hascon){
+            $start = microtime(TRUE);
+            if ($this->reconnect) $this->connect();
+            $r = @ldap_modify($this->cid, LDAP::fix($this->basedn), $attrs);
+            $this->error = @ldap_error($this->cid);
+            if(!$this->success()){
+                $this->error.= $this->makeReadableErrors($this->error,$attrs);
+            }
+
+            // Create statistic table entry 
+            stats::log('ldap', $class = get_class($this), $category = array(),  $action = __FUNCTION__, 
+                    $amount = 1, $duration = (microtime(TRUE) - $start));
+            return($r ? $r : 0);
+        }else{
+            $this->error = "Could not connect to LDAP server";
+            return("");
+        }
     }
-  }
 
-  function create_missing_trees($srp, $target)
-  {
-    global $config;
+    function add($attrs)
+    {
+        if($this->hascon){
+            $start = microtime(TRUE);
+            if ($this->reconnect) $this->connect();
+            $r = @ldap_add($this->cid, LDAP::fix($this->basedn), $attrs);
+            $this->error = @ldap_error($this->cid);
+            if(!$this->success()){
+                $this->error.= $this->makeReadableErrors($this->error,$attrs);
+            }
 
-    $real_path= substr($target, 0, strlen($target) - strlen($this->basedn) -1 );
+            // Create statistic table entry 
+            stats::log('ldap', $class = get_class($this), $category = array(),  $action = __FUNCTION__, 
+                    $amount = 1, $duration = (microtime(TRUE) - $start));
 
-    if ($target == $this->basedn){
-      $l= array("dummy");
-    } else {
-      $l= array_reverse(gosa_ldap_explode_dn($real_path));
+            return($r ? $r : 0);
+        }else{
+            $this->error = "Could not connect to LDAP server";
+            return("");
+        }
     }
-    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['URI']);
-        if ($base == $cdn){
-          $found= true;
-          break;
-        }
-      }
-      if ($found){
-        continue;
-      }
-
-      $this->cat ($srp, $cdn);
-      $attrs= $this->fetch($srp);
-
-      /* 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= LDAP::fix(preg_replace('/^[^=]+=([^,]+).*$/', '\\1', $cdn));
-        $param=preg_replace(array('/\\\\,/','/\\\\"/'),array(',','"'),$param);
-
-        $na= array();
-
-        /* Automatic or traditional? */
-        if(count($classes)){
-
-          /* Get name of first matching objectClass */
-          $ocname= "";
-          foreach($classes as $class){
-            if (isset($class['MUST']) && in_array($type, $class['MUST'])){
-
-              /* 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'];
-              }
+
+    function create_missing_trees($srp, $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['URI']);
+                if ($base == $cdn){
+                    $found= true;
+                    break;
+                }
             }
-          }
-
-          /* 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"), bold($type)), FATAL_ERROR_DIALOG);
-            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;
-
-          // Fill in MUST values - but do not overwrite existing ones.
-          if (is_array($classes[$ocname]['MUST'])){
-            foreach($classes[$ocname]['MUST'] as $attr){
-              if(isset($na[$attr]) && !empty($na[$attr])) continue;
-              $na[$attr]= "filled";
+            if ($found){
+                continue;
             }
-          }
 
-        } else {
+            $this->cat ($srp, $cdn);
+            $attrs= $this->fetch($srp);
 
-          /* 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:
-              msg_dialog::display(_("Internal error"), sprintf(_("Cannot automatically create subtrees with RDN %s: not supported"), bold($type)), FATAL_ERROR_DIALOG);
-              exit();
-          }
-
-        }
-        $this->cd($cdn);
-        $this->add($na);
-    
-        if (!$this->success()){
+            /* Create missing entry? */
+            if (count ($attrs)){
 
-          print_a(array($cdn,$na));
+                /* Catch the tag - if present */
+                if (isset($attrs['gosaUnitTag'][0])){
+                    $tag= $attrs['gosaUnitTag'][0];
+                }
 
-          msg_dialog::display(_("LDAP error"), msgPool::ldaperror($this->get_error(), $cdn, LDAP_ADD, get_class()));
-          return FALSE;
-        }
-      }
-    }
+            } else {
+                $type= preg_replace('/^([^=]+)=.*$/', '\\1', $cdn);
+                $param= LDAP::fix(preg_replace('/^[^=]+=([^,]+).*$/', '\\1', $cdn));
+                $param=preg_replace(array('/\\\\,/','/\\\\"/'),array(',','"'),$param);
 
-    return TRUE;
-  }
+                $na= array();
 
+                /* Automatic or traditional? */
+                if(count($classes)){
 
-  function recursive_remove($srp)
-  {
-    $delarray= array();
+                    /* Get name of first matching objectClass */
+                    $ocname= "";
+                    foreach($classes as $class){
+                        if (isset($class['MUST']) && in_array($type, $class['MUST'])){
 
-    /* Get sorted list of dn's to delete */
-    $this->search ($srp, "(objectClass=*)");
-    while ($this->fetch($srp)){
-      $deldn= $this->getDN($srp);
-      $delarray[$deldn]= strlen($deldn);
-    }
-    arsort ($delarray);
-    reset ($delarray);
+                            /* Look for first classes that is structural... */
+                            if (isset($class['STRUCTURAL'])){
+                                $ocname= $class['NAME'];
+                                break;
+                            }
 
-    /* Delete all dn's in subtree */
-    foreach ($delarray as $key => $value){
-      $this->rmdir($key);
-    }
-  }
+                            /* Look for classes that are auxiliary... */
+                            if (isset($class['AUXILIARY'])){
+                                $ocname= $class['NAME'];
+                            }
+                        }
+                    }
+
+                    /* 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"), bold($type)), FATAL_ERROR_DIALOG);
+                        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;
+
+                    // Fill in MUST values - but do not overwrite existing ones.
+                    if (is_array($classes[$ocname]['MUST'])){
+                        foreach($classes[$ocname]['MUST'] as $attr){
+                            if(isset($na[$attr]) && !empty($na[$attr])) continue;
+                            $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:
+                            msg_dialog::display(_("Internal error"), sprintf(_("Cannot automatically create subtrees with RDN %s: not supported"), bold($type)), FATAL_ERROR_DIALOG);
+                            exit();
+                    }
 
+                }
+                $this->cd($cdn);
+                $this->add($na);
 
-  function get_attribute($dn, $name,$r_array=0)
-  {
-    $data= "";
-    if ($this->reconnect) $this->connect();
-    $sr= @ldap_read($this->cid, LDAP::fix($dn), "objectClass=*", array("$name"));
+                if (!$this->success()){
 
-    /* fill data from LDAP */
-    if ($sr) {
-      $ei= @ldap_first_entry($this->cid, $sr);
-      if ($ei) {
-        if ($info= @ldap_get_values_len($this->cid, $ei, "$name")){
-          $data= $info[0];
+                    print_a(array($cdn,$na));
+
+                    msg_dialog::display(_("LDAP error"), msgPool::ldaperror($this->get_error(), $cdn, LDAP_ADD, get_class()));
+                    return FALSE;
+                }
+            }
         }
-      }
-    }
-    if($r_array==0) {
-      return ($data);
-    } else {
-      return ($info);
-    }
-  }
-
-
-  function get_additional_error()
-  {
-    $error= "";
-    @ldap_get_option ($this->cid, LDAP_OPT_ERROR_STRING, $error);
-    return ($error);
-  }
-
-
-  function success()
-  {
-    return (preg_match('/Success/i', $this->error));
-  }
-
-
-  function get_error()
-  {
-    if ($this->error == 'Success'){
-      return $this->error;
-    } else {
-      $adderror= $this->get_additional_error();
-      if ($adderror != ""){
-        $error= $this->error." (".$this->get_additional_error().", ".sprintf(_("while operating on %s using LDAP server %s"), bold($this->basedn), bold($this->hostname)).")";
-      } else {
-        $error= $this->error." (".sprintf(_("while operating on LDAP server %s"), bold($this->hostname)).")";
-      }
-      return $error;
+
+        return TRUE;
     }
-  }
 
-  function get_credentials($url, $referrals= NULL)
-  {
-    $ret= array();
-    $url= preg_replace('!\?\?.*$!', '', $url);
-    $server= preg_replace('!^([^:]+://[^/]+)/.*$!', '\\1', $url);
 
-    if ($referrals === NULL){
-      $referrals= $this->referrals;
+    function recursive_remove($srp)
+    {
+        $delarray= array();
+
+        /* Get sorted list of dn's to delete */
+        $this->search ($srp, "(objectClass=*)");
+        while ($this->fetch($srp)){
+            $deldn= $this->getDN($srp);
+            $delarray[$deldn]= strlen($deldn);
+        }
+        arsort ($delarray);
+        reset ($delarray);
+
+        /* Delete all dn's in subtree */
+        foreach ($delarray as $key => $value){
+            $this->rmdir($key);
+        }
     }
 
-    if (isset($referrals[$server])){
-      return ($referrals[$server]);
-    } else {
-      $ret['ADMINDN']= LDAP::fix($this->binddn);
-      $ret['ADMINPASSWORD']= $this->bindpw;
+
+    function get_attribute($dn, $name,$r_array=0)
+    {
+        $data= "";
+        if ($this->reconnect) $this->connect();
+        $sr= @ldap_read($this->cid, LDAP::fix($dn), "objectClass=*", array("$name"));
+
+        /* fill data from LDAP */
+        if ($sr) {
+            $ei= @ldap_first_entry($this->cid, $sr);
+            if ($ei) {
+                if ($info= @ldap_get_values_len($this->cid, $ei, "$name")){
+                    $data= $info[0];
+                }
+            }
+        }
+        if($r_array==0) {
+            return ($data);
+        } else {
+            return ($info);
+        }
     }
 
-    return ($ret);
-  }
-
-
-  /*! \brief  Generates an ldif for all entries matching the filter settings, scope and limit.
-   *  @param  $dn           The entry to export.
-   *  @param  $filter       Limit the exported object to those maching this filter.
-   *  @param  $scope        'base', 'sub' .. see manpage for 'ldapmodify' for details.
-   *  @param  $limit        Limits the result.
-   */
-  function generateLdif ($dn, $filter= "(objectClass=*)", $scope = 'sub', $limit=0)
-  {
-      $attrs  = (count($attributes))?implode($attributes,' '):'';
-
-      // Ensure that limit is numeric if not skip here.
-      if(!empty($limit) && !is_numeric($limit)){
-          trigger_error(sprintf("Invalid parameter for limit '%s', a numeric value is required."), $limit);
-          return(NULL);
-      }
-      $limit = (!$limit)?'':' -z '.$limit;
-
-      // Check scope values
-      $scope = trim($scope);
-      if(!empty($scope) && !in_array($scope, array('base', 'one', 'sub', 'children'))){
-          trigger_error(sprintf("Invalid parameter for scope '%s', please use 'base', 'one', 'sub' or 'children'."), $scope);
-          return(NULL);
-      }
-      $scope = (!empty($scope))?' -s '.$scope: '';
-
-      // Prepare parameters to be valid for shell execution
-      $dn = escapeshellarg($dn);
-      $pwd = $this->bindpw;
-      $host = escapeshellarg($this->hostname);
-      $admin = escapeshellarg($this->binddn);
-      $filter = escapeshellarg($filter);
-      $cmd = "ldapsearch -x -LLLL -D {$admin} {$filter} {$limit} {$scope} -H {$host} -b {$dn} -W ";
-
-      // Create list of process pipes  
-      $descriptorspec = array(
-              0 => array("pipe", "r"),  // stdin
-              1 => array("pipe", "w"),  // stdout
-              2 => array("pipe", "w")); // stderr
-    
-      // Try to open the process 
-      $process = proc_open($cmd, $descriptorspec, $pipes);
-      if (is_resource($process)) {
-
-          // Write the password to stdin
-          fwrite($pipes[0], $pwd);
-          fclose($pipes[0]);
-
-          // Get results from stdout and stderr
-          $res = stream_get_contents($pipes[1]);
-          $err = stream_get_contents($pipes[2]);
-          fclose($pipes[1]);
-
-          // Close the process and check its return value
-          if(proc_close($process) != 0){
-              trigger_error($err);
-          }
-      }
-      return($res);
-  }
-
-
-  function gen_xls ($srp, $dn, $filter= "(objectClass=*)", $attributes= array('*'), $recursive= TRUE,$r_array=0)
-  {
-    $display= array();
-
-      $this->cd($dn);
-      $this->search($srp, "$filter");
-
-      $i=0;
-      while ($attrs= $this->fetch($srp)){
-        $j=0;
-
-        foreach ($attributes as $at){
-          $display[$i][$j]= $this->get_attribute($attrs['dn'], $at,$r_array);
-          $j++;
-        }
-
-        $i++;
-      }
-
-    return ($display);
-  }
-
-
-  function dn_exists($dn)
-  {
-    return @ldap_list($this->cid, LDAP::fix($dn), "(objectClass=*)", array("objectClass"));
-  }
-  
-
-
-  /*  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($srp, $str_attr,$error,$JustModify,$DeleteOldEntries)
-  {
-    if($this->reconnect) $this->connect();
-
-    /* First we have to split the string into empty lines.
-       An empty line indicates an new Entry */
-    $entries = preg_split("/\n/",$str_attr);
-
-    $data = "";
-    $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);
-      }
+
+
+    function get_additional_error()
+    {
+        $error= "";
+        @ldap_get_option ($this->cid, LDAP_OPT_ERROR_STRING, $error);
+        return ($error);
     }
 
-    /* Every single line ... */
-    foreach($tmp as $entry) {
-      $current_line ++;
-
-      /* Removing Spaces to .. 
-         .. test if a new entry begins */
-      $tmp  = str_replace(" ","",$data );
-
-      /* .. prevent empty lines in an entry */
-      $tmp2 = str_replace(" ","",$entry);
-
-      /* If the Block ends (Empty Line) */
-      if((empty($entry))&&(!empty($tmp))) {
-        /* Add collected lines as a complete block */
-        $all[$cnt] = $data;
-        $cnt ++;
-        $data ="";
-      } else {
-
-        /* Append lines ... */
-        if(!empty($tmp2)) {
-          /* check if we need base64_decode for this line */
-          if(strstr($tmp2, "::") !== false)
-          {
-            $encoded = explode("::",$entry);
-            $attr  = trim($encoded[0]);
-            $value = base64_decode(trim($encoded[1]));
-            /* Add linenumber */
-            $data .= $current_line."#".base64_encode($attr.":".$value)."\n";
-          }
-          else
-          {
-            /* Add Linenumber */ 
-            $data .= $current_line."#".base64_encode($entry)."\n";
-          }
-        }
-      }
+
+    function success()
+    {
+        return (preg_match('/Success/i', $this->error));
     }
 
-    /* The Data we collected is not in the array all[];
-       For example the Data is stored like this..
-
-       all[0] = "1#dn : .... \n 
-       2#ObjectType: person \n ...."
-       
-       Now we check every insertblock and try to insert */
-    foreach ( $all as $single) {
-      $lineone = preg_split("/\n/",$single);  
-      $ndn = explode("#", $lineone[0]);
-      $line = base64_decode($ndn[1]);
-
-      $dnn = explode (":",$line,2);
-      $current_line = $ndn[0];
-      $dn    = $dnn[0];
-      $value = $dnn[1];
-
-      /* Every block must begin with a dn */
-      if($dn != "dn") {
-        $error= sprintf(_("Invalid DN %s: block to be imported should start with 'dn: ...' in line %s"), bold($line), bold($current_line));
-        return -2;  
-      }
-
-      /* Should we use Modify instead of Add */
-      $usemodify= false;
-
-      /* Delete before insert */
-      $usermdir= false;
-    
-      /* The dn address already exists, Don't delete destination entry, overwrite it */
-      if (($this->dn_exists($value))&&((!$JustModify)&&(!$DeleteOldEntries))) {
-
-        $usermdir = $usemodify = false;
-
-      /* Delete old entry first, then add new */
-      } elseif(($this->dn_exists($value))&&($DeleteOldEntries)){
-
-        /* Delete first, then add */
-        $usermdir = true;        
-
-      } elseif(($this->dn_exists($value))&&($JustModify)) {
-        
-        /* Modify instead of Add */
-        $usemodify = true;
-      }
-     
-      /* If we can't Import, return with a file error */
-      if(!$this->import_single_entry($srp, $single,$usemodify,$usermdir) ) {
-        $error= sprintf(_("Error while importing DN %s: please check LDIF from line %s on!"), bold($line),
-                        $current_line);
-        return UNKNOWN_TOKEN_IN_LDIF_FILE;      }
+
+    function get_error()
+    {
+        if ($this->error == 'Success'){
+            return $this->error;
+        } else {
+            $adderror= $this->get_additional_error();
+            if ($adderror != ""){
+                $error= $this->error." (".$this->get_additional_error().", ".sprintf(_("while operating on %s using LDAP server %s"), bold($this->basedn), bold($this->hostname)).")";
+            } else {
+                $error= $this->error." (".sprintf(_("while operating on LDAP server %s"), bold($this->hostname)).")";
+            }
+            return $error;
+        }
     }
 
-    return (INSERT_OK);
-  }
+    function get_credentials($url, $referrals= NULL)
+    {
+        $ret= array();
+        $url= preg_replace('!\?\?.*$!', '', $url);
+        $server= preg_replace('!^([^:]+://[^/]+)/.*$!', '\\1', $url);
 
+        if ($referrals === NULL){
+            $referrals= $this->referrals;
+        }
 
-  /* 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($srp, $str_attr,$modify,$delete)
-  {
-    global $config;
+        if (isset($referrals[$server])){
+            return ($referrals[$server]);
+        } else {
+            $ret['ADMINDN']= LDAP::fix($this->binddn);
+            $ret['ADMINPASSWORD']= $this->bindpw;
+        }
 
-    if(!$config){
-      trigger_error("Can't import ldif, can't read config object.");
+        return ($ret);
     }
-  
 
-    if($this->reconnect) $this->connect();
 
-    $ret = false;
-    $rows= preg_split("/\n/",$str_attr);
-    $data= false;
+    /*! \brief  Generates an ldif for all entries matching the filter settings, scope and limit.
+     *  @param  $dn           The entry to export.
+     *  @param  $filter       Limit the exported object to those maching this filter.
+     *  @param  $scope        'base', 'sub' .. see manpage for 'ldapmodify' for details.
+     *  @param  $limit        Limits the result.
+     */
+    function generateLdif ($dn, $filter= "(objectClass=*)", $scope = 'sub', $limit=0)
+    {
+        $attrs  = (count($attributes))?implode($attributes,' '):'';
 
-    foreach($rows as $row) {
-      
-      /* Check if we use Linenumbers (when import_complete_ldif is called we use
-         Linenumbers) Linenumbers are use like this 123#attribute : value */
-      if(!empty($row)) {
-        if(strpos($row,"#")!=FALSE) {
+        // Ensure that limit is numeric if not skip here.
+        if(!empty($limit) && !is_numeric($limit)){
+            trigger_error(sprintf("Invalid parameter for limit '%s', a numeric value is required."), $limit);
+            return(NULL);
+        }
+        $limit = (!$limit)?'':' -z '.$limit;
 
-          /* We are using line numbers 
-             Because there is a # before a : */
-          $tmp1= explode("#",$row);
-          $current_line= $tmp1[0];
-          $row= base64_decode($tmp1[1]);
+        // Check scope values
+        $scope = trim($scope);
+        if(!empty($scope) && !in_array($scope, array('base', 'one', 'sub', 'children'))){
+            trigger_error(sprintf("Invalid parameter for scope '%s', please use 'base', 'one', 'sub' or 'children'."), $scope);
+            return(NULL);
         }
+        $scope = (!empty($scope))?' -s '.$scope: '';
+
+        // Prepare parameters to be valid for shell execution
+        $dn = escapeshellarg($dn);
+        $pwd = $this->bindpw;
+        $host = escapeshellarg($this->hostname);
+        $admin = escapeshellarg($this->binddn);
+        $filter = escapeshellarg($filter);
+        $cmd = "ldapsearch -x -LLLL -D {$admin} {$filter} {$limit} {$scope} -H {$host} -b {$dn} -W ";
+
+        // Create list of process pipes  
+        $descriptorspec = array(
+                0 => array("pipe", "r"),  // stdin
+                1 => array("pipe", "w"),  // stdout
+                2 => array("pipe", "w")); // stderr
+
+        // Try to open the process 
+        $process = proc_open($cmd, $descriptorspec, $pipes);
+        if (is_resource($process)) {
+
+            // Write the password to stdin
+            fwrite($pipes[0], $pwd);
+            fclose($pipes[0]);
+
+            // Get results from stdout and stderr
+            $res = stream_get_contents($pipes[1]);
+            $err = stream_get_contents($pipes[2]);
+            fclose($pipes[1]);
+
+            // Close the process and check its return value
+            if(proc_close($process) != 0){
+                trigger_error($err);
+            }
+        }
+        return($res);
+    }
 
-        /* Split the line into  attribute  and value */
-        $attr   = explode(":", $row,2);
-        $attr[0]= trim($attr[0]);  /* attribute */
-        $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]);
-        }
+    function gen_xls ($srp, $dn, $filter= "(objectClass=*)", $attributes= array('*'), $recursive= TRUE,$r_array=0)
+    {
+        $display= array();
 
-        $attr[1] = trim($attr[1]);
+        $this->cd($dn);
+        $this->search($srp, "$filter");
 
-        /* Check for attributes that are used more than once */
-        if(!isset($data[$attr[0]])) {
-          $data[$attr[0]]=$attr[1];
-        } else {
-          $tmp = $data[$attr[0]];
-
-          if(!is_array($tmp)) {
-            $new[0]=$tmp;
-            $new[1]=$attr[1];
-            $datas[$attr[0]]['count']=1;             
-            $data[$attr[0]]=$new;
-          } else {
-            $cnt = $datas[$attr[0]]['count'];           
-            $cnt ++;
-            $data[$attr[0]][$cnt]=$attr[1];
-            $datas[$attr[0]]['count'] = $cnt;
-          }
-        }
-      }
-    }
+        $i=0;
+        while ($attrs= $this->fetch($srp)){
+            $j=0;
 
-    /* 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']);
-
-      /* Delete existing entry */
-      if($delete){
-        $this->rmdir_recursive($srp, $data['dn']);
-      }
-     
-      /* Create missing trees */
-      $this->cd ($this->basedn);
-      $this->cd($config->current['BASE']);
-      $this->create_missing_trees($srp, preg_replace("/^[^,]+,/","",$data['dn']));
-      $this->cd($data['dn']);
-
-      $dn = $data['dn'];
-      unset($data['dn']);
-      
-      if(!$modify){
-
-        $this->cat($srp, $dn);
-        if($this->count($srp)){
-        
-          /* The destination entry exists, overwrite it with the new entry */
-          $attrs = $this->fetch($srp);
-          foreach($attrs as $name => $value ){
-            if(!is_numeric($name)){
-              if(in_array($name,array("dn","count"))) continue;
-              if(!isset($data[$name])){
-                $data[$name] = array();
-              }
+            foreach ($attributes as $at){
+                $display[$i][$j]= $this->get_attribute($attrs['dn'], $at,$r_array);
+                $j++;
             }
-          }
-          $ret = $this->modify($data);
-    
-        }else{
-    
-          /* The destination entry doesn't exists, create it */
-          $ret = $this->add($data);
+
+            $i++;
         }
 
-      } else {
-        
-        /* Keep all vars that aren't touched by this ldif */
-        $ret = $this->modify($data);
-      }
+        return ($display);
     }
 
-    if (!$this->success()){
-      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($this->get_error(), $dn, "", get_class()));
+
+    function dn_exists($dn)
+    {
+        return @ldap_list($this->cid, LDAP::fix($dn), "(objectClass=*)", array("objectClass"));
     }
 
-    return($ret);
-  }
 
-  
-  function importcsv($str)
-  {
-    $lines = preg_split("/\n/",$str);
-    foreach($lines as $line)
+
+    /*  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($srp, $str_attr,$error,$JustModify,$DeleteOldEntries)
     {
-      /* continue if theres a comment */
-      if(substr(trim($line),0,1)=="#"){
-        continue;
-      }
-
-      $line= str_replace ("\t\t","\t",$line);
-      $line= str_replace ("\t"  ,"," ,$line);
-      echo $line;
-
-      $cells = explode(",",$line )  ;
-      $linet= str_replace ("\t\t",",",$line);
-      $cells = preg_split("/\t/",$line);
-      $count = count($cells);  
-    }
+        if($this->reconnect) $this->connect();
+
+        /* First we have to split the string into empty lines.
+           An empty line indicates an new Entry */
+        $entries = preg_split("/\n/",$str_attr);
+
+        $data = "";
+        $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($tmp as $entry) {
+            $current_line ++;
+
+            /* Removing Spaces to .. 
+               .. test if a new entry begins */
+            $tmp  = str_replace(" ","",$data );
+
+            /* .. prevent empty lines in an entry */
+            $tmp2 = str_replace(" ","",$entry);
+
+            /* If the Block ends (Empty Line) */
+            if((empty($entry))&&(!empty($tmp))) {
+                /* Add collected lines as a complete block */
+                $all[$cnt] = $data;
+                $cnt ++;
+                $data ="";
+            } else {
+
+                /* Append lines ... */
+                if(!empty($tmp2)) {
+                    /* check if we need base64_decode for this line */
+                    if(strstr($tmp2, "::") !== false)
+                    {
+                        $encoded = explode("::",$entry);
+                        $attr  = trim($encoded[0]);
+                        $value = base64_decode(trim($encoded[1]));
+                        /* Add linenumber */
+                        $data .= $current_line."#".base64_encode($attr.":".$value)."\n";
+                    }
+                    else
+                    {
+                        /* Add Linenumber */ 
+                        $data .= $current_line."#".base64_encode($entry)."\n";
+                    }
+                }
+            }
+        }
+
+        /* The Data we collected is not in the array all[];
+           For example the Data is stored like this..
+
+           all[0] = "1#dn : .... \n 
+           2#ObjectType: person \n ...."
+
+           Now we check every insertblock and try to insert */
+        foreach ( $all as $single) {
+            $lineone = preg_split("/\n/",$single);  
+            $ndn = explode("#", $lineone[0]);
+            $line = base64_decode($ndn[1]);
+
+            $dnn = explode (":",$line,2);
+            $current_line = $ndn[0];
+            $dn    = $dnn[0];
+            $value = $dnn[1];
+
+            /* Every block must begin with a dn */
+            if($dn != "dn") {
+                $error= sprintf(_("Invalid DN %s: block to be imported should start with 'dn: ...' in line %s"), bold($line), bold($current_line));
+                return -2;  
+            }
 
-  }
-  
-  function get_objectclasses( $force_reload = FALSE)
-  {
-    $objectclasses = array();
-    global $config;
-
-    /* Return the cached results. */
-    if(class_available('session') && session::global_is_set("LDAP_CACHE::get_objectclasses") && !$force_reload){
-      $objectclasses = session::global_get("LDAP_CACHE::get_objectclasses");
-      return($objectclasses);
+            /* Should we use Modify instead of Add */
+            $usemodify= false;
+
+            /* Delete before insert */
+            $usermdir= false;
+
+            /* The dn address already exists, Don't delete destination entry, overwrite it */
+            if (($this->dn_exists($value))&&((!$JustModify)&&(!$DeleteOldEntries))) {
+
+                $usermdir = $usemodify = false;
+
+                /* Delete old entry first, then add new */
+            } elseif(($this->dn_exists($value))&&($DeleteOldEntries)){
+
+                /* Delete first, then add */
+                $usermdir = true;        
+
+            } elseif(($this->dn_exists($value))&&($JustModify)) {
+
+                /* Modify instead of Add */
+                $usemodify = true;
+            }
+
+            /* If we can't Import, return with a file error */
+            if(!$this->import_single_entry($srp, $single,$usemodify,$usermdir) ) {
+                $error= sprintf(_("Error while importing DN %s: please check LDIF from line %s on!"), bold($line),
+                        $current_line);
+                return UNKNOWN_TOKEN_IN_LDIF_FILE;      }
+        }
+
+        return (INSERT_OK);
     }
-       
-         # Get base to look for schema 
-         $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= explode(' ', $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 != ""){
-                      $v = $this->value2container($value);
-                      if(in_array($name, array('MUST', 'MAY')) && !is_array($v)){
-                        $v = array($v);
-                      }
-                      $objectclasses[$ocname][$name]= $v;
+
+    /* 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($srp, $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;
+        $rows= preg_split("/\n/",$str_attr);
+        $data= false;
+
+        foreach($rows as $row) {
+
+            /* Check if we use Linenumbers (when import_complete_ldif is called we use
+               Linenumbers) Linenumbers are use like this 123#attribute : value */
+            if(!empty($row)) {
+                if(strpos($row,"#")!=FALSE) {
+
+                    /* We are using line numbers 
+                       Because there is a # before a : */
+                    $tmp1= explode("#",$row);
+                    $current_line= $tmp1[0];
+                    $row= base64_decode($tmp1[1]);
+                }
+
+                /* Split the line into  attribute  and value */
+                $attr   = explode(":", $row,2);
+                $attr[0]= trim($attr[0]);  /* attribute */
+                $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]])) {
+                    $data[$attr[0]]=$attr[1];
+                } else {
+                    $tmp = $data[$attr[0]];
+
+                    if(!is_array($tmp)) {
+                        $new[0]=$tmp;
+                        $new[1]=$attr[1];
+                        $datas[$attr[0]]['count']=1;             
+                        $data[$attr[0]]=$new;
+                    } else {
+                        $cnt = $datas[$attr[0]]['count'];           
+                        $cnt ++;
+                        $data[$attr[0]][$cnt]=$attr[1];
+                        $datas[$attr[0]]['count'] = $cnt;
                     }
-                    $name= "";
-                    $value= "";
-                    break;
+                }
+            }
+        }
+
+        /* 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']);
 
-          case 'NAME':
-          case 'DESC':
-          case 'SUP':
-          case 'STRUCTURAL':
-          case 'ABSTRACT':
-          case 'AUXILIARY':
-          case 'MUST':
-          case 'MAY':
-                    if ($name != ""){
-                      $v = $this->value2container($value);
-                      if(in_array($name, array('MUST', 'MAY')) && !is_array($v)){
-                        $v = array($v);
-                      }
-                      $objectclasses[$ocname][$name]= $v;
+            /* Delete existing entry */
+            if($delete){
+                $this->rmdir_recursive($srp, $data['dn']);
+            }
+
+            /* Create missing trees */
+            $this->cd ($this->basedn);
+            $this->cd($config->current['BASE']);
+            $this->create_missing_trees($srp, preg_replace("/^[^,]+,/","",$data['dn']));
+            $this->cd($data['dn']);
+
+            $dn = $data['dn'];
+            unset($data['dn']);
+
+            if(!$modify){
+
+                $this->cat($srp, $dn);
+                if($this->count($srp)){
+
+                    /* The destination entry exists, overwrite it with the new entry */
+                    $attrs = $this->fetch($srp);
+                    foreach($attrs as $name => $value ){
+                        if(!is_numeric($name)){
+                            if(in_array($name,array("dn","count"))) continue;
+                            if(!isset($data[$name])){
+                                $data[$name] = array();
+                            }
+                        }
                     }
-                    $name= $chunk;
-                    $value= "";
-                    break;
+                    $ret = $this->modify($data);
+
+                }else{
+
+                    /* The destination entry doesn't exists, create it */
+                    $ret = $this->add($data);
+                }
 
-          default:  $value.= $chunk." ";
+            } else {
+
+                /* Keep all vars that aren't touched by this ldif */
+                $ret = $this->modify($data);
+            }
+        }
+
+        if (!$this->success()){
+            msg_dialog::display(_("LDAP error"), msgPool::ldaperror($this->get_error(), $dn, "", get_class()));
         }
-      }
 
-         }
-    if(class_available("session")){
-      session::global_set("LDAP_CACHE::get_objectclasses",$objectclasses);
+        return($ret);
     }
 
-         return $objectclasses;
-  }
 
+    function importcsv($str)
+    {
+        $lines = preg_split("/\n/",$str);
+        foreach($lines as $line)
+        {
+            /* continue if theres a comment */
+            if(substr(trim($line),0,1)=="#"){
+                continue;
+            }
 
-  function value2container($value)
-  {
-    /* Set emtpy values to "true" only */
-    if (preg_match('/^\s*$/', $value)){
-      return true;
-    }
+            $line= str_replace ("\t\t","\t",$line);
+            $line= str_replace ("\t"  ,"," ,$line);
+            echo $line;
 
-    /* Remove ' and " if needed */
-    $value= preg_replace('/^[\'"]/', '', $value);
-    $value= preg_replace('/[\'"] *$/', '', $value);
+            $cells = explode(",",$line )  ;
+            $linet= str_replace ("\t\t",",",$line);
+            $cells = preg_split("/\t/",$line);
+            $count = count($cells);  
+        }
 
-    /* Convert to array if $ is inside... */
-    if (preg_match('/\$/', $value)){
-      $container= preg_split('/\s*\$\s*/', $value);
-    } else {
-      $container= chop($value);
     }
 
-    return ($container);
-  }
+    function get_objectclasses( $force_reload = FALSE)
+    {
+        $objectclasses = array();
+        global $config;
 
+        /* Return the cached results. */
+        if(class_available('session') && session::global_is_set("LDAP_CACHE::get_objectclasses") && !$force_reload){
+            $objectclasses = session::global_get("LDAP_CACHE::get_objectclasses");
+            return($objectclasses);
+        }
 
-  function log($string)
-  {
-    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);
-      }
-    }
-  }
+# Get base to look for schema 
+        $sr = @ldap_read ($this->cid, "", "objectClass=*", array("subschemaSubentry"));
+        $attr = @ldap_get_entries($this->cid,$sr);
+        if (!isset($attr[0]['subschemasubentry'][0])){
+            return array();
+        }
 
-  /* added by Guido Serra aka Zeph <zeph@purotesto.it> */
-  function getCn($dn){
-    $simple= explode(",", $dn);
+        /* 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= explode(' ', $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 != ""){
+                                  $v = $this->value2container($value);
+                                  if(in_array($name, array('MUST', 'MAY')) && !is_array($v)){
+                                      $v = array($v);
+                                  }
+                                  $objectclasses[$ocname][$name]= $v;
+                              }
+                              $name= "";
+                              $value= "";
+                              break;
+
+                    case 'NAME':
+                    case 'DESC':
+                    case 'SUP':
+                    case 'STRUCTURAL':
+                    case 'ABSTRACT':
+                    case 'AUXILIARY':
+                    case 'MUST':
+                    case 'MAY':
+                              if ($name != ""){
+                                  $v = $this->value2container($value);
+                                  if(in_array($name, array('MUST', 'MAY')) && !is_array($v)){
+                                      $v = array($v);
+                                  }
+                                  $objectclasses[$ocname][$name]= $v;
+                              }
+                              $name= $chunk;
+                              $value= "";
+                              break;
+
+                    default:  $value.= $chunk." ";
+                }
+            }
 
-    foreach($simple as $piece) {
-      $partial= explode("=", $piece);
+        }
+        if(class_available("session")){
+            session::global_set("LDAP_CACHE::get_objectclasses",$objectclasses);
+        }
 
-      if($partial[0] == "cn"){
-        return $partial[1];
-      }
+        return $objectclasses;
     }
-  }
 
 
-  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);
+    function value2container($value)
+    {
+        /* Set emtpy values to "true" only */
+        if (preg_match('/^\s*$/', $value)){
+            return true;
+        }
 
-    /* Get base to look for naming contexts */
-    $sr  = @ldap_read ($ds, "", "objectClass=*", array("+"));
-    $attr= @ldap_get_entries($ds,$sr);
+        /* 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 ($attr[0]['namingcontexts']);
-  }
+        return ($container);
+    }
 
 
-  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!");
+    function log($string)
+    {
+        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);
+            }
+        }
     }
-    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();
+
+    /* added by Guido Serra aka Zeph <zeph@purotesto.it> */
+    function getCn($dn){
+        $simple= explode(",", $dn);
+
+        foreach($simple as $piece) {
+            $partial= explode("=", $piece);
+
+            if($partial[0] == "cn"){
+                return $partial[1];
+            }
+        }
     }
 
-    /* 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']);
+
+    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']);
     }
 
-    return ($result);
-  }
+
+    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: