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 2017/02/23 22:25:19 UTC

ranger git commit: RANGER-1383: Use resource matchers for filtering service policies

Repository: ranger
Updated Branches:
  refs/heads/master 390b97a5a -> 9aa7262d3


RANGER-1383: Use resource matchers for filtering service policies


Project: http://git-wip-us.apache.org/repos/asf/ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/ranger/commit/9aa7262d
Tree: http://git-wip-us.apache.org/repos/asf/ranger/tree/9aa7262d
Diff: http://git-wip-us.apache.org/repos/asf/ranger/diff/9aa7262d

Branch: refs/heads/master
Commit: 9aa7262d3fcfb8425823a996eb32cc6fbc062ab5
Parents: 390b97a
Author: Abhay Kulkarni <ak...@hortonworks.com>
Authored: Thu Feb 23 14:25:04 2017 -0800
Committer: Abhay Kulkarni <ak...@hortonworks.com>
Committed: Thu Feb 23 14:25:04 2017 -0800

----------------------------------------------------------------------
 .../validation/RangerServiceDefHelper.java      |  85 +++++
 .../RangerDefaultPolicyResourceMatcher.java     | 125 ++++++--
 .../RangerPolicyResourceMatcher.java            |   2 +
 .../RangerPathResourceMatcher.java              |   4 +-
 .../plugin/store/AbstractPredicateUtil.java     |   6 +
 .../apache/ranger/plugin/util/SearchFilter.java |   3 +-
 ...stDefaultPolicyResourceMatcherForPolicy.java | 162 ++++++++++
 ...ltpolicyresourcematcher_for_hdfs_policy.json | 160 ++++++++++
 ...defaultpolicyresourcematcher_for_policy.json | 315 +++++++++++++++++++
 .../org/apache/ranger/biz/ServiceDBStore.java   | 158 ++++++++++
 .../apache/ranger/common/RangerSearchUtil.java  |   3 +-
 11 files changed, 990 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ranger/blob/9aa7262d/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
----------------------------------------------------------------------
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 3cdf40b..159ee1a 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
@@ -20,6 +20,7 @@
 package org.apache.ranger.plugin.model.validation;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
@@ -39,6 +40,8 @@ import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
 
 import com.google.common.collect.Lists;
+import org.apache.ranger.plugin.resourcematcher.RangerAbstractResourceMatcher;
+import org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher;
 
 public class RangerServiceDefHelper {
 	private static final Log LOG = LogFactory.getLog(RangerServiceDefHelper.class);
@@ -46,6 +49,75 @@ public class RangerServiceDefHelper {
 	static final Map<String, Delegate> _Cache = new ConcurrentHashMap<>();
 	final Delegate _delegate;
 
+	static public RangerServiceDef getServiceDefForPolicyFiltering(RangerServiceDef serviceDef) {
+
+		List<RangerResourceDef> modifiedResourceDefs = new ArrayList<RangerResourceDef>();
+
+		for (RangerResourceDef resourceDef : serviceDef.getResources()) {
+
+			final RangerResourceDef modifiedResourceDef;
+
+			String matcherClassName = resourceDef.getMatcher();
+
+			if (RangerPathResourceMatcher.class.getName().equals(matcherClassName)) {
+
+				Map<String, String> modifiedMatcherOptions = new HashMap<String, String>(resourceDef.getMatcherOptions());
+
+				modifiedMatcherOptions.put(RangerAbstractResourceMatcher.OPTION_WILD_CARD, "false");
+
+				modifiedResourceDef = new RangerResourceDef(resourceDef);
+				modifiedResourceDef.setMatcherOptions(modifiedMatcherOptions);
+				modifiedResourceDef.setRecursiveSupported(false);
+
+			} else {
+				modifiedResourceDef = resourceDef;
+			}
+
+			modifiedResourceDefs.add(modifiedResourceDef);
+		}
+
+		return new RangerServiceDef(serviceDef.getName(), serviceDef.getImplClass(), serviceDef.getLabel(),
+				serviceDef.getDescription(), serviceDef.getOptions(), serviceDef.getConfigs(), modifiedResourceDefs, serviceDef.getAccessTypes(),
+				serviceDef.getPolicyConditions(), serviceDef.getContextEnrichers(), serviceDef.getEnums());
+	}
+
+	public static Map<String, String> getFilterResourcesForAncestorPolicyFiltering(RangerServiceDef serviceDef, Map<String, String> filterResources) {
+
+		Map<String, String> ret = null;
+
+		for (RangerResourceDef resourceDef : serviceDef.getResources()) {
+
+			String matcherClassName = resourceDef.getMatcher();
+
+			if (RangerPathResourceMatcher.class.getName().equals(matcherClassName)) {
+
+				String resourceDefName = resourceDef.getName();
+
+				final Map<String, String> resourceMatcherOptions = resourceDef.getMatcherOptions();
+
+				String delimiter = resourceMatcherOptions.get(RangerPathResourceMatcher.OPTION_PATH_SEPARATOR);
+				if (StringUtils.isBlank(delimiter)) {
+					delimiter = Character.toString(RangerPathResourceMatcher.DEFAULT_PATH_SEPARATOR_CHAR);
+				}
+
+				String resourceValue = filterResources.get(resourceDefName);
+				if (StringUtils.isNotBlank(resourceValue)) {
+					if (!resourceValue.endsWith(delimiter)) {
+						resourceValue += delimiter;
+					}
+					resourceValue += RangerAbstractResourceMatcher.WILDCARD_ASTERISK;
+
+					if (ret == null) {
+						ret = new HashMap<String, String>();
+					}
+					ret.put(resourceDefName, resourceValue);
+				}
+			}
+		}
+
+		return ret;
+	}
+
 	public RangerServiceDefHelper(RangerServiceDef serviceDef) {
 		this(serviceDef, true);
 	}
@@ -102,6 +174,19 @@ public class RangerServiceDefHelper {
 		return _delegate.getResourceHierarchies(policyType);
 	}
 
+	public Set<List<RangerResourceDef>> getResourceHierarchies(Integer policyType, Collection<String> keys) {
+
+		Set<List<RangerResourceDef>> ret = new HashSet<List<RangerResourceDef>>();
+
+		for (List<RangerResourceDef> hierarchy : getResourceHierarchies(policyType)) {
+			if (getAllResourceNames(hierarchy).containsAll(keys)) {
+				ret.add(hierarchy);
+			}
+		}
+
+		return ret;
+	}
+
 	public Set<String> getMandatoryResourceNames(List<RangerResourceDef> hierarchy) {
 		Set<String> result = new HashSet<String>(hierarchy.size());
 		for (RangerResourceDef resourceDef : hierarchy) {

http://git-wip-us.apache.org/repos/asf/ranger/blob/9aa7262d/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerDefaultPolicyResourceMatcher.java
----------------------------------------------------------------------
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 fa2b940..5bb7c75 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
@@ -26,6 +26,7 @@ import java.util.Set;
 import java.util.List;
 
 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;
@@ -35,6 +36,7 @@ import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
 import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
+import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
 import org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher;
 import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher;
 
@@ -353,40 +355,71 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 	}
 
 	@Override
+	public boolean isMatch(RangerPolicy policy, MatchScope scope, Map<String, Object> evalContext) {
+
+		boolean ret = false;
+		MatchType matchType = MatchType.NONE;
+
+		Map<String, RangerPolicyResource> resources = policy.getResources();
+
+		if (MapUtils.isNotEmpty(resources)) {
+
+			RangerAccessResourceImpl accessResource = new RangerAccessResourceImpl();
+			accessResource.setServiceDef(serviceDef);
+
+			// Build up accessResource resourceDef by resourceDef.
+			// For each resourceDef,
+			// 		examine policy-values one by one.
+			// 		The first value that is acceptable, that is,
+			// 			value matches in any way, is used for that resourceDef, and
+			//			next resourceDef is processed.
+			// 		If none of the values matches, the policy as a whole definitely will not match,
+			//		therefore, the match is failed
+			// After all resourceDefs are processed, and some match is achieved at every
+			// level, the final matchType (which is for the entire policy) is checked against
+			// requested scope to determine the match-result.
+
+			// Unit tests in TestDefaultPolicyResourceForPolicy.java, test_defaultpolicyresourcematcher_for_policy.json,
+			// and test_defaultpolicyresourcematcher_for_hdfs_policy.json
+
+			for (RangerResourceDef resourceDef : firstValidResourceDefHierarchy) {
+
+				ret = false;
+				matchType = MatchType.NONE;
+
+				String name = resourceDef.getName();
+				RangerPolicyResource policyResource = resources.get(name);
+
+				if (policyResource != null) {
+					for (String value : policyResource.getValues()) {
+
+						accessResource.setValue(name, value);
+
+						matchType = getMatchType(accessResource, evalContext);
+
+						if (matchType != MatchType.NONE) { // One value for this resourceDef matched
+							ret = true;
+							break;
+						}
+					}
+				}
+
+				if (!ret) { // None of the values specified for this resourceDef matched, no point in continuing with next resourceDef
+					break;
+				}
+			}
+			ret = ret && isMatch(scope, matchType);
+		}
+		return ret;
+	}
+
+	@Override
 	public boolean isMatch(RangerAccessResource resource, MatchScope scope, Map<String, Object> evalContext) {
 
 		final boolean ret;
 
 		MatchType matchType = getMatchType(resource, evalContext);
-		switch(scope) {
-			case SELF_OR_ANCESTOR_OR_DESCENDANT: {
-				ret = matchType != MatchType.NONE;
-				break;
-			}
-			case SELF: {
-				ret = matchType == MatchType.SELF;
-				break;
-			}
-			case SELF_OR_DESCENDANT: {
-				ret = matchType == MatchType.SELF || matchType == MatchType.DESCENDANT;
-				break;
-			}
-			case SELF_OR_ANCESTOR: {
-				ret = matchType == MatchType.SELF || matchType == MatchType.ANCESTOR;
-				break;
-			}
-			case DESCENDANT: {
-				ret = matchType == MatchType.DESCENDANT;
-				break;
-			}
-			case ANCESTOR: {
-				ret = matchType == MatchType.ANCESTOR;
-				break;
-			}
-			default:
-				ret = matchType != MatchType.NONE;
-				break;
-		}
+		ret = isMatch(scope, matchType);
 
 		return ret;
 	}
@@ -549,6 +582,40 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
 		return ret;
 	}
 
+	private boolean isMatch(final MatchScope scope, final MatchType matchType) {
+		final boolean ret;
+		switch (scope) {
+			case SELF_OR_ANCESTOR_OR_DESCENDANT: {
+				ret = matchType != MatchType.NONE;
+				break;
+			}
+			case SELF: {
+				ret = matchType == MatchType.SELF;
+				break;
+			}
+			case SELF_OR_DESCENDANT: {
+				ret = matchType == MatchType.SELF || matchType == MatchType.DESCENDANT;
+				break;
+			}
+			case SELF_OR_ANCESTOR: {
+				ret = matchType == MatchType.SELF || matchType == MatchType.ANCESTOR;
+				break;
+			}
+			case DESCENDANT: {
+				ret = matchType == MatchType.DESCENDANT;
+				break;
+			}
+			case ANCESTOR: {
+				ret = matchType == MatchType.ANCESTOR;
+				break;
+			}
+			default:
+				ret = matchType != MatchType.NONE;
+				break;
+		}
+		return ret;
+	}
+
 	@Override
 	public String toString() {
 		StringBuilder sb = new StringBuilder();

http://git-wip-us.apache.org/repos/asf/ranger/blob/9aa7262d/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
index 8a784b4..b4dc2c5 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyresourcematcher/RangerPolicyResourceMatcher.java
@@ -49,6 +49,8 @@ public interface RangerPolicyResourceMatcher {
 
 	boolean isMatch(RangerAccessResource resource, MatchScope scope, Map<String, Object> evalContext);
 
+	boolean isMatch(RangerPolicy policy, MatchScope scope, Map<String, Object> evalContext);
+
 	MatchType getMatchType(RangerAccessResource resource, Map<String, Object> evalContext);
 
 	boolean isCompleteMatch(RangerAccessResource resource, Map<String, Object> evalContext);

http://git-wip-us.apache.org/repos/asf/ranger/blob/9aa7262d/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java
index 300c1f8..0a66994 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.java
@@ -37,8 +37,8 @@ import java.util.Map;
 public class RangerPathResourceMatcher extends RangerDefaultResourceMatcher {
 	private static final Log LOG = LogFactory.getLog(RangerPathResourceMatcher.class);
 
-	private static final String OPTION_PATH_SEPARATOR       = "pathSeparatorChar";
-	private static final char   DEFAULT_PATH_SEPARATOR_CHAR = org.apache.hadoop.fs.Path.SEPARATOR_CHAR;
+	public static final String OPTION_PATH_SEPARATOR       = "pathSeparatorChar";
+	public static final char   DEFAULT_PATH_SEPARATOR_CHAR = org.apache.hadoop.fs.Path.SEPARATOR_CHAR;
 
 	private boolean policyIsRecursive;
 	private char    pathSeparatorChar = '/';

http://git-wip-us.apache.org/repos/asf/ranger/blob/9aa7262d/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
index 36a9a27..7583864 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/AbstractPredicateUtil.java
@@ -467,6 +467,9 @@ public class AbstractPredicateUtil {
 								break;
 							}
 						}
+						if (ret) {
+							break;
+						}
 					}
 				} else {
 					ret = true;
@@ -519,6 +522,9 @@ public class AbstractPredicateUtil {
 								break;
 							}
 						}
+						if (ret) {
+							break;
+						}
 					}
 				} else {
 					ret = true;

http://git-wip-us.apache.org/repos/asf/ranger/blob/9aa7262d/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
index 8f6426c..fa4f767 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/SearchFilter.java
@@ -41,6 +41,7 @@ public class SearchFilter {
 	public static final String USER            = "user";          // search
 	public static final String GROUP           = "group";         // search
 	public static final String RESOURCE_PREFIX = "resource:";     // search
+	public static final String RESOURCE_MATCH_SCOPE = "resourceMatchScope"; // search - valid values: "self", "ancestor", "self_or_ancestor"
 	public static final String POL_RESOURCE    = "polResource";   // search
 	public static final String POLICY_NAME_PARTIAL = "policyNamePartial";    // search, sort
 	public static final String CREATE_TIME     = "createTime";    // sort
@@ -49,7 +50,7 @@ public class SearchFilter {
 	public static final String PAGE_SIZE       = "pageSize";
 	public static final String SORT_BY         = "sortBy";
 	public static final String RESOURCE_SIGNATURE = "resourceSignature:";     // search
-	public static final String POLICY_TYPE = "policyType"; // search
+	public static final String POLICY_TYPE     = "policyType";    // search
     public static final String GUID		   = "guid"; //search
 
 	public static final String TAG_DEF_ID                = "tagDefId";            // search

http://git-wip-us.apache.org/repos/asf/ranger/blob/9aa7262d/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/TestDefaultPolicyResourceMatcherForPolicy.java
----------------------------------------------------------------------
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/TestDefaultPolicyResourceMatcherForPolicy.java b/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/TestDefaultPolicyResourceMatcherForPolicy.java
new file mode 100644
index 0000000..f4d76ad
--- /dev/null
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/resourcematcher/TestDefaultPolicyResourceMatcherForPolicy.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.plugin.resourcematcher;
+
+import static org.junit.Assert.*;
+
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParseException;
+import org.apache.commons.lang.StringUtils;
+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.policyengine.RangerAccessResourceImpl;
+import org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
+import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class TestDefaultPolicyResourceMatcherForPolicy {
+	static Gson gsonBuilder;
+
+	@BeforeClass
+	public static void setUpBeforeClass() throws Exception {
+		gsonBuilder = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSS-Z")
+				.setPrettyPrinting()
+				.registerTypeAdapter(RangerAccessResource.class, new TestDefaultPolicyResourceMatcherForPolicy.RangerResourceDeserializer())
+				.create();
+	}
+
+	@AfterClass
+	public static void tearDownAfterClass() throws Exception {
+	}
+
+	@Before
+	public void setUp() throws Exception {
+	}
+
+	@After
+	public void tearDown() throws Exception {
+	}
+
+	@Test
+	public void testDefaultPolicyResourceMatcherForPolicy() throws Exception {
+		String[] tests = { "/resourcematcher/test_defaultpolicyresourcematcher_for_policy.json",
+				"/resourcematcher/test_defaultpolicyresourcematcher_for_hdfs_policy.json"};
+
+		runTestsFromResourceFiles(tests);
+	}
+
+	private void runTestsFromResourceFiles(String[] resourceNames) throws Exception {
+		for(String resourceName : resourceNames) {
+			InputStream       inStream = this.getClass().getResourceAsStream(resourceName);
+			InputStreamReader reader   = new InputStreamReader(inStream);
+
+			runTests(reader);
+		}
+	}
+
+	private void runTests(InputStreamReader reader) throws Exception {
+		DefaultPolicyResourceMatcherTestCases testCases = gsonBuilder.fromJson(reader, DefaultPolicyResourceMatcherTestCases.class);
+
+		for (DefaultPolicyResourceMatcherTestCases.TestCase testCase : testCases.testCases) {
+			runTest(testCase, testCases.serviceDef);
+		}
+	}
+		private void runTest(DefaultPolicyResourceMatcherTestCases.TestCase testCase, RangerServiceDef serviceDef) throws Exception {
+
+		assertTrue("invalid input: " , testCase != null && testCase.tests != null);
+
+		RangerDefaultPolicyResourceMatcher matcher = new RangerDefaultPolicyResourceMatcher();
+		matcher.setServiceDef(serviceDef);
+		matcher.setPolicyResources(testCase.policyResources);
+		matcher.init();
+
+		for(DefaultPolicyResourceMatcherTestCases.TestCase.OneTest oneTest : testCase.tests) {
+			if(oneTest == null) {
+				continue;
+			}
+
+			boolean expected = oneTest.result;
+			RangerPolicyResourceMatcher.MatchScope scope;
+			if (StringUtils.equalsIgnoreCase(oneTest.type, "selfOrDescendantMatch")) {
+				scope = RangerPolicyResourceMatcher.MatchScope.SELF_OR_DESCENDANT;
+			} else if (StringUtils.equalsIgnoreCase(oneTest.type, "descendantMatch")) {
+				scope = RangerPolicyResourceMatcher.MatchScope.DESCENDANT;
+			} else if (StringUtils.equalsIgnoreCase(oneTest.type, "exactMatch")) {
+				scope = RangerPolicyResourceMatcher.MatchScope.SELF;
+			} else if (StringUtils.equalsIgnoreCase(oneTest.type, "selfOrAncestorMatch")) {
+				scope = RangerPolicyResourceMatcher.MatchScope.SELF_OR_ANCESTOR;
+			} else if (StringUtils.equalsIgnoreCase(oneTest.type, "ancestorMatch")) {
+				scope = RangerPolicyResourceMatcher.MatchScope.ANCESTOR;
+			} else if (StringUtils.equalsIgnoreCase(oneTest.type, "anyMatch")) {
+				scope = RangerPolicyResourceMatcher.MatchScope.SELF_OR_ANCESTOR_OR_DESCENDANT;
+			} else {
+				continue;
+			}
+			boolean result = matcher.isMatch(oneTest.policy, scope, oneTest.evalContext);
+
+			assertEquals("match failed! " + ":" + testCase.name + ":" + oneTest.name + ":" + oneTest.type + ": policy=" + oneTest.policy, expected, result);
+		}
+	}
+
+	private static class DefaultPolicyResourceMatcherTestCases {
+		RangerServiceDef serviceDef;
+
+		List<TestCase> testCases;
+
+		class TestCase {
+			public String name;
+			Map<String, RangerPolicyResource> policyResources;
+			public List<OneTest> tests;
+
+			class OneTest {
+				String name;
+				String type;
+				RangerPolicy policy;
+				Map<String, Object> evalContext;
+				boolean result;
+			}
+		}
+	}
+
+	private static class RangerResourceDeserializer implements JsonDeserializer<RangerAccessResource> {
+		@Override
+		public RangerAccessResource deserialize(JsonElement jsonObj, Type type,
+												JsonDeserializationContext context) throws JsonParseException {
+			return gsonBuilder.fromJson(jsonObj, RangerAccessResourceImpl.class);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/ranger/blob/9aa7262d/agents-common/src/test/resources/resourcematcher/test_defaultpolicyresourcematcher_for_hdfs_policy.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/resourcematcher/test_defaultpolicyresourcematcher_for_hdfs_policy.json b/agents-common/src/test/resources/resourcematcher/test_defaultpolicyresourcematcher_for_hdfs_policy.json
new file mode 100644
index 0000000..b779090
--- /dev/null
+++ b/agents-common/src/test/resources/resourcematcher/test_defaultpolicyresourcematcher_for_hdfs_policy.json
@@ -0,0 +1,160 @@
+{
+  "serviceDef": {
+    "id":1,
+    "name": "hdfs",
+    "resources":
+    [
+      {
+        "itemId": 1,
+        "name": "path",
+        "type": "path",
+        "level": 10,
+        "parent": "",
+        "mandatory": true,
+        "lookupSupported": true,
+        "recursiveSupported": true,
+        "excludesSupported": false,
+        "matcher": "org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher",
+        "matcherOptions": { "wildCard":true, "ignoreCase":false },
+        "validationRegEx":"",
+        "validationMessage": "",
+        "uiHint":"",
+        "label": "Resource Path",
+        "description": "HDFS file or directory path"
+      }
+    ],
+
+    "accessTypes":
+    [
+      {
+        "itemId": 1,
+        "name": "read",
+        "label": "Read"
+      },
+
+      {
+        "itemId": 2,
+        "name": "write",
+        "label": "Write"
+      },
+
+      {
+        "itemId": 3,
+        "name": "execute",
+        "label": "Execute"
+      }
+    ]
+  },
+  "testCases": [
+    {
+      "name": "path=/finance/tax/refund",
+      "policyResources": {
+        "path": {
+          "values": [
+            "/finance/tax/refund"
+          ]
+        }
+      },
+      "tests": [
+        {
+          "name": "Exact match for 'path=/finance/tax/refund' policy",
+          "type": "exactMatch",
+          "policy": {
+            "service": "any",
+            "name": "test",
+            "policyType": 0,
+            "description": "",
+            "resourceSignature": "",
+            "isAuditEnabled": true,
+            "resources": {
+              "path": {
+                "values": [
+                  "/finance/tax/refund"
+                ],
+                "isExcludes": false,
+                "isRecursive": true
+              }
+            },
+            "policyItems": [],
+            "denyPolicyItems": [],
+            "allowExceptions": [],
+            "denyExceptions": [],
+            "dataMaskPolicyItems": [],
+            "rowFilterPolicyItems": []
+          },
+          "evalContext": {},
+          "result": true
+        }
+      ]
+    },
+    { "name": "path=/finance/tax/*",
+      "policyResources": {
+        "path": {
+          "values": [
+            "/finance/tax/*"
+          ]
+        }
+      },
+      "tests": [
+        {
+          "name": "Self or Ancestor match for 'path=/finance/tax/refund' policy",
+          "type": "selfOrAncestorMatch",
+          "policy" : {
+            "service" : "any",
+            "name" : "test",
+            "policyType":0,
+            "description":"",
+            "resourceSignature":"",
+            "isAuditEnabled":true,
+            "resources" : {
+              "path": {"values": ["/finance/tax/refund"], "isExcludes": false, "isRecursive": true}
+            },
+            "policyItems":[],
+            "denyPolicyItems":[],
+            "allowExceptions":[],
+            "denyExceptions":[],
+            "dataMaskPolicyItems":[],
+            "rowFilterPolicyItems":[]
+          },
+          "evalContext": {},
+          "result" : true
+        }
+      ]
+    }
+    ,
+    { "name": "path=/finance*",
+      "policyResources": {
+        "path": {
+          "values": [
+            "/finance*"
+          ]
+        }
+      },
+      "tests": [
+        {
+          "name": "No match for 'path=/finance/tax/refund' policy",
+          "type": "anyMatch",
+          "policy" : {
+            "service" : "any",
+            "name" : "test",
+            "policyType":0,
+            "description":"",
+            "resourceSignature":"",
+            "isAuditEnabled":true,
+            "resources" : {
+              "path": {"values": ["/finance/tax/refund"], "isExcludes": false, "isRecursive": true}
+            },
+            "policyItems":[],
+            "denyPolicyItems":[],
+            "allowExceptions":[],
+            "denyExceptions":[],
+            "dataMaskPolicyItems":[],
+            "rowFilterPolicyItems":[]
+          },
+          "evalContext": {},
+          "result" : true
+        }
+      ]
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/ranger/blob/9aa7262d/agents-common/src/test/resources/resourcematcher/test_defaultpolicyresourcematcher_for_policy.json
----------------------------------------------------------------------
diff --git a/agents-common/src/test/resources/resourcematcher/test_defaultpolicyresourcematcher_for_policy.json b/agents-common/src/test/resources/resourcematcher/test_defaultpolicyresourcematcher_for_policy.json
new file mode 100644
index 0000000..489cc13
--- /dev/null
+++ b/agents-common/src/test/resources/resourcematcher/test_defaultpolicyresourcematcher_for_policy.json
@@ -0,0 +1,315 @@
+{
+  "serviceDef": {
+    "name": "hive",
+    "id": 3,
+    "resources": [
+      {
+        "name": "database",
+        "level": 1,
+        "mandatory": true,
+        "lookupSupported": true,
+        "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+        "matcherOptions": {
+          "wildCard": true,
+          "ignoreCase": true
+        },
+        "label": "Hive Database",
+        "description": "Hive Database"
+      },
+      {
+        "name": "table",
+        "level": 2,
+        "parent": "database",
+        "mandatory": true,
+        "lookupSupported": true,
+        "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+        "matcherOptions": {
+          "wildCard": true,
+          "ignoreCase": true
+        },
+        "label": "Hive Table",
+        "description": "Hive Table"
+      },
+      {
+        "name": "udf",
+        "level": 2,
+        "parent": "database",
+        "mandatory": true,
+        "lookupSupported": true,
+        "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+        "matcherOptions": {
+          "wildCard": true,
+          "ignoreCase": true
+        },
+        "label": "Hive UDF",
+        "description": "Hive UDF"
+      },
+      {
+        "name": "column",
+        "level": 3,
+        "parent": "table",
+        "mandatory": true,
+        "lookupSupported": true,
+        "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+        "matcherOptions": {
+          "wildCard": true,
+          "ignoreCase": true
+        },
+        "label": "Hive Column",
+        "description": "Hive Column"
+      }
+    ],
+    "accessTypes": [
+      {
+        "name": "select",
+        "label": "Select"
+      },
+      {
+        "name": "update",
+        "label": "Update"
+      },
+      {
+        "name": "create",
+        "label": "Create"
+      },
+      {
+        "name": "drop",
+        "label": "Drop"
+      },
+      {
+        "name": "alter",
+        "label": "Alter"
+      },
+      {
+        "name": "index",
+        "label": "Index"
+      },
+      {
+        "name": "lock",
+        "label": "Lock"
+      },
+      {
+        "name": "all",
+        "label": "All"
+      }
+    ]
+  },
+  "testCases": [
+    {
+      "name": "database=*:table=*:column:demo",
+      "policyResources": {
+        "database": {"values": ["*"]},
+        "table": {"values": ["*"]},
+        "column":{"values":["demo"]}
+      },
+      "tests": [
+        {
+          "name": "Exact match for 'tmp:*:demo' policy",
+          "type": "exactMatch",
+          "policy" : {
+            "service" : "any",
+            "name" : "test",
+            "policyType":0,
+            "description":"",
+            "resourceSignature":"",
+            "isAuditEnabled":true,
+            "resources" : {
+              "database": {"values": ["tmp"], "isExcludes": false, "isRecursive": false},
+              "table": {"values": ["*"], "isExcludes": false, "isRecursive": false},
+              "column": {"values": ["demo"], "isExcludes": false, "isRecursive": false}
+            },
+            "policyItems":[],
+            "denyPolicyItems":[],
+            "allowExceptions":[],
+            "denyExceptions":[],
+            "dataMaskPolicyItems":[],
+            "rowFilterPolicyItems":[]
+          },
+          "evalContext": {},
+          "result" : true
+        }
+      ]
+    },
+    {
+      "name": "database=finance:table=tax:column:refund",
+      "policyResources": {
+        "database": {"values": ["finance"]},
+        "table": {"values": ["tax"]},
+        "column":{"values":["refund"]}
+      },
+      "tests": [
+        {
+          "name": "Exact match for 'finance,hr,tmp*:tax,employee,tmp*:refund,salary,tmp*' policy",
+          "type": "exactMatch",
+          "policy" : {
+            "service" : "any",
+            "name" : "test",
+            "policyType":0,
+            "description":"",
+            "resourceSignature":"",
+            "isAuditEnabled":true,
+            "resources" : {
+              "database": {"values": ["finance", "hr", "tmp*"], "isExcludes": false, "isRecursive": false},
+              "table": {"values": ["tax","employee","tmp*"], "isExcludes": false, "isRecursive": false},
+              "column": {"values": ["refund","salary","tmp*"], "isExcludes": false, "isRecursive": false}
+            },
+            "policyItems":[],
+            "denyPolicyItems":[],
+            "allowExceptions":[],
+            "denyExceptions":[],
+            "dataMaskPolicyItems":[],
+            "rowFilterPolicyItems":[]
+          },
+          "evalContext": {},
+          "result" : true
+        },
+        {
+          "name": "No match for '*:*:*' policy",
+          "type": "anyMatch",
+          "policy" : {
+            "service" : "any",
+            "name" : "test",
+            "policyType":0,
+            "description":"",
+            "resourceSignature":"",
+            "isAuditEnabled":true,
+            "resources" : {
+              "database": {"values": ["*"], "isExcludes": false, "isRecursive": false},
+              "table": {"values": ["*"], "isExcludes": false, "isRecursive": false},
+              "column": {"values": ["*"], "isExcludes": false, "isRecursive": false}
+            },
+            "policyItems":[],
+            "denyPolicyItems":[],
+            "allowExceptions":[],
+            "denyExceptions":[],
+            "dataMaskPolicyItems":[],
+            "rowFilterPolicyItems":[]
+          },
+          "evalContext": {},
+          "result" : false
+        }
+      ]
+    },
+    {
+      "name": "database=hr:table=*:column:refund",
+      "policyResources": {
+        "database": {"values": ["hr"]},
+        "table": {"values": ["*"]},
+        "column":{"values":["refund"]}
+      },
+      "tests": [
+        {
+          "name": "Exact match for 'finance,hr,tmp*:tax,employee,tmp*:refund,salary,tmp*' policy",
+          "type": "exactMatch",
+          "policy" : {
+            "service" : "any",
+            "name" : "test",
+            "policyType":0,
+            "description":"",
+            "resourceSignature":"",
+            "isAuditEnabled":true,
+            "resources" : {
+              "database": {"values": ["finance", "hr", "tmp*"], "isExcludes": false, "isRecursive": false},
+              "table": {"values": ["tax","employee","tmp*"], "isExcludes": false, "isRecursive": false},
+              "column": {"values": ["refund","salary","tmp*"], "isExcludes": false, "isRecursive": false}
+            },
+            "policyItems":[],
+            "denyPolicyItems":[],
+            "allowExceptions":[],
+            "denyExceptions":[],
+            "dataMaskPolicyItems":[],
+            "rowFilterPolicyItems":[]
+          },
+          "evalContext": {},
+          "result" : true
+        }
+        ,
+        {
+          "name": "No match for 'finance,tmp*:tax,employee,tmp*:refund,salary,tmp*' policy",
+          "type": "anyMatch",
+          "policy" : {
+            "service" : "any",
+            "name" : "test",
+            "policyType":0,
+            "description":"",
+            "resourceSignature":"",
+            "isAuditEnabled":true,
+            "resources" : {
+              "database": {"values": ["finance", "tmp*"], "isExcludes": false, "isRecursive": false},
+              "table": {"values": ["tax","employee","tmp*"], "isExcludes": false, "isRecursive": false},
+              "column": {"values": ["refund","salary","tmp*"], "isExcludes": false, "isRecursive": false}
+            },
+            "policyItems":[],
+            "denyPolicyItems":[],
+            "allowExceptions":[],
+            "denyExceptions":[],
+            "dataMaskPolicyItems":[],
+            "rowFilterPolicyItems":[]
+          },
+          "evalContext": {},
+          "result" : false
+        }
+      ]
+    },
+    {
+      "name": "database=hr:table=*:column:*",
+      "policyResources": {
+        "database": {"values": ["hr"]},
+        "table": {"values": ["*"]},
+        "column":{"values":["*"]}
+      },
+      "tests": [
+        {
+          "name": "Ancestor match for 'finance,hr,tmp*:tax,employee,tmp*:refund,salary,tmp*' policy",
+          "type": "ancestorMatch",
+          "policy" : {
+            "service" : "any",
+            "name" : "test",
+            "policyType":0,
+            "description":"",
+            "resourceSignature":"",
+            "isAuditEnabled":true,
+            "resources" : {
+              "database": {"values": ["finance", "hr", "tmp*"], "isExcludes": false, "isRecursive": false},
+              "table": {"values": ["tax","employee","tmp*"], "isExcludes": false, "isRecursive": false},
+              "column": {"values": ["refund","salary","tmp*"], "isExcludes": false, "isRecursive": false}
+            },
+            "policyItems":[],
+            "denyPolicyItems":[],
+            "allowExceptions":[],
+            "denyExceptions":[],
+            "dataMaskPolicyItems":[],
+            "rowFilterPolicyItems":[]
+          },
+          "evalContext": {},
+          "result" : true
+        },
+        {
+          "name": "Ancestor match for 'finance,hr,tmp*:*,employee,tmp*:*,salary,tmp*' policy",
+          "type": "ancestorMatch",
+          "policy" : {
+            "service" : "any",
+            "name" : "test",
+            "policyType":0,
+            "description":"",
+            "resourceSignature":"",
+            "isAuditEnabled":true,
+            "resources" : {
+              "database": {"values": ["finance", "hr", "tmp*"], "isExcludes": false, "isRecursive": false},
+              "table": {"values": ["*","employee","tmp*"], "isExcludes": false, "isRecursive": false},
+              "column": {"values": ["*","salary","tmp*"], "isExcludes": false, "isRecursive": false}
+            },
+            "policyItems":[],
+            "denyPolicyItems":[],
+            "allowExceptions":[],
+            "denyExceptions":[],
+            "dataMaskPolicyItems":[],
+            "rowFilterPolicyItems":[]
+          },
+          "evalContext": {},
+          "result" : true
+        }
+      ]
+    }
+  ]
+}

http://git-wip-us.apache.org/repos/asf/ranger/blob/9aa7262d/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
index 15f205a..bd6279b 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
@@ -44,6 +44,7 @@ import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
@@ -56,6 +57,9 @@ import org.apache.ranger.common.AppConstants;
 import org.apache.ranger.common.ContextUtil;
 import org.apache.ranger.common.MessageEnums;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
+import org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
+import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
+import org.apache.ranger.plugin.resourcematcher.RangerAbstractResourceMatcher;
 import org.apache.ranger.plugin.util.PasswordUtils;
 import org.apache.ranger.common.JSONUtil;
 import org.apache.ranger.common.PropertiesUtil;
@@ -2109,8 +2113,62 @@ public class ServiceDBStore extends AbstractServiceStore {
 		List<RangerPolicy> policies = servicePolicies != null ? servicePolicies.getPolicies() : null;
 
 		if(policies != null && filter != null) {
+			Map<String, String> filterResources = filter.getParamsWithPrefix(SearchFilter.RESOURCE_PREFIX, true);
+			String resourceMatchScope = filter.getParam(SearchFilter.RESOURCE_MATCH_SCOPE);
+
+			boolean useLegacyResourceSearch = true;
+
+			if (MapUtils.isNotEmpty(filterResources) && resourceMatchScope != null) {
+				useLegacyResourceSearch = false;
+				for (Map.Entry<String, String> entry : filterResources.entrySet()) {
+					filter.removeParam(SearchFilter.RESOURCE_PREFIX + entry.getKey());
+				}
+			}
+
+			if (LOG.isDebugEnabled()) {
+				LOG.debug("Using" + (useLegacyResourceSearch ? " old " : " new ") + "way of filtering service-policies");
+			}
+
 			ret = new ArrayList<RangerPolicy>(policies);
 			predicateUtil.applyFilter(ret, filter);
+
+			if (!useLegacyResourceSearch && CollectionUtils.isNotEmpty(ret)) {
+				RangerPolicyResourceMatcher.MatchScope scope;
+
+				if (StringUtils.equalsIgnoreCase(resourceMatchScope, "self")) {
+					scope = RangerPolicyResourceMatcher.MatchScope.SELF;
+				} else if (StringUtils.equalsIgnoreCase(resourceMatchScope, "ancestor")) {
+					scope = RangerPolicyResourceMatcher.MatchScope.ANCESTOR;
+				} else if (StringUtils.equalsIgnoreCase(resourceMatchScope, "self_or_ancestor")) {
+					scope = RangerPolicyResourceMatcher.MatchScope.SELF_OR_ANCESTOR;
+				} else {
+					// DESCENDANT match will never happen
+					scope = RangerPolicyResourceMatcher.MatchScope.SELF_OR_ANCESTOR;
+				}
+
+				RangerServiceDef serviceDef = servicePolicies.getServiceDef();
+
+				switch (scope) {
+					case SELF : {
+						serviceDef = RangerServiceDefHelper.getServiceDefForPolicyFiltering(serviceDef);
+						break;
+					}
+					case ANCESTOR : {
+						Map<String, String> updatedFilterResources = RangerServiceDefHelper.getFilterResourcesForAncestorPolicyFiltering(serviceDef, filterResources);
+						if (MapUtils.isNotEmpty(updatedFilterResources)) {
+							for (Map.Entry<String, String> entry : updatedFilterResources.entrySet()) {
+								filterResources.put(entry.getKey(), entry.getValue());
+							}
+							scope = RangerPolicyResourceMatcher.MatchScope.SELF_OR_ANCESTOR;
+						}
+						break;
+					}
+					default:
+						break;
+				}
+
+				ret = applyResourceFilter(serviceDef, ret, filterResources, filter, scope);
+			}
 		} else {
 			ret = policies;
 		}
@@ -2122,6 +2180,106 @@ public class ServiceDBStore extends AbstractServiceStore {
 		return ret;
 	}
 
+	List<RangerPolicy> applyResourceFilter(RangerServiceDef serviceDef, List<RangerPolicy> policies, Map<String, String> filterResources, SearchFilter filter, RangerPolicyResourceMatcher.MatchScope scope) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceDBStore.applyResourceFilter(policies-size=" + policies.size() + ", filterResources=" + filterResources + ", " + scope + ")");
+		}
+
+		List<RangerPolicy> ret = new ArrayList<RangerPolicy>();
+
+		List<RangerPolicyResourceMatcher> matchers = getMatchers(serviceDef, filterResources, filter);
+
+		if (CollectionUtils.isNotEmpty(matchers)) {
+
+			for (RangerPolicy policy : policies) {
+
+				for (RangerPolicyResourceMatcher matcher : matchers) {
+
+					if (LOG.isDebugEnabled()) {
+						LOG.debug("Trying to match for policy:[" + policy + "] using RangerDefaultPolicyResourceMatcher:[" + matcher + "]");
+					}
+
+					if (matcher.isMatch(policy, scope, null)) {
+						if (LOG.isDebugEnabled()) {
+							LOG.debug("matched policy:[" + policy + "]");
+						}
+						ret.add(policy);
+						break;
+					}
+				}
+			}
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceDBStore.applyResourceFilter(policies-size=" + ret.size() + ", filterResources=" + filterResources + ", " + scope + ")");
+		}
+
+		return ret;
+	}
+
+	List<RangerPolicyResourceMatcher> getMatchers(RangerServiceDef serviceDef, Map<String, String> filterResources, SearchFilter filter) {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> ServiceDBStore.getMatchers(filterResources=" + filterResources + ")");
+		}
+
+		List<RangerPolicyResourceMatcher> ret = new ArrayList<RangerPolicyResourceMatcher>();
+
+		RangerServiceDefHelper serviceDefHelper = new RangerServiceDefHelper(serviceDef);
+
+		String policyTypeStr = filter.getParam(SearchFilter.POLICY_TYPE);
+
+		int policyType = RangerPolicy.POLICY_TYPE_ACCESS;
+
+		if (StringUtils.isNotBlank(policyTypeStr)) {
+			policyType = Integer.parseInt(policyTypeStr);
+		}
+
+		Set<List<RangerResourceDef>> validResourceHierarchies = serviceDefHelper.getResourceHierarchies(policyType, filterResources.keySet());
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("Found " + validResourceHierarchies.size() + " valid resource hierarchies for key-set " + filterResources.keySet());
+		}
+
+		List<List<RangerResourceDef>> resourceHierarchies = new ArrayList<List<RangerResourceDef>>(validResourceHierarchies);
+
+		for (List<RangerResourceDef> validResourceHierarchy : resourceHierarchies) {
+
+			if (LOG.isDebugEnabled()) {
+				LOG.debug("validResourceHierarchy:[" + validResourceHierarchy + "]");
+			}
+
+			Map<String, RangerPolicyResource> policyResources = new HashMap<String, RangerPolicyResource>();
+
+			for (RangerResourceDef resourceDef : validResourceHierarchy) {
+
+				String resourceValue = filterResources.get(resourceDef.getName());
+
+				if (StringUtils.isBlank(resourceValue)) {
+					resourceValue = RangerAbstractResourceMatcher.WILDCARD_ASTERISK;
+				}
+
+				policyResources.put(resourceDef.getName(), new RangerPolicyResource(resourceValue, false, resourceDef.getRecursiveSupported()));
+			}
+
+			RangerDefaultPolicyResourceMatcher matcher = new RangerDefaultPolicyResourceMatcher();
+			matcher.setServiceDef(serviceDef);
+			matcher.setPolicyResources(policyResources);
+			matcher.init();
+
+			ret.add(matcher);
+
+			if (LOG.isDebugEnabled()) {
+				LOG.debug("Added matcher:[" + matcher + "]");
+			}
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== ServiceDBStore.getMatchers(filterResources=" + filterResources + ", " + ", count=" + ret.size() + ")");
+		}
+
+		return ret;
+	}
+
 	private List<RangerPolicy> getServicePoliciesFromDb(XXService service) throws Exception {
 		if(LOG.isDebugEnabled()) {
 			LOG.debug("==> ServiceDBStore.getServicePoliciesFromDb(" + service.getName() + ")");

http://git-wip-us.apache.org/repos/asf/ranger/blob/9aa7262d/security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java b/security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java
index 4fb52a4..c6be50e 100644
--- a/security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java
+++ b/security-admin/src/main/java/org/apache/ranger/common/RangerSearchUtil.java
@@ -81,7 +81,8 @@ public class RangerSearchUtil extends SearchUtil {
 				ret.setParam(name, values[0]);
 			}
 		}
-		
+		ret.setParam(SearchFilter.RESOURCE_MATCH_SCOPE, request.getParameter(SearchFilter.RESOURCE_MATCH_SCOPE));
+
 		extractCommonCriteriasForFilter(request, ret, sortFields);
 
 		return ret;