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/12/23 20:23:34 UTC
[ranger] branch master updated: RANGER-3122: Support delegate-admin
for specific permissions
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 9d459e0 RANGER-3122: Support delegate-admin for specific permissions
9d459e0 is described below
commit 9d459e0255484277d802b5d8e9fcdd936f3aed04
Author: Abhay Kulkarni <ab...@apache.org>
AuthorDate: Wed Dec 23 12:06:56 2020 -0800
RANGER-3122: Support delegate-admin for specific permissions
---
.../RangerDefaultPolicyEvaluator.java | 66 +++++++++++-----
.../RangerOptimizedPolicyEvaluator.java | 26 +++---
.../policyevaluator/RangerPolicyEvaluator.java | 8 +-
.../ranger/plugin/service/RangerBasePlugin.java | 2 +-
.../apache/ranger/plugin/util/ServiceDefUtil.java | 27 +++++++
.../org/apache/ranger/biz/RangerPolicyAdmin.java | 7 +-
.../apache/ranger/biz/RangerPolicyAdminImpl.java | 92 +++++++++++++++++-----
.../java/org/apache/ranger/rest/ServiceREST.java | 42 +++++-----
8 files changed, 195 insertions(+), 75 deletions(-)
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 d64d226..45774b9 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
@@ -28,6 +28,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
@@ -335,54 +336,72 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
}
@Override
- public boolean isAccessAllowed(RangerAccessResource resource, String user, Set<String> userGroups, Set<String> roles, String accessType) {
+ public Set<String> getAllowedAccesses(RangerAccessResource resource, String user, Set<String> userGroups, Set<String> roles, Set<String> accessTypes) {
if(LOG.isDebugEnabled()) {
- LOG.debug("==> RangerDefaultPolicyEvaluator.isAccessAllowed(" + resource + ", " + user + ", " + userGroups + ", " + roles + ", " + accessType + ")");
+ LOG.debug("==> RangerDefaultPolicyEvaluator.getAllowedAccesses(" + resource + ", " + user + ", " + userGroups + ", " + roles + ", " + accessTypes + ")");
+ }
+
+ Set<String> ret = null;
+
+ if (isMatch(resource, null)) {
+ ret = new HashSet<>();
+ for (String accessType : accessTypes) {
+ if (isAccessAllowed(user, userGroups, roles, resource.getOwnerUser(), accessType)) {
+ ret.add(accessType);
+ }
+ }
}
- boolean ret = isAccessAllowed(user, userGroups, roles, resource.getOwnerUser(), accessType) && isMatch(resource, null);
-
if(LOG.isDebugEnabled()) {
- LOG.debug("<== RangerDefaultPolicyEvaluator.isAccessAllowed(" + resource + ", " + user + ", " + userGroups + ", " + roles + ", " + accessType + "): " + ret);
+ LOG.debug("<== RangerDefaultPolicyEvaluator.getAllowedAccesses(" + resource + ", " + user + ", " + userGroups + ", " + roles + ", " + accessTypes + "): " + ret);
}
return ret;
}
- /*
- * This is used only by test code
- */
-
@Override
- public boolean isAccessAllowed(Map<String, RangerPolicyResource> resources, String user, Set<String> userGroups, String accessType) {
+ public Set<String> getAllowedAccesses(Map<String, RangerPolicyResource> resources, String user, Set<String> userGroups, Set<String> roles, Set<String> accessTypes, Map<String, Object> evalContext) {
if(LOG.isDebugEnabled()) {
- LOG.debug("==> RangerDefaultPolicyEvaluator.isAccessAllowed(" + resources + ", " + user + ", " + userGroups + ", " + accessType + ")");
+ LOG.debug("==> RangerDefaultPolicyEvaluator.getAllowedAccesses(" + getPolicy().getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + accessTypes + ", " + evalContext + ")");
}
- boolean ret = isAccessAllowed(user, userGroups, null, null, accessType) && isMatch(resources, null);
+ Set<String> ret = null;
+
+ if (isMatch(resources, evalContext)) {
+ ret = new HashSet<>();
+ for (String accessType : accessTypes) {
+ if (isAccessAllowed(user, userGroups, roles, null, accessType)) {
+ ret.add(accessType);
+ }
+ }
+ }
if(LOG.isDebugEnabled()) {
- LOG.debug("<== RangerDefaultPolicyEvaluator.isAccessAllowed(" + resources + ", " + user + ", " + userGroups + ", " + accessType + "): " + ret);
+ LOG.debug("<== RangerDefaultPolicyEvaluator.getAllowedAccesses(" + getPolicy().getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + accessTypes + ", " + evalContext + "): " + ret);
}
return ret;
}
+ /*
+ * This is used only by test code
+ */
@Override
- public boolean isAccessAllowed(Long policyId, Map<String, RangerPolicyResource> resources, String user, Set<String> userGroups, Set<String> roles, String accessType, Map<String, Object> evalContext) {
+ public boolean isAccessAllowed(Map<String, RangerPolicyResource> resources, String user, Set<String> userGroups, String accessType) {
if(LOG.isDebugEnabled()) {
- LOG.debug("==> RangerDefaultPolicyEvaluator.isAccessAllowed(" + policyId + ", " + user + ", " + userGroups + ", " + roles + ", " + accessType + ", " + evalContext + ")");
+ LOG.debug("==> RangerDefaultPolicyEvaluator.isAccessAllowed(" + resources + ", " + user + ", " + userGroups + ", " + accessType + ")");
}
- boolean ret = isAccessAllowed(user, userGroups, roles, null, accessType) && isMatch(resources, evalContext);
-
+ boolean ret = isAccessAllowed(user, userGroups, null, null, accessType) && isMatch(resources, null);
+
if(LOG.isDebugEnabled()) {
- LOG.debug("<== RangerDefaultPolicyEvaluator.isAccessAllowed(" + policyId + ", " + user + ", " + userGroups + ", " + roles + ", " + accessType + ", " + evalContext + "): " + ret);
+ LOG.debug("<== RangerDefaultPolicyEvaluator.isAccessAllowed(" + resources + ", " + user + ", " + userGroups + ", " + accessType + "): " + ret);
}
return ret;
}
+
@Override
public void getResourceAccessInfo(RangerAccessRequest request, RangerResourceAccessInfo result) {
if (LOG.isDebugEnabled()) {
@@ -867,6 +886,8 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
return;
}
+ prunePolicyItems(policy);
+
preprocessPolicyItems(policy.getPolicyItems(), impliedAccessGrants);
preprocessPolicyItems(policy.getDenyPolicyItems(), impliedAccessGrants);
preprocessPolicyItems(policy.getAllowExceptions(), impliedAccessGrants);
@@ -936,6 +957,15 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
return ret;
}
+ private void prunePolicyItems(RangerPolicy policy) {
+ if (getPluginContext().getConfig().getPolicyEngineOptions().evaluateDelegateAdminOnly) {
+ policy.setPolicyItems(policy.getPolicyItems().stream().filter(RangerPolicyItem::getDelegateAdmin).collect(Collectors.toList()));
+ policy.setDenyPolicyItems(policy.getDenyPolicyItems().stream().filter(RangerPolicyItem::getDelegateAdmin).collect(Collectors.toList()));
+ policy.setAllowExceptions(policy.getAllowExceptions().stream().filter(RangerPolicyItem::getDelegateAdmin).collect(Collectors.toList()));
+ policy.setDenyExceptions(policy.getDenyExceptions().stream().filter(RangerPolicyItem::getDelegateAdmin).collect(Collectors.toList()));
+ }
+ }
+
private RangerPolicyItemAccess getAccess(RangerPolicyItem policyItem, String accessType) {
RangerPolicyItemAccess ret = null;
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
index bac076c..e69e45f 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
@@ -253,13 +253,16 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
boolean ret = false;
if (hasPublicGroup || hasCurrentUser || isOwnerMatch(request) || users.contains(request.getUser()) || CollectionUtils.containsAny(groups, request.getUserGroups()) || (CollectionUtils.isNotEmpty(roles) && CollectionUtils.containsAny(roles, RangerAccessRequestUtil.getCurrentUserRolesFromContext(request.getContext())))) {
- if(request.isAccessTypeDelegatedAdmin()) {
- ret = delegateAdmin;
- } else if(hasAllPerms) {
+ if (hasAllPerms || request.isAccessTypeAny()) {
ret = true;
} else {
- ret = request.isAccessTypeAny() || accessPerms.contains(request.getAccessType());
- }
+ ret = accessPerms.contains(request.getAccessType());
+ if (!ret) {
+ if (request.isAccessTypeDelegatedAdmin()) {
+ ret = delegateAdmin;
+ }
+ }
+ }
}
return ret;
@@ -292,16 +295,17 @@ public class RangerOptimizedPolicyEvaluator extends RangerDefaultPolicyEvaluator
}
if (hasPublicGroup || hasCurrentUser || users.contains(user) || CollectionUtils.containsAny(groups, userGroups) || hasRole || (hasResourceOwner && StringUtils.equals(user, owner))) {
- boolean isAdminAccess = StringUtils.equals(accessType, RangerPolicyEngine.ADMIN_ACCESS);
-
- if(isAdminAccess) {
- ret = delegateAdmin;
- } else if(hasAllPerms) {
+ if (hasAllPerms) {
ret = true;
} else {
boolean isAccessTypeAny = StringUtils.isEmpty(accessType) || StringUtils.equals(accessType, RangerPolicyEngine.ANY_ACCESS);
+ ret = isAccessTypeAny || accessPerms.contains(accessType);
- ret = isAccessTypeAny || accessPerms.contains(accessType);
+ if (!ret) {
+ if (StringUtils.equals(accessType, RangerPolicyEngine.ADMIN_ACCESS)) {
+ ret = delegateAdmin;
+ }
+ }
}
}
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 236f998..c611b5e 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
@@ -94,16 +94,16 @@ public interface RangerPolicyEvaluator extends RangerPolicyResourceEvaluator {
boolean isCompleteMatch(Map<String, RangerPolicyResource> resources, Map<String, Object> evalContext);
- boolean isAccessAllowed(RangerAccessResource resource, String user, Set<String> userGroups, Set<String> roles, String accessType);
-
boolean isAccessAllowed(Map<String, RangerPolicyResource> resources, String user, Set<String> userGroups, 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);
void getResourceAccessInfo(RangerAccessRequest request, RangerResourceAccessInfo result);
+ Set<String> getAllowedAccesses(RangerAccessResource resource, String user, Set<String> userGroups, Set<String> roles, Set<String> accessTypes);
+
+ Set<String> getAllowedAccesses(Map<String, RangerPolicyResource> resources, String user, Set<String> userGroups, Set<String> roles, Set<String> accessTypes, Map<String, Object> evalContext);
+
PolicyACLSummary getPolicyACLSummary();
default boolean hasContextSensitiveSpecification() {
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 873553a..e1f09b8 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
@@ -705,7 +705,7 @@ public class RangerBasePlugin {
accessRequest.setResource(new RangerAccessResourceImpl(StringUtil.toStringObjectMap(request.getResource())));
accessRequest.setUser(request.getGrantor());
- accessRequest.setAccessType(RangerPolicyEngine.ADMIN_ACCESS);
+ accessRequest.setAccessType(RangerPolicyEngine.ANY_ACCESS);
accessRequest.setAction(action);
accessRequest.setClientIPAddress(request.getClientIPAddress());
accessRequest.setClientType(request.getClientType());
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
index cd6c18b..b76c96e 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServiceDefUtil.java
@@ -34,6 +34,8 @@ import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
@@ -439,4 +441,29 @@ public class ServiceDefUtil {
return ret;
}
+ public static Map<String, Collection<String>> getExpandedImpliedGrants(RangerServiceDef serviceDef) {
+ Map<String, Collection<String>> ret = new HashMap<>();
+
+ if(serviceDef != null && !CollectionUtils.isEmpty(serviceDef.getAccessTypes())) {
+ for(RangerAccessTypeDef accessTypeDef : serviceDef.getAccessTypes()) {
+ if(!CollectionUtils.isEmpty(accessTypeDef.getImpliedGrants())) {
+
+ Collection<String> impliedAccessGrants = ret.get(accessTypeDef.getName());
+
+ if(impliedAccessGrants == null) {
+ impliedAccessGrants = new HashSet<>();
+
+ ret.put(accessTypeDef.getName(), impliedAccessGrants);
+ }
+
+ impliedAccessGrants.addAll(accessTypeDef.getImpliedGrants());
+ impliedAccessGrants.add(accessTypeDef.getName());
+ } else {
+ ret.put(accessTypeDef.getName(), new HashSet<>(Collections.singleton(accessTypeDef.getName())));
+ }
+ }
+ }
+ return ret;
+ }
+
}
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 891c800..e2a0884 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
@@ -25,15 +25,16 @@ import java.util.Set;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.policyengine.RangerAccessResource;
import org.apache.ranger.plugin.util.GrantRevokeRequest;
import org.apache.ranger.plugin.util.RangerRoles;
public interface RangerPolicyAdmin {
- boolean isAccessAllowed(RangerAccessResource resource, String zoneName, String user, Set<String> userGroups, String accessType);
+ boolean isDelegatedAdminAccessAllowed(RangerAccessResource resource, String zoneName, String user, Set<String> userGroups, Set<String> accessTypes);
- boolean isAccessAllowed(RangerPolicy policy, String user, Set<String> userGroups, Set<String> roles, String accessType, Map<String, Object> evalContext);
+ boolean isDelegatedAdminAccessAllowed(RangerPolicy policy, String user, Set<String> userGroups, Set<String> roles, Map<String, Object> evalContext);
List<RangerPolicy> getExactMatchPolicies(RangerAccessResource resource, String zoneName, Map<String, Object> evalContext);
@@ -49,6 +50,8 @@ public interface RangerPolicyAdmin {
String getServiceName();
+ RangerServiceDef getServiceDef();
+
Set<String> getRolesFromUserAndGroups(String user, Set<String> groups);
String getUniquelyMatchedZoneName(GrantRevokeRequest grantRevokeRequest);
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 cd566bc..d868e39 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
@@ -20,12 +20,14 @@
package org.apache.ranger.biz;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.policyengine.PolicyEngine;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
@@ -43,12 +45,14 @@ 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.ServiceDefUtil;
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.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -94,32 +98,36 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
}
@Override
- public boolean isAccessAllowed(RangerAccessResource resource, String zoneName, String user, Set<String> userGroups, String accessType) {
+ public boolean isDelegatedAdminAccessAllowed(RangerAccessResource resource, String zoneName, String user, Set<String> userGroups, Set<String> accessTypes) {
if (LOG.isDebugEnabled()) {
- LOG.debug("==> RangerPolicyAdminImpl.isAccessAllowed(" + resource + ", " + zoneName + ", " + user + ", " + userGroups + ", " + accessType + ")");
+ LOG.debug("==> RangerPolicyAdminImpl.isDelegatedAdminAccessAllowed(" + resource + ", " + zoneName + ", " + user + ", " + userGroups + ", " + accessTypes + ")");
}
boolean ret = false;
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_REQUEST_LOG)) {
- perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_REQUEST_LOG, "RangerPolicyAdminImpl.isAccessAllowed(user=" + user + ",accessType=" + accessType + "resource=" + resource.getAsString() + ")");
+ perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_REQUEST_LOG, "RangerPolicyAdminImpl.isDelegatedAdminAccessAllowed(user=" + user + ",accessTypes=" + accessTypes + "resource=" + resource.getAsString() + ")");
}
final RangerPolicyRepository matchedRepository = policyEngine.getRepositoryForZone(zoneName);
if (matchedRepository != null) {
Set<String> roles = getRolesFromUserAndGroups(user, userGroups);
+ Set<String> requestedAccesses = new HashSet<>(accessTypes);
for (RangerPolicyEvaluator evaluator : matchedRepository.getLikelyMatchPolicyEvaluators(resource, RangerPolicy.POLICY_TYPE_ACCESS)) {
- ret = evaluator.isAccessAllowed(resource, user, userGroups, roles, accessType);
- if (ret) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Access granted by policy:[" + evaluator.getPolicy() + "]");
+ Set<String> allowedAccesses = evaluator.getAllowedAccesses(resource, user, userGroups, roles, requestedAccesses);
+ if (CollectionUtils.isNotEmpty(allowedAccesses)) {
+ requestedAccesses.removeAll(allowedAccesses);
+ if (CollectionUtils.isEmpty(requestedAccesses)) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Access granted by policy:[" + evaluator.getPolicy() + "]");
+ }
+ ret = true;
+ break;
}
-
- break;
}
}
@@ -128,23 +136,23 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
RangerPerfTracer.log(perf);
if (LOG.isDebugEnabled()) {
- LOG.debug("<== RangerPolicyAdminImpl.isAccessAllowed(" + resource + ", " + zoneName + ", " + user + ", " + userGroups + ", " + accessType + "): " + ret);
+ LOG.debug("<== RangerPolicyAdminImpl.isDelegatedAdminAccessAllowed(" + resource + ", " + zoneName + ", " + user + ", " + userGroups + ", " + accessTypes + "): " + ret);
}
return ret;
}
@Override
- public boolean isAccessAllowed(RangerPolicy policy, String user, Set<String> userGroups, Set<String> roles, String accessType, Map<String, Object> evalContext) {
+ public boolean isDelegatedAdminAccessAllowed(RangerPolicy policy, String user, Set<String> userGroups, Set<String> roles, Map<String, Object> evalContext) {
if (LOG.isDebugEnabled()) {
- LOG.debug("==> RangerPolicyAdminImpl.isAccessAllowed(" + policy.getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + accessType + ", " + evalContext + ")");
+ LOG.debug("==> RangerPolicyAdminImpl.isDelegatedAdminAccessAllowed(" + policy.getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + evalContext + ")");
}
boolean ret = false;
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_REQUEST_LOG)) {
- perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_REQUEST_LOG, "RangerPolicyEngine.isAccessAllowed(user=" + user + "," + userGroups + ", roles=" + roles + ",accessType=" + accessType + ")");
+ perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_REQUEST_LOG, "RangerPolicyEngine.isDelegatedAdminAccessAllowed(user=" + user + "," + userGroups + ", roles=" + roles + ")");
}
final RangerPolicyRepository matchedRepository = policyEngine.getRepositoryForMatchedZone(policy);
@@ -153,20 +161,27 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
// RANGER-3082
// Convert policy resources to by substituting macros with ASTERISK
Map<String, RangerPolicyResource> modifiedPolicyResources = getPolicyResourcesWithMacrosReplaced(policy.getResources(), wildcardEvalContext);
+ Set<String> accessTypes = getAllAccessTypes(policy, getServiceDef());
for (RangerPolicyEvaluator evaluator : matchedRepository.getPolicyEvaluators()) {
- ret = evaluator.isAccessAllowed(policy.getId(), modifiedPolicyResources, user, userGroups, roles, accessType, evalContext);
-
- if (ret) {
- break;
+ Set<String> allowedAccesses = evaluator.getAllowedAccesses(modifiedPolicyResources, user, userGroups, roles, accessTypes, evalContext);
+ if (CollectionUtils.isNotEmpty(allowedAccesses)) {
+ accessTypes.removeAll(allowedAccesses);
+ if (CollectionUtils.isEmpty(accessTypes)) {
+ ret = true;
+ break;
+ }
}
}
+ if (CollectionUtils.isNotEmpty(accessTypes)) {
+ LOG.info("Accesses : " + accessTypes + " are not authorized for the policy:[" + policy.getId() + "] by any of delegated-admin policies");
+ }
}
RangerPerfTracer.log(perf);
if (LOG.isDebugEnabled()) {
- LOG.debug("<== RangerPolicyAdminImpl.isAccessAllowed(" + policy.getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + accessType + ", " + evalContext + "): " + ret);
+ LOG.debug("<== RangerPolicyAdminImpl.isDelegatedAdminAccessAllowed(" + policy.getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + evalContext + "): " + ret);
}
return ret;
@@ -255,6 +270,11 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
@Override
public String getServiceName() { return policyEngine.getServiceName(); }
+
+ @Override
+ public RangerServiceDef getServiceDef() {
+ return policyEngine.getServiceDef();
+ }
@Override
public void setRoles(RangerRoles roles) {
policyEngine.setRoles(roles);
@@ -485,5 +505,41 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
return ret;
}
+
+ private Set<String> getAllAccessTypes(RangerPolicy policy, RangerServiceDef serviceDef) {
+ Set<String> ret = new HashSet<>();
+
+ Map<String, Collection<String>> expandedAccesses = ServiceDefUtil.getExpandedImpliedGrants(serviceDef);
+
+ if (MapUtils.isNotEmpty(expandedAccesses)) {
+
+ for (RangerPolicy.RangerPolicyItem item : policy.getPolicyItems()) {
+ List<RangerPolicy.RangerPolicyItemAccess> accesses = item.getAccesses();
+ for (RangerPolicy.RangerPolicyItemAccess access : accesses) {
+ ret.addAll(expandedAccesses.get(access.getType()));
+ }
+ }
+ for (RangerPolicy.RangerPolicyItem item : policy.getDenyPolicyItems()) {
+ List<RangerPolicy.RangerPolicyItemAccess> accesses = item.getAccesses();
+ for (RangerPolicy.RangerPolicyItemAccess access : accesses) {
+ ret.addAll(expandedAccesses.get(access.getType()));
+ }
+ }
+ for (RangerPolicy.RangerPolicyItem item : policy.getAllowExceptions()) {
+ List<RangerPolicy.RangerPolicyItemAccess> accesses = item.getAccesses();
+ for (RangerPolicy.RangerPolicyItemAccess access : accesses) {
+ ret.addAll(expandedAccesses.get(access.getType()));
+ }
+ }
+ for (RangerPolicy.RangerPolicyItem item : policy.getDenyExceptions()) {
+ List<RangerPolicy.RangerPolicyItemAccess> accesses = item.getAccesses();
+ for (RangerPolicy.RangerPolicyItemAccess access : accesses) {
+ ret.addAll(expandedAccesses.get(access.getType()));
+ }
+ }
+ }
+ 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 802abac..8db022e 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
@@ -113,7 +113,6 @@ import org.apache.ranger.plugin.model.validation.RangerServiceValidator;
import org.apache.ranger.plugin.model.validation.RangerValidator.Action;
import org.apache.ranger.plugin.policyengine.RangerAccessResource;
import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
-import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
import org.apache.ranger.plugin.service.ResourceLookupContext;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
@@ -1224,6 +1223,7 @@ public class ServiceREST {
Set<String> userGroups = CollectionUtils.isNotEmpty(grantRequest.getGrantorGroups()) ? grantRequest.getGrantorGroups() : userMgr.getGroupsForUser(userName);
String ownerUser = grantRequest.getOwnerUser();
RangerAccessResource resource = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(grantRequest.getResource()), ownerUser);
+ Set<String> accessTypes = grantRequest.getAccessTypes();
VXUser vxUser = xUserService.getXUserByUserName(userName);
if (vxUser.getUserRoleList().contains(RangerConstants.ROLE_ADMIN_AUDITOR) || vxUser.getUserRoleList().contains(RangerConstants.ROLE_KEY_ADMIN_AUDITOR)) {
@@ -1235,7 +1235,7 @@ public class ServiceREST {
RangerService rangerService = svcStore.getServiceByName(serviceName);
String zoneName = getRangerAdminZoneName(serviceName, grantRequest);
- boolean isAdmin = bizUtil.isUserRangerAdmin(userName) || bizUtil.isUserServiceAdmin(rangerService, userName) || hasAdminAccess(serviceName, zoneName, userName, userGroups, resource);
+ boolean isAdmin = bizUtil.isUserRangerAdmin(userName) || bizUtil.isUserServiceAdmin(rangerService, userName) || hasAdminAccess(serviceName, zoneName, userName, userGroups, resource, accessTypes);
if(!isAdmin) {
throw restErrorUtil.createGrantRevokeRESTException( "User doesn't have necessary permission to grant access");
@@ -1343,6 +1343,7 @@ public class ServiceREST {
String ownerUser = grantRequest.getOwnerUser();
RangerAccessResource resource = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(grantRequest.getResource()), ownerUser);
+ Set<String> accessTypes = grantRequest.getAccessTypes();
String zoneName = getRangerAdminZoneName(serviceName, grantRequest);
boolean isAllowed = false;
@@ -1352,7 +1353,7 @@ public class ServiceREST {
isAllowed = true;
}
} else {
- isAllowed = bizUtil.isUserRangerAdmin(userName) || bizUtil.isUserServiceAdmin(rangerService, userName) || hasAdminAccess(serviceName, zoneName, userName, userGroups, resource);
+ isAllowed = bizUtil.isUserRangerAdmin(userName) || bizUtil.isUserServiceAdmin(rangerService, userName) || hasAdminAccess(serviceName, zoneName, userName, userGroups, resource, accessTypes);
}
if (isAllowed) {
@@ -1458,6 +1459,7 @@ public class ServiceREST {
Set<String> userGroups = CollectionUtils.isNotEmpty(revokeRequest.getGrantorGroups()) ? revokeRequest.getGrantorGroups() : userMgr.getGroupsForUser(userName);
String ownerUser = revokeRequest.getOwnerUser();
RangerAccessResource resource = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(revokeRequest.getResource()), ownerUser);
+ Set<String> accessTypes = revokeRequest.getAccessTypes();
VXUser vxUser = xUserService.getXUserByUserName(userName);
if (vxUser.getUserRoleList().contains(RangerConstants.ROLE_ADMIN_AUDITOR) || vxUser.getUserRoleList().contains(RangerConstants.ROLE_KEY_ADMIN_AUDITOR)) {
@@ -1469,7 +1471,7 @@ public class ServiceREST {
RangerService rangerService = svcStore.getServiceByName(serviceName);
String zoneName = getRangerAdminZoneName(serviceName, revokeRequest);
- boolean isAdmin = bizUtil.isUserRangerAdmin(userName) || bizUtil.isUserServiceAdmin(rangerService, userName) || hasAdminAccess(serviceName, zoneName, userName, userGroups, resource);
+ boolean isAdmin = bizUtil.isUserRangerAdmin(userName) || bizUtil.isUserServiceAdmin(rangerService, userName) || hasAdminAccess(serviceName, zoneName, userName, userGroups, resource, accessTypes);
if(!isAdmin) {
throw restErrorUtil.createGrantRevokeRESTException("User doesn't have necessary permission to revoke access");
@@ -1541,6 +1543,7 @@ public class ServiceREST {
String ownerUser = revokeRequest.getOwnerUser();
RangerAccessResource resource = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(revokeRequest.getResource()), ownerUser);
+ Set<String> accessTypes = revokeRequest.getAccessTypes();
String zoneName = getRangerAdminZoneName(serviceName, revokeRequest);
@@ -1551,7 +1554,7 @@ public class ServiceREST {
isAllowed = true;
}
} else {
- isAllowed = bizUtil.isUserRangerAdmin(userName) || bizUtil.isUserServiceAdmin(rangerService, userName) || hasAdminAccess(serviceName, zoneName, userName, userGroups, resource);
+ isAllowed = bizUtil.isUserRangerAdmin(userName) || bizUtil.isUserServiceAdmin(rangerService, userName) || hasAdminAccess(serviceName, zoneName, userName, userGroups, resource, accessTypes);
}
if (isAllowed) {
@@ -3511,15 +3514,13 @@ public class ServiceREST {
List<RangerPolicy> listToFilter = entry.getValue();
if (CollectionUtils.isNotEmpty(listToFilter)) {
- boolean isServiceAdminUser = isAdmin || svcStore.isServiceAdminUser(serviceName, userName);
- if (isAdmin || isKeyAdmin || isAuditAdmin
- || isAuditKeyAdmin) {
- XXService xService = daoManager.getXXService()
- .findByName(serviceName);
- Long serviceDefId = xService.getType();
- boolean isKmsService = serviceDefId
- .equals(EmbeddedServiceDefsUtil.instance()
- .getKmsServiceDefId());
+ boolean isServiceAdminUser = svcStore.isServiceAdminUser(serviceName, userName);
+ if (isServiceAdminUser) {
+ ret.addAll(listToFilter);
+ } else if (isAdmin || isKeyAdmin || isAuditAdmin || isAuditKeyAdmin) {
+ XXService xService = daoManager.getXXService().findByName(serviceName);
+ Long serviceDefId = xService.getType();
+ boolean isKmsService = serviceDefId.equals(EmbeddedServiceDefsUtil.instance().getKmsServiceDefId());
if (isAdmin) {
if (!isKmsService) {
@@ -3551,9 +3552,8 @@ public class ServiceREST {
Set<String> roles = policyAdmin.getRolesFromUserAndGroups(userName, userGroups);
for (RangerPolicy policy : listToFilter) {
- if (policyAdmin.isAccessAllowed(policy, userName, userGroups, roles, RangerPolicyEngine.ADMIN_ACCESS, evalContext)
- || (!StringUtils.isEmpty(policy.getZoneName()) && (serviceMgr.isZoneAdmin(policy.getZoneName()) || serviceMgr.isZoneAuditor(policy.getZoneName())))
- || isServiceAdminUser) {
+ if ((policyAdmin.isDelegatedAdminAccessAllowed(policy, userName, userGroups, roles, evalContext))
+ || (!StringUtils.isEmpty(policy.getZoneName()) && (serviceMgr.isZoneAdmin(policy.getZoneName()) || serviceMgr.isZoneAuditor(policy.getZoneName())))) {
ret.add(policy);
}
}
@@ -3567,7 +3567,7 @@ public class ServiceREST {
return ret;
}
-
+
void ensureAdminAccess(RangerPolicy policy) {
boolean isAdmin = bizUtil.isAdmin();
boolean isKeyAdmin = bizUtil.isKeyAdmin();
@@ -3651,18 +3651,18 @@ public class ServiceREST {
Set<String> roles = policyAdmin.getRolesFromUserAndGroups(userName, userGroups);
- isAllowed = policyAdmin.isAccessAllowed(policy, userName, userGroups, roles, RangerPolicyEngine.ADMIN_ACCESS, evalContext);
+ isAllowed = policyAdmin.isDelegatedAdminAccessAllowed(policy, userName, userGroups, roles, evalContext);
}
return isAllowed;
}
- private boolean hasAdminAccess(String serviceName, String zoneName, String userName, Set<String> userGroups, RangerAccessResource resource) {
+ private boolean hasAdminAccess(String serviceName, String zoneName, String userName, Set<String> userGroups, RangerAccessResource resource, Set<String> accessTypes) {
boolean isAllowed = false;
RangerPolicyAdmin policyAdmin = getPolicyAdminForDelegatedAdmin(serviceName);
if(policyAdmin != null) {
- isAllowed = policyAdmin.isAccessAllowed(resource, zoneName, userName, userGroups, RangerPolicyEngine.ADMIN_ACCESS);
+ isAllowed = CollectionUtils.isNotEmpty(accessTypes) && policyAdmin.isDelegatedAdminAccessAllowed(resource, zoneName, userName, userGroups, accessTypes);
}
return isAllowed;