X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gosa-core%2Finclude%2Fclass_userinfo.inc;h=4045821ba85e0d5311ce31f6360678db2e522c6c;hb=46e5854a4fc9e9ed72276149b64ee8399abdb7d9;hp=de0d89715c2a9209eef6a6e2d74a08abee6f88a6;hpb=1e73841b2c486817aeb75934af3496b8bfd7a184;p=gosa.git diff --git a/gosa-core/include/class_userinfo.inc b/gosa-core/include/class_userinfo.inc index de0d89715..4045821ba 100644 --- a/gosa-core/include/class_userinfo.inc +++ b/gosa-core/include/class_userinfo.inc @@ -1,21 +1,23 @@ ignore_acl_for_current_user()){ + return("rwcdm"); + } + /* Get list of objectClasses and get the permissions for it */ $acl= ""; if (isset($this->ocMapping[$category])){ foreach($this->ocMapping[$category] as $oc){ $acl.= $this->get_permissions($dn, $category."/".$oc); } + }else{ + trigger_error("ACL request for an invalid category (".$category.")."); } 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) { + /* If we are forced to skip ACLs checks for the current user + then return all permissions. + */ + if($this->ignore_acl_for_current_user()){ + return("rwcdm"); + } + /* Push cache answer? */ - $ACL_CACHE = session::get('ACL_CACHE'); + $ACL_CACHE = &session::get('ACL_CACHE'); if (isset($ACL_CACHE["$dn+$object+$attribute"])){ /* Remove write if needed */ @@ -202,6 +300,10 @@ class userinfo return($ret); } + /* Get ldap object, for later filter checks + */ + $ldap = $this->config->get_ldap_link(); + $acl= array("r" => "", "w" => "", "c" => "", "d" => "", "m" => "", "a" => ""); /* Build dn array */ @@ -213,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 */ @@ -236,6 +341,43 @@ 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; + } + } + } + + /* 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])){ $acl= $this->mergeACL($acl, $subacl['type'], $subacl['acl'][$object][$attribute]); @@ -253,30 +395,26 @@ 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){ - if ($value != ""){ + if ($value !== ""){ $ret.= $key; } } - $ACL_CACHE = session::get('ACL_CACHE'); $ACL_CACHE["$dn+$object+$attribute"]= $ret; - session::set('ACL_CACHE',$ACL_CACHE); /* Remove write if needed */ if ($skip_write){ @@ -288,8 +426,16 @@ 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 + then return all departments as valid. + */ + if($this->ignore_acl_for_current_user()){ + return(array_keys($this->config->idepartments)); + } + /* Use cached results if possilbe */ $ACL_CACHE = session::get('ACL_CACHE'); if(isset($ACL_CACHE['MODULE_DEPARTMENTS'][serialize($module)])){ @@ -319,78 +465,63 @@ 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 = &session::get('ACL_CACHE'); $ACL_CACHE['MODULE_DEPARTMENTS'][serialize($module)] = $deps; - session::set('ACL_CACHE',$ACL_CACHE); return ($deps); } @@ -503,6 +634,16 @@ class userinfo } return($acl); } + + + /*! \brief Returns TRUE if the current user is configured in IGNORE_ACL=".." in your gosa.conf + @param Return Boolean TRUE if we have to skip ACL checks else FALSE. + */ + function ignore_acl_for_current_user() + { + return(isset($this->config->current['IGNORE_ACL']) && $this->config->current['IGNORE_ACL'] == $this->dn); + } + } // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler: