Repository: incubator-ranger Updated Branches: refs/heads/tag-policy 2e4b430fd -> 05df8e782
RANGER-606: fix policy evaluation order to ensure that deny policies are evaluated before allow policies Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/05df8e78 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/05df8e78 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/05df8e78 Branch: refs/heads/tag-policy Commit: 05df8e782b538bf305789882d9819eb755766fc0 Parents: 2e4b430 Author: Madhan Neethiraj <[email protected]> Authored: Mon Aug 24 14:05:03 2015 -0700 Committer: Madhan Neethiraj <[email protected]> Committed: Mon Aug 24 14:05:03 2015 -0700 ---------------------------------------------------------------------- .../policyengine/RangerPolicyRepository.java | 10 ++ .../RangerAbstractPolicyEvaluator.java | 4 - .../RangerOptimizedPolicyEvaluator.java | 171 ++++++++++--------- 3 files changed, 99 insertions(+), 86 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/05df8e78/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java index 84b3b1d..0bbabc8 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java @@ -266,6 +266,16 @@ public class RangerPolicyRepository { } this.contextEnrichers = Collections.unmodifiableList(contextEnrichers); + if(LOG.isDebugEnabled()) { + LOG.debug("policy evaluation order: " + this.policyEvaluators.size() + " policies"); + + int order = 0; + for(RangerPolicyEvaluator policyEvaluator : this.policyEvaluators) { + RangerPolicy policy = policyEvaluator.getPolicy(); + + LOG.debug("policy evaluation order: #" + (++order) + " - policy id=" + policy.getId() + "; name=" + policy.getName() + "; evalOrder=" + policyEvaluator.getEvalOrder()); + } + } } private RangerContextEnricher buildContextEnricher(RangerServiceDef.RangerContextEnricherDef enricherDef) { http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/05df8e78/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java index 178b9d8..1308e63 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java @@ -78,10 +78,6 @@ public abstract class RangerAbstractPolicyEvaluator implements RangerPolicyEvalu int result = Integer.compare(this.getEvalOrder(), other.getEvalOrder()); - if (result == 0) { - result = Integer.compare(getCustomConditionsCount(), other.getCustomConditionsCount()); - } - if(LOG.isDebugEnabled()) { LOG.debug("<== RangerAbstractPolicyEvaluator.compareTo(), result:" + result); } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/05df8e78/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java index f660ae6..7bd1208 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java @@ -44,20 +44,25 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator // For computation of priority - private static final String RANGER_POLICY_EVAL_MATCH_ANY_PATTERN_STRING = "*"; - private static final String RANGER_POLICY_EVAL_MATCH_ONE_CHARACTER_STRING = "?"; - private static final int RANGER_POLICY_EVAL_MATCH_ANY_WILDCARD_PREMIUM = 25; - private static final int RANGER_POLICY_EVAL_CONTAINS_MATCH_ANY_WILDCARD_PREMIUM = 10; - private static final int RANGER_POLICY_EVAL_CONTAINS_MATCH_ONE_CHARACTER_WILDCARD_PREMIUM = 10; - private static final int RANGER_POLICY_EVAL_HAS_EXCLUDES_PREMIUM = 25; - private static final int RANGER_POLICY_EVAL_IS_RECURSIVE_PREMIUM = 25; - private static final int RANGER_POLICY_EVAL_PUBLIC_GROUP_ACCESS_PREMIUM = 25; - private static final int RANGER_POLICY_EVAL_ALL_ACCESS_TYPES_PREMIUM = 25; - private static final int RANGER_POLICY_EVAL_EXCLUSIVE_ALLOW_POLICY_PREMIUM = 400; - private static final int RANGER_POLICY_EVAL_DENY_POLICY_PREMIUM = 600; - - private static final int RANGER_POLICY_EVAL_RESERVED_SLOTS_NUMBER = 10000; - private static final int RANGER_POLICY_EVAL_RESERVED_SLOTS_PER_LEVEL_NUMBER = 1000; + private static final String RANGER_POLICY_EVAL_MATCH_ANY_PATTERN_STRING = "*"; + private static final String RANGER_POLICY_EVAL_MATCH_ONE_CHARACTER_STRING = "?"; + + private static final int RANGER_POLICY_EVAL_SCORE_DEFAULT = 10000; + private static final int RANGER_POLICY_EVAL_SCORE_DISCOUNT_DENY_POLICY = 4000; + private static final int RANGER_POLICY_EVAL_SCORE_DISCOUNT_EXCLUSIVE_ALLOW_POLICY = 2000; + + private static final int RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_RESOURCE = 100; + private static final int RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_USERSGROUPS = 25; + private static final int RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_ACCESS_TYPES = 25; + private static final int RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_CUSTOM_CONDITIONS = 25; + + private static final int RANGER_POLICY_EVAL_SCORE_RESOURCE_DISCOUNT_MATCH_ANY_WILDCARD = 25; + private static final int RANGER_POLICY_EVAL_SCORE_RESOURCE_DISCOUNT_HAS_MATCH_ANY_WILDCARD = 10; + private static final int RANGER_POLICY_EVAL_SCORE_RESOURCE_DISCOUNT_HAS_MATCH_ONE_CHARACTER_WILDCARD = 5; + private static final int RANGER_POLICY_EVAL_SCORE_RESOURCE_DISCOUNT_IS_EXCLUDES = 5; + private static final int RANGER_POLICY_EVAL_SCORE_RESORUCE_DISCOUNT_IS_RECURSIVE = 5; + private static final int RANGER_POLICY_EVAL_SCORE_CUSTOM_CONDITION_PENALTY = 5; + @Override public void init(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options) { @@ -102,112 +107,114 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator } } + class LevelResourceNames implements Comparable<LevelResourceNames> { + final int level; + final RangerPolicy.RangerPolicyResource policyResource; + + public LevelResourceNames(int level, RangerPolicy.RangerPolicyResource policyResource) { + this.level = level; + this.policyResource = policyResource; + } + + @Override + public int compareTo(LevelResourceNames other) { + // Sort in ascending order of level numbers + return Integer.compare(this.level, other.level); + } + } + public int computeEvalOrder() { if(LOG.isDebugEnabled()) { LOG.debug("==> RangerOptimizedPolicyEvaluator.computeEvalOrder()"); } - RangerServiceDef serviceDef = getServiceDef(); - RangerPolicy policy = getPolicy(); - class LevelResourceNames implements Comparable<LevelResourceNames> { - int level; - RangerPolicy.RangerPolicyResource policyResource; - - @Override - public int compareTo(LevelResourceNames other) { - // Sort in ascending order of level numbers - return Integer.compare(this.level, other.level); - } - } - List<LevelResourceNames> tmpList = new ArrayList<LevelResourceNames>(); + int evalOrder = RANGER_POLICY_EVAL_SCORE_DEFAULT; + RangerServiceDef serviceDef = getServiceDef(); List<RangerServiceDef.RangerResourceDef> resourceDefs = serviceDef.getResources(); - - for (Map.Entry<String, RangerPolicy.RangerPolicyResource> keyValuePair : policy.getResources().entrySet()) { - String serviceDefResourceName = keyValuePair.getKey(); - RangerPolicy.RangerPolicyResource policyResource = keyValuePair.getValue(); - List<String> policyResourceNames = policyResource.getValues(); - - RangerServiceDef.RangerResourceDef found = null; - for (RangerServiceDef.RangerResourceDef resourceDef : resourceDefs) { - if (serviceDefResourceName.equals(resourceDef.getName())) { - found = resourceDef; - break; - } + RangerPolicy policy = getPolicy(); + List<LevelResourceNames> tmpList = new ArrayList<LevelResourceNames>(); + + for (Map.Entry<String, RangerPolicy.RangerPolicyResource> kv : policy.getResources().entrySet()) { + String resourceName = kv.getKey(); + RangerPolicy.RangerPolicyResource policyResource = kv.getValue(); + List<String> resourceValues = policyResource.getValues(); + + if(CollectionUtils.isNotEmpty(resourceValues)) { + for (RangerServiceDef.RangerResourceDef resourceDef : resourceDefs) { + if (resourceName.equals(resourceDef.getName())) { + tmpList.add(new LevelResourceNames(resourceDef.getLevel(), policyResource)); + break; + } + } } - if (found != null) { - int level = found.getLevel(); - if (policyResourceNames != null) { - LevelResourceNames item = new LevelResourceNames(); - item.level = level; - item.policyResource = policyResource; - tmpList.add(item); - } - - } - } Collections.sort(tmpList); // Sort in ascending order of levels - CharSequence matchesAnySeq = RANGER_POLICY_EVAL_MATCH_ANY_PATTERN_STRING.subSequence(0, 1); - CharSequence matchesSingleCharacterSeq = RANGER_POLICY_EVAL_MATCH_ONE_CHARACTER_STRING.subSequence(0, 1); - - int priorityLevel = RANGER_POLICY_EVAL_RESERVED_SLOTS_NUMBER; - boolean seenFirstMatchAny = false; - + int resourceDiscount = 0; for (LevelResourceNames item : tmpList) { // Expect lowest level first - List<String> resourceNames = item.policyResource.getValues(); - boolean foundStarWildcard = false; + boolean foundStarWildcard = false; boolean foundQuestionWildcard = false; - boolean foundMatchAny = false; + boolean foundMatchAny = false; - for (String resourceName : resourceNames) { - if (resourceName.isEmpty() ||resourceName.equals(RANGER_POLICY_EVAL_MATCH_ANY_PATTERN_STRING)) { + for (String resourceName : item.policyResource.getValues()) { + if (resourceName.isEmpty() || resourceName.equals(RANGER_POLICY_EVAL_MATCH_ANY_PATTERN_STRING)) { foundMatchAny = true; break; - } - if (resourceName.contains(matchesAnySeq)) + } else if (resourceName.contains(RANGER_POLICY_EVAL_MATCH_ANY_PATTERN_STRING)) { foundStarWildcard = true; - else if (resourceName.contains(matchesSingleCharacterSeq)) + } else if (resourceName.contains(RANGER_POLICY_EVAL_MATCH_ONE_CHARACTER_STRING)) { foundQuestionWildcard = true; + } } if (foundMatchAny) { - if (seenFirstMatchAny) - priorityLevel -= RANGER_POLICY_EVAL_MATCH_ANY_WILDCARD_PREMIUM; - else { - seenFirstMatchAny = true; - } + resourceDiscount += RANGER_POLICY_EVAL_SCORE_RESOURCE_DISCOUNT_MATCH_ANY_WILDCARD; } else { - priorityLevel += RANGER_POLICY_EVAL_RESERVED_SLOTS_PER_LEVEL_NUMBER; - if (foundStarWildcard) priorityLevel -= RANGER_POLICY_EVAL_CONTAINS_MATCH_ANY_WILDCARD_PREMIUM; - else if (foundQuestionWildcard) priorityLevel -= RANGER_POLICY_EVAL_CONTAINS_MATCH_ONE_CHARACTER_WILDCARD_PREMIUM; + if (foundStarWildcard) { + resourceDiscount += RANGER_POLICY_EVAL_SCORE_RESOURCE_DISCOUNT_HAS_MATCH_ANY_WILDCARD; + } else if (foundQuestionWildcard) { + resourceDiscount += RANGER_POLICY_EVAL_SCORE_RESOURCE_DISCOUNT_HAS_MATCH_ONE_CHARACTER_WILDCARD; + } RangerPolicy.RangerPolicyResource resource = item.policyResource; - if (resource.getIsExcludes()) priorityLevel -= RANGER_POLICY_EVAL_HAS_EXCLUDES_PREMIUM; - if (resource.getIsRecursive()) priorityLevel -= RANGER_POLICY_EVAL_IS_RECURSIVE_PREMIUM; + + if (resource.getIsExcludes()) { + resourceDiscount += RANGER_POLICY_EVAL_SCORE_RESOURCE_DISCOUNT_IS_EXCLUDES; + } + + if (resource.getIsRecursive()) { + resourceDiscount += RANGER_POLICY_EVAL_SCORE_RESORUCE_DISCOUNT_IS_RECURSIVE; + } } } + evalOrder -= Math.min(RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_RESOURCE, resourceDiscount); + if (hasPublicGroup) { - priorityLevel -= RANGER_POLICY_EVAL_PUBLIC_GROUP_ACCESS_PREMIUM; + evalOrder -= RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_USERSGROUPS; } else { - priorityLevel -= groups.size(); + evalOrder -= Math.min(groups.size() + users.size(), RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_USERSGROUPS); } - priorityLevel -= users.size(); - priorityLevel -= Math.round(((float)RANGER_POLICY_EVAL_ALL_ACCESS_TYPES_PREMIUM * accessPerms.size()) / serviceDef.getAccessTypes().size()); + evalOrder -= Math.round(((float)RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_ACCESS_TYPES * accessPerms.size()) / serviceDef.getAccessTypes().size()); + + int customConditionsDiscount = RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_CUSTOM_CONDITIONS - (RANGER_POLICY_EVAL_SCORE_CUSTOM_CONDITION_PENALTY * this.getCustomConditionsCount()); + if(customConditionsDiscount > 0) { + evalOrder -= customConditionsDiscount; + } if (policy.isPolicyTypeDeny()) { - priorityLevel -= RANGER_POLICY_EVAL_DENY_POLICY_PREMIUM; + evalOrder -= RANGER_POLICY_EVAL_SCORE_DISCOUNT_DENY_POLICY; } else if (policy.isPolicyTypeExclusiveAllow()) { - priorityLevel -= RANGER_POLICY_EVAL_EXCLUSIVE_ALLOW_POLICY_PREMIUM; + evalOrder -= RANGER_POLICY_EVAL_SCORE_DISCOUNT_EXCLUSIVE_ALLOW_POLICY; } if(LOG.isDebugEnabled()) { - LOG.debug("<== RangerOptimizedPolicyEvaluator.computeEvalOrder(), policyName:" + policy.getName() + ", priority:" + priorityLevel); + LOG.debug("<== RangerOptimizedPolicyEvaluator.computeEvalOrder(), policyName:" + policy.getName() + ", priority:" + evalOrder); } - return priorityLevel; + + return evalOrder; } @Override
