Code

Fixed Problem with saving new ACL for a tagged department.
[gosa.git] / gosa-core / include / class_plugin.inc
index 8eec579c440ece59c05ab39906138cf558687d76..57fc5107d0b1493be47f47d40687ade74c39fdf9 100644 (file)
@@ -1,21 +1,23 @@
 <?php
 /*
-   This code is part of GOsa (https://gosa.gonicus.de)
-   Copyright (C) 2003  Cajus Pollmeier
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * This code is part of GOsa (http://www.gosa-project.org)
+ * Copyright (C) 2003-2008 GONICUS GmbH
+ *
+ * ID: $$Id$$
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 /*! \brief   The plugin base class
@@ -88,6 +90,7 @@ class plugin
 
   /* Save unit tags */
   var $gosaUnitTag= "";
+  var $skipTagging= FALSE;
 
   /*!
     \brief Used standard values
@@ -150,13 +153,13 @@ class plugin
     $this->acl_base= $dn;
 
     /* Get LDAP descriptor */
-    $ldap= $this->config->get_ldap_link();
     if ($dn !== NULL){
 
       /* Load data to 'attrs' and save 'dn' */
       if ($parent !== NULL){
         $this->attrs= $parent->attrs;
       } else {
+        $ldap= $this->config->get_ldap_link();
         $ldap->cat ($dn);
         $this->attrs= $ldap->fetch();
       }
@@ -212,15 +215,23 @@ class plugin
           unset($this->saved_attributes[$index]);
           continue;
         }
-        if ($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'])){
+        $this->saved_attributes['gosaUnitTag'] = $this->attrs['gosaUnitTag'][0];
+      }
     }
 
     /* Save initial account state */
@@ -314,9 +325,6 @@ class plugin
           $data = "";  
         }
         $this->$val= $data;
-        //echo "<font color='blue'>".$val."</font><br>";
-      }else{
-        //echo "<font color='red'>".$val."</font><br>";
       }
     }
   }
@@ -361,14 +369,14 @@ class plugin
     }
 
     /* Handle tagging */
-    $this->tag_attrs(&$this->attrs);
+    $this->tag_attrs($this->attrs);
   }
 
 
   function cleanup()
   {
     foreach ($this->attrs as $index => $value){
-
+      
       /* Convert arrays with one element to non arrays, if the saved
          attributes are no array, too */
       if (is_array($this->attrs[$index]) && 
@@ -433,8 +441,7 @@ class plugin
     if ($command != ""){
 
       if (!check_command($command)){
-        $message[]= sprintf(_("Command '%s', specified as CHECK hook for plugin '%s' doesn't seem to exist."), $command,
-                            get_class($this));
+        $message[]= msgPool::cmdnotfound("CHECK", get_class($this));
       } else {
 
         /* Generate "ldif" for check hook */
@@ -487,14 +494,14 @@ class plugin
       $current_csn = getEntryCSN($this->dn);
       if($current_csn != $this->entryCSN && !empty($this->entryCSN) && !empty($current_csn)){
         $this->entryCSN = $current_csn;
-        $message[] = _("The object has changed since opened in GOsa. Please ensure that nobody has done serious changes that may get lost   if you save this entry.");
+        $message[] = _("The object has changed since opened in GOsa. All changes that may be done by others get lost if you save this entry!");
       }
     }
     return ($message);
   }
 
   /* Adapt from template, using 'dn' */
-  function adapt_from_template($dn)
+  function adapt_from_template($dn, $skip= array())
   {
     /* Include global link_info */
     $ldap= $this->config->get_ldap_link();
@@ -506,6 +513,11 @@ class plugin
     /* Walk through attributes */
     foreach ($this->attributes as $val){
 
+      /* Skip the ones in skip list */
+      if (in_array($val, $skip)){
+        continue;
+      }
+
       if (isset($this->attrs["$val"][0])){
 
         /* If attribute is set, replace dynamic parts: 
@@ -601,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__,
@@ -620,7 +639,7 @@ class plugin
 
         exec($command);
       } else {
-        $message= sprintf(_("Command '%s', specified as POSTCREATE for plugin '%s' doesn't seem to exist."), $command, get_class($this));
+        $message= msgPool::cmdnotfound("POSTCREATE", get_class($this));
         msg_dialog::display(_("Error"), $message, ERROR_DIALOG);
       }
     }
@@ -633,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= sprintf(_("Command '%s', specified as POSTMODIFY for plugin '%s' doesn't seem to exist."), $command, get_class($this));
+        $message= msgPool::cmdnotfound("POSTMODIFY", get_class($this));
         msg_dialog::display(_("Error"), $message, ERROR_DIALOG);
       }
     }
@@ -664,22 +688,24 @@ 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 ($add_attrs as $name => $value){
-        $command= preg_replace("/%$name/", $value, $command);
+      foreach ($tmp as $name => $len){
+        $value = $add_attrs[$name];
+        $command= preg_replace("/%$name/", "$value ", $command);
       }
 
       if (check_command($command)){
@@ -688,7 +714,7 @@ class plugin
 
         exec($command);
       } else {
-        $message= sprintf(_("Command '%s', specified as POSTREMOVE for plugin '%s' doesn't seem to exist."), $command, get_class($this));
+        $message= msgPool::cmdnotfound("POSTREMOVE", get_class($this));
         msg_dialog::display(_("Error"), $message, ERROR_DIALOG);
       }
     }
@@ -806,7 +832,7 @@ class plugin
     $ldap->cd($dst_dn);
     $ldap->add($new);
 
-    if ($ldap->error != "Success"){
+    if (!$ldap->success()){
       trigger_error("Trying to save $dst_dn failed.",
           E_USER_WARNING);
       return(FALSE);
@@ -820,7 +846,7 @@ class plugin
   {
     /* Rename dn in possible object groups */
     $ldap= $this->config->get_ldap_link();
-    $ldap->search('(&(objectClass=gosaGroupOfNames)(member='.@LDAP::preapre4filter($src_dn).'))',
+    $ldap->search('(&(objectClass=gosaGroupOfNames)(member='.@LDAP::prepare4filter($src_dn).'))',
         array('cn'));
     while ($attrs= $ldap->fetch()){
       $og= new ogroup($this->config, $ldap->getDN());
@@ -858,6 +884,11 @@ class plugin
 
   function move($src_dn, $dst_dn)
   {
+    /* Do not copy if only upper- lowercase has changed */
+    if(strtolower($src_dn) == strtolower($dst_dn)){
+      return(TRUE);
+    }
+
     /* Copy source to destination */
     if (!$this->copy($src_dn, $dst_dn)){
       return (FALSE);
@@ -866,7 +897,7 @@ class plugin
     /* Delete source */
     $ldap= $this->config->get_ldap_link();
     $ldap->rmdir_recursive($src_dn);
-    if ($ldap->error != "Success"){
+    if (!$ldap->success()){
       trigger_error("Trying to delete $src_dn failed.",
           E_USER_WARNING);
       return (FALSE);
@@ -890,31 +921,11 @@ class plugin
       return (FALSE);
     }
 
-    /* Perform a search for all objects to be moved */
-    $objects= array();
-    $ldap->cd($src_dn);
-    $ldap->search("(objectClass=*)", array("dn"));
-    while($attrs= $ldap->fetch()){
-      $dn= $attrs['dn'];
-      $objects[$dn]= strlen($dn);
-    }
-
-    /* Sort objects by indent level */
-    asort($objects);
-    reset($objects);
-
-    /* Copy objects from small to big indent levels by replacing src_dn by dst_dn */
-    foreach ($objects as $object => $len){
-      $src= $object;
-      $dst= preg_replace("/$src_dn$/", "$dst_dn", $object);
-      if (!$this->copy($src, $dst)){
-        return (FALSE);
-      }
-    }
+    $this->copy($src_dn, $dst_dn);
 
     /* Remove src_dn */
     $ldap->cd($src_dn);
-    $ldap->recursive_remove();
+    $ldap->recursive_remove($src_dn);
     return (TRUE);
   }
 
@@ -972,21 +983,26 @@ class plugin
               $tmp = $source[$var][$i];
             }
             $this->$var = $tmp;
-#            echo $var."=".$tmp."<br>";
           }else{
             $this->$var = $source[$var][0];
-#            echo $var."=".$source[$var][0]."<br>";
           }
         }else{
           $this->$var= $source[$var];
-#          echo $var."=".$source[$var]."<br>";
         }
       }
     }
   }
 
-  function tag_attrs($at, $dn= "", $tag= "", $show= false)
+  function tag_attrs(&$at, $dn= "", $tag= "", $show= false)
   {
+    /* Skip tagging? 
+       If this is called from departmentGeneric, we have to skip this
+        tagging procedure. 
+     */
+    if($this->skipTagging){
+      return;
+    }
+
     /* No dn? Self-operation... */
     if ($dn == ""){
       $dn= $this->dn;
@@ -1000,7 +1016,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;
           }
 
@@ -1023,18 +1039,27 @@ class plugin
         }
       }
     }
-
+  
     /* Remove tags that may already be here... */
-    remove_objectClass("gosaAdministrativeUnitTag", &$at);
+    remove_objectClass("gosaAdministrativeUnitTag", $at);
     if (isset($at['gosaUnitTag'])){
         unset($at['gosaUnitTag']);
     }
 
     /* Set tag? */
     if ($tag != ""){
-      add_objectClass("gosaAdministrativeUnitTag", &$at);
+      add_objectClass("gosaAdministrativeUnitTag", $at);
       $at['gosaUnitTag']= $tag;
     }
+
+    /* Initially this object was tagged. 
+       - But now, it is no longer inside a tagged department. 
+       So force the remove of the tag.
+       (objectClass was already removed obove)
+     */
+    if($tag == "" && $this->gosaUnitTag){
+      $at['gosaUnitTag'] = array();
+    }
   }
 
 
@@ -1075,9 +1100,13 @@ class plugin
       $password       = $tmp['SNAPSHOT_PASSWORD'];
       $snapldapbase   = $tmp['SNAPSHOT_BASE'];
 
-      $ldap_to        = new LDAP($user,$password, $server);
+      $ldap_to        = new ldapMultiplexer(new LDAP($user,$password, $server));
       $ldap_to -> cd($snapldapbase);
-      show_ldap_error($ldap->get_error(), sprintf(_("Saving object snapshot with dn '%s' failed."),$snapldapbase));
+
+      if (!$ldap_to->success()){
+        msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
+      }
+
     }
 
     /* check if the dn exists */ 
@@ -1123,9 +1152,14 @@ class plugin
       $ldap_to->create_missing_trees($new_base);
       $ldap_to->cd($new_dn);
       $ldap_to->add($target);
-    
-      show_ldap_error($ldap->get_error(), sprintf(_("Saving object snapshot with dn '%s' failed."),$new_base));
-      show_ldap_error($ldap_to->get_error(), sprintf(_("Saving object snapshot with dn '%s' failed."),$new_base));
+      if (!$ldap_to->success()){
+        msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $new_dn, LDAP_ADD, get_class()));
+      }
+
+      if (!$ldap->success()){
+        msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $new_base, "", get_class()));
+      }
+
     }
   }
 
@@ -1197,9 +1231,11 @@ class plugin
       $password     = $cfg['SNAPSHOT_PASSWORD'];
       $snapldapbase = $cfg['SNAPSHOT_BASE'];
 
-      $ldap_to      = new LDAP($user,$password, $server);
+      $ldap_to      = new ldapMultiplexer(new LDAP($user,$password, $server));
       $ldap_to -> cd ($snapldapbase);
-      show_ldap_error($ldap->get_error(), sprintf(_("Method get available snapshots with dn '%s' failed."),$this->dn));
+      if (!$ldap_to->success()){
+        msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
+      }
     }else{
       $ldap_to    = $ldap;
     }
@@ -1253,9 +1289,11 @@ class plugin
       $user         = $cfg['SNAPSHOT_USER'];
       $password     = $cfg['SNAPSHOT_PASSWORD'];
       $snapldapbase = $cfg['SNAPSHOT_BASE'];
-      $ldap_to      = new LDAP($user,$password, $server);
+      $ldap_to      = new ldapMultiplexer(new LDAP($user,$password, $server));
       $ldap_to->cd ($snapldapbase);
-      show_ldap_error($ldap_to->get_error(), sprintf(_("Method get deleted snapshots with dn '%s' failed."),$this->dn));
+      if (!$ldap_to->success()){
+        msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
+      }
     }else{
       $ldap_to    = $ldap;
     }
@@ -1317,9 +1355,11 @@ class plugin
       $user         = $cfg['SNAPSHOT_USER'];
       $password     = $cfg['SNAPSHOT_PASSWORD'];
       $snapldapbase = $cfg['SNAPSHOT_BASE'];
-      $ldap_to      = new LDAP($user,$password, $server);
+      $ldap_to      = new ldapMultiplexer(new LDAP($user,$password, $server));
       $ldap_to->cd ($snapldapbase);
-      show_ldap_error($ldap->get_error(), sprintf(_("Restore snapshot with dn '%s' failed."),$snapldapbase));
+      if (!$ldap_to->success()){
+        msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
+      }
     }else{
       $ldap_to    = $ldap;
     }
@@ -1332,8 +1372,11 @@ class plugin
     $data  = gzuncompress($ldap_to->get_attribute($dn,'gosaSnapshotData'));
 
     /* Import the given data */
+    $err = "";
     $ldap->import_complete_ldif($data,$err,false,false);
-    show_ldap_error($ldap->get_error(), sprintf(_("Restore snapshot with dn '%s' failed."),$dn));
+    if (!$ldap->success()){
+      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, "", get_class()));
+    }
   }
 
 
@@ -1514,12 +1557,12 @@ class plugin
     if(isset($this->base) && isset($this->config->idepartments[$this->base])){
       $deps[$this->base] = $this->config->idepartments[$this->base];
     }else{
-      echo "No default base found. ".$this->base."<br> ";
+      trigger_error("No default base found in class ".get_class($this).". ".$this->base);
     }
-
     return($deps);
   }
 
+
   /* This function modifies object acls too, if an object is moved.
    *  $old_dn   specifies the actually used dn
    *  $new_dn   specifies the destiantion dn
@@ -1597,14 +1640,10 @@ class plugin
        /* Acls for this object must be adjusted */
        if($found){
 
-          if($output_changes){
-            echo "<font color='green'>".
-                  _("Changing ACL dn")."&nbsp;:&nbsp;<br>&nbsp;-"._("from")."&nbsp;<b>&nbsp;".
-                  $old_dn.
-                  "</b><br>&nbsp;-"._("to")."&nbsp;<b>".
-                  $new_dn.
-                  "</b></font><br>";
-          }
+          $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>";
+          @DEBUG (DEBUG_ACL, __LINE__, __FUNCTION__, __FILE__,$debug_info,"ACL");
+
           $update[$attrs['dn']] =array();
           foreach($acls as $acl){
             $update[$attrs['dn']]['gosaAclEntry'][] = $acl;