You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ab...@apache.org on 2020/11/26 06:54:47 UTC
[ranger] branch master updated: RANGER-3082: User with
delegated-admin is unable to create policy
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 6b5d5fb RANGER-3082: User with delegated-admin is unable to create policy
6b5d5fb is described below
commit 6b5d5fb3469df532df4528e1c4cd8cb503f44eba
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 39869d3..5202587 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;
@@ -3533,6 +3534,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);
@@ -3592,7 +3596,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);
@@ -3687,9 +3691,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;