You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2022/12/15 22:12:24 UTC

[ranger] branch master updated: RANGER-4014: fix for handling resource names having macros in masking/row-filtering policies

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

madhan 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 77303d0a2 RANGER-4014: fix for handling resource names having macros in masking/row-filtering policies
77303d0a2 is described below

commit 77303d0a293d7dc62c908e9d5cc9e8017b0d89cb
Author: Madhan Neethiraj <ma...@apache.org>
AuthorDate: Mon Dec 12 13:22:53 2022 -0800

    RANGER-4014: fix for handling resource names having macros in masking/row-filtering policies
---
 .../model/validation/RangerServiceDefHelper.java   | 43 +++++++++++++++++
 .../RangerAbstractPolicyEvaluator.java             |  2 +-
 .../RangerDefaultPolicyResourceMatcher.java        | 18 +++++++-
 .../policyengine/test_aclprovider_mask_filter.json | 54 ++++++++++++++++++++++
 4 files changed, 115 insertions(+), 2 deletions(-)

diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
index b4b2780a9..4e287f9a4 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
@@ -307,12 +307,17 @@ public class RangerServiceDefHelper {
 		return ret;
 	}
 
+	public RangerResourceDef getWildcardEnabledResourceDef(String resourceName, Integer policyType) {
+		return _delegate.getWildcardEnabledResourceDef(resourceName, policyType);
+	}
+
 	/**
 	 * Not designed for public access.  Package level only for testability.
 	 */
 	static class Delegate {
 		final RangerServiceDef _serviceDef;
 		final Map<Integer, Set<List<RangerResourceDef>>> _hierarchies = new HashMap<>();
+		final Map<Integer, Map<String, RangerResourceDef>> _wildcardEnabledResourceDefs = new HashMap<>();
 		final Date _serviceDefFreshnessDate;
 		final String _serviceName;
 		final boolean _checkForCycles;
@@ -429,6 +434,44 @@ public class RangerServiceDefHelper {
 			return graph;
 		}
 
+		RangerResourceDef getWildcardEnabledResourceDef(String resourceName, Integer policyType) {
+			if (policyType == null) {
+				policyType = RangerPolicy.POLICY_TYPE_ACCESS;
+			}
+
+			Map<String, RangerResourceDef> wResourceDefs = _wildcardEnabledResourceDefs.get(policyType);
+
+			if (wResourceDefs == null) {
+				wResourceDefs = new HashMap<>();
+
+				_wildcardEnabledResourceDefs.put(policyType, wResourceDefs);
+			}
+
+			RangerResourceDef ret = null;
+
+			if (!wResourceDefs.containsKey(resourceName)) {
+				List<RangerResourceDef> resourceDefs = getResourceDefs(_serviceDef, policyType);
+
+				if (resourceDefs != null) {
+					for (RangerResourceDef resourceDef : resourceDefs) {
+						if (StringUtils.equals(resourceName, resourceDef.getName())) {
+							ret = new RangerResourceDef(resourceDef);
+
+							ret.getMatcherOptions().put(RangerAbstractResourceMatcher.OPTION_WILD_CARD, Boolean.TRUE.toString());
+
+							break;
+						}
+					}
+				}
+
+				wResourceDefs.put(resourceName, ret);
+			} else {
+				ret = wResourceDefs.get(resourceName);
+			}
+
+			return ret;
+		}
+
 		List<RangerResourceDef> getResourceDefs(RangerServiceDef serviceDef, Integer policyType) {
 			final List<RangerResourceDef> resourceDefs;
 
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
index 159617b39..5650b9ea8 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyEvaluator.java
@@ -348,7 +348,7 @@ public abstract class RangerAbstractPolicyEvaluator implements RangerPolicyEvalu
 						if (resourceMatcher.getNeedsDynamicEval()) {
 							Map<String, RangerPolicyResource> updatedResource = getPolicyResourcesWithMacrosReplaced(resource, policyEngine);
 
-							ret = new RangerDefaultPolicyResourceMatcher();
+							ret = new RangerDefaultPolicyResourceMatcher(true);
 
 							ret.setPolicyResources(updatedResource, resourceMatcher.getPolicyType());
 							ret.setServiceDef(serviceDef);
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
index 78e2f1884..e887730c9 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
@@ -41,6 +41,8 @@ import org.apache.ranger.plugin.util.RangerPerfTracer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.apache.ranger.plugin.resourcematcher.RangerAbstractResourceMatcher.OPTION_WILD_CARD;
+
 public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceMatcher {
     private static final Logger LOG = LoggerFactory.getLogger(RangerDefaultPolicyResourceMatcher.class);
 
@@ -57,6 +59,16 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
     private boolean                             isInitialized = false;
     private RangerServiceDefHelper              serviceDefHelper;
 
+    private final boolean forceEnableWildcardMatch;
+
+    public RangerDefaultPolicyResourceMatcher() {
+        this.forceEnableWildcardMatch = false;
+    }
+
+    public RangerDefaultPolicyResourceMatcher(boolean forceEnableWildcardMatch) {
+        this.forceEnableWildcardMatch = forceEnableWildcardMatch;
+    }
+
     @Override
     public void setServiceDef(RangerServiceDef serviceDef) {
         if (isInitialized) {
@@ -760,7 +772,7 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
         return ret;
     }
 
-    private static RangerResourceMatcher createResourceMatcher(RangerResourceDef resourceDef, RangerPolicyResource resource) {
+    private RangerResourceMatcher createResourceMatcher(RangerResourceDef resourceDef, RangerPolicyResource resource) {
         if(LOG.isDebugEnabled()) {
             LOG.debug("==> RangerDefaultPolicyResourceMatcher.createResourceMatcher(" + resourceDef + ", " + resource + ")");
         }
@@ -787,6 +799,10 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
                 ret = new RangerDefaultResourceMatcher();
             }
 
+            if (forceEnableWildcardMatch && !Boolean.parseBoolean(resourceDef.getMatcherOptions().get(OPTION_WILD_CARD))) {
+                resourceDef = serviceDefHelper.getWildcardEnabledResourceDef(resourceDef.getName(), policyType);
+            }
+
             ret.setResourceDef(resourceDef);
             ret.setPolicyResource(resource);
             ret.init();
diff --git a/agents-common/src/test/resources/policyengine/test_aclprovider_mask_filter.json b/agents-common/src/test/resources/policyengine/test_aclprovider_mask_filter.json
index 6ff4886ce..c8f7acf5e 100644
--- a/agents-common/src/test/resources/policyengine/test_aclprovider_mask_filter.json
+++ b/agents-common/src/test/resources/policyengine/test_aclprovider_mask_filter.json
@@ -63,6 +63,18 @@
                 "label": "Shuffle",
                 "description": "Randomly shuffle the contents"
               },
+              {
+                "itemId": 3,
+                "name": "MASH_HASH",
+                "label": "Hash",
+                "description": "Hash value of the contents"
+              },
+              {
+                "itemId": 4,
+                "name": "MASH_NONE",
+                "label": "No masking",
+                "description": "Unmasked value of the contents"
+              },
               {
                 "itemId": 10,
                 "name": "NULL",
@@ -139,6 +151,20 @@
               }
             ]
           },
+          { "id": 104, "name": "db=test_db, table=dept_${{USER.dept}}, column=col1: unmasked for users in the department",
+            "isEnabled": true, "isAuditEnabled": true, "policyPriority": 1, "policyType": 1,
+            "resources": { "database": { "values": [ "test_db" ] }, "table": { "values": [ "dept_${{USER.dept}}" ] }, "column": { "values": [ "col1" ] } },
+            "dataMaskPolicyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true } ], "users": [ "{USER}" ], "groups": [], "delegateAdmin": false, "dataMaskInfo": { "dataMaskType": "MASK_NONE" } }
+            ]
+          },
+          { "id": 105, "name": "db=test_db, table=dept_hr, column=col1: mask hash for all users",
+            "isEnabled": true, "isAuditEnabled": true, "policyPriority": 0, "policyType": 1,
+            "resources": { "database": { "values": [ "test_db" ] }, "table": { "values": [ "dept_hr" ] }, "column": { "values": [ "col1" ] } },
+            "dataMaskPolicyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true } ], "users": [], "groups": [ "public" ], "delegateAdmin": false, "dataMaskInfo": { "dataMaskType": "MASK_HASH" } }
+            ]
+          },
           {"id":201,"name":"db=employee, table=personal: row-filter","isEnabled":true,"isAuditEnabled":true,"policyType":2,
             "resources":{"database":{"values":["employee"]},"table":{"values":["personal"]}},
             "rowFilterPolicyItems":[
@@ -175,6 +201,20 @@
                 "rowFilterInfo": {"filterExpr":"dept='purchase'"}
               }
             ]
+          },
+          { "id": 204, "name": "db=test_db, table=dept_${{USER.dept}}: no filter for users in the department",
+            "isEnabled": true, "isAuditEnabled": true, "policyPriority": 1, "policyType": 2,
+            "resources": { "database": { "values": [ "test_db" ] }, "table": { "values": [ "dept_${{USER.dept}}" ] } },
+            "rowFilterPolicyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true } ], "users": [ "{USER}" ], "groups": [], "delegateAdmin": false, "rowFilterInfo": { "filterExpr": "1 = 1" } }
+            ]
+          },
+          { "id": 205, "name": "db=test_db, table=dept_hr: row-filter",
+            "isEnabled": true, "isAuditEnabled": true, "policyPriority": 0, "policyType": 2,
+            "resources": { "database": { "values": [ "test_db" ] }, "table": { "values": [ "dept_hr" ] } },
+            "rowFilterPolicyItems": [
+              { "accesses": [ { "type": "select", "isAllowed": true } ], "users": [], "groups": [ "public" ], "delegateAdmin": false, "rowFilterInfo": { "filterExpr": "dept != 'hr'" } }
+            ]
           }
         ],
         "tagPolicies": {
@@ -331,6 +371,13 @@
             {"users":["user2"], "groups":[], "roles":[], "accessTypes":["select"], "maskInfo":{"dataMaskType":"HASH"}, "isConditional": true}
           ]
         },
+        { "name": "mask: test_db.dept_hr.col1: conditional",
+          "resource": { "elements": { "database": "test_db", "table":"dept_hr", "column":"col1" } },
+          "dataMasks": [
+            { "users": [ ], "groups": [ "public" ], "roles": [], "accessTypes": [ "select" ], "maskInfo": { "dataMaskType": "MASK_NONE" }, "isConditional": true },
+            { "users": [ ], "groups": [ "public" ], "roles": [], "accessTypes": [ "select" ], "maskInfo": { "dataMaskType": "MASK_HASH" }, "isConditional": false }
+          ]
+        },
         {"name":"row-filter: employee.personal",
           "resource":{"elements":{"database":"employee", "table":"personal"}},
           "rowFilters":[
@@ -352,6 +399,13 @@
             {"users":["user1"], "groups":[], "roles":[], "accessTypes":["select"], "filterInfo":{"filterExpr":"dept='production'"}, "isConditional": true},
             {"users":["user2"], "groups":[], "roles":[], "accessTypes":["select"], "filterInfo":{"filterExpr":"dept='purchase'"}, "isConditional": true}
           ]
+        },
+        { "name": "row-filter: test_db.dept_hr: conditional",
+          "resource": { "elements": { "database": "test_db", "table":"dept_hr" } },
+          "rowFilters": [
+            { "users": [], "groups": [ "public" ], "roles": [], "accessTypes": [ "select" ], "filterInfo": { "filterExpr": "1 = 1" },        "isConditional": true },
+            { "users": [], "groups": [ "public" ], "roles": [], "accessTypes": [ "select" ], "filterInfo": { "filterExpr": "dept != 'hr'" }, "isConditional": false }
+          ]
         }
       ]
     }