Code

Updated department handling for the rootDSE entry.
[gosa.git] / gosa-core / include / class_userinfo.inc
index f244f57e153365e52e3625ed0e61e3f5f362aa80..4045821ba85e0d5311ce31f6360678db2e522c6c 100644 (file)
@@ -172,7 +172,6 @@ class userinfo
       }
 
     }
-
   }
 
 
@@ -198,6 +197,86 @@ class userinfo
     return ($acl);
   }
 
+  
+  /*! \brief Check if the given object (dn) is copyable
+      @param  String The object dn 
+      @param  String The acl  category (e.g. users) 
+      @param  String The acl  class (e.g. user) 
+      @return Boolean   TRUE if the given object is copyable else FALSE 
+  */
+  function is_copyable($dn, $object, $class)
+  {
+    return(preg_match("/r/",$this->has_complete_category_acls($dn, $object)));
+  }
+
+
+  /*! \brief Check if the given object (dn) is cutable
+      @param  String The object dn 
+      @param  String The acl  category (e.g. users) 
+      @param  String The acl  class (e.g. user) 
+      @return Boolean   TRUE if the given object is cutable else FALSE 
+  */
+  function is_cutable($dn, $object, $class)
+  {
+    $remove = preg_match("/d/",$this->get_permissions($dn,$object."/".$class));
+    $read   = preg_match("/r/",$this->has_complete_category_acls($dn, $object));
+    return($remove && $read);
+  }
+
+
+  /*! \brief  Checks if we are allowed to paste an object to the given destination ($dn)
+      @param  String The destination dn 
+      @param  String The acl  category (e.g. users) 
+      @param  String The acl  class (e.g. user) 
+      @return Boolean   TRUE if we are allowed to paste an object.
+  */
+  function is_pasteable($dn, $object)
+  {
+    return(preg_match("/w/",$this->has_complete_category_acls($dn, $object)));
+  }
+
+
+  /*! \brief  Checks if we are allowed to restore a snapshot for the given dn.
+      @param  String The destination dn 
+      @param  String The acl  category (e.g. users) 
+      @return Boolean   TRUE if we are allowed to restore a snapshot.
+  */
+  function allow_snapshot_restore($dn, $object)
+  {
+    if(!is_array($object)){
+      $object = array($object);
+    }
+    $r = $w = $c = TRUE;
+    foreach($object as $category){
+      $w &= preg_match("/w/",$this->has_complete_category_acls($dn, $category));
+      $c &= preg_match("/c/",$this->has_complete_category_acls($dn, $category));
+      $r &= preg_match("/r/",$this->has_complete_category_acls($dn, $category));
+#     print_a(array($category => array($r.$w.$c)));
+    }
+    return($r && $w ); 
+  }  
+
+
+  /*! \brief  Checks if we are allowed to create a snapshot of the given dn.
+      @param  String The source dn 
+      @param  String The acl category (e.g. users) 
+      @return Boolean   TRUE if we are allowed to restore a snapshot.
+  */
+  function allow_snapshot_create($dn, $object)
+  {
+    if(!is_array($object)){
+      $object = array($object);
+    }
+    $r = $w = $c = TRUE;
+    foreach($object as $category){
+      $w &= preg_match("/w/",$this->has_complete_category_acls($dn, $category));
+      $c &= preg_match("/c/",$this->has_complete_category_acls($dn, $category));
+      $r &= preg_match("/r/",$this->has_complete_category_acls($dn, $category));
+#      print_a(array($category => array($r.$w.$c)));
+    }
+    return($r) ; 
+  }  
+
 
   function get_permissions($dn, $object, $attribute= "", $skip_write= FALSE)
   {
@@ -236,13 +315,16 @@ class userinfo
     foreach ($path as $element){
 
       /* Clean potential ACLs for each level */
-      $acl= $this->cleanACL($acl);
+      if(in_array($cpath,$this->config->departments)){
+        $acl= $this->cleanACL($acl);
+      }
 
       if ($cpath == ""){
         $cpath= $element;
       } else {
         $cpath= $element.','.$cpath;
       }
+
       if (isset($this->ACL[$cpath])){
 
         /* Inspect this ACL, place the result into ACL */
@@ -259,26 +341,42 @@ class userinfo
             continue;
           }
 
-         /* With user filter */
-         if (isset($subacl['filter']) && !empty($subacl['filter'])){
-           $sdn = preg_replace("/^[^,]*+,/","",$dn);
-           $ldap->cd($sdn);
-           $ldap->ls($subacl['filter'],$sdn);
-           if(!$ldap->count()){
-             continue;
-           }else{
-             $found = FALSE; 
-             while($attrs = $ldap->fetch()){
-               if($attrs['dn'] == $dn){
-                 $found = TRUE;
-                 break;
-               }
-             }
-             if(!$found){
-               continue;
-             }
-           }
-         }
+          /* With user filter */
+          if (isset($subacl['filter']) && !empty($subacl['filter'])){
+            $sdn = preg_replace("/^[^,]*+,/","",$dn);
+            $ldap->cd($sdn);
+            $ldap->ls($subacl['filter'],$sdn);
+            if(!$ldap->count()){
+              continue;
+            }else{
+              $found = FALSE; 
+              while($attrs = $ldap->fetch()){
+                if($attrs['dn'] == $dn){
+                  $found = TRUE;
+                  break;
+                }
+              }
+              if(!$found){
+                continue;
+              }
+            }
+          }
+
+          /* Self ACLs? 
+           */
+          if(isset($subacl['acl'][$object][0]) && preg_match("/s/",$subacl['acl'][$object][0]) && $dn != $this->dn){
+            continue;
+          }
+
+          /* If attribute is "", we want to know, if we've *any* permissions here... 
+              Merge global class ACLs [0] with attributes specific ACLs [attribute].
+           */
+          if ($attribute == "" && isset($subacl['acl'][$object])){
+            foreach($subacl['acl'][$object] as $attr => $dummy){
+              $acl= $this->mergeACL($acl, $subacl['type'], $subacl['acl'][$object][$attr]);
+            }
+            continue;
+          }
 
           /* Per attribute ACL? */
           if (isset($subacl['acl'][$object][$attribute])){
@@ -297,27 +395,21 @@ class userinfo
             $acl= $this->mergeACL($acl, $subacl['type'], $subacl['acl']['all'][0]);
             continue;
           }
-
-          /* If attribute is "", we want to know, if we've *any* permissions here... */
-          if ($attribute == "" && isset($subacl['acl'][$object])){
-            foreach($subacl['acl'][$object] as $attr => $dummy){
-              $acl= $this->mergeACL($acl, $subacl['type'], $subacl['acl'][$object][$attr]);
-            }
-            continue;
-          }
-
         }
       }
     }
 
+    /* If the requested ACL is for a container object, then alter 
+        ACLs by applying cleanACL a last time.
+     */
+    if(in_array($dn,$this->config->departments)){
+      $acl = $this->cleanACL($acl);
+    }
+
     /* Assemble string */
     $ret= "";
     foreach ($acl as $key => $value){
-      /*  Why doesn't 
-            if($value !=""){ 
-          work here??? It skips 0 too.
-       */
-      if (!preg_match("/^$/",$value)){ 
+      if ($value !== ""){
         $ret.= $key;
       }
     }
@@ -334,7 +426,7 @@ class userinfo
 
   /* Extract all departments that are accessible (direct or 'on the way' to an
      accessible department) */
-  function get_module_departments($module)
+  function get_module_departments($module, $skip_self_acls = FALSE )
   {
     
     /* If we are forced to skip ACLs checks for the current user 
@@ -373,75 +465,61 @@ class userinfo
       }
     }
 
-    /* For all gosaDepartments */
-    foreach ($this->config->departments as $dn){
-      $acl= array("r" => "", "w" => "", "c" => "", "d" => "", "m" => "", "a" => "");
-
-      /* Build dn array */
-      $path= split(',', $dn);
-      $path= array_reverse($path);
-
-      /* Walk along the path to evaluate the acl */
-      $cpath= "";
-      foreach ($path as $element){
-
-        /* Clean potential ACLs for each level */
-        $acl= $this->cleanACL($acl);
-
-        if ($cpath == ""){
-          $cpath= $element;
-        } else {
-          $cpath= $element.','.$cpath;
-        }
-        if (isset($this->ACL[$cpath])){
-
-          /* Inspect this ACL, place the result into ACL */
-          foreach ($this->ACL[$cpath] as $subacl){
-
-            /* Reset? Just clean the ACL and turn over to the next one... */
-            if ($subacl['type'] == 'reset'){
-              $acl= $this->cleanACL($acl, TRUE);
-              continue;
-            }
-    
-            if($subacl['type'] == 'role'){
-              echo "role skipped";
-              continue;
-            }
-
-            /* Per object ACL? */
-            foreach ($objects as $object){
-              if (isset($subacl['acl']["$module/$object"])){
-                foreach($subacl['acl']["$module/$object"] as $attribute => $dcl){
-                  $acl= $this->mergeACL($acl, $subacl['type'], $subacl['acl']["$module/$object"][$attribute]);
-                }
+    /* Search for per object ACLs. 
+     */
+    $this->config->get_departments();
+    $this->config->make_idepartments();
+
+    foreach($this->ACL as $dn => $infos){
+      foreach($infos as $info){
+        $found = FALSE;
+        foreach($info['acl'] as $cat => $data){
+
+          /* Skip self acls? */
+          if($skip_self_acls && isset($data['0']) && preg_match("//s",$data['0'])) continue;
+
+          if(is_array($module)){
+            foreach($module as $mod){
+              if(preg_match("/^".normalizePreg($mod)."/",$cat)){
+                $found =TRUE;
+                break;
               }
             }
-
-            /* Global ACL? */
-            if (isset($subacl['acl']["$module/all"][0])){
-              $acl= $this->mergeACL($acl, $subacl['type'], $subacl['acl']["$module/all"][0]);
-              continue;
+          }else{
+            if(preg_match("/^".normalizePreg($module)."/",$cat)){
+              $found =TRUE;
+              break;
             }
+          }
+        } 
 
-            /* Global ACL? */
-            if (isset($subacl['acl']["all"][0])){
-              $acl= $this->mergeACL($acl, $subacl['type'], $subacl['acl']["all"][0]);
-              continue;
-            }
+        if($found && !isset($this->config->idepartments[$dn])){
+          while(!isset($this->config->idepartments[$dn]) && preg_match("/,/",$dn)){
+            $dn = preg_replace("/^[^,]+,/","",$dn);
+          }
+          if(isset($this->config->idepartments[$dn])){
+            $deps[] = $dn;
           }
         }
       }
+    }
 
-      /* Add department, if we have (some) permissions for the required module */
-      foreach ($acl as $val){
-        if ($val != ""){
-          $deps[]= $dn;
-          break;
+    /* For all gosaDepartments */
+    foreach ($this->config->departments as $dn){
+      if(!is_array($module)){
+        $module = array($module);
+      }
+      $acl = "";
+      foreach($module as $mod){
+        if(preg_match("/\//",$mod)){
+          $acl.=  $this->get_permissions($dn,$mod);
+        }else{
+          $acl.=  $this->get_category_permissions($dn,$mod);
         }
       }
+      if($acl !== "") $deps[] = $dn;
     }
-
+  
     $ACL_CACHE = &session::get('ACL_CACHE');
     $ACL_CACHE['MODULE_DEPARTMENTS'][serialize($module)] = $deps;
     return ($deps);