This is an automated email from the ASF dual-hosted git repository.

abhay pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new 691a55c  RANGER-2858:'show databases' gives permission denied error, 
even though the user has permissions on a few of the databases in security zone 
policies
691a55c is described below

commit 691a55cd38ef216258aec370859d5b2d823320da
Author: Abhay Kulkarni <[email protected]>
AuthorDate: Tue Jun 16 16:03:13 2020 -0700

    RANGER-2858:'show databases' gives permission denied error, even though the 
user has permissions on a few of the databases in security zone policies
---
 .../ranger/plugin/policyengine/PolicyEngine.java   |  97 ++--
 .../plugin/policyengine/RangerPolicyEngine.java    |   4 +-
 .../policyengine/RangerPolicyEngineImpl.java       | 523 +++++++++++----------
 .../ranger/plugin/service/RangerBasePlugin.java    |   4 +-
 .../org/apache/ranger/biz/RangerPolicyAdmin.java   |   7 +-
 .../apache/ranger/biz/RangerPolicyAdminImpl.java   |  61 ++-
 .../java/org/apache/ranger/rest/ServiceREST.java   |  57 ++-
 7 files changed, 411 insertions(+), 342 deletions(-)

diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
index e6de06f..c22f61f 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/PolicyEngine.java
@@ -296,56 +296,68 @@ public class PolicyEngine {
         return ret;
     }
 
-    public RangerPolicyRepository 
getRepositoryForMatchedZone(RangerAccessResource resource) {
+    public RangerPolicyRepository getRepositoryForMatchedZone(RangerPolicy 
policy) {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> PolicyEngine.getRepositoryForMatchedZone(" + 
resource +  ")");
+            LOG.debug("==> PolicyEngine.getRepositoryForMatchedZone(" + policy 
+ ")");
         }
 
-        String                       zoneName = getMatchedZoneName(resource);
+        String                       zoneName = policy.getZoneName();
         final RangerPolicyRepository ret      = getRepositoryForZone(zoneName);
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("<== PolicyEngine.getRepositoryForMatchedZone(" + 
resource +  ")");
+            LOG.debug("<== PolicyEngine.getRepositoryForMatchedZone(" + policy 
+ ")");
         }
 
         return ret;
     }
 
-    public RangerPolicyRepository getRepositoryForMatchedZone(RangerPolicy 
policy) {
+    public Set<String> 
getMatchedZonesForResourceAndChildren(RangerAccessResource accessResource) {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> PolicyEngine.getRepositoryForMatchedZone(" + policy 
+ ")");
+            LOG.debug("==> 
PolicyEngine.getMatchedZonesForResourceAndChildren(" + accessResource + ")");
         }
 
-        String                       zoneName = policy.getZoneName();
-        final RangerPolicyRepository ret      = getRepositoryForZone(zoneName);
+        Set<String> ret = null;
+
+        if (MapUtils.isNotEmpty(this.resourceZoneTrie)) {
+            ret = 
getMatchedZonesForResourceAndChildren(accessResource.getAsMap(), 
accessResource);
+        }
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("<== PolicyEngine.getRepositoryForMatchedZone(" + policy 
+ ")");
+            LOG.debug("<== 
PolicyEngine.getMatchedZonesForResourceAndChildren(" + accessResource + ") : " 
+ ret);
         }
 
         return ret;
     }
 
-    public String getMatchedZoneName(RangerAccessResource accessResource) {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("==> PolicyEngine.getMatchedZoneName(" + accessResource 
+ ")");
+    public String getUniquelyMatchedZoneName(Map<String, ?> resourceAsMap) {
+        String ret = null;
+        Set<String> matchedZones = 
getMatchedZonesForResourceAndChildren(resourceAsMap, 
convertToAccessResource(resourceAsMap));
+        if (CollectionUtils.isNotEmpty(matchedZones) && matchedZones.size() == 
1) {
+            String[] matchedZonesArray = new String[1];
+            matchedZones.toArray(matchedZonesArray);
+            ret = matchedZonesArray[0];
         }
+        return ret;
+    }
 
-        String ret = null;
+    public RangerPolicyRepository getRepositoryForZone(String zoneName) {
+        final RangerPolicyRepository ret;
 
-        if (MapUtils.isNotEmpty(this.resourceZoneTrie)) {
-            ret = getMatchedZoneName(accessResource.getAsMap(), 
accessResource);
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("zoneName:[" + zoneName + "]");
         }
 
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("<== PolicyEngine.getMatchedZoneName(" + accessResource 
+ ") : " + ret);
+        if (StringUtils.isNotEmpty(zoneName)) {
+            ret = getZonePolicyRepositories().get(zoneName);
+        } else {
+            ret = getPolicyRepository();
         }
 
-        return ret;
-    }
+        if (ret == null) {
+            LOG.error("policyRepository for zoneName:[" + zoneName + "],  
serviceName:[" + getServiceName() + "], policyVersion:[" + getPolicyVersion() + 
"] is null!! ERROR!");
+        }
 
-    public String getMatchedZoneName(Map<String, ?> resourceAsMap) {
-        return getMatchedZoneName(resourceAsMap, 
convertToAccessResource(resourceAsMap));
+        return ret;
     }
 
     public boolean hasTagPolicies(RangerPolicyRepository tagPolicyRepository) {
@@ -396,12 +408,12 @@ public class PolicyEngine {
         }
     }
 
-    private String getMatchedZoneName(Map<String, ?> resource, 
RangerAccessResource accessResource) {
+    private Set<String> getMatchedZonesForResourceAndChildren(Map<String, ?> 
resource, RangerAccessResource accessResource) {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> PolicyEngine.getMatchedZoneName(" + resource + ", " 
+ accessResource + ")");
+            LOG.debug("==> 
PolicyEngine.getMatchedZonesForResourceAndChildren(" + resource + ", " + 
accessResource + ")");
         }
 
-        String ret = null;
+        Set<String> ret = null;
 
         if (MapUtils.isNotEmpty(this.resourceZoneTrie)) {
             List<Set<RangerZoneResourceMatcher>> zoneMatchersList = null;
@@ -470,7 +482,7 @@ public class PolicyEngine {
                 }
 
                 if (intersection.size() > 0) {
-                    Set<String> matchedZoneNames = new HashSet<>();
+                    ret = new HashSet<>();
 
                     for (RangerZoneResourceMatcher zoneMatcher : intersection) 
{
                         if (LOG.isDebugEnabled()) {
@@ -484,7 +496,7 @@ public class PolicyEngine {
                             }
 
                             // Actual match happened
-                            
matchedZoneNames.add(zoneMatcher.getSecurityZoneName());
+                            ret.add(zoneMatcher.getSecurityZoneName());
                         } else {
                             if (LOG.isDebugEnabled()) {
                                 LOG.debug("Did not match resource:[" + 
accessResource + "] using zoneMatcher:[" + zoneMatcher + "]");
@@ -493,24 +505,14 @@ public class PolicyEngine {
                     }
 
                     if (LOG.isDebugEnabled()) {
-                        LOG.debug("The following zone-names matched 
resource:[" + accessResource + "]: " + matchedZoneNames);
-                    }
-
-                    if (matchedZoneNames.size() == 1) {
-                        String[] zones = new String[1];
-
-                        matchedZoneNames.toArray(zones);
-
-                        ret = zones[0];
-                    } else {
-                        LOG.error("Internal error, multiple zone-names are 
matched. The following zone-names matched resource:[" + resource + "]: " + 
matchedZoneNames);
+                        LOG.debug("The following zone-names matched 
resource:[" + accessResource + "]: " + ret);
                     }
                 }
             }
         }
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("<== PolicyEngine.getMatchedZoneName(" + resource + ", " 
+ accessResource + ") : " + ret);
+            LOG.debug("<== 
PolicyEngine.getMatchedZonesForResourceAndChildren(" + resource + ", " + 
accessResource + ") : " + ret);
         }
 
         return ret;
@@ -528,25 +530,6 @@ public class PolicyEngine {
         return ret;
     }
 
-    private RangerPolicyRepository getRepositoryForZone(String zoneName) {
-        final RangerPolicyRepository ret;
-
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("zoneName:[" + zoneName + "]");
-        }
-
-        if (StringUtils.isNotEmpty(zoneName)) {
-            ret = getZonePolicyRepositories().get(zoneName);
-        } else {
-            ret = getPolicyRepository();
-        }
-
-        if (ret == null) {
-            LOG.error("policyRepository for zoneName:[" + zoneName + "],  
serviceName:[" + getServiceName() + "], policyVersion:[" + getPolicyVersion() + 
"] is null!! ERROR!");
-        }
-
-        return ret;
-    }
 
     private PolicyEngine(final PolicyEngine other, ServicePolicies 
servicePolicies) {
         this.useForwardedIPAddress = other.useForwardedIPAddress;
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
index fdec9ca..100d1f1 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
@@ -67,6 +67,8 @@ public interface RangerPolicyEngine {
 
        Set<String> getRolesFromUserAndGroups(String user, Set<String> groups);
 
+       String getUniquelyMatchedZoneName(GrantRevokeRequest 
grantRevokeRequest);
+
        // Helpers
 
        List<RangerPolicy> getResourcePolicies(String zoneName);
@@ -75,8 +77,6 @@ public interface RangerPolicyEngine {
 
        List<RangerPolicy> getTagPolicies();
 
-       String getMatchedZoneName(GrantRevokeRequest grantRevokeRequest);
-
        // This API is used only used by test code
        RangerResourceAccessInfo getResourceAccessInfo(RangerAccessRequest 
request);
 }
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
index 0930e2c..2a7166a 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
@@ -21,6 +21,7 @@ package org.apache.ranger.plugin.policyengine;
 
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.ListUtils;
+import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -175,289 +176,126 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
 
                requestProcessor.preProcess(request);
 
-               String zoneName = 
policyEngine.getMatchedZoneName(request.getResource());
+               String zoneName = 
policyEngine.getUniquelyMatchedZoneName(request.getResource().getAsMap());
 
                if (LOG.isDebugEnabled()) {
                        LOG.debug("zoneName:[" + zoneName + "]");
                }
+               List<RangerPolicyEvaluator>                      allEvaluators  
         = new ArrayList<>();
+               Map<Long, RangerPolicyResourceMatcher.MatchType> 
tagMatchTypeMap         = new HashMap<>();
+               Set<Long>                                        
policyIdForTemporalTags = new HashSet<>();
 
-               final RangerPolicyRepository matchedRepository;
+               getResourceACLEvaluatorsForZone(request, zoneName, 
allEvaluators, tagMatchTypeMap, policyIdForTemporalTags);
 
-               if (StringUtils.isNotEmpty(zoneName)) {
-                       matchedRepository = 
policyEngine.getZonePolicyRepositories().get(zoneName);
-               } else {
-                       matchedRepository = policyEngine.getPolicyRepository();
-               }
-
-               if (matchedRepository == null) {
-                       LOG.error("policyRepository for zoneName:[" + zoneName 
+ "],  serviceName:[" + policyEngine.getPolicyRepository().getServiceName() + 
"], policyVersion:[" + getPolicyVersion() + "] is null!! ERROR!");
-               } else {
-                       List<RangerPolicyEvaluator>                      
allEvaluators           = new ArrayList<>();
-                       Map<Long, RangerPolicyResourceMatcher.MatchType> 
tagMatchTypeMap         = null;
-                       Set<Long>                                        
policyIdForTemporalTags = null;
-                       Set<RangerTagForEval>                            tags   
                 = 
RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
-                       List<PolicyEvaluatorForTag>                      
tagPolicyEvaluators     = policyEngine.getTagPolicyRepository() == null ? null 
: policyEngine.getTagPolicyRepository().getLikelyMatchPolicyEvaluators(tags, 
RangerPolicy.POLICY_TYPE_ACCESS, null);
+               allEvaluators.sort(RangerPolicyEvaluator.EVAL_ORDER_COMPARATOR);
 
-                       if (CollectionUtils.isNotEmpty(tagPolicyEvaluators)) {
-                               tagMatchTypeMap = new HashMap<>();
-
-                               final boolean useTagPoliciesFromDefaultZone = 
!policyEngine.isResourceZoneAssociatedWithTagService(zoneName);
-
-                               for (PolicyEvaluatorForTag tagEvaluator : 
tagPolicyEvaluators) {
-                                       RangerPolicyEvaluator evaluator      = 
tagEvaluator.getEvaluator();
-                                       String                policyZoneName = 
evaluator.getPolicy().getZoneName();
+               if (CollectionUtils.isNotEmpty(allEvaluators)) {
+                       Integer policyPriority = null;
 
-                                       if (useTagPoliciesFromDefaultZone) {
-                                               if 
(StringUtils.isNotEmpty(policyZoneName)) {
-                                                       if 
(LOG.isDebugEnabled()) {
-                                                               LOG.debug("Tag 
policy [zone:" + policyZoneName + "] does not belong to default zone. Not 
evaluating this policy:[" + evaluator.getPolicy() + "]");
-                                                       }
-
-                                                       continue;
-                                               }
-                                       } else {
-                                               if 
(!StringUtils.equals(zoneName, policyZoneName)) {
-                                                       if 
(LOG.isDebugEnabled()) {
-                                                               LOG.debug("Tag 
policy [zone:" + policyZoneName + "] does not belong to the zone:[" + zoneName 
+ "] of the accessed resource. Not evaluating this policy:[" + 
evaluator.getPolicy() + "]");
-                                                       }
-
-                                                       continue;
-                                               }
-                                       }
-
-                                       RangerTagForEval tag = 
tagEvaluator.getTag();
-
-                                       allEvaluators.add(evaluator);
-                                       tagMatchTypeMap.put(evaluator.getId(), 
tag.getMatchType());
-
-                                       if 
(CollectionUtils.isNotEmpty(tag.getValidityPeriods())) {
-                                               if (policyIdForTemporalTags == 
null) {
-                                                       policyIdForTemporalTags 
= new HashSet<>();
-                                               }
-
-                                               
policyIdForTemporalTags.add(evaluator.getId());
-                                       }
+                       for (RangerPolicyEvaluator evaluator : allEvaluators) {
+                               if (policyPriority == null) {
+                                       policyPriority = 
evaluator.getPolicyPriority();
                                }
-                       }
-
-                       List<RangerPolicyEvaluator> resourcePolicyEvaluators = 
matchedRepository.getLikelyMatchPolicyEvaluators(request.getResource(), 
RangerPolicy.POLICY_TYPE_ACCESS);
-
-                       allEvaluators.addAll(resourcePolicyEvaluators);
 
-                       
allEvaluators.sort(RangerPolicyEvaluator.EVAL_ORDER_COMPARATOR);
-
-                       if (CollectionUtils.isNotEmpty(allEvaluators)) {
-                               Integer policyPriority = null;
-
-                               for (RangerPolicyEvaluator evaluator : 
allEvaluators) {
-                                       if (policyPriority == null) {
-                                               policyPriority = 
evaluator.getPolicyPriority();
-                                       }
+                               if (policyPriority != 
evaluator.getPolicyPriority()) {
+                                       ret.finalizeAcls();
 
-                                       if (policyPriority != 
evaluator.getPolicyPriority()) {
-                                               ret.finalizeAcls();
-
-                                               policyPriority = 
evaluator.getPolicyPriority();
-                                       }
+                                       policyPriority = 
evaluator.getPolicyPriority();
+                               }
 
-                                       RangerPolicyResourceMatcher.MatchType 
matchType = tagMatchTypeMap != null ? tagMatchTypeMap.get(evaluator.getId()) : 
null;
+                               RangerPolicyResourceMatcher.MatchType matchType 
=  tagMatchTypeMap.get(evaluator.getId());
 
-                                       if (matchType == null) {
-                                               matchType = 
evaluator.getPolicyResourceMatcher().getMatchType(request.getResource(), 
request.getContext());
-                                       }
+                               if (matchType == null) {
+                                       matchType = 
evaluator.getPolicyResourceMatcher().getMatchType(request.getResource(), 
request.getContext());
+                               }
 
-                                       final boolean isMatched;
+                               final boolean isMatched;
 
-                                       if (request.getResourceMatchingScope() 
== RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
-                                               isMatched = matchType != 
RangerPolicyResourceMatcher.MatchType.NONE;
-                                       } else {
-                                               isMatched = matchType == 
RangerPolicyResourceMatcher.MatchType.SELF || matchType == 
RangerPolicyResourceMatcher.MatchType.SELF_AND_ALL_DESCENDANTS;
-                                       }
+                               if (request.getResourceMatchingScope() == 
RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
+                                       isMatched = matchType != 
RangerPolicyResourceMatcher.MatchType.NONE;
+                               } else {
+                                       isMatched = matchType == 
RangerPolicyResourceMatcher.MatchType.SELF || matchType == 
RangerPolicyResourceMatcher.MatchType.SELF_AND_ALL_DESCENDANTS;
+                               }
 
-                                       if (!isMatched) {
-                                               continue;
-                                       }
+                               if (!isMatched) {
+                                       continue;
+                               }
 
-                                       PolicyACLSummary aclSummary = 
evaluator.getPolicyACLSummary();
+                               PolicyACLSummary aclSummary = 
evaluator.getPolicyACLSummary();
 
-                                       if (aclSummary != null) {
-                                               boolean isConditional = 
(policyIdForTemporalTags != null && 
policyIdForTemporalTags.contains(evaluator.getId())) || 
evaluator.getValidityScheduleEvaluatorsCount() != 0;
-                                               Integer accessResult;
+                               if (aclSummary != null) {
+                                       boolean isConditional = 
policyIdForTemporalTags.contains(evaluator.getId()) || 
evaluator.getValidityScheduleEvaluatorsCount() != 0;
+                                       Integer accessResult;
 
-                                               for (Map.Entry<String, 
Map<String, PolicyACLSummary.AccessResult>> userAccessInfo : 
aclSummary.getUsersAccessInfo().entrySet()) {
-                                                       final String userName = 
userAccessInfo.getKey();
+                                       for (Map.Entry<String, Map<String, 
PolicyACLSummary.AccessResult>> userAccessInfo : 
aclSummary.getUsersAccessInfo().entrySet()) {
+                                               final String userName = 
userAccessInfo.getKey();
 
-                                                       for (Map.Entry<String, 
PolicyACLSummary.AccessResult> accessInfo : 
userAccessInfo.getValue().entrySet()) {
-                                                               if 
(isConditional) {
-                                                                       
accessResult = ACCESS_CONDITIONAL;
-                                                               } else {
-                                                                       
accessResult = accessInfo.getValue().getResult();
+                                               for (Map.Entry<String, 
PolicyACLSummary.AccessResult> accessInfo : 
userAccessInfo.getValue().entrySet()) {
+                                                       if (isConditional) {
+                                                               accessResult = 
ACCESS_CONDITIONAL;
+                                                       } else {
+                                                               accessResult = 
accessInfo.getValue().getResult();
 
-                                                                       if 
(accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
-                                                                               
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
-                                                                       }
+                                                               if 
(accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
+                                                                       
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
                                                                }
-
-                                                               RangerPolicy 
policy = evaluator.getPolicy();
-
-                                                               
ret.setUserAccessInfo(userName, accessInfo.getKey(), accessResult, policy);
                                                        }
-                                               }
-
-                                               for (Map.Entry<String, 
Map<String, PolicyACLSummary.AccessResult>> groupAccessInfo : 
aclSummary.getGroupsAccessInfo().entrySet()) {
-                                                       final String groupName 
= groupAccessInfo.getKey();
-
-                                                       for (Map.Entry<String, 
PolicyACLSummary.AccessResult> accessInfo : 
groupAccessInfo.getValue().entrySet()) {
-                                                               if 
(isConditional) {
-                                                                       
accessResult = ACCESS_CONDITIONAL;
-                                                               } else {
-                                                                       
accessResult = accessInfo.getValue().getResult();
 
-                                                                       if 
(accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
-                                                                               
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
-                                                                       }
-                                                               }
-
-                                                               RangerPolicy 
policy = evaluator.getPolicy();
+                                                       RangerPolicy policy = 
evaluator.getPolicy();
 
-                                                               
ret.setGroupAccessInfo(groupName, accessInfo.getKey(), accessResult, policy);
-                                                       }
+                                                       
ret.setUserAccessInfo(userName, accessInfo.getKey(), accessResult, policy);
                                                }
+                                       }
 
-                                               for (Map.Entry<String, 
Map<String, PolicyACLSummary.AccessResult>> roleAccessInfo : 
aclSummary.getRolesAccessInfo().entrySet()) {
-                                                       final String roleName = 
roleAccessInfo.getKey();
+                                       for (Map.Entry<String, Map<String, 
PolicyACLSummary.AccessResult>> groupAccessInfo : 
aclSummary.getGroupsAccessInfo().entrySet()) {
+                                               final String groupName = 
groupAccessInfo.getKey();
 
-                                                       for (Map.Entry<String, 
PolicyACLSummary.AccessResult> accessInfo : 
roleAccessInfo.getValue().entrySet()) {
-                                                               if 
(isConditional) {
-                                                                       
accessResult = ACCESS_CONDITIONAL;
-                                                               } else {
-                                                                       
accessResult = accessInfo.getValue().getResult();
+                                               for (Map.Entry<String, 
PolicyACLSummary.AccessResult> accessInfo : 
groupAccessInfo.getValue().entrySet()) {
+                                                       if (isConditional) {
+                                                               accessResult = 
ACCESS_CONDITIONAL;
+                                                       } else {
+                                                               accessResult = 
accessInfo.getValue().getResult();
 
-                                                                       if 
(accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
-                                                                               
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
-                                                                       }
+                                                               if 
(accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
+                                                                       
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
                                                                }
+                                                       }
 
-                                                               RangerPolicy 
policy = evaluator.getPolicy();
+                                                       RangerPolicy policy = 
evaluator.getPolicy();
 
-                                                               
ret.setRoleAccessInfo(roleName, accessInfo.getKey(), accessResult, policy);
-                                                       }
+                                                       
ret.setGroupAccessInfo(groupName, accessInfo.getKey(), accessResult, policy);
                                                }
                                        }
-                               }
-
-                               ret.finalizeAcls();
-                       }
-               }
-
-               RangerPerfTracer.logAlways(perf);
 
-               if (LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerPolicyEngineImpl.getResourceACLs(request=" + request + ") : ret=" + ret);
-               }
-
-               return ret;
-       }
-
-       PolicyEngine getPolicyEngine() {
-               return policyEngine;
-       }
-
-       // This API is used only used by test code
-       @Override
-       public RangerResourceAccessInfo 
getResourceAccessInfo(RangerAccessRequest request) {
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerPolicyEngineImpl.getResourceAccessInfo(" + request + ")");
-               }
-
-               requestProcessor.preProcess(request);
-
-               RangerResourceAccessInfo ret      = new 
RangerResourceAccessInfo(request);
-               String                   zoneName = 
policyEngine.getMatchedZoneName(request.getResource());
-
-               if (LOG.isDebugEnabled()) {
-                       LOG.debug("zoneName:[" + zoneName + "]");
-               }
-
-               final RangerPolicyRepository matchedRepository;
-
-               if (StringUtils.isNotEmpty(zoneName)) {
-                       matchedRepository = 
policyEngine.getZonePolicyRepositories().get(zoneName);
-               } else {
-                       matchedRepository = policyEngine.getPolicyRepository();
-               }
-
-               if (matchedRepository == null) {
-                       LOG.error("policyRepository for zoneName:[" + zoneName 
+ "],  serviceName:[" + policyEngine.getPolicyRepository().getServiceName() + 
"], policyVersion:[" + getPolicyVersion() + "] is null!! ERROR!");
-               } else {
-                       List<RangerPolicyEvaluator> tagPolicyEvaluators = 
policyEngine.getTagPolicyRepository() == null ? null : 
policyEngine.getTagPolicyRepository().getPolicyEvaluators();
-
-                       if (CollectionUtils.isNotEmpty(tagPolicyEvaluators)) {
-                               Set<RangerTagForEval> tags = 
RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
-
-                               if (CollectionUtils.isNotEmpty(tags)) {
-                                       final boolean 
useTagPoliciesFromDefaultZone = 
!policyEngine.isResourceZoneAssociatedWithTagService(zoneName);
-
-                                       for (RangerTagForEval tag : tags) {
-                                               RangerAccessRequest         
tagEvalRequest = new RangerTagAccessRequest(tag, 
policyEngine.getTagPolicyRepository().getServiceDef(), request);
-                                               List<RangerPolicyEvaluator> 
evaluators     = 
policyEngine.getTagPolicyRepository().getLikelyMatchPolicyEvaluators(tagEvalRequest.getResource(),
 RangerPolicy.POLICY_TYPE_ACCESS);
-
-                                               for (RangerPolicyEvaluator 
evaluator : evaluators) {
-                                                       String policyZoneName = 
evaluator.getPolicy().getZoneName();
-
-                                                       if 
(useTagPoliciesFromDefaultZone) {
-                                                               if 
(StringUtils.isNotEmpty(policyZoneName)) {
-                                                                       if 
(LOG.isDebugEnabled()) {
-                                                                               
LOG.debug("Tag policy [zone:" + policyZoneName + "] does not belong to default 
zone. Not evaluating this policy:[" + evaluator.getPolicy() + "]");
-                                                                       }
+                                       for (Map.Entry<String, Map<String, 
PolicyACLSummary.AccessResult>> roleAccessInfo : 
aclSummary.getRolesAccessInfo().entrySet()) {
+                                               final String roleName = 
roleAccessInfo.getKey();
 
-                                                                       
continue;
-                                                               }
+                                               for (Map.Entry<String, 
PolicyACLSummary.AccessResult> accessInfo : 
roleAccessInfo.getValue().entrySet()) {
+                                                       if (isConditional) {
+                                                               accessResult = 
ACCESS_CONDITIONAL;
                                                        } else {
-                                                               if 
(!StringUtils.equals(zoneName, policyZoneName)) {
-                                                                       if 
(LOG.isDebugEnabled()) {
-                                                                               
LOG.debug("Tag policy [zone:" + policyZoneName + "] does not belong to the 
zone:[" + zoneName + "] of the accessed resource. Not evaluating this policy:[" 
+ evaluator.getPolicy() + "]");
-                                                                       }
+                                                               accessResult = 
accessInfo.getValue().getResult();
 
-                                                                       
continue;
+                                                               if 
(accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
+                                                                       
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
                                                                }
                                                        }
 
-                                                       
evaluator.getResourceAccessInfo(tagEvalRequest, ret);
+                                                       RangerPolicy policy = 
evaluator.getPolicy();
+
+                                                       
ret.setRoleAccessInfo(roleName, accessInfo.getKey(), accessResult, policy);
                                                }
                                        }
                                }
                        }
 
-                       List<RangerPolicyEvaluator> resPolicyEvaluators = 
matchedRepository.getLikelyMatchPolicyEvaluators(request.getResource(), 
RangerPolicy.POLICY_TYPE_ACCESS);
-
-                       if (CollectionUtils.isNotEmpty(resPolicyEvaluators)) {
-                               for (RangerPolicyEvaluator evaluator : 
resPolicyEvaluators) {
-                                       
evaluator.getResourceAccessInfo(request, ret);
-                               }
-                       }
-
-                       ret.getAllowedUsers().removeAll(ret.getDeniedUsers());
-                       ret.getAllowedGroups().removeAll(ret.getDeniedGroups());
-               }
-
-               if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerPolicyEngineImpl.getResourceAccessInfo(" + request + "): " + ret);
-               }
-
-               return ret;
-       }
-
-       @Override
-       public String getMatchedZoneName(GrantRevokeRequest grantRevokeRequest) 
{
-               if (LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerPolicyEngineImpl.getMatchedZoneName(" + grantRevokeRequest + ")");
+                       ret.finalizeAcls();
                }
 
-               String ret = 
policyEngine.getMatchedZoneName(grantRevokeRequest.getResource());
+               RangerPerfTracer.logAlways(perf);
 
                if (LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerPolicyEngineImpl.getMatchedZoneName(" + grantRevokeRequest + ") : " + 
ret);
+                       LOG.debug("<== 
RangerPolicyEngineImpl.getResourceACLs(request=" + request + ") : ret=" + ret);
                }
 
                return ret;
@@ -497,6 +335,21 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
        }
 
        @Override
+       public String getUniquelyMatchedZoneName(GrantRevokeRequest 
grantRevokeRequest) {
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("==> 
RangerPolicyEngineImpl.getUniquelyMatchedZoneName(" + grantRevokeRequest + ")");
+               }
+
+               String ret = 
policyEngine.getUniquelyMatchedZoneName(grantRevokeRequest.getResource());
+
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("<== 
RangerPolicyEngineImpl.getUniquelyMatchedZoneName(" + grantRevokeRequest + ") : 
" + ret);
+               }
+
+               return ret;
+       }
+
+       @Override
        public List<RangerPolicy> getResourcePolicies(String zoneName) {
                return policyEngine.getResourcePolicies(zoneName);
        }
@@ -515,6 +368,38 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                return tagPolicyRepository == null ? ListUtils.EMPTY_LIST : 
tagPolicyRepository.getPolicies();
        }
 
+       // This API is used only used by test code
+       @Override
+       public RangerResourceAccessInfo 
getResourceAccessInfo(RangerAccessRequest request) {
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("==> 
RangerPolicyEngineImpl.getResourceAccessInfo(" + request + ")");
+               }
+
+               requestProcessor.preProcess(request);
+
+               RangerResourceAccessInfo ret       = new 
RangerResourceAccessInfo(request);
+               Set<String>              zoneNames = 
policyEngine.getMatchedZonesForResourceAndChildren(request.getResource());
+
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("zoneNames:[" + zoneNames + "]");
+               }
+
+               if (CollectionUtils.isEmpty(zoneNames)) {
+                       getResourceAccessInfoForZone(request, ret, null);
+               } else {
+                       for (String zoneName : zoneNames) {
+                               getResourceAccessInfoForZone(request, ret, 
zoneName);
+
+                       }
+               }
+
+               if(LOG.isDebugEnabled()) {
+                       LOG.debug("<== 
RangerPolicyEngineImpl.getResourceAccessInfo(" + request + "): " + ret);
+               }
+
+               return ret;
+       }
+
        public void releaseResources(boolean isForced) {
                if (LOG.isDebugEnabled()) {
                        LOG.debug("==> 
RangerPolicyEngineImpl.releaseResources(isForced=" + isForced + ")");
@@ -535,6 +420,10 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                }
        }
 
+       PolicyEngine getPolicyEngine() {
+               return policyEngine;
+       }
+
        private RangerPolicyEngineImpl(final PolicyEngine policyEngine, 
RangerPolicyEngineImpl other) {
                this.policyEngine     = policyEngine;
                this.requestProcessor = new 
RangerDefaultRequestProcessor(policyEngine);
@@ -549,24 +438,64 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                RangerAccessResult     ret                 = null;
                RangerPolicyRepository policyRepository    = 
policyEngine.getPolicyRepository();
                RangerPolicyRepository tagPolicyRepository = 
policyEngine.getTagPolicyRepository();
-               String                 zoneName            = 
policyEngine.getMatchedZoneName(request.getResource()); // Evaluate zone-name 
from request
+               Set<String>            zoneNames            = 
policyEngine.getMatchedZonesForResourceAndChildren(request.getResource()); // 
Evaluate zone-name from request
 
                if (LOG.isDebugEnabled()) {
-                       LOG.debug("zoneName:[" + zoneName + "]");
+                       LOG.debug("zoneNames:[" + zoneNames + "]");
                }
 
-               if (StringUtils.isNotEmpty(zoneName)) {
-                       policyRepository = 
policyEngine.getZonePolicyRepositories().get(zoneName);
+               if (CollectionUtils.isEmpty(zoneNames) || (zoneNames.size() > 1 
&& !request.isAccessTypeAny())) {
+                       // Evaluate default policies
+                       policyRepository = 
policyEngine.getRepositoryForZone(null);
+
+                       ret = evaluatePoliciesNoAudit(request, policyType, 
null, policyRepository, tagPolicyRepository);
 
-                       if (policyRepository == null) {
-                               LOG.error("policyRepository for zoneName:[" + 
zoneName + "],  serviceName:[" + 
policyEngine.getPolicyRepository().getServiceName() + "], policyVersion:[" + 
getPolicyVersion() + "] is null!! ERROR!");
+                       ret.setZoneName(null);
+               } else if (zoneNames.size() == 1 || request.isAccessTypeAny()) {
+                       // Evaluate zone specific policies
+                       for (String zoneName : zoneNames) {
+                               policyRepository = 
policyEngine.getRepositoryForZone(zoneName);
+
+                               ret = evaluatePoliciesNoAudit(request, 
policyType, zoneName, policyRepository, tagPolicyRepository);
+
+                               if (ret.getIsAllowed()) {
+                                       if (LOG.isDebugEnabled()) {
+                                               LOG.debug("Zone:[" + zoneName + 
"] allowed access. Completed processing other zones");
+                                       }
+                                       ret.setZoneName(zoneName);
+                                       break;
+                               }
                        }
                }
 
-               if (policyRepository != null) {
-                       ret = evaluatePoliciesNoAudit(request, policyType, 
zoneName, policyRepository, tagPolicyRepository);
+               if (request.isAccessTypeAny() && 
CollectionUtils.isEmpty(zoneNames) && ret != null && !ret.getIsAllowed() && 
MapUtils.isNotEmpty(policyEngine.getZonePolicyRepositories())) {
+                       // resource is empty and access is ANY
+                       if (LOG.isDebugEnabled()) {
+                               LOG.debug("Process all security-zones");
+                       }
+                       RangerAccessResult accessResult;
+
+                       for (Map.Entry<String, RangerPolicyRepository> entry : 
policyEngine.getZonePolicyRepositories().entrySet()) {
+                               String someZone = entry.getKey();
+                               policyRepository = entry.getValue();
 
-                       ret.setZoneName(zoneName);
+                               if (LOG.isDebugEnabled()) {
+                                       LOG.debug("Evaluating policies for 
zone:[" + someZone + "]");
+                               }
+
+                               if (policyRepository != null) {
+                                       accessResult = 
evaluatePoliciesNoAudit(request, policyType, someZone, policyRepository, 
tagPolicyRepository);
+
+                                       if (accessResult.getIsAllowed()) {
+                                               if (LOG.isDebugEnabled()) {
+                                                       LOG.debug("Zone:[" + 
someZone + "] allowed access. Completed processing other zones");
+                                               }
+                                               
accessResult.setZoneName(someZone);
+                                               ret = accessResult;
+                                               break;
+                                       }
+                               }
+                       }
                }
 
                if (LOG.isDebugEnabled()) {
@@ -822,6 +751,116 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                return ret;
        }
 
+       private void getResourceACLEvaluatorsForZone(RangerAccessRequest 
request, String zoneName, List<RangerPolicyEvaluator> allEvaluators, Map<Long, 
RangerPolicyResourceMatcher.MatchType> tagMatchTypeMap, Set<Long> 
policyIdForTemporalTags) {
+               final RangerPolicyRepository matchedRepository = 
policyEngine.getRepositoryForZone(zoneName);
+
+               if (matchedRepository == null) {
+                       LOG.error("policyRepository for zoneName:[" + zoneName 
+ "],  serviceName:[" + policyEngine.getPolicyRepository().getServiceName() + 
"], policyVersion:[" + getPolicyVersion() + "] is null!! ERROR!");
+               } else {
+                       Set<RangerTagForEval> tags = 
RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
+                       List<PolicyEvaluatorForTag> tagPolicyEvaluators = 
policyEngine.getTagPolicyRepository() == null ? null : 
policyEngine.getTagPolicyRepository().getLikelyMatchPolicyEvaluators(tags, 
RangerPolicy.POLICY_TYPE_ACCESS, null);
+
+                       if (CollectionUtils.isNotEmpty(tagPolicyEvaluators)) {
+
+                               final boolean useTagPoliciesFromDefaultZone = 
!policyEngine.isResourceZoneAssociatedWithTagService(zoneName);
+
+                               for (PolicyEvaluatorForTag tagEvaluator : 
tagPolicyEvaluators) {
+                                       RangerPolicyEvaluator evaluator = 
tagEvaluator.getEvaluator();
+                                       String policyZoneName = 
evaluator.getPolicy().getZoneName();
+
+                                       if (useTagPoliciesFromDefaultZone) {
+                                               if 
(StringUtils.isNotEmpty(policyZoneName)) {
+                                                       if 
(LOG.isDebugEnabled()) {
+                                                               LOG.debug("Tag 
policy [zone:" + policyZoneName + "] does not belong to default zone. Not 
evaluating this policy:[" + evaluator.getPolicy() + "]");
+                                                       }
+
+                                                       continue;
+                                               }
+                                       } else {
+                                               if 
(!StringUtils.equals(zoneName, policyZoneName)) {
+                                                       if 
(LOG.isDebugEnabled()) {
+                                                               LOG.debug("Tag 
policy [zone:" + policyZoneName + "] does not belong to the zone:[" + zoneName 
+ "] of the accessed resource. Not evaluating this policy:[" + 
evaluator.getPolicy() + "]");
+                                                       }
+
+                                                       continue;
+                                               }
+                                       }
+
+                                       RangerTagForEval tag = 
tagEvaluator.getTag();
+
+                                       allEvaluators.add(evaluator);
+                                       tagMatchTypeMap.put(evaluator.getId(), 
tag.getMatchType());
+
+                                       if 
(CollectionUtils.isNotEmpty(tag.getValidityPeriods())) {
+                                               
policyIdForTemporalTags.add(evaluator.getId());
+                                       }
+                               }
+                       }
+
+                       List<RangerPolicyEvaluator> resourcePolicyEvaluators = 
matchedRepository.getLikelyMatchPolicyEvaluators(request.getResource(), 
RangerPolicy.POLICY_TYPE_ACCESS);
+
+                       allEvaluators.addAll(resourcePolicyEvaluators);
+               }
+       }
+
+       private void getResourceAccessInfoForZone(RangerAccessRequest request, 
RangerResourceAccessInfo ret, String zoneName) {
+               final RangerPolicyRepository matchedRepository = 
policyEngine.getRepositoryForZone(zoneName);
+
+               if (matchedRepository == null) {
+                       LOG.error("policyRepository for zoneName:[" + zoneName 
+ "],  serviceName:[" + policyEngine.getPolicyRepository().getServiceName() + 
"], policyVersion:[" + getPolicyVersion() + "] is null!! ERROR!");
+               } else {
+                       List<RangerPolicyEvaluator> tagPolicyEvaluators = 
policyEngine.getTagPolicyRepository() == null ? null : 
policyEngine.getTagPolicyRepository().getPolicyEvaluators();
+
+                       if (CollectionUtils.isNotEmpty(tagPolicyEvaluators)) {
+                               Set<RangerTagForEval> tags = 
RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
+
+                               if (CollectionUtils.isNotEmpty(tags)) {
+                                       final boolean 
useTagPoliciesFromDefaultZone = 
!policyEngine.isResourceZoneAssociatedWithTagService(zoneName);
+
+                                       for (RangerTagForEval tag : tags) {
+                                               RangerAccessRequest         
tagEvalRequest = new RangerTagAccessRequest(tag, 
policyEngine.getTagPolicyRepository().getServiceDef(), request);
+                                               List<RangerPolicyEvaluator> 
evaluators     = 
policyEngine.getTagPolicyRepository().getLikelyMatchPolicyEvaluators(tagEvalRequest.getResource(),
 RangerPolicy.POLICY_TYPE_ACCESS);
+
+                                               for (RangerPolicyEvaluator 
evaluator : evaluators) {
+                                                       String policyZoneName = 
evaluator.getPolicy().getZoneName();
+
+                                                       if 
(useTagPoliciesFromDefaultZone) {
+                                                               if 
(StringUtils.isNotEmpty(policyZoneName)) {
+                                                                       if 
(LOG.isDebugEnabled()) {
+                                                                               
LOG.debug("Tag policy [zone:" + policyZoneName + "] does not belong to default 
zone. Not evaluating this policy:[" + evaluator.getPolicy() + "]");
+                                                                       }
+
+                                                                       
continue;
+                                                               }
+                                                       } else {
+                                                               if 
(!StringUtils.equals(zoneName, policyZoneName)) {
+                                                                       if 
(LOG.isDebugEnabled()) {
+                                                                               
LOG.debug("Tag policy [zone:" + policyZoneName + "] does not belong to the 
zone:[" + zoneName + "] of the accessed resource. Not evaluating this policy:[" 
+ evaluator.getPolicy() + "]");
+                                                                       }
+
+                                                                       
continue;
+                                                               }
+                                                       }
+
+                                                       
evaluator.getResourceAccessInfo(tagEvalRequest, ret);
+                                               }
+                                       }
+                               }
+                       }
+
+                       List<RangerPolicyEvaluator> resPolicyEvaluators = 
matchedRepository.getLikelyMatchPolicyEvaluators(request.getResource(), 
RangerPolicy.POLICY_TYPE_ACCESS);
+
+                       if (CollectionUtils.isNotEmpty(resPolicyEvaluators)) {
+                               for (RangerPolicyEvaluator evaluator : 
resPolicyEvaluators) {
+                                       
evaluator.getResourceAccessInfo(request, ret);
+                               }
+                       }
+
+                       ret.getAllowedUsers().removeAll(ret.getDeniedUsers());
+                       ret.getAllowedGroups().removeAll(ret.getDeniedGroups());
+               }
+       }
+
        private static class ServiceConfig {
                private final Set<String> auditExcludedUsers;
                private final Set<String> auditExcludedGroups;
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
index a6ea48d..d5e5c79 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
@@ -505,7 +505,7 @@ public class RangerBasePlugin {
                        RangerPolicyEngine policyEngine = this.policyEngine;
 
                        if (policyEngine != null) {
-                               
request.setZoneName(policyEngine.getMatchedZoneName(request));
+                               
request.setZoneName(policyEngine.getUniquelyMatchedZoneName(request));
                        }
 
                        getAdminClient().grantAccess(request);
@@ -531,7 +531,7 @@ public class RangerBasePlugin {
                        RangerPolicyEngine policyEngine = this.policyEngine;
 
                        if (policyEngine != null) {
-                               
request.setZoneName(policyEngine.getMatchedZoneName(request));
+                               
request.setZoneName(policyEngine.getUniquelyMatchedZoneName(request));
                        }
 
                        getAdminClient().revokeAccess(request);
diff --git 
a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdmin.java 
b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdmin.java
index 29c3604..e011c0b 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdmin.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdmin.java
@@ -26,15 +26,16 @@ import java.util.Set;
 import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
+import org.apache.ranger.plugin.util.GrantRevokeRequest;
 import org.apache.ranger.plugin.util.RangerRoles;
 
 public interface RangerPolicyAdmin {
 
-    boolean isAccessAllowed(RangerAccessResource resource, String user, 
Set<String> userGroups, String accessType);
+    boolean isAccessAllowed(RangerAccessResource resource, String zoneName, 
String user, Set<String> userGroups, String accessType);
 
     boolean isAccessAllowed(RangerPolicy policy, String user, Set<String> 
userGroups, Set<String> roles, String accessType);
 
-    List<RangerPolicy> getExactMatchPolicies(RangerAccessResource resource, 
Map<String, Object> evalContext);
+    List<RangerPolicy> getExactMatchPolicies(RangerAccessResource resource, 
String zoneName, Map<String, Object> evalContext);
 
     List<RangerPolicy> getExactMatchPolicies(RangerPolicy policy, Map<String, 
Object> evalContext);
 
@@ -50,6 +51,8 @@ public interface RangerPolicyAdmin {
 
     Set<String> getRolesFromUserAndGroups(String user, Set<String> groups);
 
+    String getUniquelyMatchedZoneName(GrantRevokeRequest grantRevokeRequest);
+
     // This API is used only by test-code
     boolean isAccessAllowedByUnzonedPolicies(Map<String, RangerPolicyResource> 
resources, String user, Set<String> userGroups, String accessType);
 
diff --git 
a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminImpl.java 
b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminImpl.java
index 1b5aa9e..6fc0abf 100644
--- 
a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminImpl.java
+++ 
b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminImpl.java
@@ -27,6 +27,7 @@ import 
org.apache.ranger.plugin.contextenricher.RangerTagForEval;
 import org.apache.ranger.plugin.model.RangerPolicy;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
 import org.apache.ranger.plugin.policyengine.PolicyEngine;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequestProcessor;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
@@ -37,6 +38,7 @@ import 
org.apache.ranger.plugin.policyengine.RangerTagResource;
 import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
 import 
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
 import org.apache.ranger.plugin.service.RangerDefaultRequestProcessor;
+import org.apache.ranger.plugin.util.GrantRevokeRequest;
 import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
 import org.apache.ranger.plugin.util.RangerRoles;
@@ -80,9 +82,9 @@ public class RangerPolicyAdminImpl implements 
RangerPolicyAdmin {
     }
 
     @Override
-    public boolean isAccessAllowed(RangerAccessResource resource, String user, 
Set<String> userGroups, String accessType) {
+    public boolean isAccessAllowed(RangerAccessResource resource, String 
zoneName, String user, Set<String> userGroups, String accessType) {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> RangerPolicyAdminImpl.isAccessAllowed(" + resource 
+ ", " + user + ", " + userGroups + ", " + accessType + ")");
+            LOG.debug("==> RangerPolicyAdminImpl.isAccessAllowed(" + resource 
+ ", " + zoneName + ", " + user + ", " + userGroups + ", " + accessType + ")");
         }
 
         boolean          ret  = false;
@@ -92,7 +94,7 @@ public class RangerPolicyAdminImpl implements 
RangerPolicyAdmin {
             perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_REQUEST_LOG, 
"RangerPolicyAdminImpl.isAccessAllowed(user=" + user + ",accessType=" + 
accessType + "resource=" + resource.getAsString() + ")");
         }
 
-        final RangerPolicyRepository matchedRepository = 
policyEngine.getRepositoryForMatchedZone(resource);
+        final RangerPolicyRepository matchedRepository = 
policyEngine.getRepositoryForZone(zoneName);
 
         if (matchedRepository != null) {
             Set<String> roles = getRolesFromUserAndGroups(user, userGroups);
@@ -114,7 +116,7 @@ public class RangerPolicyAdminImpl implements 
RangerPolicyAdmin {
         RangerPerfTracer.log(perf);
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerPolicyAdminImpl.isAccessAllowed(" + resource 
+ ", " + user + ", " + userGroups + ", " + accessType + "): " + ret);
+            LOG.debug("<== RangerPolicyAdminImpl.isAccessAllowed(" + resource 
+ ", " + zoneName + ", " + user + ", " + userGroups + ", " + accessType + "): " 
+ ret);
         }
 
         return ret;
@@ -155,13 +157,14 @@ public class RangerPolicyAdminImpl implements 
RangerPolicyAdmin {
     }
 
     @Override
-    public List<RangerPolicy> getExactMatchPolicies(RangerAccessResource 
resource, Map<String, Object> evalContext) {
+    public List<RangerPolicy> getExactMatchPolicies(RangerAccessResource 
resource, String zoneName, Map<String, Object> evalContext) {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> RangerPolicyAdminImpl.getExactMatchPolicies(" + 
resource + ", " + evalContext + ")");
+            LOG.debug("==> RangerPolicyAdminImpl.getExactMatchPolicies(" + 
resource + ", " + zoneName + ", " + evalContext  + ")");
         }
 
         List<RangerPolicy>     ret              = null;
-        RangerPolicyRepository policyRepository = 
policyEngine.getRepositoryForMatchedZone(resource);
+
+        RangerPolicyRepository policyRepository = 
policyEngine.getRepositoryForZone(zoneName);
 
         if (policyRepository != null) {
             for (RangerPolicyEvaluator evaluator : 
policyRepository.getPolicyEvaluators()) {
@@ -176,7 +179,7 @@ public class RangerPolicyAdminImpl implements 
RangerPolicyAdmin {
         }
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerPolicyAdminImpl.getExactMatchPolicies(" + 
resource + ", " + evalContext + "): " + ret);
+            LOG.debug("<==> RangerPolicyAdminImpl.getExactMatchPolicies(" + 
resource + ", " + zoneName + ", " + evalContext  + "): " + ret);
         }
 
         return ret;
@@ -246,6 +249,21 @@ public class RangerPolicyAdminImpl implements 
RangerPolicyAdmin {
         return 
policyEngine.getPluginContext().getAuthContext().getRolesForUserAndGroups(user, 
groups);
     }
 
+    @Override
+    public String getUniquelyMatchedZoneName(GrantRevokeRequest 
grantRevokeRequest) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> RangerPolicyAdminImpl.getUniquelyMatchedZoneName(" 
+ grantRevokeRequest + ")");
+        }
+
+        String ret = 
policyEngine.getUniquelyMatchedZoneName(grantRevokeRequest.getResource());
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerPolicyAdminImpl.getUniquelyMatchedZoneName(" 
+ grantRevokeRequest + ") : " + ret);
+        }
+
+        return ret;
+    }
+
     // This API is used only by test-code; checks only policies within default 
security-zone
     @Override
     public boolean isAccessAllowedByUnzonedPolicies(Map<String, 
RangerPolicyResource> resources, String user, Set<String> userGroups, String 
accessType) {
@@ -323,8 +341,25 @@ public class RangerPolicyAdminImpl implements 
RangerPolicyAdmin {
 
         requestProcessor.preProcess(request);
 
-        String                       zoneName          = 
policyEngine.getMatchedZoneName(resource);
-        final RangerPolicyRepository matchedRepository = 
policyEngine.getRepositoryForMatchedZone(resource);
+        Set<String> zoneNames = 
policyEngine.getMatchedZonesForResourceAndChildren(resource);
+
+        if (CollectionUtils.isEmpty(zoneNames)) {
+            getMatchingPoliciesForZone(request, null, ret);
+        } else {
+            for (String zoneName : zoneNames) {
+                getMatchingPoliciesForZone(request, zoneName, ret);
+            }
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== RangerPolicyAdminImpl.getMatchingPolicies(" + 
resource + ", " + accessType + ") : " + ret.size());
+        }
+
+        return ret;
+    }
+
+    private void getMatchingPoliciesForZone(RangerAccessRequest request, 
String zoneName, List<RangerPolicy> ret) {
+        final RangerPolicyRepository matchedRepository = 
policyEngine.getRepositoryForZone(zoneName);
 
         if (matchedRepository != null) {
             if 
(policyEngine.hasTagPolicies(policyEngine.getTagPolicyRepository())) {
@@ -385,12 +420,6 @@ public class RangerPolicyAdminImpl implements 
RangerPolicyAdmin {
             }
 
         }
-
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerPolicyAdminImpl.getMatchingPolicies(" + 
resource + ", " + accessType + ") : " + ret.size());
-        }
-
-        return ret;
     }
 }
 
diff --git 
a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java 
b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
index 1bdee86..2a507dd 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
@@ -1285,21 +1285,21 @@ public class ServiceREST {
                                        }
                                        RangerService rangerService = 
svcStore.getServiceByName(serviceName);
 
-                                       boolean isAdmin = 
bizUtil.isUserRangerAdmin(userName) || 
bizUtil.isUserServiceAdmin(rangerService, userName) || 
hasAdminAccess(serviceName, userName, userGroups, resource);
-
+                                       String zoneName = 
getRangerAdminZoneName(serviceName, grantRequest);
+                                       boolean isAdmin = 
bizUtil.isUserRangerAdmin(userName) || 
bizUtil.isUserServiceAdmin(rangerService, userName) || 
hasAdminAccess(serviceName, zoneName, userName, userGroups, resource);
 
                                        if(!isAdmin) {
                                                throw 
restErrorUtil.createGrantRevokeRESTException( "User doesn't have necessary 
permission to grant access");
                                        }
 
-                                       RangerPolicy policy = 
getExactMatchPolicyForResource(serviceName, resource, userName);
+                                       RangerPolicy policy = 
getExactMatchPolicyForResource(serviceName, resource, zoneName, userName);
        
                                        if(policy != null) {
                                                boolean policyUpdated = false;
                                                policyUpdated = 
ServiceRESTUtil.processGrantRequest(policy, grantRequest);
        
                                                if(policyUpdated) {
-                                                       
policy.setZoneName(grantRequest.getZoneName());
+                                                       
policy.setZoneName(zoneName);
                                                        
svcStore.updatePolicy(policy);
                                                } else {
                                                        
LOG.error("processGrantRequest processing failed");
@@ -1338,7 +1338,7 @@ public class ServiceREST {
                                                }
        
                                                
policy.getPolicyItems().add(policyItem);
-                                               
policy.setZoneName(grantRequest.getZoneName());
+                                               policy.setZoneName(zoneName);
 
                                                svcStore.createPolicy(policy);
                                        }
@@ -1394,6 +1394,7 @@ public class ServiceREST {
                                        String                           
ownerUser  = grantRequest.getOwnerUser();
 
                                        RangerAccessResource resource   = new 
RangerAccessResourceImpl(StringUtil.toStringObjectMap(grantRequest.getResource()),
 ownerUser);
+                                       String               zoneName   = 
getRangerAdminZoneName(serviceName, grantRequest);
 
                                        boolean isAllowed = false;
 
@@ -1402,18 +1403,18 @@ public class ServiceREST {
                                                        isAllowed = true;
                                                }
                                        } else {
-                                               isAllowed = 
bizUtil.isUserRangerAdmin(userName) || 
bizUtil.isUserServiceAdmin(rangerService, userName) || 
hasAdminAccess(serviceName, userName, userGroups, resource);
+                                               isAllowed = 
bizUtil.isUserRangerAdmin(userName) || 
bizUtil.isUserServiceAdmin(rangerService, userName) || 
hasAdminAccess(serviceName, zoneName, userName, userGroups, resource);
                                        }
 
                                        if (isAllowed) {
-                                               RangerPolicy policy = 
getExactMatchPolicyForResource(serviceName, resource, userName);
+                                               RangerPolicy policy = 
getExactMatchPolicyForResource(serviceName, resource, zoneName, userName);
 
                                                if(policy != null) {
                                                        boolean policyUpdated = 
false;
                                                        policyUpdated = 
ServiceRESTUtil.processGrantRequest(policy, grantRequest);
 
                                                        if(policyUpdated) {
-                                                               
policy.setZoneName(grantRequest.getZoneName());
+                                                               
policy.setZoneName(zoneName);
                                                                
svcStore.updatePolicy(policy);
                                                        } else {
                                                                
LOG.error("processSecureGrantRequest processing failed");
@@ -1452,7 +1453,7 @@ public class ServiceREST {
                                                        }
 
                                                        
policy.getPolicyItems().add(policyItem);
-                                                       
policy.setZoneName(grantRequest.getZoneName());
+                                                       
policy.setZoneName(zoneName);
 
                                                        
svcStore.createPolicy(policy);
                                                }
@@ -1517,21 +1518,22 @@ public class ServiceREST {
                                                throw 
restErrorUtil.generateRESTException(vXResponse);
                                        }
                                        RangerService rangerService = 
svcStore.getServiceByName(serviceName);
+                                       String        zoneName      = 
getRangerAdminZoneName(serviceName, revokeRequest);
 
-                                       boolean isAdmin = 
bizUtil.isUserRangerAdmin(userName) || 
bizUtil.isUserServiceAdmin(rangerService, userName) || 
hasAdminAccess(serviceName, userName, userGroups, resource);
+                                       boolean isAdmin = 
bizUtil.isUserRangerAdmin(userName) || 
bizUtil.isUserServiceAdmin(rangerService, userName) || 
hasAdminAccess(serviceName, zoneName, userName, userGroups, resource);
 
                                        if(!isAdmin) {
                                                throw 
restErrorUtil.createGrantRevokeRESTException("User doesn't have necessary 
permission to revoke access");
                                        }
 
-                                       RangerPolicy policy = 
getExactMatchPolicyForResource(serviceName, resource, userName);
+                                       RangerPolicy policy = 
getExactMatchPolicyForResource(serviceName, resource, zoneName, userName);
 
                                        if(policy != null) {
                                                boolean policyUpdated = false;
                                                policyUpdated = 
ServiceRESTUtil.processRevokeRequest(policy, revokeRequest);
 
                                                if(policyUpdated) {
-                                                       
policy.setZoneName(revokeRequest.getZoneName());
+                                                       
policy.setZoneName(zoneName);
                                                        
svcStore.updatePolicy(policy);
                                                } else {
                                                        
LOG.error("processRevokeRequest processing failed");
@@ -1590,6 +1592,8 @@ public class ServiceREST {
                                        String ownerUser = 
revokeRequest.getOwnerUser();
 
                                        RangerAccessResource resource = new 
RangerAccessResourceImpl(StringUtil.toStringObjectMap(revokeRequest.getResource()),
 ownerUser);
+                                       String               zoneName = 
getRangerAdminZoneName(serviceName, revokeRequest);
+
 
                                        boolean isAllowed = false;
 
@@ -1598,18 +1602,18 @@ public class ServiceREST {
                                                        isAllowed = true;
                                                }
                                        } else {
-                                               isAllowed = 
bizUtil.isUserRangerAdmin(userName) || 
bizUtil.isUserServiceAdmin(rangerService, userName) || 
hasAdminAccess(serviceName, userName, userGroups, resource);
+                                               isAllowed = 
bizUtil.isUserRangerAdmin(userName) || 
bizUtil.isUserServiceAdmin(rangerService, userName) || 
hasAdminAccess(serviceName, zoneName, userName, userGroups, resource);
                                        }
 
                                        if (isAllowed) {
-                                               RangerPolicy policy = 
getExactMatchPolicyForResource(serviceName, resource, userName);
+                                               RangerPolicy policy = 
getExactMatchPolicyForResource(serviceName, resource, zoneName, userName);
 
                                                if(policy != null) {
                                                        boolean policyUpdated = 
false;
                                                        policyUpdated = 
ServiceRESTUtil.processRevokeRequest(policy, revokeRequest);
 
                                                        if(policyUpdated) {
-                                                               
policy.setZoneName(revokeRequest.getZoneName());
+                                                               
policy.setZoneName(zoneName);
                                                                
svcStore.updatePolicy(policy);
                                                        } else {
                                                                
LOG.error("processSecureRevokeRequest processing failed");
@@ -3320,14 +3324,14 @@ public class ServiceREST {
                }
        }
 
-       private RangerPolicy getExactMatchPolicyForResource(String serviceName, 
RangerAccessResource resource, String user) throws Exception {
+       private RangerPolicy getExactMatchPolicyForResource(String serviceName, 
RangerAccessResource resource, String zoneName, String user) throws Exception {
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
ServiceREST.getExactMatchPolicyForResource(" + resource + ", " + user + ")");
+                       LOG.debug("==> 
ServiceREST.getExactMatchPolicyForResource(" + resource + ", " + zoneName + ", 
" + user + ")");
                }
 
                RangerPolicy       ret         = null;
                RangerPolicyAdmin  policyAdmin = getPolicyAdmin(serviceName);
-               List<RangerPolicy> policies    = policyAdmin != null ? 
policyAdmin.getExactMatchPolicies(resource, null) : null;
+               List<RangerPolicy> policies    = policyAdmin != null ? 
policyAdmin.getExactMatchPolicies(resource, zoneName, null) : null;
 
                if(CollectionUtils.isNotEmpty(policies)) {
                        // at this point, ret is a policy in policy-engine; the 
caller might update the policy (for grant/revoke); so get a copy from the store
@@ -3335,7 +3339,7 @@ public class ServiceREST {
                }
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
ServiceREST.getExactMatchPolicyForResource(" + resource + ", " + user + "): " + 
ret);
+                       LOG.debug("<== 
ServiceREST.getExactMatchPolicyForResource(" + resource + ", " + zoneName + ", 
" + user + "): " + ret);
                }
 
                return ret;
@@ -3744,13 +3748,13 @@ public class ServiceREST {
 
                return isAllowed;
        }
-       private boolean hasAdminAccess(String serviceName, String userName, 
Set<String> userGroups, RangerAccessResource resource) {
+       private boolean hasAdminAccess(String serviceName, String zoneName, 
String userName, Set<String> userGroups, RangerAccessResource resource) {
                boolean isAllowed = false;
 
                RangerPolicyAdmin policyAdmin = 
getPolicyAdminForDelegatedAdmin(serviceName);
 
                if(policyAdmin != null) {
-                       isAllowed = policyAdmin.isAccessAllowed(resource, 
userName, userGroups, RangerPolicyEngine.ADMIN_ACCESS);
+                       isAllowed = policyAdmin.isAccessAllowed(resource, 
zoneName, userName, userGroups, RangerPolicyEngine.ADMIN_ACCESS);
                }
 
                return isAllowed;
@@ -4315,6 +4319,17 @@ public class ServiceREST {
                        bizUtil.bulkModeOnlyFlushAndClear();
                }
        }
+
+       private String getRangerAdminZoneName(String serviceName, 
GrantRevokeRequest grantRevokeRequest) {
+               String ret = grantRevokeRequest.getZoneName();
+
+               if (StringUtils.isEmpty(ret)) {
+                       RangerPolicyAdmin policyAdmin = 
getPolicyAdmin(serviceName);
+                       ret = 
policyAdmin.getUniquelyMatchedZoneName(grantRevokeRequest);
+               }
+
+               return ret;
+       }
 }
 
 

Reply via email to