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 f29d29b  RANGER-2876: allow-exception policy-items are not correctly 
handled when access-type is '_any'
f29d29b is described below

commit f29d29b8da7ac8d4afa0d10e504b146381307d6d
Author: Abhay Kulkarni <[email protected]>
AuthorDate: Mon Aug 10 21:04:50 2020 -0700

    RANGER-2876: allow-exception policy-items are not correctly handled when 
access-type is '_any'
---
 .../RangerDefaultPolicyEvaluator.java              | 105 ++++++++++++++++-----
 .../RangerDefaultPolicyItemEvaluator.java          |  45 +--------
 .../test_policyengine_descendant_tags.json         |   4 +-
 .../policyengine/test_policyengine_hive.json       |  26 +++++
 .../policyengine/test_policyengine_tag_hive.json   |  10 +-
 .../test_policyengine_tag_hive_filebased.json      |   4 +-
 6 files changed, 122 insertions(+), 72 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 d75bf46..24cb424 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
@@ -45,6 +45,7 @@ import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerAccessTypeDef;
 import org.apache.ranger.plugin.model.RangerValiditySchedule;
 import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
+import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
 import org.apache.ranger.plugin.policyengine.RangerAccessResult;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
@@ -685,44 +686,36 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                return ret;
        }
 
-       private Integer getAccessResultForAnyAccess(Map<String, 
PolicyACLSummary.AccessResult> accessses) {
-               Integer ret = null;
+       private Integer getAccessResultForAnyAccess(Map<String, 
PolicyACLSummary.AccessResult> accesses) {
+               final Integer ret;
 
                int allowedAccessCount = 0;
                int deniedAccessCount = 0;
-               int undeterminedAccessCount = 0;
-               int accessesSize = 0;
 
-               for (Map.Entry<String, PolicyACLSummary.AccessResult> entry : 
accessses.entrySet()) {
+               for (Map.Entry<String, PolicyACLSummary.AccessResult> entry : 
accesses.entrySet()) {
                        if (StringUtils.equals(entry.getKey(), 
RangerPolicyEngine.ADMIN_ACCESS)) {
-                               // Dont count admin access if present
+                               // Don't count admin access if present
                                continue;
                        }
                        PolicyACLSummary.AccessResult accessResult = 
entry.getValue();
                        if (accessResult.getResult() == 
RangerPolicyEvaluator.ACCESS_ALLOWED) {
                                allowedAccessCount++;
+                               break;
                        } else if (accessResult.getResult() == 
RangerPolicyEvaluator.ACCESS_DENIED) {
                                deniedAccessCount++;
-                       } else if (accessResult.getResult() == 
RangerPolicyEvaluator.ACCESS_UNDETERMINED && !accessResult.getHasSeenDeny()) {
-                           undeterminedAccessCount++;
                        }
-                       accessesSize++;
                }
 
-               int accessTypeCount = getServiceDef().getAccessTypes().size();
-
-               if (accessTypeCount == accessesSize) {
-                       // All permissions are represented
-                       if (deniedAccessCount > 0 || undeterminedAccessCount == 
accessTypeCount) {
-                               // at least one is denied or all are 
undetermined
-                               ret = RangerPolicyEvaluator.ACCESS_DENIED;
-                       }
-               }
-               if (ret == null) {
-                       if (allowedAccessCount > 0 || undeterminedAccessCount > 
0) {
-                               ret = RangerPolicyEvaluator.ACCESS_ALLOWED;
-                       }
+               if (allowedAccessCount > 0) {
+                       // At least one access allowed
+                       ret = RangerPolicyEvaluator.ACCESS_ALLOWED;
+               } else if (deniedAccessCount == 
getServiceDef().getAccessTypes().size()) {
+                       // All accesses explicitly denied
+                       ret = RangerPolicyEvaluator.ACCESS_DENIED;
+               } else {
+                       ret = null;
                }
+
                return ret;
        }
 
@@ -1102,11 +1095,8 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
 
                switch (policyType) {
                        case RangerPolicy.POLICY_TYPE_ACCESS: {
-                               ret = getMatchingPolicyItem(request, 
denyEvaluators, denyExceptionEvaluators);
+                               ret = 
getMatchingPolicyItemForAccessPolicy(request, result);
 
-                               if(ret == null && 
!result.getIsAccessDetermined()) { // a deny policy could have set 
isAllowed=true, but in such case it wouldn't set isAccessDetermined=true
-                                       ret = getMatchingPolicyItem(request, 
allowEvaluators, allowExceptionEvaluators);
-                               }
                                break;
                        }
                        case RangerPolicy.POLICY_TYPE_DATAMASK: {
@@ -1124,6 +1114,69 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                return ret;
        }
 
+       protected RangerPolicyItemEvaluator 
getMatchingPolicyItemForAccessPolicy(RangerAccessRequest request, 
RangerAccessResult result) {
+               RangerPolicyItemEvaluator ret = null;
+
+               if (request.isAccessTypeAny()) {
+                       RangerPolicyItemEvaluator denyingPolicyItemEvaluator = 
null;
+                       int                       deniedAccessesCount        = 
0;
+                       int                       accessDefsCount            = 
0;
+
+                       List<RangerAccessTypeDef> allAccessDefs = 
getServiceDef().getAccessTypes();
+
+                       for (RangerAccessTypeDef accessTypeDef : allAccessDefs) 
{
+                               RangerAccessRequestImpl newRequest = new 
RangerAccessRequestImpl();
+                               newRequest.setResource(request.getResource());
+                               newRequest.setUser(request.getUser());
+                               
newRequest.setUserGroups(request.getUserGroups());
+                               newRequest.setUserRoles(request.getUserRoles());
+                               
newRequest.setForwardedAddresses(request.getForwardedAddresses());
+                               
newRequest.setAccessTime(request.getAccessTime());
+                               
newRequest.setRemoteIPAddress(request.getRemoteIPAddress());
+                               
newRequest.setClientType(request.getClientType());
+                               newRequest.setAction(request.getAction());
+                               
newRequest.setRequestData(request.getRequestData());
+                               newRequest.setSessionId(request.getSessionId());
+                               newRequest.setContext(request.getContext());
+                               
newRequest.setClusterName(request.getClusterName());
+
+                               
newRequest.setAccessType(accessTypeDef.getName());
+
+                               ret = 
getMatchingPolicyItemForAccessPolicyForSpecificAccess(newRequest, result);
+
+                               if (ret != null) {
+                                       if (ret.getPolicyItemType() == 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_ALLOW) {
+                                               break;
+                                       } else if (ret.getPolicyItemType() == 
RangerPolicyItemEvaluator.POLICY_ITEM_TYPE_DENY) {
+                                               if (denyingPolicyItemEvaluator 
== null) {
+                                                       
denyingPolicyItemEvaluator = ret;
+                                               }
+                                               ret = null;
+                                               deniedAccessesCount++;
+                                       }
+                               }
+                               accessDefsCount++;
+                       }
+                       if (ret == null && denyingPolicyItemEvaluator != null 
&& deniedAccessesCount == accessDefsCount) {
+                               ret = denyingPolicyItemEvaluator;
+                       }
+               } else {
+                       ret = 
getMatchingPolicyItemForAccessPolicyForSpecificAccess(request, result);
+               }
+
+               return ret;
+       }
+
+       protected RangerPolicyItemEvaluator 
getMatchingPolicyItemForAccessPolicyForSpecificAccess(RangerAccessRequest 
request, RangerAccessResult result) {
+               RangerPolicyItemEvaluator ret = getMatchingPolicyItem(request, 
denyEvaluators, denyExceptionEvaluators);
+
+               if(ret == null && !result.getIsAccessDetermined()) { // a deny 
policy could have set isAllowed=true, but in such case it wouldn't set 
isAccessDetermined=true
+                       ret = getMatchingPolicyItem(request, allowEvaluators, 
allowExceptionEvaluators);
+               }
+
+               return ret;
+       }
+
        protected <T extends RangerPolicyItemEvaluator> T 
getMatchingPolicyItem(RangerAccessRequest request, List<T> evaluators) {
                T ret = getMatchingPolicyItem(request, evaluators, null);
 
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
index 90d96d9..8f2d3f1 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
@@ -19,7 +19,6 @@
 package org.apache.ranger.plugin.policyevaluator;
 
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -52,7 +51,6 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
 
        private boolean hasCurrentUser;
        private boolean hasResourceOwner;
-       private boolean hasAllPerms;
 
        public RangerDefaultPolicyItemEvaluator(RangerServiceDef serviceDef, 
RangerPolicy policy, RangerPolicyItem policyItem, int policyItemType, int 
policyItemIndex, RangerPolicyEngineOptions options) {
                super(serviceDef, policy, policyItem, policyItemType, 
policyItemIndex, options);
@@ -63,26 +61,6 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
                        LOG.debug("==> 
RangerDefaultPolicyItemEvaluator(policyId=" + policyId + ", policyItem=" + 
policyItem + ", serviceType=" + getServiceType() + ", conditionsDisabled=" + 
getConditionsDisabledOption() + ")");
                }
 
-               Set<String> accessPerms    = new HashSet<String>();
-
-               List<RangerPolicy.RangerPolicyItemAccess> policyItemAccesses = 
policyItem.getAccesses();
-               for(RangerPolicy.RangerPolicyItemAccess policyItemAccess : 
policyItemAccesses) {
-
-                       if (policyItemAccess.getIsAllowed()) {
-                               accessPerms.add(policyItemAccess.getType());
-                       }
-               }
-
-               hasAllPerms = true;
-               List<RangerServiceDef.RangerAccessTypeDef> serviceAccessTypes = 
serviceDef.getAccessTypes();
-               for (RangerServiceDef.RangerAccessTypeDef serviceAccessType : 
serviceAccessTypes) {
-                       String serviceAccessTypeName = 
serviceAccessType.getName();
-                       if (!accessPerms.contains(serviceAccessTypeName)) {
-                               hasAllPerms = false;
-                               break;
-                       }
-               }
-
                RangerCustomConditionEvaluator rangerCustomConditionEvaluator = 
new RangerCustomConditionEvaluator();
 
                conditionEvaluators = 
rangerCustomConditionEvaluator.getPolicyItemConditionEvaluator(policy,policyItem,serviceDef,options,policyItemIndex);
@@ -119,25 +97,10 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
                                } else if 
(CollectionUtils.isNotEmpty(policyItem.getAccesses())) {
                                        boolean isAccessTypeMatched = false;
 
-                                       if (request.isAccessTypeAny()) {
-                                               if (getPolicyItemType() == 
POLICY_ITEM_TYPE_DENY || getPolicyItemType() == 
POLICY_ITEM_TYPE_DENY_EXCEPTIONS) {
-                                                       if (hasAllPerms) {
-                                                               
isAccessTypeMatched = true;
-                                                       }
-                                               } else {
-                                                       for 
(RangerPolicy.RangerPolicyItemAccess access : policyItem.getAccesses()) {
-                                                               if 
(access.getIsAllowed()) {
-                                                                       
isAccessTypeMatched = true;
-                                                                       break;
-                                                               }
-                                                       }
-                                               }
-                                       } else {
-                                               for 
(RangerPolicy.RangerPolicyItemAccess access : policyItem.getAccesses()) {
-                                                       if 
(access.getIsAllowed() && StringUtils.equalsIgnoreCase(access.getType(), 
request.getAccessType())) {
-                                                               
isAccessTypeMatched = true;
-                                                               break;
-                                                       }
+                                       for 
(RangerPolicy.RangerPolicyItemAccess access : policyItem.getAccesses()) {
+                                               if (access.getIsAllowed() && 
StringUtils.equalsIgnoreCase(access.getType(), request.getAccessType())) {
+                                                       isAccessTypeMatched = 
true;
+                                                       break;
                                                }
                                        }
 
diff --git 
a/agents-common/src/test/resources/policyengine/test_policyengine_descendant_tags.json
 
b/agents-common/src/test/resources/policyengine/test_policyengine_descendant_tags.json
index a2ec460..934655b 100644
--- 
a/agents-common/src/test/resources/policyengine/test_policyengine_descendant_tags.json
+++ 
b/agents-common/src/test/resources/policyengine/test_policyengine_descendant_tags.json
@@ -156,7 +156,7 @@
       {"id":2,"name":"PII_TAG_POLICY","isEnabled":true,"isAuditEnabled":true,
         "resources":{"tag":{"values":["PII"],"isRecursive":false}},
         "policyItems":[
-          
{"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive", 
"user1"],"groups":[],"delegateAdmin":false}
+          {"accesses":[{"type":"hive:select","isAllowed":true}, 
{"type":"hive:update","isAllowed":true}],"users":["hive", 
"user1"],"groups":[],"delegateAdmin":false}
           ,
           
{"accesses":[{"type":"hive:all","isAllowed":true}],"users":["user2"],"groups":[],"delegateAdmin":false}
         ],
@@ -170,7 +170,7 @@
       
{"id":3,"name":"EXPIRES_ON_TAG_POLICY","isEnabled":true,"isAuditEnabled":true,
         "resources":{"tag":{"values":["EXPIRES_ON"],"isRecursive":false}},
         "policyItems":[
-          
{"accesses":[{"type":"hive:select","isAllowed":true}],"users":["user", 
"user1"],"groups":[],"delegateAdmin":false}
+          {"accesses":[{"type":"hive:select","isAllowed":true}, 
{"type":"hive:update","isAllowed":true}],"users":["user", 
"user1"],"groups":[],"delegateAdmin":false}
         ],
         "denyPolicyItems":[
           
{"accesses":[{"type":"hive:select","isAllowed":true}],"users":["user"],"groups":[],"delegateAdmin":false}
diff --git 
a/agents-common/src/test/resources/policyengine/test_policyengine_hive.json 
b/agents-common/src/test/resources/policyengine/test_policyengine_hive.json
index ba5a53c..52864a0 100644
--- a/agents-common/src/test/resources/policyengine/test_policyengine_hive.json
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_hive.json
@@ -99,10 +99,36 @@
       "policyItems":[
         
{"accesses":[{"type":"create","isAllowed":true}],"users":["user1","user2"],"groups":["group1","group2"],"delegateAdmin":false}
       ]
+    },
+    {"id":8,"name":"db=dummy; table=*; 
column=*","isEnabled":true,"isAuditEnabled":true,
+      
"resources":{"database":{"values":["dummy"]},"table":{"values":["*"]},"column":{"values":["*"]}},
+      "policyItems":[
+        
{"accesses":[{"type":"create","isAllowed":true},{"type":"update","isAllowed":true},{"type":"drop","isAllowed":true}],"users":["user1","user2"],"groups":[],"delegateAdmin":false}
+      ],
+      "allowExceptions":[
+        {"accesses":[{"type":"create","isAllowed":true}, 
{"type":"update","isAllowed":true}],"users":["user1"],"groups":[],"delegateAdmin":false},
+        {"accesses":[{"type":"create","isAllowed":true}, 
{"type":"update","isAllowed":true},{"type":"drop","isAllowed":true}],"users":["user2"],"groups":[],"delegateAdmin":false}
+      ]
     }
   ],
 
   "tests":[
+    {"name":"ALLOW 'any dummy/*/*;' for user1",
+      "request":{
+        "resource":{"elements":{"database":"dummy", "table": "dummy", 
"column": "dummy"}},
+        
"accessType":"","user":"user1","userGroups":["users"],"requestData":"any 
dummy/dummy/dummy for user1"
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":8}
+    }
+    ,
+    {"name":"DENY 'any dummy/*/*;' for user2",
+      "request":{
+        "resource":{"elements":{"database":"dummy", "table": "dummy", 
"column": "dummy"}},
+        
"accessType":"","user":"user2","userGroups":["users"],"requestData":"any 
dummy/dummy/dummy for user2"
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":-1}
+    }
+  ,
     {"name":"ALLOW 'read s3a://qe-s3-bucket-mst/demo;' for user1",
       "request":{
         "resource":{"elements":{"url":"s3a://qe-s3-bucket-mst/demo"}},
diff --git 
a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json 
b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
index 79417a0..a8ec027 100644
--- 
a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
+++ 
b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json
@@ -322,13 +322,21 @@
       },
       "result":{"isAudited":true,"isAllowed":false,"policyId":3}
     },
+    {"name":"DENY 'desc default.table1;' for testuser",
+      "request":{
+        "resource":{"elements":{"database":"default", "table":"table1"}},
+        "accessType":"","user":"testuser","userGroups":[],"requestData":"desc 
default.table1;' for testuser",
+        "context": {"TAGS":"[{\"type\":\"PII-FINAL\", 
\"attributes\":{\"expiry\":\"2026/06/15\"}}]"}
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":-1}
+    },
     {"name":"ALLOW 'use default;' for hive",
       "request":{
         "resource":{"elements":{"database":"default"}},
         "accessType":"","user":"hive","userGroups":[],"requestData":"use 
default",
         "context": {"TAGS":"[{\"type\":\"PII-FINAL\", 
\"attributes\":{\"expiry\":\"2026/06/15\"}}]"}
       },
-      "result":{"isAudited":true,"isAllowed":false,"policyId":3}
+      "result":{"isAudited":true,"isAllowed":true,"policyId":101}
     },
     {"name":"DENY 'use default;' for user1",
       "request":{
diff --git 
a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
 
b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
index 73fe540..21d936a 100644
--- 
a/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
+++ 
b/agents-common/src/test/resources/policyengine/test_policyengine_tag_hive_filebased.json
@@ -283,12 +283,12 @@
       },
       "result":{"isAudited":true,"isAllowed":true,"policyId":2}
     },
-    {"name":"DENY 'desc default.table1;' for hive using PII, PII-FINAL tags",
+    {"name":"ALLOW 'desc default.table1;' for hive using PII, PII-FINAL tags",
       "request":{
         "resource":{"elements":{"database":"default", "table":"table1"}},
         "accessType":"","user":"hive","userGroups":[],"requestData":"desc 
default.table1;' for hive"
       },
-      "result":{"isAudited":true,"isAllowed":false,"policyId":3}
+      "result":{"isAudited":true,"isAllowed":true,"policyId":101}
     },
     {"name":"DENY 'desc default.table2;' for user1 using PII-FINAL tag",
       "request":{

Reply via email to