Code

Added fall back to old style move method.
[gosa.git] / gosa-core / include / class_plugin.inc
index 580be7939ac143b284262d3860afcc144e22683a..3765ed2d038cd79d69df3f66fcb801ce21560969 100644 (file)
@@ -215,13 +215,18 @@ class plugin
           unset($this->saved_attributes[$index]);
           continue;
         }
-        if (isset($this->saved_attributes[$index][0]) && $this->saved_attributes[$index]["count"] == 1){
-          $tmp= $this->saved_attributes[$index][0];
-          unset($this->saved_attributes[$index]);
-          $this->saved_attributes[$index]= $tmp;
-          continue;
-        }
 
+        if (isset($this->saved_attributes[$index][0])){
+          if(!isset($this->saved_attributes[$index]["count"])){
+            $this->saved_attributes[$index]["count"] = count($this->saved_attributes[$index]);
+          }
+          if($this->saved_attributes[$index]["count"] == 1){
+            $tmp= $this->saved_attributes[$index][0];
+            unset($this->saved_attributes[$index]);
+            $this->saved_attributes[$index]= $tmp;
+            continue;
+          }
+        }
         unset($this->saved_attributes["$index"]["count"]);
       }
       if(isset($this->attrs['gosaUnitTag'])){
@@ -608,18 +613,25 @@ class plugin
 
     if ($command != ""){
 
-      /* Additional attributes */
-      foreach ($add_attrs as $name => $value){
-        $command= preg_replace("/%$name( |$)/", "$value ", $command);
-      }
-
       /* Walk through attribute list */
       foreach ($this->attributes as $attr){
         if (!is_array($this->$attr)){
-          $command= preg_replace("/%$attr( |$)/", $this->$attr." ", $command);
+          $add_attrs[$attr] = $this->$attr;
         }
       }
-      $command= preg_replace("/%dn( |$)/", $this->dn." ", $command);
+      $add_attrs['dn']=$this->dn;
+
+      $tmp = array();
+      foreach($add_attrs as $name => $value){
+        $tmp[$name] =  strlen($name);
+      }
+      arsort($tmp);
+      
+      /* Additional attributes */
+      foreach ($tmp as $name => $len){
+        $value = $add_attrs[$name];
+        $command= preg_replace("/%$name/", "$value", $command);
+      }
 
       if (check_command($command)){
         @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__,
@@ -627,7 +639,7 @@ class plugin
 
         exec($command);
       } else {
-        $message[]= msgPool::cmdnotfound("POSTCREATE", get_class($this));
+        $message= msgPool::cmdnotfound("POSTCREATE", get_class($this));
         msg_dialog::display(_("Error"), $message, ERROR_DIALOG);
       }
     }
@@ -640,26 +652,31 @@ class plugin
 
     if ($command != ""){
 
-      /* Additional attributes */
-      foreach ($add_attrs as $name => $value){
-        $command= preg_replace("/%$name( |$)/", "$value ", $command);
-      }
-
       /* Walk through attribute list */
       foreach ($this->attributes as $attr){
         if (!is_array($this->$attr)){
-          $command= preg_replace("/%$attr( |$)/", $this->$attr." ", $command);
+          $add_attrs[$attr] = $this->$attr;
         }
       }
-      $command= preg_replace("/%dn( |$)/", $this->dn." ", $command);
+      $add_attrs['dn']=$this->dn;
 
-      if (check_command($command)){
-        @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__,
-            $command, "Execute");
+      $tmp = array();
+      foreach($add_attrs as $name => $value){
+        $tmp[$name] =  strlen($name);
+      }
+      arsort($tmp);
+      
+      /* Additional attributes */
+      foreach ($tmp as $name => $len){
+        $value = $add_attrs[$name];
+        $command= preg_replace("/%$name/", "$value", $command);
+      }
 
+      if (check_command($command)){
+        @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__,$command, "Execute");
         exec($command);
       } else {
-        $message[]= msgPool::cmdnotfound("POSTMODIFY", get_class($this));
+        $message= msgPool::cmdnotfound("POSTMODIFY", get_class($this));
         msg_dialog::display(_("Error"), $message, ERROR_DIALOG);
       }
     }
@@ -671,18 +688,25 @@ class plugin
     $command= $this->config->search(get_class($this), "POSTREMOVE",array('menu','tabs'));
     if ($command != ""){
 
-      /* Additional attributes */
-      foreach ($add_attrs as $name => $value){
-        $command= preg_replace("/%$name( |$)/", "$value ", $command);
-      }
-
       /* Walk through attribute list */
       foreach ($this->attributes as $attr){
         if (!is_array($this->$attr)){
-          $command= preg_replace("/%$attr( |$)/", $this->$attr." ", $command);
+          $add_attrs[$attr] = $this->$attr;
         }
       }
-      $command= preg_replace("/%dn( |$)/", $this->dn." ", $command);
+      $add_attrs['dn']=$this->dn;
+
+      $tmp = array();
+      foreach($add_attrs as $name => $value){
+        $tmp[$name] =  strlen($name);
+      }
+      arsort($tmp);
+      
+      /* Additional attributes */
+      foreach ($tmp as $name => $len){
+        $value = $add_attrs[$name];
+        $command= preg_replace("/%$name/", "$value", $command);
+      }
 
       if (check_command($command)){
         @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__,
@@ -690,7 +714,7 @@ class plugin
 
         exec($command);
       } else {
-        $message[]= msgPool::cmdnotfound("POSTREMOVE", get_class($this));
+        $message= msgPool::cmdnotfound("POSTREMOVE", get_class($this));
         msg_dialog::display(_("Error"), $message, ERROR_DIALOG);
       }
     }
@@ -729,7 +753,7 @@ class plugin
   function rebind($ldap, $referral)
   {
     $credentials= LDAP::get_credentials($referral, $this->config->current['REFERRAL']);
-    if (ldap_bind($ldap, $credentials['ADMIN'], $credentials['PASSWORD'])) {
+    if (ldap_bind($ldap, $credentials['ADMIN'], $this->config->get_credentials($credentials['PASSWORD']))) {
       $this->error = "Success";
       $this->hascon=true;
       $this->reconnect= true;
@@ -858,6 +882,114 @@ class plugin
   }
 
 
+
+  /*! \brief  Move a given ldap object indentified by $src_dn   \
+               to the given destination $dst_dn   \
+              * Ensure that all references are updated (ogroups) \
+              * Update ACLs   \
+              * Update accessTo   \
+      @param  String  The source dn.
+      @param  String  The destination dn.
+      @return Boolean TRUE on success else FALSE.
+   */
+  function rename($src_dn, $dst_dn)
+  {
+    $start = microtime(1);
+
+    /* Try to move the source entry to the destination position */
+    $ldap = $this->config->get_ldap_link();
+    if (!$ldap->rename_dn($src_dn,$dst_dn)){
+      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $src_dn, "", get_class()));
+      return(FALSE);
+    }
+
+    /* Get list of groups within this tree,
+        maybe we have to update ACL references.
+     */
+    $leaf_groups = get_list("(objectClass=posixGroup)",array("all"),$dst_dn,
+          array("dn","objectClass"),GL_SUBSEARCH | GL_NO_ACL_CHECK);
+    
+    /* Get list of users within this tree,
+        maybe we have to update ACL references.
+     */
+    $leaf_users=  get_list("(objectClass=gosaAccount)",array("all"),$dst_dn,
+          array("dn","objectClass"),GL_SUBSEARCH | GL_NO_ACL_CHECK);
+
+
+    /* Updated acls set for this groups */
+    foreach($leaf_groups as $group){
+      $new_dn = $group['dn'];
+      $old_dn = preg_replace("/".normalizePreg($dst_dn)."$/i",$src_dn,$new_dn);
+      $this->update_acls($old_dn,$new_dn); 
+    }
+
+    /* Updated acls set for this users */
+    foreach($leaf_users as $user){
+      $new_dn = $user['dn'];
+      $old_dn = preg_replace("/".normalizePreg($dst_dn)."$/i",$src_dn,$new_dn);
+      $this->update_acls($old_dn,$new_dn); 
+    }
+
+    /* Get all objectGroups defined in this database. 
+        and check if there is an entry matching the source dn,
+        if this is the case, then update this objectgroup to use the new dn.
+     */
+    $ogroups = get_sub_list("(&(objectClass=gosaGroupOfNames)(member=*))","ogroups",
+        array(get_ou("ogroupou")),$this->config->current['BASE'],array("member"),
+        GL_SUBSEARCH | GL_NO_ACL_CHECK) ;
+
+    /* Walk through all objectGroups and check if there are 
+        members matching the source dn 
+     */
+    foreach($ogroups as $ogroup){
+      if(isset($ogroup['member'])){
+
+        /* Reset class object, this will be initialized with class_ogroup on demand 
+         */
+        $o_ogroup = NULL; 
+        for($i = 0 ; $i < $ogroup['member']['count'] ; $i ++){
+
+          $c_mem = $ogroup['member'][$i];
+  
+          if(preg_match("/".normalizePreg($src_dn)."$/i",$c_mem)){
+            $d_mem = preg_replace("/".normalizePreg($src_dn)."$/i",$dst_dn,$ogroup['member'][$i]);
+
+            if($o_ogroup == NULL){
+              $o_ogroup = new ogroup($this->config,$ogroup['dn']);
+            }              
+
+            unset($o_ogroup->member[$c_mem]);
+            $o_ogroup->member[$d_mem]= $d_mem;
+          }
+        }
+       
+        /* Save object group if there were changes made on the membership */ 
+        if($o_ogroup != NULL){
+          $o_ogroup->save();
+        }
+      }
+    }
+    /* Check if there are gosa departments moved. 
+       If there were deps moved, the force reload of config->deps.
+     */
+    $leaf_deps=  get_list("(objectClass=gosaDepartment)",array("all"),$dst_dn,
+          array("dn","objectClass"),GL_SUBSEARCH | GL_NO_ACL_CHECK);
+  
+    if(count($leaf_deps)){
+      $this->config->get_departments();
+      $this->config->make_idepartments();
+      session::set("config",$this->config);
+      $ui =get_userinfo();
+      $ui->reset_acl_cache();
+    }
+
+    return(TRUE); 
+  }
+
+
+
   function move($src_dn, $dst_dn)
   {
     /* Do not copy if only upper- lowercase has changed */
@@ -865,6 +997,21 @@ class plugin
       return(TRUE);
     }
 
+    
+    /* Try to move the entry instead of copy & delete
+     */
+    if(TRUE){
+
+      /* Try to move with ldap routines, if this was not successfull
+          fall back to the old style copy & remove method 
+       */
+      if($this->rename($src_dn, $dst_dn)){
+        return(TRUE)
+      }else{
+        // See code below.
+      }
+    }
+
     /* Copy source to destination */
     if (!$this->copy($src_dn, $dst_dn)){
       return (FALSE);
@@ -992,7 +1139,7 @@ class plugin
         foreach ($this->config->adepartments as $key => $ntag){
 
           /* This one is bigger than our dn, its not relevant... */
-          if ($len <= strlen($key)){
+          if ($len < strlen($key)){
             continue;
           }
 
@@ -1076,7 +1223,7 @@ class plugin
       $password       = $tmp['SNAPSHOT_PASSWORD'];
       $snapldapbase   = $tmp['SNAPSHOT_BASE'];
 
-      $ldap_to        = new ldapMultipelxer(new LDAP($user,$password, $server));
+      $ldap_to        = new ldapMultiplexer(new LDAP($user,$password, $server));
       $ldap_to -> cd($snapldapbase);
 
       if (!$ldap_to->success()){
@@ -1348,6 +1495,7 @@ class plugin
     $data  = gzuncompress($ldap_to->get_attribute($dn,'gosaSnapshotData'));
 
     /* Import the given data */
+    $err = "";
     $ldap->import_complete_ldif($data,$err,false,false);
     if (!$ldap->success()){
       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, "", get_class()));
@@ -1570,12 +1718,12 @@ class plugin
 
         $acls = array();
 
+        /* Reset vars */
+        $found = false;
+
         /* Walk through acls */
         for($i = 0 ; $i <  $attrs['gosaAclEntry']['count'] ; $i ++ ){
 
-          /* Reset vars */
-          $found = false;
-
           /* Get Acl parts */
           $acl_parts = split(":",$attrs['gosaAclEntry'][$i]);
 
@@ -1595,7 +1743,7 @@ class plugin
               $members[$key] = base64_encode($new_dn);
             }
           } 
-         
+       
           /* Create new member string */ 
           $new_members = "";
           foreach($members as $member){
@@ -1610,6 +1758,7 @@ class plugin
            $acl_str .= $t.":";
           }
           $acl_str = preg_replace("/:$/","",$acl_str);
+          $acls[] = $acl_str;
        }
 
        /* Acls for this object must be adjusted */