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 fe27e0b  RANGER-3397: Update ACL computation to (optionally) expand 
Ranger Roles to users and groups and include chained-plugins in ACL computation
fe27e0b is described below

commit fe27e0b32d388033d305b6e58b9686566ee40eb1
Author: Abhay Kulkarni <ab...@apache.org>
AuthorDate: Fri Sep 3 16:50:29 2021 -0700

    RANGER-3397: Update ACL computation to (optionally) expand Ranger Roles to 
users and groups and include chained-plugins in ACL computation
---
 .../plugin/policyengine/RangerPolicyEngine.java    |   2 +
 .../policyengine/RangerPolicyEngineImpl.java       |  23 ++--
 .../policyengine/RangerPolicyEngineOptions.java    |  11 +-
 .../RangerDefaultPolicyEvaluator.java              | 131 ++++++++++++++++---
 .../policyevaluator/RangerPolicyEvaluator.java     |   8 +-
 .../ranger/plugin/service/RangerBasePlugin.java    | 127 +++++++++++++++++-
 .../ranger/plugin/service/RangerChainedPlugin.java |   7 +
 .../apache/ranger/plugin/util/RangerRolesUtil.java |  64 ++++++----
 .../ranger/plugin/policyengine/TestPolicyACLs.java |  14 +-
 .../policyengine/test_aclprovider_hdfs.json        | 131 +++++++++++++++++++
 .../aclprovider/test_aclprovider_default.json      | 142 +++++++++++++++++++++
 11 files changed, 597 insertions(+), 63 deletions(-)

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 7a4bb12..7bf8c7c 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
@@ -70,6 +70,8 @@ public interface RangerPolicyEngine {
 
        RangerResourceACLs getResourceACLs(RangerAccessRequest request);
 
+       RangerResourceACLs getResourceACLs(RangerAccessRequest request, Integer 
requestedPolicyType);
+
        Set<String> getRolesFromUserAndGroups(String user, Set<String> groups);
 
        RangerRoles getRangerRoles();
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 9e0a89e..c92b550 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
@@ -243,8 +243,13 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
 
        @Override
        public RangerResourceACLs getResourceACLs(RangerAccessRequest request) {
+               return getResourceACLs(request, null);
+       }
+
+       @Override
+       public RangerResourceACLs getResourceACLs(RangerAccessRequest request, 
Integer requestedPolicyType) {
                if (LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerPolicyEngineImpl.getResourceACLs(request=" + request + ")");
+                       LOG.debug("==> 
RangerPolicyEngineImpl.getResourceACLs(request=" + request + ", policyType=" + 
requestedPolicyType + ")");
                }
 
                RangerResourceACLs ret  = new RangerResourceACLs();
@@ -269,7 +274,10 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                                LOG.debug("zoneName:[" + zoneName + "]");
                        }
 
-                       for (int policyType : RangerPolicy.POLICY_TYPES) {
+                       int[] policyTypes = requestedPolicyType == null ? 
RangerPolicy.POLICY_TYPES : new int[] { requestedPolicyType };
+
+
+                       for (int policyType : policyTypes) {
                                List<RangerPolicyEvaluator> allEvaluators       
    = new ArrayList<>();
                                Map<Long, MatchType>        tagMatchTypeMap     
    = new HashMap<>();
                                Set<Long>                   
policyIdForTemporalTags = new HashSet<>();
@@ -331,7 +339,7 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                RangerPerfTracer.logAlways(perf);
 
                if (LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerPolicyEngineImpl.getResourceACLs(request=" + request + ") : ret=" + ret);
+                       LOG.debug("<== 
RangerPolicyEngineImpl.getResourceACLs(request=" + request + ", policyType=" + 
requestedPolicyType + ") : ret=" + ret);
                }
 
                return ret;
@@ -773,7 +781,6 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                                if (ret.getIsAuditedDetermined() && 
ret.getIsAccessDetermined()) {
                                        break;            // Break out of 
policy-evaluation loop
                                }
-
                        }
 
                        if (!ret.getIsAccessDetermined()) {
@@ -1136,6 +1143,10 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                return ret;
        }
 
+       private boolean getIsFallbackSupported() {
+               return 
policyEngine.getPluginContext().getConfig().getIsFallbackSupported();
+       }
+
        private void updateFromPolicyACLs(RangerPolicyEvaluator evaluator, 
Set<Long> policyIdForTemporalTags, RangerResourceACLs resourceACLs) {
                PolicyACLSummary aclSummary = evaluator.getPolicyACLSummary();
 
@@ -1248,10 +1259,6 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                }
        }
 
-       private boolean getIsFallbackSupported() {
-               return 
policyEngine.getPluginContext().getConfig().getIsFallbackSupported();
-       }
-
        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/policyengine/RangerPolicyEngineOptions.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java
index 0816ec1..07d0a39 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineOptions.java
@@ -36,6 +36,7 @@ public class RangerPolicyEngineOptions {
        public boolean enableTagEnricherWithLocalRefresher = false;
        public boolean disableAccessEvaluationWithPolicyACLSummary = true;
        public boolean optimizeTrieForRetrieval = false;
+       public boolean disableRoleResolution = true;
 
        private RangerServiceDefHelper serviceDefHelper;
 
@@ -53,6 +54,7 @@ public class RangerPolicyEngineOptions {
                this.enableTagEnricherWithLocalRefresher = 
other.enableTagEnricherWithLocalRefresher;
                this.disableAccessEvaluationWithPolicyACLSummary = 
other.disableAccessEvaluationWithPolicyACLSummary;
                this.optimizeTrieForRetrieval = other.optimizeTrieForRetrieval;
+               this.disableRoleResolution = other.disableRoleResolution;
                this.serviceDefHelper = null;
        }
 
@@ -73,6 +75,7 @@ public class RangerPolicyEngineOptions {
                enableTagEnricherWithLocalRefresher = false;
                disableAccessEvaluationWithPolicyACLSummary = 
conf.getBoolean(propertyPrefix + 
".policyengine.option.disable.access.evaluation.with.policy.acl.summary", true);
                optimizeTrieForRetrieval = conf.getBoolean(propertyPrefix + 
".policyengine.option.optimize.trie.for.retrieval", false);
+               disableRoleResolution = conf.getBoolean(propertyPrefix + 
".policyengine.option.disable.role.resolution", true);
 
        }
 
@@ -89,6 +92,7 @@ public class RangerPolicyEngineOptions {
                enableTagEnricherWithLocalRefresher = false;
                disableAccessEvaluationWithPolicyACLSummary = 
conf.getBoolean(propertyPrefix + 
".policyengine.option.disable.access.evaluation.with.policy.acl.summary", true);
                optimizeTrieForRetrieval = conf.getBoolean(propertyPrefix + 
".policyengine.option.optimize.trie.for.retrieval", false);
+               disableRoleResolution = conf.getBoolean(propertyPrefix + 
".policyengine.option.disable.role.resolution", true);
 
        }
 
@@ -150,7 +154,8 @@ public class RangerPolicyEngineOptions {
                                        && this.cacheAuditResults == 
that.cacheAuditResults
                                        && this.evaluateDelegateAdminOnly == 
that.evaluateDelegateAdminOnly
                                        && 
this.enableTagEnricherWithLocalRefresher == 
that.enableTagEnricherWithLocalRefresher
-                                       && this.optimizeTrieForRetrieval == 
that.optimizeTrieForRetrieval;
+                                       && this.optimizeTrieForRetrieval == 
that.optimizeTrieForRetrieval
+                                       && this.disableRoleResolution == 
that.disableRoleResolution;
                }
                return ret;
        }
@@ -178,7 +183,8 @@ public class RangerPolicyEngineOptions {
                ret *= 2;
                ret += optimizeTrieForRetrieval ? 1 : 0;
                ret *= 2;
-               return ret;
+               ret += disableRoleResolution ? 1 : 0;
+               ret *= 2;               return ret;
        }
 
        @Override
@@ -195,6 +201,7 @@ public class RangerPolicyEngineOptions {
                                ", disableTrieLookupPrefilter: " + 
disableTrieLookupPrefilter +
                                ", optimizeTrieForRetrieval: " + 
optimizeTrieForRetrieval +
                                ", cacheAuditResult: " + cacheAuditResults +
+                               ", disableRoleResolution: " + 
disableRoleResolution +
                                " }";
 
        }
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
index 02a096f..9f0abf2 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
@@ -81,6 +81,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
        private String perfTag;
        private PolicyACLSummary aclSummary                 = null;
        private boolean          useAclSummaryForEvaluation = false;
+       private boolean          disableRoleResolution      = true;
 
        protected boolean needsDynamicEval() { return resourceMatcher != null 
&& resourceMatcher.getNeedsDynamicEval(); }
 
@@ -160,7 +161,6 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                                        allowExceptionEvaluators = 
Collections.<RangerPolicyItemEvaluator>emptyList();
                                        denyExceptionEvaluators  = 
Collections.<RangerPolicyItemEvaluator>emptyList();
                                }
-
                        }
 
                        dataMaskEvaluators  = 
createDataMaskPolicyItemEvaluators(policy, serviceDef, options, 
policy.getDataMaskPolicyItems());
@@ -544,51 +544,58 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                        perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICY_INIT_ACLSUMMARY_LOG, 
"RangerPolicyEvaluator.init.ACLSummary(" + perfTag + ")");
                }
 
-               final boolean hasNonPublicGroupOrConditionsInAllowExceptions = 
hasNonPublicGroupOrConditions(getPolicy().getAllowExceptions());
-               final boolean hasNonPublicGroupOrConditionsInDenyExceptions  = 
hasNonPublicGroupOrConditions(getPolicy().getDenyExceptions());
-               final boolean hasPublicGroupInAllowAndUsersInAllowExceptions = 
hasPublicGroupAndUserInException(getPolicy().getPolicyItems(), 
getPolicy().getAllowExceptions());
-               final boolean hasPublicGroupInDenyAndUsersInDenyExceptions   = 
hasPublicGroupAndUserInException(getPolicy().getDenyPolicyItems(), 
getPolicy().getDenyExceptions());
+               RangerPolicy policy;
+               if (!disableRoleResolution && hasRoles(getPolicy())) {
+                       policy = getPolicyWithRolesResolved(getPolicy());
+               } else {
+                       policy = getPolicy();
+               }
+
+               final boolean hasNonPublicGroupOrConditionsInAllowExceptions = 
hasNonPublicGroupOrConditions(policy.getAllowExceptions());
+               final boolean hasNonPublicGroupOrConditionsInDenyExceptions  = 
hasNonPublicGroupOrConditions(policy.getDenyExceptions());
+               final boolean hasPublicGroupInAllowAndUsersInAllowExceptions = 
hasPublicGroupAndUserInException(policy.getPolicyItems(), 
policy.getAllowExceptions());
+               final boolean hasPublicGroupInDenyAndUsersInDenyExceptions   = 
hasPublicGroupAndUserInException(policy.getDenyPolicyItems(), 
policy.getDenyExceptions());
                final boolean hasContextSensitiveSpecification               = 
hasContextSensitiveSpecification();
-               final boolean hasRoles                                          
                                 = hasRoles();
+               final boolean hasRoles                                       = 
hasRoles(policy);
                final boolean isUsableForEvaluation                          =  
  !hasNonPublicGroupOrConditionsInAllowExceptions
                                                                               
&& !hasNonPublicGroupOrConditionsInDenyExceptions
                                                                               
&& !hasPublicGroupInAllowAndUsersInAllowExceptions
                                                                               
&& !hasPublicGroupInDenyAndUsersInDenyExceptions
-                                                                              
&& !hasContextSensitiveSpecification
-                                                                              
&& !hasRoles;
+                                                                               
&& !hasContextSensitiveSpecification
+                                                                               
&& !hasRoles;
 
                if (isUsableForEvaluation || isCreationForced) {
                        ret = new PolicyACLSummary();
 
-                       for (RangerPolicyItem policyItem : 
getPolicy().getDenyPolicyItems()) {
+                       for (RangerPolicyItem policyItem : 
policy.getDenyPolicyItems()) {
                                ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY, 
hasNonPublicGroupOrConditionsInDenyExceptions || 
hasPublicGroupInDenyAndUsersInDenyExceptions);
                        }
 
                        if (!hasNonPublicGroupOrConditionsInDenyExceptions && 
!hasPublicGroupInDenyAndUsersInDenyExceptions) {
-                               for (RangerPolicyItem policyItem : 
getPolicy().getDenyExceptions()) {
+                               for (RangerPolicyItem policyItem : 
policy.getDenyExceptions()) {
                                        ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS, false);
                                }
                        }
 
-                       for (RangerPolicyItem policyItem : 
getPolicy().getPolicyItems()) {
+                       for (RangerPolicyItem policyItem : 
policy.getPolicyItems()) {
                                ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW, 
hasNonPublicGroupOrConditionsInAllowExceptions || 
hasPublicGroupInAllowAndUsersInAllowExceptions);
                        }
 
                        if (!hasNonPublicGroupOrConditionsInAllowExceptions && 
!hasPublicGroupInAllowAndUsersInAllowExceptions) {
-                               for (RangerPolicyItem policyItem : 
getPolicy().getAllowExceptions()) {
+                               for (RangerPolicyItem policyItem : 
policy.getAllowExceptions()) {
                                        ret.processPolicyItem(policyItem, 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS, false);
                                }
                        }
 
-                       for (RangerRowFilterPolicyItem policyItem : 
getPolicy().getRowFilterPolicyItems()) {
+                       for (RangerRowFilterPolicyItem policyItem : 
policy.getRowFilterPolicyItems()) {
                                ret.processRowFilterPolicyItem(policyItem);
                        }
 
-                       for (RangerDataMaskPolicyItem policyItem : 
getPolicy().getDataMaskPolicyItems()) {
+                       for (RangerDataMaskPolicyItem policyItem : 
policy.getDataMaskPolicyItems()) {
                                ret.processDataMaskPolicyItem(policyItem);
                        }
 
-                       final boolean isDenyAllElse = 
Boolean.TRUE.equals(getPolicy().getIsDenyAllElse());
+                       final boolean isDenyAllElse = 
Boolean.TRUE.equals(policy.getIsDenyAllElse());
 
                        final Set<String> allAccessTypeNames;
 
@@ -612,6 +619,100 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                return ret;
        }
 
+       private RangerPolicy getPolicyWithRolesResolved(final RangerPolicy 
policy) {
+               // Create new policy with no roles in it
+               // For each policyItem, expand roles into users and groups; and 
replace all policyItems with expanded roles - TBD
+
+               RangerPolicy ret = new RangerPolicy();
+               ret.updateFrom(policy);
+               ret.setId(policy.getId());
+               ret.setGuid(policy.getGuid());
+               ret.setVersion(policy.getVersion());
+
+               List<RangerPolicyItem> policyItems = new ArrayList<>();
+               List<RangerPolicyItem> denyPolicyItems = new ArrayList<>();
+               List<RangerPolicyItem> allowExceptions = new ArrayList<>();
+               List<RangerPolicyItem> denyExceptions = new ArrayList<>();
+               List<RangerDataMaskPolicyItem> dataMaskPolicyItems = new 
ArrayList<>();
+               List<RangerRowFilterPolicyItem> rowFilterPolicyItems = new 
ArrayList<>();
+
+               for (RangerPolicyItem policyItem : policy.getPolicyItems()) {
+                       RangerPolicyItem newPolicyItem = new 
RangerPolicyItem(policyItem.getAccesses(), policyItem.getUsers(), 
policyItem.getGroups(), policyItem.getRoles(), policyItem.getConditions(), 
policyItem.getDelegateAdmin());
+                       getPolicyItemWithRolesResolved(newPolicyItem, 
policyItem);
+
+                       policyItems.add(newPolicyItem);
+               }
+               ret.setPolicyItems(policyItems);
+
+               for (RangerPolicyItem policyItem : policy.getDenyPolicyItems()) 
{
+                       RangerPolicyItem newPolicyItem = new 
RangerPolicyItem(policyItem.getAccesses(), policyItem.getUsers(), 
policyItem.getGroups(), policyItem.getRoles(), policyItem.getConditions(), 
policyItem.getDelegateAdmin());
+                       getPolicyItemWithRolesResolved(newPolicyItem, 
policyItem);
+
+                       denyPolicyItems.add(newPolicyItem);
+               }
+               ret.setDenyPolicyItems(denyPolicyItems);
+
+               for (RangerPolicyItem policyItem : policy.getAllowExceptions()) 
{
+                       RangerPolicyItem newPolicyItem = new 
RangerPolicyItem(policyItem.getAccesses(), policyItem.getUsers(), 
policyItem.getGroups(), policyItem.getRoles(), policyItem.getConditions(), 
policyItem.getDelegateAdmin());
+                       getPolicyItemWithRolesResolved(newPolicyItem, 
policyItem);
+
+                       allowExceptions.add(newPolicyItem);
+               }
+               ret.setAllowExceptions(allowExceptions);
+
+               for (RangerPolicyItem policyItem : policy.getDenyExceptions()) {
+                       RangerPolicyItem newPolicyItem = new 
RangerPolicyItem(policyItem.getAccesses(), policyItem.getUsers(), 
policyItem.getGroups(), policyItem.getRoles(), policyItem.getConditions(), 
policyItem.getDelegateAdmin());
+                       getPolicyItemWithRolesResolved(newPolicyItem, 
policyItem);
+
+                       denyExceptions.add(newPolicyItem);
+               }
+               ret.setDenyExceptions(denyExceptions);
+
+               for (RangerDataMaskPolicyItem policyItem : 
policy.getDataMaskPolicyItems()) {
+                       RangerDataMaskPolicyItem newPolicyItem = new 
RangerDataMaskPolicyItem(policyItem.getAccesses(), 
policyItem.getDataMaskInfo(), policyItem.getUsers(), policyItem.getGroups(), 
policyItem.getRoles(), policyItem.getConditions(), 
policyItem.getDelegateAdmin());
+                       getPolicyItemWithRolesResolved(newPolicyItem, 
policyItem);
+
+                       dataMaskPolicyItems.add(newPolicyItem);
+               }
+               ret.setDataMaskPolicyItems(dataMaskPolicyItems);
+
+               for (RangerRowFilterPolicyItem policyItem : 
policy.getRowFilterPolicyItems()) {
+                       RangerRowFilterPolicyItem newPolicyItem = new 
RangerRowFilterPolicyItem(policyItem.getRowFilterInfo(), 
policyItem.getAccesses(), policyItem.getUsers(), policyItem.getGroups(), 
policyItem.getRoles(), policyItem.getConditions(), 
policyItem.getDelegateAdmin());
+                       getPolicyItemWithRolesResolved(newPolicyItem, 
policyItem);
+
+                       rowFilterPolicyItems.add(newPolicyItem);
+               }
+               ret.setRowFilterPolicyItems(rowFilterPolicyItems);
+
+               return ret;
+       }
+
+       private void getPolicyItemWithRolesResolved(RangerPolicyItem 
newPolicyItem, final RangerPolicyItem policyItem) {
+               Set<String> usersFromRoles = new HashSet<>();
+               Set<String> groupsFromRoles = new HashSet<>();
+
+               List<String> roles = policyItem.getRoles();
+
+               for (String role : roles) {
+                       Set<String> users = 
getPluginContext().getAuthContext().getRangerRolesUtil().getRoleToUserMapping().get(role);
+                       Set<String> groups = 
getPluginContext().getAuthContext().getRangerRolesUtil().getRoleToGroupMapping().get(role);
+                       if (CollectionUtils.isNotEmpty(users)) {
+                               usersFromRoles.addAll(users);
+                       }
+                       if (CollectionUtils.isNotEmpty(groups)) {
+                               groupsFromRoles.addAll(groups);
+                       }
+                       if (CollectionUtils.isNotEmpty(usersFromRoles) || 
CollectionUtils.isNotEmpty(groupsFromRoles)) {
+                               usersFromRoles.addAll(policyItem.getUsers());
+                               groupsFromRoles.addAll(policyItem.getGroups());
+
+                               newPolicyItem.setUsers(new 
ArrayList<>(usersFromRoles));
+                               newPolicyItem.setGroups(new 
ArrayList<>(groupsFromRoles));
+                               newPolicyItem.setRoles(null);
+                       }
+               }
+       }
+
        private boolean hasPublicGroupAndUserInException(List<RangerPolicyItem> 
grants, List<RangerPolicyItem> exceptionItems) {
                boolean ret = false;
 
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
index 0157c00..15a6465 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
@@ -55,8 +55,10 @@ import 
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatche
 
 import static 
org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW;
 import static 
org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW_EXCEPTIONS;
+import static 
org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DATAMASK;
 import static 
org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY;
 import static 
org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY_EXCEPTIONS;
+import static 
org.apache.ranger.plugin.policyevaluator.RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ROWFILTER;
 
 public interface RangerPolicyEvaluator extends RangerPolicyResourceEvaluator {
        Comparator<RangerPolicyEvaluator> EVAL_ORDER_COMPARATOR = new 
RangerPolicyEvaluator.PolicyEvalOrderComparator();
@@ -140,9 +142,7 @@ public interface RangerPolicyEvaluator extends 
RangerPolicyResourceEvaluator {
                return false;
        }
 
-       default boolean hasRoles() {
-               RangerPolicy policy = getPolicy();
-
+        default boolean hasRoles(final RangerPolicy policy) {
                for (RangerPolicyItem policyItem : policy.getPolicyItems()) {
                        if (hasRoles(policyItem)) {
                                return true;
@@ -297,7 +297,7 @@ public interface RangerPolicyEvaluator extends 
RangerPolicyResourceEvaluator {
 
                void processPolicyItem(RangerPolicyItem policyItem, int 
policyItemType, boolean isConditional) {
                        final Integer result;
-                       final boolean hasContextSensitiveSpecification = 
RangerPolicyEvaluator.hasContextSensitiveSpecification(policyItem);
+                       final boolean hasContextSensitiveSpecification = 
CollectionUtils.isNotEmpty(policyItem.getConditions());
 
                        switch (policyItemType) {
                                case POLICY_ITEM_TYPE_ALLOW:
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 7e0894d..3ad74e5 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
@@ -49,6 +49,7 @@ import 
org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngineImpl;
 import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
 import org.apache.ranger.plugin.policyengine.RangerResourceAccessInfo;
+import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
 import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
 import org.apache.ranger.plugin.util.*;
 
@@ -539,13 +540,43 @@ public class RangerBasePlugin {
        }
 
        public RangerResourceACLs getResourceACLs(RangerAccessRequest request) {
+               return getResourceACLs(request, null);
+       }
+
+       public RangerResourceACLs getResourceACLs(RangerAccessRequest request, 
Integer policyType) {
+               RangerResourceACLs ret          = null;
                RangerPolicyEngine policyEngine = this.policyEngine;
 
                if(policyEngine != null) {
-                       return policyEngine.getResourceACLs(request);
+                       ret = policyEngine.getResourceACLs(request, policyType);
                }
 
-               return null;
+               for (RangerChainedPlugin chainedPlugin : chainedPlugins) {
+                       RangerResourceACLs chainedResourceACLs = 
chainedPlugin.getResourceACLs(request, policyType);
+
+                       if (chainedResourceACLs != null) {
+                               if (LOG.isDebugEnabled()) {
+                                       LOG.debug("Chained-plugin returned 
non-null ACLs!!");
+                               }
+                               if 
(chainedPlugin.isAuthorizeOnlyWithChainedPlugin()) {
+                                       if (LOG.isDebugEnabled()) {
+                                               LOG.debug("Chained-plugin is 
configured to ignore Base-plugin's ACLs");
+                                       }
+                                       ret = chainedResourceACLs;
+                                       break;
+                               } else {
+                                       if (ret != null) {
+                                               ret = 
getMergedResourceACLs(ret, chainedResourceACLs);
+                                       }
+                               }
+                       } else {
+                               if (LOG.isDebugEnabled()) {
+                                       LOG.debug("Chained-plugin returned null 
ACLs!!");
+                               }
+                       }
+               }
+
+               return ret;
        }
 
        public Set<String> getRolesFromUserAndGroups(String user, Set<String> 
groups) {
@@ -1035,6 +1066,98 @@ public class RangerBasePlugin {
                }
        }
 
+       private RangerResourceACLs getMergedResourceACLs(RangerResourceACLs 
baseACLs, RangerResourceACLs chainedACLs) {
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("==> 
RangerBasePlugin.getMergedResourceACLs()");
+                       LOG.debug("baseACLs:[" + baseACLs + "]");
+                       LOG.debug("chainedACLS:[" + chainedACLs + "]");
+               }
+
+               overrideACLs(chainedACLs, baseACLs, 
RangerRolesUtil.ROLES_FOR.USER);
+               overrideACLs(chainedACLs, baseACLs, 
RangerRolesUtil.ROLES_FOR.GROUP);
+               overrideACLs(chainedACLs, baseACLs, 
RangerRolesUtil.ROLES_FOR.ROLE);
+
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("<== RangerBasePlugin.getMergedResourceACLs() 
: ret:[" + baseACLs + "]");
+               }
+               return baseACLs;
+       }
+
+       private void overrideACLs(final RangerResourceACLs chainedResourceACLs, 
RangerResourceACLs baseResourceACLs, final RangerRolesUtil.ROLES_FOR userType) {
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("==> RangerBasePlugin.overrideACLs(isUser=" + 
userType.name() + ")");
+               }
+               Map<String, Map<String, RangerResourceACLs.AccessResult>> 
chainedACLs = null;
+               Map<String, Map<String, RangerResourceACLs.AccessResult>> 
baseACLs    = null;
+
+               switch (userType) {
+                       case USER:
+                               chainedACLs = chainedResourceACLs.getUserACLs();
+                               baseACLs    = baseResourceACLs.getUserACLs();
+                               break;
+                       case GROUP:
+                               chainedACLs = 
chainedResourceACLs.getGroupACLs();
+                               baseACLs    = baseResourceACLs.getGroupACLs();
+                               break;
+                       case ROLE:
+                               chainedACLs = chainedResourceACLs.getRoleACLs();
+                               baseACLs    = baseResourceACLs.getRoleACLs();
+                               break;
+                       default:
+                               break;
+               }
+
+               for (Map.Entry<String, Map<String, 
RangerResourceACLs.AccessResult>> chainedPermissionsMap : 
chainedACLs.entrySet()) {
+                       String                                       name       
        = chainedPermissionsMap.getKey();
+                       Map<String, RangerResourceACLs.AccessResult> 
chainedPermissions = chainedPermissionsMap.getValue();
+                       Map<String, RangerResourceACLs.AccessResult> 
basePermissions    = baseACLs.get(name);
+
+                       for (Map.Entry<String, RangerResourceACLs.AccessResult> 
chainedPermission : chainedPermissions.entrySet()) {
+                               String chainedAccessType                        
    = chainedPermission.getKey();
+                               RangerResourceACLs.AccessResult 
chainedAccessResult = chainedPermission.getValue();
+                               RangerResourceACLs.AccessResult 
baseAccessResult    = basePermissions == null ? null : 
basePermissions.get(chainedAccessType);
+
+                               final boolean useChainedAccessResult;
+
+                               if (baseAccessResult == null) {
+                                       useChainedAccessResult = true;
+                               } else {
+                                       if 
(chainedAccessResult.getPolicy().getPolicyPriority() > 
baseAccessResult.getPolicy().getPolicyPriority()) {
+                                               useChainedAccessResult = true;
+                                       } else if 
(chainedAccessResult.getPolicy().getPolicyPriority().equals(baseAccessResult.getPolicy().getPolicyPriority()))
 {
+                                               if 
(chainedAccessResult.getResult() == baseAccessResult.getResult()) {
+                                                       useChainedAccessResult 
= true;
+                                               } else {
+                                                       useChainedAccessResult 
= chainedAccessResult.getResult() == RangerPolicyEvaluator.ACCESS_DENIED;
+                                               }
+                                       } else { // 
chainedAccessResult.getPolicy().getPolicyPriority() < 
baseAccessResult.getPolicy().getPolicyPriority()
+                                               useChainedAccessResult = false;
+                                       }
+                               }
+
+                               final RangerResourceACLs.AccessResult 
finalAccessResult = useChainedAccessResult ? chainedAccessResult : 
baseAccessResult;
+
+                               switch (userType) {
+                                       case USER:
+                                               
baseResourceACLs.setUserAccessInfo(name, chainedAccessType, 
finalAccessResult.getResult(), finalAccessResult.getPolicy());
+                                               break;
+                                       case GROUP:
+                                               
baseResourceACLs.setGroupAccessInfo(name, chainedAccessType, 
finalAccessResult.getResult(), finalAccessResult.getPolicy());
+                                               break;
+                                       case ROLE:
+                                               
baseResourceACLs.setRoleAccessInfo(name, chainedAccessType, 
finalAccessResult.getResult(), finalAccessResult.getPolicy());
+                                               break;
+                                       default:
+                                               break;
+                               }
+                       }
+               }
+
+               if (LOG.isDebugEnabled()) {
+                       LOG.debug("<== 
RangerBasePlugin.mergeACLsOneWay(isUser=" + userType.name() + ")");
+               }
+       }
+
        private static AuditProviderFactory getAuditProviderFactory(String 
serviceName) {
                AuditProviderFactory ret = AuditProviderFactory.getInstance();
 
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerChainedPlugin.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerChainedPlugin.java
index 0fca2d9..7a48a09 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerChainedPlugin.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerChainedPlugin.java
@@ -23,6 +23,7 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
 import org.apache.ranger.plugin.policyengine.RangerAccessResult;
+import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
 
 import java.util.Collection;
 
@@ -59,4 +60,10 @@ public abstract class RangerChainedPlugin {
 
     public abstract Collection<RangerAccessResult> 
isAccessAllowed(Collection<RangerAccessRequest> requests);
 
+    public abstract RangerResourceACLs getResourceACLs(RangerAccessRequest 
request);
+
+    public abstract RangerResourceACLs getResourceACLs(RangerAccessRequest 
request, Integer policyType);
+
+    public boolean  isAuthorizeOnlyWithChainedPlugin() { return false; }
+
 }
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRolesUtil.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRolesUtil.java
index a6e461c..f785e11 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRolesUtil.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRolesUtil.java
@@ -34,8 +34,12 @@ public class RangerRolesUtil {
     private final Map<String, Set<String>> userRoleMapping = new HashMap<>();
     private final Map<String, Set<String>> groupRoleMapping = new HashMap<>();
     private final Map<String, Set<String>> roleRoleMapping  = new HashMap<>();
+
+    private final Map<String, Set<String>> roleToUserMapping = new HashMap<>();
+    private final Map<String, Set<String>> roleToGroupMapping = new 
HashMap<>();
+
     private RangerRoles                    roles            = null;
-    private enum  ROLES_FOR {USER, GROUP, ROLE};
+    public  enum  ROLES_FOR {USER, GROUP, ROLE}
 
     public RangerRolesUtil(RangerRoles roles) {
         if (roles != null) {
@@ -49,7 +53,22 @@ public class RangerRolesUtil {
                     buildMap(userRoleMapping, role, containedRoles, 
ROLES_FOR.USER);
                     buildMap(groupRoleMapping, role, containedRoles, 
ROLES_FOR.GROUP);
                     buildMap(roleRoleMapping, role, containedRoles, 
ROLES_FOR.ROLE);
+
+                    Set<String> roleUsers  = new HashSet<>();
+                    Set<String> roleGroups = new HashSet<>();
+
+                    addMemberNames(role.getUsers(), roleUsers);
+                    addMemberNames(role.getGroups(), roleGroups);
+
+                    for (RangerRole containedRole : containedRoles) {
+                        addMemberNames(containedRole.getUsers(), roleUsers);
+                        addMemberNames(containedRole.getGroups(), roleGroups);
+                    }
+
+                    roleToUserMapping.put(role.getName(), roleUsers);
+                    roleToGroupMapping.put(role.getName(), roleGroups);
                 }
+
             }
         } else {
             roleVersion = -1L;
@@ -74,6 +93,14 @@ public class RangerRolesUtil {
         return this.roleRoleMapping;
     }
 
+    public Map<String, Set<String>> getRoleToUserMapping() {
+        return this.roleToUserMapping;
+    }
+
+    public Map<String, Set<String>> getRoleToGroupMapping() {
+        return this.roleToGroupMapping;
+    }
+
     private Set<RangerRole> getAllContainedRoles(Set<RangerRole> roles, 
RangerRole role) {
         Set<RangerRole> allRoles = new HashSet<>();
 
@@ -104,22 +131,6 @@ public class RangerRolesUtil {
         }
     }
 
-    private void buildMap(Map<String, Set<String>> map, RangerRole role, 
String roleName, boolean isUser) {
-        for (RangerRole.RoleMember userOrGroup : isUser ? role.getUsers() : 
role.getGroups()) {
-            if (StringUtils.isNotEmpty(userOrGroup.getName())) {
-                Set<String> roleNames = map.get(userOrGroup.getName());
-
-                if (roleNames == null) {
-                    roleNames = new HashSet<>();
-
-                    map.put(userOrGroup.getName(), roleNames);
-                }
-
-                roleNames.add(roleName);
-            }
-        }
-    }
-
     private void buildMap(Map<String, Set<String>> map, RangerRole role, 
String roleName, ROLES_FOR roles_for) {
         List<RangerRole.RoleMember> userOrGroupOrRole = null;
         switch(roles_for) {
@@ -141,23 +152,20 @@ public class RangerRolesUtil {
     private void getRoleMap(Map<String, Set<String>> map, String roleName, 
List<RangerRole.RoleMember> userOrGroupOrRole) {
         for (RangerRole.RoleMember roleMember : userOrGroupOrRole) {
             if (StringUtils.isNotEmpty(roleMember.getName())) {
-                Set<String> roleNames = map.get(roleMember.getName());
-                if (roleNames == null) {
-                    roleNames = new HashSet<>();
-
-                    map.put(roleMember.getName(), roleNames);
-                }
+                Set<String> roleNames = 
map.computeIfAbsent(roleMember.getName(), k -> new HashSet<>());
                 roleNames.add(roleName);
             }
         }
     }
 
     private RangerRole getContainedRole(Set<RangerRole> roles, String role) {
-        return (roles
-                .stream()
-                .filter(containedRole -> role.equals(containedRole.getName()))
-                .findAny()
-                .orElse(null));
+        return (roles.stream().filter(containedRole -> 
role.equals(containedRole.getName())).findAny().orElse(null));
+    }
+
+    private void addMemberNames(List<RangerRole.RoleMember> members, 
Set<String> names) {
+        for (RangerRole.RoleMember member : members) {
+            names.add(member.getName());
+        }
     }
 }
 
diff --git 
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyACLs.java
 
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyACLs.java
index d2983a2..b6135b0 100644
--- 
a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyACLs.java
+++ 
b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyACLs.java
@@ -86,6 +86,13 @@ public class TestPolicyACLs {
                runTestsFromResourceFiles(tests);
        }
 
+       @Test
+       public void testResourceACLs_hdfs() throws Exception {
+               String[] tests = {"/policyengine/test_aclprovider_hdfs.json"};
+
+               runTestsFromResourceFiles(tests);
+       }
+
        private void runTestsFromResourceFiles(String[] resourceNames) throws 
Exception {
                for(String resourceName : resourceNames) {
                        InputStream       inStream = 
this.getClass().getResourceAsStream(resourceName);
@@ -101,8 +108,9 @@ public class TestPolicyACLs {
                assertTrue("invalid input: " + testName, testCases != null && 
testCases.testCases != null);
 
                for(PolicyACLsTests.TestCase testCase : testCases.testCases) {
+                       String                    serviceType         = 
testCase.servicePolicies.getServiceDef().getName();
                        RangerPolicyEngineOptions policyEngineOptions = new 
RangerPolicyEngineOptions();
-                       RangerPluginContext       pluginContext       = new 
RangerPluginContext(new RangerPluginConfig("hive", null, "test-policy-acls", 
"cl1", "on-prem", policyEngineOptions));
+                       RangerPluginContext       pluginContext       = new 
RangerPluginContext(new RangerPluginConfig(serviceType, null, 
"test-policy-acls", "cl1", "on-prem", policyEngineOptions));
                        RangerPolicyEngine        policyEngine        = new 
RangerPolicyEngineImpl(testCase.servicePolicies, pluginContext, null);
 
                        for(PolicyACLsTests.TestCase.OneTest oneTest : 
testCase.tests) {
@@ -259,9 +267,7 @@ public class TestPolicyACLs {
                                } else if 
(!(MapUtils.isEmpty(acls.getRoleACLs()) && 
MapUtils.isEmpty(oneTest.rolePermissions))) {
                                        roleACLsMatched = false;
                                }
-
-                               assertTrue("getResourceACLs() failed! " + 
testCase.name + ":" + oneTest.name + " - userACLsMatched=" + userACLsMatched + 
"; groupACLsMatched=" + groupACLsMatched + "; roleACLsMatched=" + 
roleACLsMatched + "; rowFiltersMatched=" + rowFiltersMatched + "; 
dataMaskingMatched=" + dataMaskingMatched,
-                                                  userACLsMatched && 
groupACLsMatched && roleACLsMatched && rowFiltersMatched && dataMaskingMatched);
+                               assertTrue("getResourceACLs() failed! " + 
testCase.name + ":" + oneTest.name, userACLsMatched && groupACLsMatched && 
roleACLsMatched && rowFiltersMatched && dataMaskingMatched);
                        }
                }
        }
diff --git 
a/agents-common/src/test/resources/policyengine/test_aclprovider_hdfs.json 
b/agents-common/src/test/resources/policyengine/test_aclprovider_hdfs.json
new file mode 100644
index 0000000..9526763
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/test_aclprovider_hdfs.json
@@ -0,0 +1,131 @@
+{
+  "testCases": [
+    {
+      "name": "Test-ACL-Provider-for-HDFS",
+
+      "servicePolicies": {
+        "serviceName": "hivedev",
+        "serviceDef": {
+          "name": "hdfs",
+          "id": 1,
+          "resources": [
+            {
+              "name": "path",
+              "type": "path",
+              "level": 1,
+              "mandatory": true,
+              "lookupSupported": true,
+              "matcher": 
"org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher",
+              "matcherOptions": {
+                "wildCard": true,
+                "ignoreCase": true
+              },
+              "label": "Resource Path",
+              "description": "HDFS file or directory path"
+            }
+          ],
+          "accessTypes": [
+            {
+              "name": "read",
+              "label": "Read"
+            },
+            {
+              "name": "write",
+              "label": "Write"
+            },
+            {
+              "name": "execute",
+              "label": "Execute"
+            }
+          ],
+          "contextEnrichers": [
+            {
+              "itemId": 1,
+              "name": "GeolocationEnricher",
+              "enricher": 
"org.apache.ranger.plugin.contextenricher.RangerFileBasedGeolocationProvider",
+              "enricherOptions": {
+                "FilePath": "/etc/ranger/geo/geo.txt",
+                "ForceRead": "false",
+                "IPInDotFormat": "true",
+                "geolocation.meta.prefix": "TEST_"
+              }
+            }
+          ],
+          "policyConditions": [
+            {
+              "itemId": 1,
+              "name": "ScriptConditionEvaluator",
+              "evaluator": 
"org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator",
+              "evaluatorOptions": {
+                "engineName": "JavaScript"
+              },
+              "label": "Script",
+              "description": "Script to execute"
+            }
+          ]
+        },
+        "policies": [
+          {
+            "id": 1, "name": "audit-all-access under /finance/restricted/",
+            "resources": {
+              "path": {"values": ["/finance/restricted/"], "isRecursive": true}
+            },
+            "policyItems": [
+              {"accesses": [], "users": [], "groups": [ "public"]}
+            ]
+          },
+          {
+            "id": 2, "name": "allow-read-to-all under /public/",
+            "resources": {
+              "path": {"values": [ "/public/*" ], "isRecursive": true}
+            },
+            "policyItems": [
+              {"accesses": [{"type": "read", "isAllowed": true},{"type": 
"execute", "isAllowed": true}], "users": [], "groups": ["public"]}
+            ]
+          },
+          {
+            "id": 3, "name": "allow-read-to-finance under /finance/restricted",
+            "resources": {
+              "path": {"values": [ "/finance/restricted" ], "isRecursive": 
true}
+            },
+            "policyItems": [
+              {"accesses": [{"type": "read", "isAllowed": true}], "users": [], 
"groups": ["finance"]}
+            ]
+          },
+          {
+            "id": 4, "name": "allow-read-to-finance under /finance/limited",
+            "resources": {
+              "path": {"values": [ "/finance/limited"], "isRecursive": true}
+            },
+            "policyItems": [
+              {"accesses": [{"type": "read", "isAllowed": true}], "users": [], 
"groups": ["stewards"]}
+            ]
+          }
+        ]
+      },
+      "tests": [
+        {
+          "name": "test-finance-restricted",
+          "resource": {"elements":{"path":"/finance/restricted"}},
+          "userPermissions": {},
+          "groupPermissions": {"finance": {"read": {"result": 1, "isFinal": 
true}}},
+          "rolePermissions": {}
+        },
+        {
+          "name": "test-finance-limited",
+          "resource": {"elements":{"path":"/finance/limited"}},
+          "userPermissions": {},
+          "groupPermissions": {"stewards": {"read": {"result": 1, "isFinal": 
true}}},
+          "rolePermissions": {}
+        },
+        {
+          "name": "test-anything-under-public",
+          "resource": {"elements":{"path":"/public/anything"}},
+          "userPermissions": {},
+          "groupPermissions": {"public": {"read": {"result": 1, "isFinal": 
true}, "execute": {"result": 1, "isFinal": true}}},
+          "rolePermissions": {}
+        }
+      ]
+    }
+  ]
+}
diff --git 
a/hdfs-agent/src/test/resources/aclprovider/test_aclprovider_default.json 
b/hdfs-agent/src/test/resources/aclprovider/test_aclprovider_default.json
new file mode 100644
index 0000000..c345ec6
--- /dev/null
+++ b/hdfs-agent/src/test/resources/aclprovider/test_aclprovider_default.json
@@ -0,0 +1,142 @@
+{
+  "testCases": [
+    {
+      "name": "Test-ACL-Provider",
+      "roles" : { "serviceName":  "hdfsdev", "roleVersion": 1,
+        "rangerRoles": [ { "name":  "admin", "users":  
[{"name":"admin-1","isAdmin": false}, {"name":"admin-2", "isAdmin": false}], 
"groups" : [{"name":"admin-group-1", "isAdmin":false}, {"name":"admin-group-2", 
"isAdmin": false}], "roles": [{"name": "sub-admin-1","isAdmin":false}, 
{"name":"sub-admin-2", "isAdmin": false}] },
+          { "name":  "sub-admin-1", "users":  [{"name":"sub-admin-user-1", 
"isAdmin": false}], "groups" : [], "roles": [] },
+          { "name":  "sub-admin-2", "users":  [], "groups" : 
[{"name":"sub-admin-group-2", "isAdmin":false}], "roles": [] }
+        ]
+      },
+      "servicePolicies": {
+        "serviceName": "hdfsdev",
+        "serviceDef": {
+          "name": "hdfs", "id": 1,
+          "resources": [
+            {"name": "path", "type": "path", "level": 1, "mandatory": true, 
"lookupSupported": true,
+              "matcher": 
"org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher",
+              "matcherOptions": {"wildCard": true, "ignoreCase": true},
+              "label": "Resource Path", "description": "HDFS file or directory 
path"
+            }
+          ],
+          "accessTypes": [
+            {"name": "read", "label": "Read"},
+            {"name": "write", "label": "Write"},
+            {"name": "execute", "label": "Execute"}
+          ],
+          "contextEnrichers": [
+            {
+              "itemId": 1,
+              "name": "GeolocationEnricher",
+              "enricher": 
"org.apache.ranger.plugin.contextenricher.RangerFileBasedGeolocationProvider",
+              "enricherOptions": {"FilePath": "/etc/ranger/geo/geo.txt", 
"ForceRead": "false", "IPInDotFormat": "true", "geolocation.meta.prefix": 
"TEST_"}
+            }
+          ],
+          "policyConditions": [
+            {
+              "itemId": 1,
+              "name": "ScriptConditionEvaluator",
+              "evaluator": 
"org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator",
+              "evaluatorOptions": {"engineName": "JavaScript"},
+              "label": "Script",
+              "description": "Script to execute"
+            }
+          ]
+        },
+        "serviceConfig": {"ranger.plugin.hdfs.chained.service" :  
"mapped_hive", "ranger.plugin.hdfs.chained.service.mapped_hive.impl": 
"org.apache.ranger.chainedplugin.hdfs.hive.RangerHdfsHiveChainedPlugin"},
+        "policies": [
+          {
+            "id": 10,
+            "name": "allow-read-to-user1,user3 /test/restricted",
+            "isEnabled": true, "isAuditEnabled": true, "isDenyAllElse": true,
+            "resources": {"path": {"values": ["/test/restricted"], 
"isRecursive": true}},
+            "policyItems": [
+              { "accesses": [{"type": "read", "isAllowed": true}], "users": 
["user1", "user2", "user3"], "groups": [], 
"roles":["sub-admin-1"],"delegateAdmin": false }
+            ],
+            "allowExceptions": [
+              { "accesses": [{"type": "read", "isAllowed": true}], "users": 
["user2"], "groups": [], "delegateAdmin": false }
+            ]
+          },
+          {
+            "id": 20,
+            "name": "allow-read-to-user2 /test/restricted/a",
+            "isEnabled": true, "isAuditEnabled": true,
+            "resources": {"path": {"values": 
["/test/restricted/a"],"isRecursive": true}},
+            "policyItems": [
+              { "accesses": [ {"type": "read", "isAllowed": true}, {"type": 
"write", "isAllowed": true} ], "users": ["user2", "non-user1", "non-user2", 
"non-user3"], "groups": ["public"], "delegateAdmin": false }
+            ],
+            "denyPolicyItems": [
+              { "accesses": [ {"type": "read", "isAllowed": true} ], "users": 
["non-user4"], "groups": [], "delegateAdmin": false }
+            ]
+          },
+          {
+            "id": 30,
+            "name": "deny-read-to-user3 /test/restricted/b",
+            "isEnabled": true, "isAuditEnabled": true,
+            "resources": {"path": {"values": ["/test/restricted/b"], 
"isRecursive": true} },
+            "policyItems": [
+              { "accesses": [ {"type": "read", "isAllowed": true} ], "users": 
["non-user5", "non-user6", "non-user7", "non-user8"], "groups": ["public"], 
"delegateAdmin": false, "conditions": [ { "type": "ScriptConditionEvaluator", 
"values": [ "var country_code = 
ctx.getRequestContextAttribute('LOCATION_TEST_COUNTRY_CODE'); ctx.result = 
!!country_code;" ] } ] }
+            ],
+            "denyPolicyItems": [
+              { "accesses": [ { "type": "read", "isAllowed": true } ], 
"users": [ "user3", "non-user9" ], "groups": [], "delegateAdmin": false }
+            ]
+          },
+          {
+            "id": 1,
+            "name": "audit-all-access under /finance/restricted",
+            "isEnabled": true, "isAuditEnabled": true,
+            "resources": { "path": { "values": [ "/finance/restricted" ], 
"isRecursive": true } },
+            "policyItems": [
+              { "accesses": [], "users": [], "groups": [ "public" ], 
"delegateAdmin": false }
+            ]
+          },
+          {
+            "id": 2,
+            "name": "allow-read-to-all under /public/*",
+            "isEnabled": true, "isAuditEnabled": false,
+            "resources": { "path": { "values": [ "/public/*" ], "isRecursive": 
true } },
+            "policyItems": [
+              { "accesses": [ { "type": "read", "isAllowed": true }, { "type": 
"execute", "isAllowed": true } ], "users": [], "groups": [ "public" ], 
"delegateAdmin": false }
+            ]
+          },
+          {
+            "id": 3,
+            "name": "allow-read-to-finance under /finance/restricted",
+            "isEnabled": true, "isAuditEnabled": true,
+            "resources": { "path": { "values": [ "/finance/restricted" ], 
"isRecursive": true } },
+            "policyItems": [
+              { "accesses": [ { "type": "read", "isAllowed": true } ], 
"users": [], "groups": [ "finance" ], "delegateAdmin": false, "conditions": [ { 
"type": "ScriptConditionEvaluator", "values": [ "var country_code = 
ctx.getRequestContextAttribute('LOCATION_TEST_COUNTRY_CODE'); ctx.result = 
!!country_code;" ] } ] }
+            ]
+          },
+          {
+            "id": 4,
+            "name": "No access for /forbidden",
+            "isEnabled": true, "isAuditEnabled": true,
+            "isDenyAllElse": true,
+            "resources": { "path": { "values": [ "/forbidden" ], 
"isRecursive": true } },
+            "policyItems": [
+              { "accesses": [ { "type": "read", "isAllowed": true }, { "type": 
"read", "isAllowed": true }, { "type": "write", "isAllowed": true },{ "type": 
"execute", "isAllowed": true } ], "users": [], "groups": [ "public" ], 
"delegateAdmin": false }
+            ]
+          }
+        ]
+      }
+    ,
+      "tests": [
+        {
+          "name": "/test/restricted access",
+          "resource": {"elements":{"path":"/test/restricted" }},
+          "userPermissions": {"user1": {"read": {"result":-1, "isFinal" : 
true}, "write": {"result":-1,"isFinal":true}, "execute":{"result":-1, 
"isFinal": true}}, "user2": {"read": {"result":-1, "isFinal" : true}, "write": 
{"result":-1,"isFinal":true}, "execute":{"result":-1, "isFinal": 
true}},"user3": {"read": {"result":0, "isFinal" : true}, "write": 
{"result":0,"isFinal":true}, "execute":{"result":0, "isFinal": true}}, 
"sub-admin-user-1": {"read": {"result":1, "isFinal" : true}, "write [...]
+          "groupPermissions": {"public": {"read": {"result":2, "isFinal" : 
true},"write": {"result":-1,"isFinal":true}, "execute":{"result":-1, "isFinal": 
true}}}
+        },
+        {
+          "name": "all-deny-test",
+          "resource": {"elements":{"path":"/forbidden" }},
+          "userPermissions": {},
+          "groupPermissions": {"public": {"read": {"result":1, "isFinal" : 
true},"write": {"result":1,"isFinal":true}, "execute":{"result":1, "isFinal": 
true}},
+            "other": {"read": {"result":-1, "isFinal" : true},"write": 
{"result":-1,"isFinal":true}, "execute":{"result":-1, "isFinal": true}}}
+        }
+      ]
+    }
+  ]
+}
+

Reply via email to