Code

Updated toggle method
[gosa.git] / gosa-core / include / class_plugin.inc
index dee53fbb0e430cf55c139e40fba865d2404c849c..bb5bd9e87b0cd310fa2ec80b50471993504ef6ad 100644 (file)
@@ -113,6 +113,7 @@ class plugin
 
   var $acl_base= "";
   var $acl_category= "";
 
   var $acl_base= "";
   var $acl_category= "";
+  var $read_only = FALSE; // Used when the entry is opened as "readonly" due to locks.
 
   /* This can be set to render the tabulators in another stylesheet */
   var $pl_notify= FALSE;
 
   /* This can be set to render the tabulators in another stylesheet */
   var $pl_notify= FALSE;
@@ -138,7 +139,7 @@ class plugin
     \param dn Distinguished name to initialize plugin from
     \sa plugin()
    */
     \param dn Distinguished name to initialize plugin from
     \sa plugin()
    */
-  function plugin (&$config, $dn= NULL, $parent= NULL)
+  function plugin (&$config, $dn= NULL, $object= NULL)
   {
     /* Configuration is fine, allways */
     $this->config= &$config;   
   {
     /* Configuration is fine, allways */
     $this->config= &$config;   
@@ -149,6 +150,16 @@ class plugin
       return;
     }
 
       return;
     }
 
+    /* Check if this entry was opened in read only mode */
+    if(isset($_POST['open_readonly'])){
+      if(session::global_is_set("LOCK_CACHE")){
+        $cache = &session::get("LOCK_CACHE");
+        if(isset($cache['READ_ONLY'][$this->dn])){
+          $this->read_only = TRUE;
+        }
+      }
+    }
+
     /* Save current dn as acl_base */
     $this->acl_base= $dn;
 
     /* Save current dn as acl_base */
     $this->acl_base= $dn;
 
@@ -156,8 +167,8 @@ class plugin
     if ($dn !== NULL){
 
       /* Load data to 'attrs' and save 'dn' */
     if ($dn !== NULL){
 
       /* Load data to 'attrs' and save 'dn' */
-      if ($parent !== NULL){
-        $this->attrs= $parent->attrs;
+      if ($object !== NULL){
+        $this->attrs= $object->attrs;
       } else {
         $ldap= $this->config->get_ldap_link();
         $ldap->cat ($dn);
       } else {
         $ldap= $this->config->get_ldap_link();
         $ldap->cat ($dn);
@@ -241,22 +252,21 @@ class plugin
   }
 
 
   }
 
 
-  /*! \brief execute plugin
-
-    Generates the html output for this node
+  /*! \brief Generates the html output for this node
    */
   function execute()
   {
     /* This one is empty currently. Fabian - please fill in the docu code */
    */
   function execute()
   {
     /* This one is empty currently. Fabian - please fill in the docu code */
-    session::set('current_class_for_help',get_class($this));
+    session::global_set('current_class_for_help',get_class($this));
 
     /* Reset Lock message POST/GET check array, to prevent perg_match errors*/
     session::set('LOCK_VARS_TO_USE',array());
 
     /* Reset Lock message POST/GET check array, to prevent perg_match errors*/
     session::set('LOCK_VARS_TO_USE',array());
-    session::set('LOCK_VARS_USED',array());
+    session::set('LOCK_VARS_USED_GET',array());
+    session::set('LOCK_VARS_USED_POST',array());
+    session::set('LOCK_VARS_USED_REQUEST',array());
   }
 
   }
 
-  /*! \brief execute plugin
-     Removes object from parent
+  /*! \brief Removes object from parent
    */
   function remove_from_parent()
   {
    */
   function remove_from_parent()
   {
@@ -294,7 +304,7 @@ class plugin
   }
 
 
   }
 
 
-  /*! \brief   Save HTML posted data to object 
+  /*! \brief Save HTML posted data to object 
    */
   function save_object()
   {
    */
   function save_object()
   {
@@ -332,7 +342,7 @@ class plugin
   }
 
 
   }
 
 
-  /* Save data to LDAP, depending on is_account we save or delete */
+  /*! \brief Save data to LDAP, depending on is_account we save or delete */
   function save()
   {
     /* include global link_info */
   function save()
   {
     /* include global link_info */
@@ -427,7 +437,7 @@ class plugin
     }
   }
 
     }
   }
 
-  /* Check formular input */
+  /*! \brief Check formular input */
   function check()
   {
     $message= array();
   function check()
   {
     $message= array();
@@ -551,14 +561,14 @@ class plugin
     }
   }
 
     }
   }
 
-  /* Indicate whether a password change is needed or not */
+  /* \brief Indicate whether a password change is needed or not */
   function password_change_needed()
   {
     return FALSE;
   }
 
 
   function password_change_needed()
   {
     return FALSE;
   }
 
 
-  /* Show header message for tab dialogs */
+  /*! \brief Show header message for tab dialogs */
   function show_enable_header($button_text, $text, $disabled= FALSE)
   {
     if (($disabled == TRUE) || (!$this->acl_is_createable())){
   function show_enable_header($button_text, $text, $disabled= FALSE)
   {
     if (($disabled == TRUE) || (!$this->acl_is_createable())){
@@ -574,7 +584,7 @@ class plugin
   }
 
 
   }
 
 
-  /* Show header message for tab dialogs */
+  /*! \brief Show header message for tab dialogs */
   function show_disable_header($button_text, $text, $disabled= FALSE)
   {
     if (($disabled == TRUE) || !$this->acl_is_removeable()){
   function show_disable_header($button_text, $text, $disabled= FALSE)
   {
     if (($disabled == TRUE) || !$this->acl_is_removeable()){
@@ -590,7 +600,7 @@ class plugin
   }
 
 
   }
 
 
-  /* Show header message for tab dialogs */
+  /*! \brief Show header message for tab dialogs */
   function show_header($button_text, $text, $disabled= FALSE)
   {
     echo "FIXME: show_header should be replaced by show_disable_header and show_enable_header<br>";
   function show_header($button_text, $text, $disabled= FALSE)
   {
     echo "FIXME: show_header should be replaced by show_disable_header and show_enable_header<br>";
@@ -607,7 +617,7 @@ class plugin
     return($display);
   }
 
     return($display);
   }
 
-
+  /*! \brief Executes commands after an object has been created */
   function postcreate($add_attrs= array())
   {
     /* Find postcreate entries for this class */
   function postcreate($add_attrs= array())
   {
     /* Find postcreate entries for this class */
@@ -650,6 +660,7 @@ class plugin
     }
   }
 
     }
   }
 
+  /*! \brief Execute commands after an object has been modified */
   function postmodify($add_attrs= array())
   {
     /* Find postcreate entries for this class */
   function postmodify($add_attrs= array())
   {
     /* Find postcreate entries for this class */
@@ -691,6 +702,7 @@ class plugin
     }
   }
 
     }
   }
 
+  /*! \brief Executes a command after an object has been removed */
   function postremove($add_attrs= array())
   {
     /* Find postremove entries for this class */
   function postremove($add_attrs= array())
   {
     /* Find postremove entries for this class */
@@ -733,7 +745,40 @@ class plugin
     }
   }
 
     }
   }
 
+
   /* Create unique DN */
   /* Create unique DN */
+  function create_unique_dn2($data, $base)
+  {
+    $ldap= $this->config->get_ldap_link();
+    $base= preg_replace("/^,*/", "", $base);
+
+    /* Try to use plain entry first */
+    $dn= "$data,$base";
+    $attribute= preg_replace('/=.*$/', '', $data);
+    $ldap->cat ($dn, array('dn'));
+    if (!$ldap->fetch()){
+      return ($dn);
+    }
+
+    /* Look for additional attributes */
+    foreach ($this->attributes as $attr){
+      if ($attr == $attribute || $this->$attr == ""){
+        continue;
+      }
+
+      $dn= "$data+$attr=".$this->$attr.",$base";
+      $ldap->cat ($dn, array('dn'));
+      if (!$ldap->fetch()){
+        return ($dn);
+      }
+    }
+
+    /* None found */
+    return ("none");
+  }
+
+
+  /*! \brief Create unique DN */
   function create_unique_dn($attribute, $base)
   {
     $ldap= $this->config->get_ldap_link();
   function create_unique_dn($attribute, $base)
   {
     $ldap= $this->config->get_ldap_link();
@@ -763,6 +808,7 @@ class plugin
     return ("none");
   }
 
     return ("none");
   }
 
+
   function rebind($ldap, $referral)
   {
     $credentials= LDAP::get_credentials($referral, $this->config->current['REFERRAL']);
   function rebind($ldap, $referral)
   {
     $credentials= LDAP::get_credentials($referral, $this->config->current['REFERRAL']);
@@ -792,7 +838,8 @@ class plugin
       ldap_set_rebind_proc($ds, array(&$this, "rebind"));
     }
 
       ldap_set_rebind_proc($ds, array(&$this, "rebind"));
     }
 
-    $r=ldap_bind($ds,$this->config->current['ADMINDN'], $this->config->current['ADMINPASSWORD']);
+    $pwd = $this->config->get_credentials($this->config->current['ADMINPASSWORD']);
+    $r=ldap_bind($ds,$this->config->current['ADMINDN'], $pwd);
     $sr=ldap_read($ds, LDAP::fix($src_dn), "objectClass=*");
 
     /* Fill data from LDAP */
     $sr=ldap_read($ds, LDAP::fix($src_dn), "objectClass=*");
 
     /* Fill data from LDAP */
@@ -839,6 +886,9 @@ class plugin
     /* FAIvariable=.../..., cn=.. 
         could not be saved, because the attribute FAIvariable was different to 
         the dn FAIvariable=..., cn=... */
     /* FAIvariable=.../..., cn=.. 
         could not be saved, because the attribute FAIvariable was different to 
         the dn FAIvariable=..., cn=... */
+
+    if(!is_array($new['objectClass'])) $new['objectClass'] = array($new['objectClass']);
+
     if(in_array_ics("FAIdebconfInfo",$new['objectClass'])){
       $new['FAIvariable'] = $ldap->fix($new['FAIvariable']);
     }
     if(in_array_ics("FAIdebconfInfo",$new['objectClass'])){
       $new['FAIvariable'] = $ldap->fix($new['FAIvariable']);
     }
@@ -896,14 +946,18 @@ 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.
+  /*! \brief  Rename/Move a given src_dn to the given dest_dn
+   *
+   * 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  'src_dn' the source DN.
+   * \param  string  'dst_dn' the destination DN.
+   * \return boolean TRUE on success else FALSE.
    */
   function rename($src_dn, $dst_dn)
   {
    */
   function rename($src_dn, $dst_dn)
   {
@@ -913,77 +967,62 @@ class plugin
     $ldap = $this->config->get_ldap_link();
     $ldap->cd($this->config->current['BASE']);
     $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dst_dn));
     $ldap = $this->config->get_ldap_link();
     $ldap->cd($this->config->current['BASE']);
     $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dst_dn));
-
     if (!$ldap->rename_dn($src_dn,$dst_dn)){
     if (!$ldap->rename_dn($src_dn,$dst_dn)){
-      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $src_dn, "", get_class()));
+#      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $src_dn, "", get_class()));
+      new log("debug","Ldap Protocol v3 implementation error, ldap_rename failed, falling back to manual copy.","FROM: $src_dn  -- TO: $dst_dn",array(),$ldap->get_error());
+      @DEBUG(DEBUG_LDAP,__LINE__,__FUNCTION__,__FILE__,"Rename failed FROM: $src_dn  -- TO:  $dst_dn", 
+          "Ldap Protocol v3 implementation error, falling back to maunal method.");
       return(FALSE);
     }
 
       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,
+    /* Get list of users,groups and roles within this tree,
         maybe we have to update ACL references.
      */
         maybe we have to update ACL references.
      */
-    $leaf_users=  get_list("(objectClass=gosaAccount)",array("all"),$dst_dn,
+    $leaf_objs = get_list("(|(objectClass=posixGroup)(objectClass=gosaAccount)(objectClass=gosaRole))",array("all"),$dst_dn,
           array("dn","objectClass"),GL_SUBSEARCH | GL_NO_ACL_CHECK);
           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("/".preg_quote($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("/".preg_quote($dst_dn, '/')."$/i",$src_dn,$new_dn);
+    foreach($leaf_objs as $obj){
+      $new_dn = $obj['dn'];
+      $old_dn = preg_replace("/".preg_quote(LDAP::convert($dst_dn), '/')."$/i",$src_dn,LDAP::convert($new_dn));
       $this->update_acls($old_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("ogroupRDN")),$this->config->current['BASE'],array("member"),
-        GL_SUBSEARCH | GL_NO_ACL_CHECK) ;
+    // Migrate objectgroups if needed
+    $ogroups = get_sub_list("(&(objectClass=gosaGroupOfNames)(member=".LDAP::prepare4filter(LDAP::fix($src_dn))."))","ogroups", array(get_ou("ogroupRDN")),$this->config->current['BASE'],array("dn"), GL_SUBSEARCH | GL_NO_ACL_CHECK);
 
 
-    /* Walk through all objectGroups and check if there are 
-        members matching the source dn 
-     */
+    // Walk through all objectGroups
     foreach($ogroups as $ogroup){
     foreach($ogroups as $ogroup){
-      if(isset($ogroup['member'])){
+      // Migrate old to new dn
+      $o_ogroup= new ogroup($this->config,$ogroup['dn']);
+      if (isset($o_group->member[$src_dn])) {
+        unset($o_ogroup->member[$src_dn]);
+      }
+      $o_ogroup->member[$dst_dn]= $dst_dn;
+      
+      // Save object group
+      $o_ogroup->save();
+    }
 
 
-        /* Reset class object, this will be initialized with class_ogroup on demand 
-         */
-        $o_ogroup = NULL; 
-        for($i = 0 ; $i < $ogroup['member']['count'] ; $i ++){
+    // Migrate rfc groups if needed
+    $groups = get_sub_list("(&(objectClass=posixGroup)(member=".LDAP::prepare4filter(LDAP::fix($src_dn))."))","groups", array(get_ou("groupRDN")),$this->config->current['BASE'],array("dn"), GL_SUBSEARCH | GL_NO_ACL_CHECK);
 
 
-          $c_mem = $ogroup['member'][$i];
-  
-          if(preg_match("/".preg_quote($src_dn, '/')."$/i",$c_mem)){
-            $d_mem = preg_replace("/".preg_quote($src_dn, '/')."$/i",$dst_dn,$ogroup['member'][$i]);
+    // Walk through all POSIX groups
+    foreach($groups as $group){
 
 
-            if($o_ogroup == NULL){
-              $o_ogroup = new ogroup($this->config,$ogroup['dn']);
-            }              
+      // Migrate old to new dn
+      $o_group= new group($this->config,$group['dn']);
+      $o_group->save();
+    }
 
 
-            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();
-        }
+    /* Update roles to use the new entry dn */
+    $roles = get_sub_list("(&(objectClass=organizationalRole)(roleOccupant=".LDAP::prepare4filter(LDAP::fix($src_dn))."))","roles", array(get_ou("roleRDN")),$this->config->current['BASE'],array("dn"), GL_SUBSEARCH | GL_NO_ACL_CHECK);
+
+    // Walk through all roles
+    foreach($roles as $role){
+      $role = new roleGeneric($this->config,$role['dn']);
+      $key= array_search($src_dn, $role->roleOccupant);      
+      if($key !== FALSE){
+        $role->roleOccupant[$key] = $dst_dn;
+        $role->save();
       }
     }
  
       }
     }
  
@@ -996,7 +1035,7 @@ class plugin
     if(count($leaf_deps)){
       $this->config->get_departments();
       $this->config->make_idepartments();
     if(count($leaf_deps)){
       $this->config->get_departments();
       $this->config->make_idepartments();
-      session::set("config",$this->config);
+      session::global_set("config",$this->config);
       $ui =get_userinfo();
       $ui->reset_acl_cache();
     }
       $ui =get_userinfo();
       $ui->reset_acl_cache();
     }
@@ -1005,7 +1044,7 @@ class plugin
   }
 
 
   }
 
 
-
   function move($src_dn, $dst_dn)
   {
     /* Do not copy if only upper- lowercase has changed */
   function move($src_dn, $dst_dn)
   {
     /* Do not copy if only upper- lowercase has changed */
@@ -1046,7 +1085,7 @@ class plugin
   }
 
 
   }
 
 
-  /* Move/Rename complete trees */
+  /* \brief Move/Rename complete trees */
   function recursive_move($src_dn, $dst_dn)
   {
     /* Check if the destination entry exists */
   function recursive_move($src_dn, $dst_dn)
   {
     /* Check if the destination entry exists */
@@ -1096,6 +1135,7 @@ class plugin
   }
 
 
   }
 
 
+  /*! \brief Prepare for Copy & Paste */
   function PrepareForCopyPaste($source)
   {
     $todo = $this->attributes;
   function PrepareForCopyPaste($source)
   {
     $todo = $this->attributes;
@@ -1116,11 +1156,8 @@ class plugin
       if (isset($source[$var])){
         if(isset($source[$var]['count'])){
           if($source[$var]['count'] > 1){
       if (isset($source[$var])){
         if(isset($source[$var]['count'])){
           if($source[$var]['count'] > 1){
-            $this->$var = array();
-            $tmp = array();
-            for($i = 0 ; $i < $source[$var]['count']; $i++){
-              $tmp = $source[$var][$i];
-            }
+            $tmp= $source[$var];
+            unset($tmp['count']);
             $this->$var = $tmp;
           }else{
             $this->$var = $source[$var][0];
             $this->$var = $tmp;
           }else{
             $this->$var = $source[$var][0];
@@ -1132,12 +1169,13 @@ class plugin
     }
   }
 
     }
   }
 
-  function tag_attrs(&$at, $dn= "", $tag= "", $show= false)
-  {
-    /* Skip tagging? 
+  /*! \brief Get gosaUnitTag for the given DN
        If this is called from departmentGeneric, we have to skip this
         tagging procedure. 
        If this is called from departmentGeneric, we have to skip this
         tagging procedure. 
-     */
+    */
+  function tag_attrs(&$at, $dn= "", $tag= "", $show= false)
+  {
+    /* Skip tagging? */
     if($this->skipTagging){
       return;
     }
     if($this->skipTagging){
       return;
     }
@@ -1178,7 +1216,8 @@ class plugin
         }
       }
     }
         }
       }
     }
-  
+
+  /*! \brief Add unit tag */ 
     /* Remove tags that may already be here... */
     remove_objectClass("gosaAdministrativeUnitTag", $at);
     if (isset($at['gosaUnitTag'])){
     /* Remove tags that may already be here... */
     remove_objectClass("gosaAdministrativeUnitTag", $at);
     if (isset($at['gosaUnitTag'])){
@@ -1202,7 +1241,11 @@ class plugin
   }
 
 
   }
 
 
-  /* Add possibility to stop remove process */
+  /*! \brief Test for removability of the object
+   *
+   * Allows testing of conditions for removal of object. If removal should be aborted
+   * the function needs to remove an error message.
+   * */
   function allow_remove()
   {
     $reason= "";
   function allow_remove()
   {
     $reason= "";
@@ -1210,7 +1253,7 @@ class plugin
   }
 
 
   }
 
 
-  /* Create a snapshot of the current object */
+  /*! \brief Create a snapshot of the current object */
   function create_snapshot($type= "snapshot", $description= array())
   {
 
   function create_snapshot($type= "snapshot", $description= array())
   {
 
@@ -1236,7 +1279,7 @@ class plugin
     }else{
       $server         = $config->get_cfg_value("snapshotURI");
       $user           = $config->get_cfg_value("snapshotAdminDn");
     }else{
       $server         = $config->get_cfg_value("snapshotURI");
       $user           = $config->get_cfg_value("snapshotAdminDn");
-      $password       = $config->get_cfg_value("snapshotAdminPassword");
+      $password       = $this->config->get_credentials($config->get_cfg_value("snapshotAdminPassword"));
       $snapldapbase   = $config->get_cfg_value("snapshotBase");
 
       $ldap_to        = new ldapMultiplexer(new LDAP($user,$password, $server));
       $snapldapbase   = $config->get_cfg_value("snapshotBase");
 
       $ldap_to        = new ldapMultiplexer(new LDAP($user,$password, $server));
@@ -1302,6 +1345,7 @@ class plugin
     }
   }
 
     }
   }
 
+  /*! \brief Remove a snapshot */
   function remove_snapshot($dn)
   {
     $ui       = get_userinfo();
   function remove_snapshot($dn)
   {
     $ui       = get_userinfo();
@@ -1309,44 +1353,27 @@ class plugin
     $this->dn = $dn;
     $ldap = $this->config->get_ldap_link();
     $ldap->cd($this->config->current['BASE']);
     $this->dn = $dn;
     $ldap = $this->config->get_ldap_link();
     $ldap->cd($this->config->current['BASE']);
-    $ldap->rmdir_recursive($dn);
+    $ldap->rmdir_recursive($this->dn);
+    if(!$ldap->success()){
+      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn));
+    }
     $this->dn = $old_dn;
   }
 
 
     $this->dn = $old_dn;
   }
 
 
-  /* returns true if snapshots are enabled, and false if it is disalbed
-     There will also be some errors psoted, if the configuration failed */
+  /*! \brief Test if snapshotting is enabled
+   *
+   * Test weither snapshotting is enabled or not. There will also be some errors posted,
+   * if the configuration failed 
+   * \return TRUE if snapshots are enabled, and FALSE if it is disabled
+   */
   function snapshotEnabled()
   {
   function snapshotEnabled()
   {
-    $config = $this->config;
-    if($config->get_cfg_value("enableSnapshots") == "true"){
-           /* Check if the snapshot_base is defined */
-           if ($config->get_cfg_value("snapshotBase") == ""){
-                   msg_dialog::display(_("Configuration error"), sprintf(_("The snapshot functionality is enabled, but the required variable '%s' is not set."),"snapshotBase"), ERROR_DIALOG);
-                   return(FALSE);
-           }
-
-           /* check if there are special server configurations for snapshots */
-           if ($config->get_cfg_value("snapshotURI") != ""){
-
-                   /* check if all required vars are available to create a new ldap connection */
-                   $missing = "";
-                   foreach(array("snapshotURI","snapshotAdminDn","snapshotAdminPassword","snapshotBase") as $var){
-                           if($config->get_cfg_value($var) == ""){
-                                   $missing .= $var." ";
-                                   msg_dialog::display(_("Configuration error"), sprintf(_("The snapshot functionality is enabled, but the required variable '%s' is not set."), $missing), ERROR_DIALOG);
-                                   return(FALSE);
-                           }
-                   }
-           }
-           return(TRUE);
-    }
-    return(FALSE);
+    return $this->config->snapshotEnabled();
   }
 
 
   }
 
 
-  /* Return available snapshots for the given base 
-   */
+  /* \brief Return available snapshots for the given base */
   function Available_SnapsShots($dn,$raw = false)
   {
     if(!$this->snapshotEnabled()) return(array());
   function Available_SnapsShots($dn,$raw = false)
   {
     if(!$this->snapshotEnabled()) return(array());
@@ -1363,7 +1390,7 @@ class plugin
     }else{
       $server         = $this->config->get_cfg_value("snapshotURI");
       $user           = $this->config->get_cfg_value("snapshotAdminDn");
     }else{
       $server         = $this->config->get_cfg_value("snapshotURI");
       $user           = $this->config->get_cfg_value("snapshotAdminDn");
-      $password       = $this->config->get_cfg_value("snapshotAdminPassword");
+      $password       = $this->config->get_credentials($this->config->get_cfg_value("snapshotAdminPassword"));
       $snapldapbase   = $this->config->get_cfg_value("snapshotBase");
       $ldap_to        = new ldapMultiplexer(new LDAP($user,$password, $server));
       $ldap_to -> cd($snapldapbase);
       $snapldapbase   = $this->config->get_cfg_value("snapshotBase");
       $ldap_to        = new ldapMultiplexer(new LDAP($user,$password, $server));
       $ldap_to -> cd($snapldapbase);
@@ -1421,7 +1448,7 @@ class plugin
     }else{
       $server         = $this->config->get_cfg_value("snapshotURI");
       $user           = $this->config->get_cfg_value("snapshotAdminDn");
     }else{
       $server         = $this->config->get_cfg_value("snapshotURI");
       $user           = $this->config->get_cfg_value("snapshotAdminDn");
-      $password       = $this->config->get_cfg_value("snapshotAdminPassword");
+      $password       = $this->config->get_credentials($this->config->get_cfg_value("snapshotAdminPassword"));
       $snapldapbase   = $this->config->get_cfg_value("snapshotBase");
       $ldap_to        = new ldapMultiplexer(new LDAP($user,$password, $server));
       $ldap_to -> cd($snapldapbase);
       $snapldapbase   = $this->config->get_cfg_value("snapshotBase");
       $ldap_to        = new ldapMultiplexer(new LDAP($user,$password, $server));
       $ldap_to -> cd($snapldapbase);
@@ -1472,7 +1499,7 @@ class plugin
   } 
 
 
   } 
 
 
-  /* Restore selected snapshot */
+  /* \brief Restore selected snapshot */
   function restore_snapshot($dn)
   {
     if(!$this->snapshotEnabled()) return(array());
   function restore_snapshot($dn)
   {
     if(!$this->snapshotEnabled()) return(array());
@@ -1487,7 +1514,7 @@ class plugin
     }else{
       $server         = $this->config->get_cfg_value("snapshotURI");
       $user           = $this->config->get_cfg_value("snapshotAdminDn");
     }else{
       $server         = $this->config->get_cfg_value("snapshotURI");
       $user           = $this->config->get_cfg_value("snapshotAdminDn");
-      $password       = $this->config->get_cfg_value("snapshotAdminPassword");
+      $password       = $this->config->get_credentials($this->config->get_cfg_value("snapshotAdminPassword"));
       $snapldapbase   = $this->config->get_cfg_value("snapshotBase");
       $ldap_to        = new ldapMultiplexer(new LDAP($user,$password, $server));
       $ldap_to -> cd($snapldapbase);
       $snapldapbase   = $this->config->get_cfg_value("snapshotBase");
       $ldap_to        = new ldapMultiplexer(new LDAP($user,$password, $server));
       $ldap_to -> cd($snapldapbase);
@@ -1519,10 +1546,11 @@ class plugin
     $this->parent = $parent;
 
     foreach($_POST as $name => $value){
     $this->parent = $parent;
 
     foreach($_POST as $name => $value){
-                       $entry = base64_decode(preg_replace("/_[xy]$/","",$name));
 
       /* Create a new snapshot, display a dialog */
 
       /* Create a new snapshot, display a dialog */
-      if(preg_match("/^CreateSnapShotDialog_/",$name) && $once){
+      if(preg_match("/^CreateSnapShotDialog_[^_]*_[xy]$/",$name) && $once){
+
+                         $entry = base64_decode(preg_replace("/^CreateSnapShotDialog_([^_]*)_[xy]$/","\\1",$name));
         $once = false;
         $entry = preg_replace("/^CreateSnapShotDialog_/","",$entry);
 
         $once = false;
         $entry = preg_replace("/^CreateSnapShotDialog_/","",$entry);
 
@@ -1536,8 +1564,8 @@ class plugin
       /* Restore a snapshot, display a dialog with all snapshots of the current object */
       if(preg_match("/^RestoreSnapShotDialog_/",$name) && $once){
         $once = false;
       /* Restore a snapshot, display a dialog with all snapshots of the current object */
       if(preg_match("/^RestoreSnapShotDialog_/",$name) && $once){
         $once = false;
-        $entry = preg_replace("/^RestoreSnapShotDialog_/","",$entry);
-        if(!empty($entry) && $ui->allow_snapshot_restore($entry,$this->parent->acl_module)){
+        $entry = base64_decode(preg_replace("/^RestoreSnapShotDialog_([^_]*)_[xy]$/i","\\1",$name));
+        if(!empty($entry) && $ui->allow_snapshot_restore($this->dn,$this->parent->acl_module)){
           $this->snapDialog = new SnapShotDialog($this->config,$entry,$this);
           $this->snapDialog->display_restore_dialog = true;
         }else{
           $this->snapDialog = new SnapShotDialog($this->config,$entry,$this);
           $this->snapDialog->display_restore_dialog = true;
         }else{
@@ -1550,7 +1578,7 @@ class plugin
           || preg_match("/^RestoreDeletedSnapShot_/",$name)) && $once){
         $once = false;
 
           || preg_match("/^RestoreDeletedSnapShot_/",$name)) && $once){
         $once = false;
 
-        if($ui->allow_snapshot_restore($base,$this->parent->acl_module)){
+        if($ui->allow_snapshot_restore($this->dn,$this->parent->acl_module)){
           $this->snapDialog = new SnapShotDialog($this->config,"",$this);
           $this->snapDialog->set_snapshot_bases($baseSuffixe);
           $this->snapDialog->display_restore_dialog      = true;
           $this->snapDialog = new SnapShotDialog($this->config,"",$this);
           $this->snapDialog->set_snapshot_bases($baseSuffixe);
           $this->snapDialog->display_restore_dialog      = true;
@@ -1563,8 +1591,9 @@ class plugin
       /* Restore selected snapshot */
       if(preg_match("/^RestoreSnapShot_/",$name) && $once){
         $once = false;
       /* Restore selected snapshot */
       if(preg_match("/^RestoreSnapShot_/",$name) && $once){
         $once = false;
-        $entry = preg_replace("/^RestoreSnapShot_/","",$entry);
-        if(!empty($entry) && $ui->allow_snapshot_restore($entry,$this->parent->acl_module)){
+        $entry = base64_decode(preg_replace("/^RestoreSnapShot_([^_]*)_[xy]$/i","\\1",$name));
+
+        if(!empty($entry) && $ui->allow_snapshot_restore($this->dn,$this->parent->acl_module)){
           $this->restore_snapshot($entry);
           $this->snapDialog = NULL;
         }else{
           $this->restore_snapshot($entry);
           $this->snapDialog = NULL;
         }else{
@@ -1604,6 +1633,7 @@ class plugin
   }
 
 
   }
 
 
+  /*! \brief Return plugin informations for acl handling */
   static function plInfo()
   {
     return array();
   static function plInfo()
   {
     return array();
@@ -1624,6 +1654,7 @@ class plugin
 
   function acl_is_writeable($attribute,$skip_write = FALSE)
   {
 
   function acl_is_writeable($attribute,$skip_write = FALSE)
   {
+    if($this->read_only) return(FALSE);
     $ui= get_userinfo();
     return preg_match('/w/', $ui->get_permissions($this->acl_base, $this->acl_category.get_class($this), $attribute, $skip_write));
   }
     $ui= get_userinfo();
     return preg_match('/w/', $ui->get_permissions($this->acl_base, $this->acl_category.get_class($this), $attribute, $skip_write));
   }
@@ -1638,6 +1669,7 @@ class plugin
 
   function acl_is_createable($base ="")
   {
 
   function acl_is_createable($base ="")
   {
+    if($this->read_only) return(FALSE);
     $ui= get_userinfo();
     if($base == "") $base = $this->acl_base;
     return preg_match('/c/', $ui->get_permissions($base, $this->acl_category.get_class($this), '0'));
     $ui= get_userinfo();
     if($base == "") $base = $this->acl_base;
     return preg_match('/c/', $ui->get_permissions($base, $this->acl_category.get_class($this), '0'));
@@ -1646,6 +1678,7 @@ class plugin
 
   function acl_is_removeable($base ="")
   {
 
   function acl_is_removeable($base ="")
   {
+    if($this->read_only) return(FALSE);
     $ui= get_userinfo();
     if($base == "") $base = $this->acl_base;
     return preg_match('/d/', $ui->get_permissions($base, $this->acl_category.get_class($this), '0'));
     $ui= get_userinfo();
     if($base == "") $base = $this->acl_base;
     return preg_match('/d/', $ui->get_permissions($base, $this->acl_category.get_class($this), '0'));
@@ -1654,6 +1687,7 @@ class plugin
 
   function acl_is_moveable($base = "")
   {
 
   function acl_is_moveable($base = "")
   {
+    if($this->read_only) return(FALSE);
     $ui= get_userinfo();
     if($base == "") $base = $this->acl_base;
     return preg_match('/m/', $ui->get_permissions($base, $this->acl_category.get_class($this), '0'));
     $ui= get_userinfo();
     if($base == "") $base = $this->acl_base;
     return preg_match('/m/', $ui->get_permissions($base, $this->acl_category.get_class($this), '0'));
@@ -1668,15 +1702,17 @@ class plugin
   function getacl($attribute,$skip_write= FALSE)
   {
     $ui= get_userinfo();
   function getacl($attribute,$skip_write= FALSE)
   {
     $ui= get_userinfo();
+    $skip_write |= $this->read_only;
     return  $ui->get_permissions($this->acl_base, $this->acl_category.get_class($this), $attribute,$skip_write);
   }
 
 
     return  $ui->get_permissions($this->acl_base, $this->acl_category.get_class($this), $attribute,$skip_write);
   }
 
 
-  /*! \brief    Returns a list of all available departments for this object.  
-                If this object is new, all departments we are allowed to create a new user in are returned.
-                If this is an existing object, return all deps. we are allowed to move tis object too.
-
-      @return   Array [dn] => "..name"  // All deps. we are allowed to act on.
+  /*! \brief Returns a list of all available departments for this object.
+   * 
+   * If this object is new, all departments we are allowed to create a new user in
+   * are returned. If this is an existing object, return all deps. 
+   * We are allowed to move tis object too.
+   * \return array [dn] => "..name"  // All deps. we are allowed to act on.
   */
   function get_allowed_bases()
   {
   */
   function get_allowed_bases()
   {
@@ -1710,9 +1746,9 @@ class plugin
   }
 
 
   }
 
 
-  /* This function modifies object acls too, if an object is moved.
-   *  $old_dn   specifies the actually used dn
-   *  $new_dn   specifies the destiantion dn
+  /* This function updates ACL settings if $old_dn was used.
+   *  \param string 'old_dn' specifies the actually used dn
+   *  \param string 'new_dn' specifies the destiantion dn
    */
   function update_acls($old_dn,$new_dn,$output_changes = FALSE)
   {
    */
   function update_acls($old_dn,$new_dn,$output_changes = FALSE)
   {
@@ -1723,11 +1759,11 @@ class plugin
     }
 
     /* Update userinfo if necessary */
     }
 
     /* Update userinfo if necessary */
-    $ui = session::get('ui');
+    $ui = session::global_get('ui');
     if($ui->dn == $old_dn){
       $ui->dn = $new_dn;
     if($ui->dn == $old_dn){
       $ui->dn = $new_dn;
-      session::set('ui',$ui);
-      new log("view","acl/".get_class($this),$this->dn,array(),"Updated current user dn from '".$old_dn."' to '".$new_dn."'");
+      session::global_set('ui',$ui);
+      new log("view","acl/".get_class($this),$this->dn,array(),"Updated current object dn from '".$old_dn."' to '".$new_dn."'");
     }
 
     /* Object was moved, ensure that all acls will be moved too */
     }
 
     /* Object was moved, ensure that all acls will be moved too */
@@ -1737,59 +1773,46 @@ class plugin
       $update = array();
       $ldap = $this->config->get_ldap_link();
       $ldap->cd ($this->config->current['BASE']);
       $update = array();
       $ldap = $this->config->get_ldap_link();
       $ldap->cd ($this->config->current['BASE']);
-      $ldap->search("(&(objectClass=gosaAcl)(gosaAclEntry=*))",array("cn","gosaAclEntry"));
+      $ldap->search("(&(objectClass=gosaAcl)(gosaAclEntry=*".base64_encode($old_dn)."*))",array("cn","gosaAclEntry"));
       while($attrs = $ldap->fetch()){
       while($attrs = $ldap->fetch()){
-
         $acls = array();
         $acls = array();
-
-        /* Reset vars */
         $found = false;
         $found = false;
-
-        /* Walk through acls */
         for($i = 0 ; $i <  $attrs['gosaAclEntry']['count'] ; $i ++ ){
         for($i = 0 ; $i <  $attrs['gosaAclEntry']['count'] ; $i ++ ){
+          $acl_parts = explode(":",$attrs['gosaAclEntry'][$i]);
 
 
-          /* Get Acl parts */
-          $acl_parts = split(":",$attrs['gosaAclEntry'][$i]);
+          /* Roles uses antoher data storage order, members are stored int the third part, 
+             while the members in direct ACL assignments are stored in the second part.
+           */
+          $id = ($acl_parts[1] == "role") ? 3 : 2;
 
 
-          /* Get every single member for this acl */  
-          $members = array();  
-          if(preg_match("/,/",$acl_parts[2])){
-            $members = split(",",$acl_parts[2]);
-          }else{
-            $members = array($acl_parts[2]);
-          } 
-      
-          /* Check if member match current dn */
+          /* Update member entries to use $new_dn instead of old_dn
+           */
+          $members = explode(",",$acl_parts[$id]);
           foreach($members as $key => $member){
             $member = base64_decode($member);
             if($member == $old_dn){
           foreach($members as $key => $member){
             $member = base64_decode($member);
             if($member == $old_dn){
-              $found = true;
               $members[$key] = base64_encode($new_dn);
               $members[$key] = base64_encode($new_dn);
+              $found = TRUE;
             }
           } 
             }
           } 
-       
-          /* Create new member string */ 
-          $new_members = "";
-          foreach($members as $member){
-            $new_members .= $member.",";
-          }
-          $new_members = preg_replace("/,$/","",$new_members);
-          $acl_parts[2] = $new_members;
-        
-          /* Reconstruckt acl entry */
-          $acl_str  ="";
-          foreach($acl_parts as $t){
-           $acl_str .= $t.":";
+
+          /* Check if the selected role has to updated
+           */
+          if($acl_parts[1] == "role" && $acl_parts[2] == base64_encode($old_dn)){
+            $acl_parts[2] = base64_encode($new_dn);
+            $found = TRUE;
           }
           }
-          $acl_str = preg_replace("/:$/","",$acl_str);
-          $acls[] = $acl_str;
-       }
 
 
-       /* Acls for this object must be adjusted */
-       if($found){
+          /* Build new acl string */ 
+          $acl_parts[$id] = implode($members,",");
+          $acls[] = implode($acl_parts,":");
+        }
+
+        /* Acls for this object must be adjusted */
+        if($found){
 
           $debug_info=  _("Changing ACL dn")."&nbsp;:&nbsp;<br>&nbsp;-"._("from")."&nbsp;<b>&nbsp;".
 
           $debug_info=  _("Changing ACL dn")."&nbsp;:&nbsp;<br>&nbsp;-"._("from")."&nbsp;<b>&nbsp;".
-                  $old_dn."</b><br>&nbsp;-"._("to")."&nbsp;<b>".$new_dn."</b><br>";
+            $old_dn."</b><br>&nbsp;-"._("to")."&nbsp;<b>".$new_dn."</b><br>";
           @DEBUG (DEBUG_ACL, __LINE__, __FUNCTION__, __FILE__,$debug_info,"ACL");
 
           $update[$attrs['dn']] =array();
           @DEBUG (DEBUG_ACL, __LINE__, __FUNCTION__, __FILE__,$debug_info,"ACL");
 
           $update[$attrs['dn']] =array();
@@ -1809,9 +1832,10 @@ class plugin
 
   
 
 
   
 
-  /* This function enables the entry Serial ID check.
-   * If an entry was edited while we have edited the entry too,
-   *  an error message will be shown. 
+  /*! \brief Enable the Serial ID check
+   *
+   * This function enables the entry Serial ID check.  If an entry was edited while
+   * we have edited the entry too, an error message will be shown. 
    * To configure this check correctly read the FAQ.
    */    
   function enable_CSN_check()
    * To configure this check correctly read the FAQ.
    */    
   function enable_CSN_check()
@@ -1823,7 +1847,7 @@ class plugin
 
   /*! \brief  Prepares the plugin to be used for multiple edit
    *          Update plugin attributes with given array of attribtues.
 
   /*! \brief  Prepares the plugin to be used for multiple edit
    *          Update plugin attributes with given array of attribtues.
-   *  @param  array   Array with attributes that must be updated.
+   *  \param  array   Array with attributes that must be updated.
    */
   function init_multiple_support($attrs,$all)
   {
    */
   function init_multiple_support($attrs,$all)
   {
@@ -1834,9 +1858,10 @@ class plugin
     /* Copy needed attributes */
     foreach ($this->attributes as $val){
       $found= array_key_ics($val, $this->multi_attrs);
     /* Copy needed attributes */
     foreach ($this->attributes as $val){
       $found= array_key_ics($val, $this->multi_attrs);
       if ($found != ""){
       if ($found != ""){
-        if(isset($this->multi_attrs["$found"][0])){
-          $this->$val= $this->multi_attrs["$found"][0];
+        if(isset($this->multi_attrs["$val"][0])){
+          $this->$val= $this->multi_attrs["$val"][0];
         }
       }
     }
         }
       }
     }
@@ -1853,7 +1878,7 @@ class plugin
 
 
   /*! \brief  Returns all values that have been modfied in multiple edit mode.
 
 
   /*! \brief  Returns all values that have been modfied in multiple edit mode.
-      @return array Cotaining all mdofied values. 
+      \return array Cotaining all modified values. 
    */
   function get_multi_edit_values()
   {
    */
   function get_multi_edit_values()
   {
@@ -1877,24 +1902,23 @@ class plugin
   }
 
 
   }
 
 
-  /*! \brief execute plugin
-
-    Generates the html output for this node
-   */
+  /*! \brief Generates the html output for this node for multi edit*/
   function multiple_execute()
   {
     /* This one is empty currently. Fabian - please fill in the docu code */
   function multiple_execute()
   {
     /* This one is empty currently. Fabian - please fill in the docu code */
-    session::set('current_class_for_help',get_class($this));
+    session::global_set('current_class_for_help',get_class($this));
 
     /* Reset Lock message POST/GET check array, to prevent perg_match errors*/
     session::set('LOCK_VARS_TO_USE',array());
 
     /* Reset Lock message POST/GET check array, to prevent perg_match errors*/
     session::set('LOCK_VARS_TO_USE',array());
-    session::set('LOCK_VARS_USED',array());
+    session::set('LOCK_VARS_USED_GET',array());
+    session::set('LOCK_VARS_USED_POST',array());
+    session::set('LOCK_VARS_USED_REQUEST',array());
     
     return("Multiple edit is currently not implemented for this plugin.");
   }
 
 
     
     return("Multiple edit is currently not implemented for this plugin.");
   }
 
 
-  /*! \brief   Save HTML posted data to object for multiple edit
+  /*! \brief Save HTML posted data to object for multiple edit
    */
   function multiple_save_object()
   {
    */
   function multiple_save_object()
   {
@@ -1933,7 +1957,7 @@ class plugin
   }
 
 
   }
 
 
-  /*! \brief  Returns all attributes of this plugin, 
+  /*! \brief Returns all attributes of this plugin, 
                to be able to detect multiple used attributes 
                in multi_plugg::detect_multiple_used_attributes().
       @return array Attributes required for intialization of multi_plug
                to be able to detect multiple used attributes 
                in multi_plugg::detect_multiple_used_attributes().
       @return array Attributes required for intialization of multi_plug
@@ -1946,7 +1970,7 @@ class plugin
 
 
   /*! \brief  Check given values in multiple edit
 
 
   /*! \brief  Check given values in multiple edit
-      @return array Error messages
+      \return array Error messages
    */
   function multiple_check()
   {
    */
   function multiple_check()
   {
@@ -1956,7 +1980,7 @@ class plugin
 
 
   /*! \brief  Returns the snapshot header part for "Actions" menu in management dialogs 
 
 
   /*! \brief  Returns the snapshot header part for "Actions" menu in management dialogs 
-      @param  $layer_menu  
+      \param  $layer_menu  
    */   
   function get_snapshot_header($base,$category)
   {
    */   
   function get_snapshot_header($base,$category)
   {
@@ -2046,10 +2070,10 @@ class plugin
     /* Check permissions for each category, if there is at least one category which 
         support read or paste permissions for the given base, then display the specific actions.
      */
     /* Check permissions for each category, if there is at least one category which 
         support read or paste permissions for the given base, then display the specific actions.
      */
-    $readable = $pasteable = TRUE;
+    $readable = $pasteable = false;
     foreach($category as $cat){
     foreach($category as $cat){
-      $readable |= $ui->get_category_permissions($base,$cat);
-      $pasteable|= $ui->is_pasteable($base,$cat);
+      $readable= $readable || preg_match('/r/', $ui->get_category_permissions($base, $cat));
+      $pasteable= $pasteable || $ui->is_pasteable($base, $cat) == 1;
     }
   
     if(($cut || $copy) && isset($this->CopyPasteHandler) && is_object($this->CopyPasteHandler)){
     }
   
     if(($cut || $copy) && isset($this->CopyPasteHandler) && is_object($this->CopyPasteHandler)){
@@ -2083,6 +2107,11 @@ class plugin
   {
      return(array());
   }
   {
      return(array());
   }
+
+  function is_modal_dialog()
+  {
+    return(isset($this->dialog) && $this->dialog);
+  }
 }
 
 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
 }
 
 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler: