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 2021/10/06 04:31:57 UTC

[ranger] branch master updated: RANGER-3462: User with delegated admin permission on a resource cannot fetch policy for the resource

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 d90361d  RANGER-3462: User with delegated admin permission on a resource cannot fetch policy for the resource
d90361d is described below

commit d90361db662de1531eafa4d05853e7bc7e08c2a2
Author: Abhay Kulkarni <ab...@apache.org>
AuthorDate: Tue Oct 5 19:19:37 2021 -0700

    RANGER-3462: User with delegated admin permission on a resource cannot fetch policy for the resource
---
 .../org/apache/ranger/biz/RangerPolicyAdmin.java   |  7 +++-
 .../apache/ranger/biz/RangerPolicyAdminCache.java  |  2 +
 .../apache/ranger/biz/RangerPolicyAdminImpl.java   | 48 +++++++++++++++++++---
 .../java/org/apache/ranger/rest/ServiceREST.java   | 15 +++++--
 4 files changed, 63 insertions(+), 9 deletions(-)

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 e2a0884..f1ce602 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
@@ -27,6 +27,7 @@ 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.store.ServiceStore;
 import org.apache.ranger.plugin.util.GrantRevokeRequest;
 import org.apache.ranger.plugin.util.RangerRoles;
 
@@ -34,7 +35,9 @@ public interface RangerPolicyAdmin {
 
     boolean isDelegatedAdminAccessAllowed(RangerAccessResource resource, String zoneName, String user, Set<String> userGroups, Set<String> accessTypes);
 
-    boolean isDelegatedAdminAccessAllowed(RangerPolicy policy, String user, Set<String> userGroups, Set<String> roles, Map<String, Object> evalContext);
+    boolean isDelegatedAdminAccessAllowedForRead(RangerPolicy policy, String user, Set<String> userGroups, Set<String> roles, Map<String, Object> evalContext);
+
+    boolean isDelegatedAdminAccessAllowedForModify(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);
 
@@ -62,4 +65,6 @@ public interface RangerPolicyAdmin {
     // This API is used only by test-code
     List<RangerPolicy> getAllowedUnzonedPolicies(String user, Set<String> userGroups, String accessType);
 
+    void setServiceStore(ServiceStore svcStore);
+
 }
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java
index a6f0a1a..5a69231 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/RangerPolicyAdminCache.java
@@ -96,6 +96,8 @@ public class RangerPolicyAdminCache {
 		}
 		if (ret == null) {
 			LOG.error("Policy-engine is not built! Returning null policy-engine!");
+		} else {
+			ret.setServiceStore(svcStore);
 		}
 
 		return ret;
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 090384b..5311a54 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
@@ -42,6 +42,7 @@ 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.store.ServiceStore;
 import org.apache.ranger.plugin.util.GrantRevokeRequest;
 import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
@@ -70,6 +71,7 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
         @Override
         public Object get(Object key) { return RangerAbstractResourceMatcher.WILDCARD_ASTERISK; }
     };
+    private       ServiceDBStore               serviceDBStore;
 
     static {
         wildcardEvalContext.put(RangerAbstractResourceMatcher.WILDCARD_ASTERISK, RangerAbstractResourceMatcher.WILDCARD_ASTERISK);
@@ -104,6 +106,13 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
     }
 
     @Override
+    public void setServiceStore(ServiceStore svcStore) {
+        if (svcStore instanceof ServiceDBStore) {
+            this.serviceDBStore = (ServiceDBStore) svcStore;
+        }
+    }
+
+    @Override
     public boolean isDelegatedAdminAccessAllowed(RangerAccessResource resource, String zoneName, String user, Set<String> userGroups, Set<String> accessTypes) {
         if (LOG.isDebugEnabled()) {
             LOG.debug("==> RangerPolicyAdminImpl.isDelegatedAdminAccessAllowed(" + resource + ", " + zoneName + ", " + user + ", " + userGroups + ", " + accessTypes + ")");
@@ -161,9 +170,33 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
     }
 
     @Override
-    public boolean isDelegatedAdminAccessAllowed(RangerPolicy policy, String user, Set<String> userGroups, Set<String> roles, Map<String, Object> evalContext) {
+    public boolean isDelegatedAdminAccessAllowedForRead(RangerPolicy policy, String user, Set<String> userGroups, Set<String> roles, Map<String, Object> evalContext) {
+        return isDelegatedAdminAccessAllowed(policy, user, userGroups, roles, true, evalContext);
+    }
+
+    @Override
+    public boolean isDelegatedAdminAccessAllowedForModify(RangerPolicy policy, String user, Set<String> userGroups, Set<String> roles, Map<String, Object> evalContext) {
+        boolean ret = isDelegatedAdminAccessAllowed(policy, user, userGroups, roles, false, evalContext);
+        if (ret) {
+            // Get old policy from policy-engine
+            RangerPolicy oldPolicy = null;
+            if (policy.getId() != null) {
+                try {
+                    oldPolicy = serviceDBStore.getPolicy(policy.getId());
+                } catch (Exception e) {
+                    // Ignore
+                }
+            }
+            if (oldPolicy != null) {
+                ret = isDelegatedAdminAccessAllowed(oldPolicy, user, userGroups, roles, false, evalContext);
+            }
+        }
+        return ret;
+    }
+
+    boolean isDelegatedAdminAccessAllowed(RangerPolicy policy, String user, Set<String> userGroups, Set<String> roles, boolean isRead, Map<String, Object> evalContext) {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> RangerPolicyAdminImpl.isDelegatedAdminAccessAllowed(" + policy.getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + evalContext + ")");
+            LOG.debug("==> RangerPolicyAdminImpl.isDelegatedAdminAccessAllowed(" + policy.getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + isRead + ", " + evalContext + ")");
         }
 
         boolean          ret  = false;
@@ -200,14 +233,19 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
                         continue;
                     }
 
-                    accessTypes.removeAll(allowedAccesses);
+                    boolean isAllowedAccessesModified = accessTypes.removeAll(allowedAccesses);
+
+                    if (isRead && isAllowedAccessesModified) {
+                        ret = true;
+                        break;
+                    }
 
                     if (CollectionUtils.isEmpty(accessTypes)) {
                         ret = true;
                         break;
                     }
                 }
-                if (CollectionUtils.isNotEmpty(accessTypes)) {
+                if (!ret && CollectionUtils.isNotEmpty(accessTypes)) {
                     LOG.info("Accesses : " + accessTypes + " are not authorized for the policy:[" + policy.getId() + "] by any of delegated-admin policies");
                 }
 
@@ -218,7 +256,7 @@ public class RangerPolicyAdminImpl implements RangerPolicyAdmin {
         RangerPerfTracer.log(perf);
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerPolicyAdminImpl.isDelegatedAdminAccessAllowed(" + policy.getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + evalContext + "): " + ret);
+            LOG.debug("<== RangerPolicyAdminImpl.isDelegatedAdminAccessAllowed(" + policy.getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + isRead + ", " + 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 f1123d1..f0bf64e7 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
@@ -3520,7 +3520,7 @@ public class ServiceREST {
 						Set<String> roles = policyAdmin.getRolesFromUserAndGroups(userName, userGroups);
 
 						for (RangerPolicy policy : listToFilter) {
-							if ((policyAdmin.isDelegatedAdminAccessAllowed(policy, userName, userGroups, roles, evalContext))
+							if ((policyAdmin.isDelegatedAdminAccessAllowedForRead(policy, userName, userGroups, roles, evalContext))
 									|| (!StringUtils.isEmpty(policy.getZoneName()) && (serviceMgr.isZoneAdmin(policy.getZoneName()) || serviceMgr.isZoneAuditor(policy.getZoneName())))) {
 								ret.add(policy);
 							}
@@ -3619,7 +3619,7 @@ public class ServiceREST {
 
 			Set<String> roles = policyAdmin.getRolesFromUserAndGroups(userName, userGroups);
 
-			isAllowed = policyAdmin.isDelegatedAdminAccessAllowed(policy, userName, userGroups, roles, evalContext);
+			isAllowed = policyAdmin.isDelegatedAdminAccessAllowedForModify(policy, userName, userGroups, roles, evalContext);
 		}
 
 		return isAllowed;
@@ -3927,7 +3927,16 @@ public class ServiceREST {
 			boolean isAllowed = false;
 
 			Set<String> userGroups = userMgr.getGroupsForUser(userName);
-			isAllowed = hasAdminAccess(policy, userName, userGroups);
+			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.isDelegatedAdminAccessAllowedForRead(policy, userName, userGroups, roles, evalContext);
+			}
 
 			if (!isAllowed) {
 				throw restErrorUtil.createRESTException(HttpServletResponse.SC_UNAUTHORIZED, "User '"