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

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


The following commit(s) were added to refs/heads/ranger-2.2 by this push:
     new af38489  RANGER-3082: User with delegated-admin is unable to create 
policy
af38489 is described below

commit af384899abda5888414700beff26fc67a518b7e3
Author: Abhay Kulkarni <ab...@apache.org>
AuthorDate: Wed Nov 25 22:42:06 2020 -0800

    RANGER-3082: User with delegated-admin is unable to create policy
---
 .../ranger/plugin/policyengine/PolicyEngine.java   | 25 +++++++-
 .../RangerDefaultPolicyEvaluator.java              |  8 +--
 .../policyevaluator/RangerPolicyEvaluator.java     |  2 +-
 .../org/apache/ranger/biz/RangerPolicyAdmin.java   |  2 +-
 .../apache/ranger/biz/RangerPolicyAdminImpl.java   | 72 ++++++++++++++++++++--
 .../java/org/apache/ranger/rest/ServiceREST.java   | 11 +++-
 6 files changed, 106 insertions(+), 14 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 3250719..2742312 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
@@ -40,12 +40,14 @@ import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.validation.RangerZoneResourceMatcher;
 import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
 import 
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
+import org.apache.ranger.plugin.resourcematcher.RangerAbstractResourceMatcher;
 import org.apache.ranger.plugin.service.RangerAuthContext;
 import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
 import org.apache.ranger.plugin.util.RangerPolicyDeltaUtil;
 import org.apache.ranger.plugin.util.RangerRoles;
 import org.apache.ranger.plugin.util.ServicePolicies;
+import org.apache.ranger.plugin.util.StringTokenReplacer;
 
 public class PolicyEngine {
     private static final Log LOG = LogFactory.getLog(PolicyEngine.class);
@@ -62,6 +64,7 @@ public class PolicyEngine {
     private final Map<String, String>                 zoneTagServiceMap = new 
HashMap<>();
     private       boolean                             useForwardedIPAddress;
     private       String[]                            trustedProxyAddresses;
+    private final Map<String, StringTokenReplacer>    tokenReplacers = new 
HashMap<>();
 
     public boolean getUseForwardedIPAddress() {
         return useForwardedIPAddress;
@@ -109,6 +112,10 @@ public class PolicyEngine {
 
     public RangerPluginContext getPluginContext() { return pluginContext; }
 
+    public StringTokenReplacer getStringTokenReplacer(String resourceName) {
+        return tokenReplacers.get(resourceName);
+    }
+
     @Override
     public String toString() {
         return toString(new StringBuilder()).toString();
@@ -159,7 +166,7 @@ public class PolicyEngine {
         return resourceZoneTrie;
     }
 
-    public PolicyEngine(ServicePolicies servicePolicies, RangerPluginContext 
pluginContext, RangerRoles roles) {
+        public PolicyEngine(ServicePolicies servicePolicies, 
RangerPluginContext pluginContext, RangerRoles roles) {
         if (LOG.isDebugEnabled()) {
             LOG.debug("==> PolicyEngine(" + ", " + servicePolicies + ", " + 
pluginContext + ")");
         }
@@ -233,6 +240,20 @@ public class PolicyEngine {
             }
         }
 
+        for (RangerServiceDef.RangerResourceDef resourceDef : 
getServiceDef().getResources()) {
+            Map<String, String> matchOptions = resourceDef.getMatcherOptions();
+
+            if 
(RangerAbstractResourceMatcher.getOptionReplaceTokens(matchOptions)) {
+                String delimiterPrefix = 
RangerAbstractResourceMatcher.getOptionDelimiterPrefix(matchOptions);
+                char delimiterStart = 
RangerAbstractResourceMatcher.getOptionDelimiterStart(matchOptions);
+                char delimiterEnd = 
RangerAbstractResourceMatcher.getOptionDelimiterEnd(matchOptions);
+                char escapeChar = 
RangerAbstractResourceMatcher.getOptionDelimiterEscape(matchOptions);
+
+                StringTokenReplacer tokenReplacer = new 
StringTokenReplacer(delimiterStart, delimiterEnd, escapeChar, delimiterPrefix);
+                tokenReplacers.put(resourceDef.getName(), tokenReplacer);
+            }
+        }
+
         RangerPerfTracer.log(perf);
 
         if (PERF_POLICYENGINE_INIT_LOG.isDebugEnabled()) {
@@ -639,7 +660,7 @@ public class PolicyEngine {
 
         List<RangerContextEnricher> tmpList;
         List<RangerContextEnricher> tagContextEnrichers      = 
tagPolicyRepository == null ? null :tagPolicyRepository.getContextEnrichers();
-        List<RangerContextEnricher> resourceContextEnrichers = 
policyRepository.getContextEnrichers();
+        List<RangerContextEnricher> resourceContextEnrichers = 
policyRepository == null ? null : policyRepository.getContextEnrichers();
 
         if (CollectionUtils.isEmpty(tagContextEnrichers)) {
             tmpList = resourceContextEnrichers;
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 f3e0dab..07fb638 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
@@ -369,15 +369,15 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
        }
 
        @Override
-       public boolean isAccessAllowed(RangerPolicy policy, String user, 
Set<String> userGroups, Set<String> roles,  String accessType) {
+       public boolean isAccessAllowed(Long policyId, Map<String, 
RangerPolicyResource> resources, String user, Set<String> userGroups, 
Set<String> roles,  String accessType, Map<String, Object> evalContext) {
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.isAccessAllowed(" + policy.getId() + ", " + user + 
", " + userGroups + ", " + roles + ", " + accessType + ")");
+                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.isAccessAllowed(" + policyId + ", " + user + ", " 
+ userGroups + ", " + roles + ", " + accessType + ", " + evalContext + ")");
                }
 
-               boolean ret = isAccessAllowed(user, userGroups, roles, null, 
accessType) && isMatch(policy, null);
+               boolean ret = isAccessAllowed(user, userGroups, roles, null, 
accessType) && isMatch(resources, evalContext);
                
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerDefaultPolicyEvaluator.isAccessAllowed(" + policy.getId() + ", " + user + 
", " + userGroups + ", " + roles + ", " + accessType + "): " + ret);
+                       LOG.debug("<== 
RangerDefaultPolicyEvaluator.isAccessAllowed(" + policyId + ", " + user + ", " 
+ userGroups + ", " + roles + ", " + accessType + ", " + evalContext + "): " + 
ret);
                }
 
                return ret;
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 14b626d..236f998 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
@@ -98,7 +98,7 @@ public interface RangerPolicyEvaluator extends 
RangerPolicyResourceEvaluator {
 
        boolean isAccessAllowed(Map<String, RangerPolicyResource> resources, 
String user, Set<String> userGroups, String accessType);
 
-       boolean isAccessAllowed(RangerPolicy policy, String user, Set<String> 
userGroups, Set<String> roles, String accessType);
+       boolean isAccessAllowed(Long policyId, Map<String, 
RangerPolicyResource> resources, String user, Set<String> userGroups, 
Set<String> roles, String accessType, Map<String, Object> evalContext);
 
        void updateAccessResult(RangerAccessResult result, 
RangerPolicyResourceMatcher.MatchType matchType, boolean isAllowed, String 
reason);
 
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 e011c0b..891c800 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
@@ -33,7 +33,7 @@ public interface RangerPolicyAdmin {
 
     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);
+    boolean isAccessAllowed(RangerPolicy policy, String user, Set<String> 
userGroups, Set<String> roles, String accessType, Map<String, Object> 
evalContext);
 
     List<RangerPolicy> getExactMatchPolicies(RangerAccessResource resource, 
String zoneName, Map<String, Object> evalContext);
 
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 6fc0abf..cd566bc 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
@@ -37,14 +37,18 @@ import 
org.apache.ranger.plugin.policyengine.RangerPolicyRepository;
 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.resourcematcher.RangerAbstractResourceMatcher;
 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;
 import org.apache.ranger.plugin.util.ServicePolicies;
+import org.apache.ranger.plugin.util.StringTokenReplacer;
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -56,6 +60,14 @@ public class RangerPolicyAdminImpl implements 
RangerPolicyAdmin {
 
     private final PolicyEngine                 policyEngine;
     private final RangerAccessRequestProcessor requestProcessor;
+    private final static Map<String, Object>          wildcardEvalContext = 
new HashMap<String, Object>() {
+        @Override
+        public Object get(Object key) { return 
RangerAbstractResourceMatcher.WILDCARD_ASTERISK; }
+    };
+
+    static {
+        
wildcardEvalContext.put(RangerAbstractResourceMatcher.WILDCARD_ASTERISK, 
RangerAbstractResourceMatcher.WILDCARD_ASTERISK);
+    }
 
     static public RangerPolicyAdmin getPolicyAdmin(final RangerPolicyAdminImpl 
other, final ServicePolicies servicePolicies) {
         RangerPolicyAdmin ret = null;
@@ -123,9 +135,9 @@ public class RangerPolicyAdminImpl implements 
RangerPolicyAdmin {
     }
 
     @Override
-    public boolean isAccessAllowed(RangerPolicy policy, String user, 
Set<String> userGroups, Set<String> roles, String accessType) {
+    public boolean isAccessAllowed(RangerPolicy policy, String user, 
Set<String> userGroups, Set<String> roles, String accessType, Map<String, 
Object> evalContext) {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> RangerPolicyAdminImpl.isAccessAllowed(" + 
policy.getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + 
accessType + ")");
+            LOG.debug("==> RangerPolicyAdminImpl.isAccessAllowed(" + 
policy.getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + 
accessType + ", " + evalContext + ")");
         }
 
         boolean          ret  = false;
@@ -138,8 +150,12 @@ public class RangerPolicyAdminImpl implements 
RangerPolicyAdmin {
         final RangerPolicyRepository matchedRepository = 
policyEngine.getRepositoryForMatchedZone(policy);
 
         if (matchedRepository != null) {
+            // RANGER-3082
+            // Convert policy resources to by substituting macros with ASTERISK
+            Map<String, RangerPolicyResource> modifiedPolicyResources = 
getPolicyResourcesWithMacrosReplaced(policy.getResources(), 
wildcardEvalContext);
+
             for (RangerPolicyEvaluator evaluator : 
matchedRepository.getPolicyEvaluators()) {
-                ret = evaluator.isAccessAllowed(policy, user, userGroups, 
roles, accessType);
+                ret = evaluator.isAccessAllowed(policy.getId(), 
modifiedPolicyResources, user, userGroups, roles, accessType, evalContext);
 
                 if (ret) {
                     break;
@@ -150,7 +166,7 @@ public class RangerPolicyAdminImpl implements 
RangerPolicyAdmin {
         RangerPerfTracer.log(perf);
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerPolicyAdminImpl.isAccessAllowed(" + 
policy.getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + 
accessType + "): " + ret);
+            LOG.debug("<== RangerPolicyAdminImpl.isAccessAllowed(" + 
policy.getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + 
accessType + ", " + evalContext + "): " + ret);
         }
 
         return ret;
@@ -421,5 +437,53 @@ public class RangerPolicyAdminImpl implements 
RangerPolicyAdmin {
 
         }
     }
+
+    private Map<String, RangerPolicyResource> 
getPolicyResourcesWithMacrosReplaced(Map<String, RangerPolicyResource> 
resources, Map<String, Object> evalContext) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> 
RangerPolicyAdminImpl.getPolicyResourcesWithMacrosReplaced(" + resources  + ", 
" + evalContext + ")");
+        }
+
+        final Map<String, RangerPolicyResource>  ret;
+
+        Collection<String> resourceKeys = resources == null ? null : 
resources.keySet();
+
+        if (CollectionUtils.isNotEmpty(resourceKeys)) {
+            ret = new HashMap<>();
+
+            for (String resourceName : resourceKeys) {
+                RangerPolicyResource resourceValues = 
resources.get(resourceName);
+                List<String>         values         = resourceValues == null ? 
null : resourceValues.getValues();
+
+                if (CollectionUtils.isNotEmpty(values)) {
+                    StringTokenReplacer tokenReplacer = 
policyEngine.getStringTokenReplacer(resourceName);
+
+                    if (tokenReplacer != null) {
+                        List<String> modifiedValues = new ArrayList<>();
+
+                        for (String value : values) {
+                            // RANGER-3082 - replace macros in value with 
ASTERISK
+                            String modifiedValue = 
tokenReplacer.replaceTokens(value, evalContext);
+                            modifiedValues.add(modifiedValue);
+                        }
+
+                        RangerPolicyResource modifiedPolicyResource = new 
RangerPolicyResource(modifiedValues, resourceValues.getIsExcludes(), 
resourceValues.getIsRecursive());
+                        ret.put(resourceName, modifiedPolicyResource);
+                    } else {
+                        ret.put(resourceName, resourceValues);
+                    }
+                } else {
+                    ret.put(resourceName, resourceValues);
+                }
+            }
+        } else {
+            ret = resources;
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== 
RangerPolicyEngineImpl.getPolicyResourcesWithMacrosReplaced(" + resources  + ", 
" + evalContext + "): " + ret);
+        }
+
+        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 3a1510c..9aad6db 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
@@ -120,6 +120,7 @@ import org.apache.ranger.plugin.store.PList;
 import org.apache.ranger.plugin.store.ServiceStore;
 import org.apache.ranger.plugin.util.GrantRevokeRequest;
 import org.apache.ranger.plugin.util.JsonUtilsV2;
+import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
 import org.apache.ranger.plugin.util.SearchFilter;
 import org.apache.ranger.plugin.util.ServicePolicies;
@@ -3550,6 +3551,9 @@ public class ServiceREST {
                        Set<String> userGroups = null;
 
                        Map<String, List<RangerPolicy>> servicePoliciesMap = 
new HashMap<String, List<RangerPolicy>>();
+                       Map<String, Object>             evalContext        = 
new HashMap<>();
+
+                       
RangerAccessRequestUtil.setCurrentUserInContext(evalContext, userName);
 
                        for (int i = 0; i < policies.size(); i++) {
                                RangerPolicy       policy      = 
policies.get(i);
@@ -3609,7 +3613,7 @@ public class ServiceREST {
                                                Set<String> roles = 
policyAdmin.getRolesFromUserAndGroups(userName, userGroups);
 
                                                for (RangerPolicy policy : 
listToFilter) {
-                                                       if 
(policyAdmin.isAccessAllowed(policy, userName, userGroups, roles, 
RangerPolicyEngine.ADMIN_ACCESS)
+                                                       if 
(policyAdmin.isAccessAllowed(policy, userName, userGroups, roles, 
RangerPolicyEngine.ADMIN_ACCESS, evalContext)
                                                                        || 
(!StringUtils.isEmpty(policy.getZoneName()) && 
(serviceMgr.isZoneAdmin(policy.getZoneName()) || 
serviceMgr.isZoneAuditor(policy.getZoneName())))
                                                                        || 
isServiceAdminUser) {
                                                                ret.add(policy);
@@ -3704,9 +3708,12 @@ public class ServiceREST {
                RangerPolicyAdmin policyAdmin = 
getPolicyAdminForDelegatedAdmin(policy.getService());
 
                if(policyAdmin != null) {
+                       Map evalContext = new HashMap<>();
+                       
RangerAccessRequestUtil.setCurrentUserInContext(evalContext, userName);
+
                        Set<String> roles = 
policyAdmin.getRolesFromUserAndGroups(userName, userGroups);
 
-                       isAllowed = policyAdmin.isAccessAllowed(policy, 
userName, userGroups, roles, RangerPolicyEngine.ADMIN_ACCESS);
+                       isAllowed = policyAdmin.isAccessAllowed(policy, 
userName, userGroups, roles, RangerPolicyEngine.ADMIN_ACCESS, evalContext);
                }
 
                return isAllowed;

Reply via email to