RANGER-698: updated Ranger policies to support variables like {USER} in 
resource-names

Signed-off-by: Madhan Neethiraj <[email protected]>


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

Branch: refs/heads/master
Commit: c659d9aa711595af9e701210484dc72cd8ff8985
Parents: a39c00f
Author: Abhay Kulkarni <[email protected]>
Authored: Thu Sep 1 07:39:58 2016 -0700
Committer: Madhan Neethiraj <[email protected]>
Committed: Thu Sep 1 16:25:20 2016 -0700

----------------------------------------------------------------------
 ...rHiveResourcesAccessedTogetherCondition.java |   2 +-
 ...veResourcesNotAccessedTogetherCondition.java |   2 +-
 .../RangerServiceResourceMatcher.java           |   4 +-
 .../contextenricher/RangerTagEnricher.java      |  10 +-
 .../ranger/plugin/model/RangerServiceDef.java   |   2 +-
 .../plugin/policyengine/RangerPolicyEngine.java |   6 +-
 .../policyengine/RangerPolicyEngineImpl.java    |  21 +-
 .../RangerAbstractPolicyItemEvaluator.java      |   3 +-
 .../RangerCachedPolicyEvaluator.java            |  36 +--
 .../RangerDefaultPolicyEvaluator.java           |  82 +++---
 .../RangerDefaultPolicyItemEvaluator.java       |   8 +-
 .../RangerOptimizedPolicyEvaluator.java         |  22 +-
 .../policyevaluator/RangerPolicyEvaluator.java  |   6 +-
 .../RangerPolicyItemEvaluator.java              |   1 -
 .../RangerDefaultPolicyResourceMatcher.java     |  72 +++---
 .../RangerPolicyResourceMatcher.java            |  14 +-
 .../RangerAbstractResourceMatcher.java          | 248 ++++++++++++-------
 .../RangerDefaultResourceMatcher.java           |  20 +-
 .../RangerPathResourceMatcher.java              |  44 ++--
 .../resourcematcher/RangerResourceMatcher.java  |   8 +-
 .../plugin/resourcematcher/ResourceMatcher.java |  47 +++-
 .../plugin/util/RangerAccessRequestUtil.java    |  20 ++
 .../plugin/util/RangerRequestedResources.java   |   5 +-
 .../ranger/plugin/util/RangerResourceTrie.java  |  24 +-
 .../ranger/plugin/util/ServiceDefUtil.java      |  23 ++
 .../ranger/plugin/util/StringTokenReplacer.java | 126 ++++++++++
 .../RangerAbstractResourceMatcherTest.java      |   6 +-
 .../RangerDefaultResourceMatcherTest.java       |  30 ++-
 .../RangerPathResourceMatcherTest.java          |  40 +--
 .../resourcematcher/TestResourceMatcher.java    |  20 +-
 .../test_policyengine_hdfs_resourcespec.json    |  31 ++-
 .../test_resourcematcher_default.json           |  25 +-
 .../test_resourcematcher_dynamic.json           |  33 +++
 .../test_resourcematcher_path.json              |   2 +-
 ...resourcematcher_wildcards_as_delimiters.json |  28 +++
 .../org/apache/ranger/rest/PublicAPIsv2.java    |   4 +-
 .../org/apache/ranger/rest/ServiceREST.java     |  38 +--
 37 files changed, 809 insertions(+), 304 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesAccessedTogetherCondition.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesAccessedTogetherCondition.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesAccessedTogetherCondition.java
index fc9842e..b18e7cd 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesAccessedTogetherCondition.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesAccessedTogetherCondition.java
@@ -72,7 +72,7 @@ public class RangerHiveResourcesAccessedTogetherCondition 
extends RangerAbstract
                if (isInitialized && CollectionUtils.isNotEmpty(matchers)) {
                        RangerRequestedResources resources = 
RangerAccessRequestUtil.getRequestedResourcesFromContext(request.getContext());
 
-                       ret = resources == null ? false : 
!resources.isMutuallyExcluded(matchers);
+                       ret = resources == null ? false : 
!resources.isMutuallyExcluded(matchers, request.getContext());
                } else {
                        
LOG.error("RangerHiveResourcesAccessedTogetherCondition.isMatched() - condition 
is not initialized correctly and will NOT be enforced");
                }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesNotAccessedTogetherCondition.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesNotAccessedTogetherCondition.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesNotAccessedTogetherCondition.java
index 3b8e009..5036a06 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesNotAccessedTogetherCondition.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/conditionevaluator/RangerHiveResourcesNotAccessedTogetherCondition.java
@@ -72,7 +72,7 @@ public class RangerHiveResourcesNotAccessedTogetherCondition 
extends RangerAbstr
                if (isInitialized && CollectionUtils.isNotEmpty(matchers)) {
                        RangerRequestedResources resources = 
RangerAccessRequestUtil.getRequestedResourcesFromContext(request.getContext());
 
-                       ret = resources == null ? true : 
resources.isMutuallyExcluded(matchers);
+                       ret = resources == null ? true : 
resources.isMutuallyExcluded(matchers, request.getContext());
                } else {
                        
LOG.error("RangerHiveResourcesNotAccessedTogetherCondition.isMatched() - 
Enforcer is not initialized correctly, Mutual Exclusion will NOT be enforced");
                }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
index cf7b8e7..637423e 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerServiceResourceMatcher.java
@@ -71,8 +71,8 @@ public class RangerServiceResourceMatcher implements 
RangerPolicyResourceEvaluat
                return Long.compare(getId(), other.getId());
        }
 
-       public boolean isMatch(RangerAccessResource requestedResource) {
-               return policyResourceMatcher != null ? 
policyResourceMatcher.isExactHeadMatch(requestedResource) : false;
+       public boolean isMatch(RangerAccessResource requestedResource, 
Map<String, Object> evalContext) {
+               return policyResourceMatcher != null ? 
policyResourceMatcher.isExactHeadMatch(requestedResource, evalContext) : false;
        }
 
        RangerServiceDef getServiceDef() {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
index 5b60a53..1a6e1b2 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/contextenricher/RangerTagEnricher.java
@@ -132,7 +132,7 @@ public class RangerTagEnricher extends 
RangerAbstractContextEnricher {
                        LOG.debug("==> RangerTagEnricher.enrich(" + request + 
")");
                }
 
-               List<RangerTag> matchedTags = 
findMatchingTags(request.getResource());
+               List<RangerTag> matchedTags = 
findMatchingTags(request.getResource(), request.getContext());
 
                
RangerAccessRequestUtil.setRequestTagsInContext(request.getContext(), 
matchedTags);
 
@@ -202,9 +202,9 @@ public class RangerTagEnricher extends 
RangerAbstractContextEnricher {
                return ret;
        }
 
-       private List<RangerTag> findMatchingTags(final RangerAccessResource 
resource) {
+       private List<RangerTag> findMatchingTags(final RangerAccessResource 
resource, final Map<String, Object> evalContext) {
                if (LOG.isDebugEnabled()) {
-                       LOG.debug("==> RangerTagEnricher.findMatchingTags(" + 
resource + ")");
+                       LOG.debug("==> RangerTagEnricher.findMatchingTags(" + 
resource + ", " + evalContext + ")");
                }
 
                List<RangerTag> ret = null;
@@ -216,7 +216,7 @@ public class RangerTagEnricher extends 
RangerAbstractContextEnricher {
 
                        for (RangerServiceResourceMatcher resourceMatcher : 
serviceResourceMatchers) {
 
-                               boolean matchResult = 
resourceMatcher.isMatch(resource);
+                               boolean matchResult = 
resourceMatcher.isMatch(resource, evalContext);
 
                                if (matchResult) {
                                        if (ret == null) {
@@ -237,7 +237,7 @@ public class RangerTagEnricher extends 
RangerAbstractContextEnricher {
                }
 
                if (LOG.isDebugEnabled()) {
-                       LOG.debug("<== RangerTagEnricher.findMatchingTags(" + 
resource + ")");
+                       LOG.debug("<== RangerTagEnricher.findMatchingTags(" + 
resource + ", " + evalContext + ")");
                }
 
                return ret;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
index f6931b3..2d27961 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerServiceDef.java
@@ -1260,7 +1260,6 @@ public class RangerServiceDef extends 
RangerBaseModelObject implements java.io.S
                private String              rbKeyDescription       = null;
                private String              rbKeyValidationMessage = null;
 
-
                public RangerResourceDef() {
                        this(null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, null, null, null);
                }
@@ -1931,6 +1930,7 @@ public class RangerServiceDef extends 
RangerBaseModelObject implements java.io.S
                        result = prime * result + ((name == null) ? 0 : 
name.hashCode());
                        result = prime * result
                                        + ((rbKeyLabel == null) ? 0 : 
rbKeyLabel.hashCode());
+
                        return result;
                }
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
index a5e92da..698d99a 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngine.java
@@ -37,6 +37,8 @@ public interface RangerPolicyEngine {
        String AUDIT_NONE = "audit-none";
        String AUDIT_DEFAULT = "audit-default";
 
+       String USER_CURRENT = "{USER}";
+
        String getServiceName();
 
        RangerServiceDef getServiceDef();
@@ -61,9 +63,9 @@ public interface RangerPolicyEngine {
 
        boolean isAccessAllowed(Map<String, RangerPolicyResource> resources, 
String user, Set<String> userGroups, String accessType);
 
-       List<RangerPolicy> getExactMatchPolicies(RangerAccessResource resource);
+       List<RangerPolicy> getExactMatchPolicies(RangerAccessResource resource, 
Map<String, Object> evalContext);
 
-       List<RangerPolicy> getExactMatchPolicies(Map<String, 
RangerPolicyResource> resources);
+       List<RangerPolicy> getExactMatchPolicies(Map<String, 
RangerPolicyResource> resources, Map<String, Object> evalContext);
 
        List<RangerPolicy> getAllowedPolicies(String user, Set<String> 
userGroups, String accessType);
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
index 6d3645f..9a63516 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyEngineImpl.java
@@ -198,6 +198,8 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                        ((RangerAccessRequestImpl) 
request).extractAndSetClientIPAddress(useForwardedIPAddress, 
trustedProxyAddresses);
                }
 
+               
RangerAccessRequestUtil.setCurrentUserInContext(request.getContext(), 
request.getUser());
+
                List<RangerContextEnricher> enrichers = allContextEnrichers;
 
                if(!CollectionUtils.isEmpty(enrichers)) {
@@ -441,15 +443,15 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
        }
 
        @Override
-       public List<RangerPolicy> getExactMatchPolicies(RangerAccessResource 
resource) {
+       public List<RangerPolicy> getExactMatchPolicies(RangerAccessResource 
resource, Map<String, Object> evalContext) {
                if (LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerPolicyEngineImpl.getExactMatchPolicies(" + resource + ")");
+                       LOG.debug("==> 
RangerPolicyEngineImpl.getExactMatchPolicies(" + resource + ", " + evalContext 
+ ")");
                }
 
                List<RangerPolicy> ret = null;
 
                for (RangerPolicyEvaluator evaluator : 
policyRepository.getPolicyEvaluators()) {
-                       if (evaluator.isCompleteMatch(resource)) {
+                       if (evaluator.isCompleteMatch(resource, evalContext)) {
                                if(ret == null) {
                                        ret = new ArrayList<RangerPolicy>();
                                }
@@ -459,22 +461,22 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                }
 
                if (LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerPolicyEngineImpl.getExactMatchPolicies(" + resource + "): " + ret);
+                       LOG.debug("<== 
RangerPolicyEngineImpl.getExactMatchPolicies(" + resource + ", " + evalContext 
+ "): " + ret);
                }
 
                return ret;
        }
 
        @Override
-       public List<RangerPolicy> getExactMatchPolicies(Map<String, 
RangerPolicyResource> resources) {
+       public List<RangerPolicy> getExactMatchPolicies(Map<String, 
RangerPolicyResource> resources, Map<String, Object> evalContext) {
                if (LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerPolicyEngineImpl.getExactMatchPolicies(" + resources + ")");
+                       LOG.debug("==> 
RangerPolicyEngineImpl.getExactMatchPolicies(" + resources + ", " + evalContext 
+ ")");
                }
 
                List<RangerPolicy> ret = null;
 
                for (RangerPolicyEvaluator evaluator : 
policyRepository.getPolicyEvaluators()) {
-                       if (evaluator.isCompleteMatch(resources)) {
+                       if (evaluator.isCompleteMatch(resources, evalContext)) {
                                if(ret == null) {
                                        ret = new ArrayList<RangerPolicy>();
                                }
@@ -484,7 +486,7 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
                }
 
                if (LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerPolicyEngineImpl.getExactMatchPolicies(" + resources + "): " + ret);
+                       LOG.debug("<== 
RangerPolicyEngineImpl.getExactMatchPolicies(" + resources + ", " + evalContext 
+ "): " + ret);
                }
 
                return ret;
@@ -652,8 +654,6 @@ public class RangerPolicyEngineImpl implements 
RangerPolicyEngine {
 
                                        for (RangerPolicyEvaluator evaluator : 
evaluators) {
                                                
tagEvalResult.incrementEvaluatedPoliciesCount();
-                                               if(! 
evaluator.isMatch(tagEvalRequest.getResource())) 
-                                                       continue;
 
                                                
evaluator.evaluate(tagEvalRequest, tagEvalResult);
 
@@ -953,6 +953,7 @@ class RangerTagAccessRequest extends 
RangerAccessRequestImpl {
 
                
RangerAccessRequestUtil.setCurrentTagInContext(request.getContext(), 
resourceTag);
                
RangerAccessRequestUtil.setCurrentResourceInContext(request.getContext(), 
request.getResource());
+               
RangerAccessRequestUtil.setCurrentUserInContext(request.getContext(), 
request.getUser());
 
                super.setContext(requestContext);
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
index 514884f..b36bc1f 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAbstractPolicyItemEvaluator.java
@@ -120,7 +120,8 @@ public abstract class RangerAbstractPolicyItemEvaluator 
implements RangerPolicyI
                int evalOrder = RANGER_POLICY_ITEM_EVAL_ORDER_DEFAULT;
 
                if(policyItem != null) {
-                       if(CollectionUtils.isNotEmpty(policyItem.getGroups()) 
&& policyItem.getGroups().contains(RangerPolicyEngine.GROUP_PUBLIC)) {
+                       if((CollectionUtils.isNotEmpty(policyItem.getGroups()) 
&& policyItem.getGroups().contains(RangerPolicyEngine.GROUP_PUBLIC))
+                               || 
(CollectionUtils.isNotEmpty(policyItem.getUsers()) && 
policyItem.getUsers().contains(RangerPolicyEngine.USER_CURRENT))) {
                                evalOrder -= 
RANGER_POLICY_ITEM_EVAL_ORDER_MAX_DISCOUNT_USERSGROUPS;
                        } else {
                                int userGroupCount = 0;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCachedPolicyEvaluator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCachedPolicyEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCachedPolicyEvaluator.java
index 91a53d8..7711765 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCachedPolicyEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerCachedPolicyEvaluator.java
@@ -26,6 +26,8 @@ import org.apache.ranger.plugin.model.RangerServiceDef;
 import org.apache.ranger.plugin.policyengine.RangerAccessResource;
 import org.apache.ranger.plugin.policyengine.RangerPolicyEngineOptions;
 
+import java.util.Map;
+
 public class RangerCachedPolicyEvaluator extends 
RangerOptimizedPolicyEvaluator {
     private static final Log LOG = 
LogFactory.getLog(RangerCachedPolicyEvaluator.class);
 
@@ -47,34 +49,38 @@ public class RangerCachedPolicyEvaluator extends 
RangerOptimizedPolicyEvaluator
     }
 
     @Override
-    public boolean isMatch(RangerAccessResource resource) {
+    public boolean isMatch(RangerAccessResource resource, Map<String, Object> 
evalContext) {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> RangerCachedPolicyEvaluator.isMatch(" + resource + 
")");
+            LOG.debug("==> RangerCachedPolicyEvaluator.isMatch(" + resource + 
", " + evalContext + ")");
         }
 
         boolean result = false;
 
-        // Check in the evaluator-owned cache for the match, if found return. 
else call super.isMatch(), add result to cache
-        RangerResourceAccessCache.LookupResult lookup = cache.lookup(resource);
+        if (needsDynamicEval()) {
+            result = super.isMatch(resource, evalContext);
+        } else {
+            // Check in the evaluator-owned cache for the match, if found 
return. else call super.isMatch(), add result to cache
+            RangerResourceAccessCache.LookupResult lookup = 
cache.lookup(resource);
 
-        if (lookup != 
RangerResourceAccessCache.LookupResult.IN_NOTMATCHED_CACHE) {
-            // We dont know definitely that this previously not matched
-            if (lookup != 
RangerResourceAccessCache.LookupResult.IN_MATCHED_CACHE) {
-                result = super.isMatch(resource);
+            if (lookup != 
RangerResourceAccessCache.LookupResult.IN_NOTMATCHED_CACHE) {
+                // We dont know definitely that this previously not matched
+                if (lookup != 
RangerResourceAccessCache.LookupResult.IN_MATCHED_CACHE) {
+                    result = super.isMatch(resource, evalContext);
 
-                // update the cache with the result of the match
-                if(result) {
-                       cache.add(resource, 
RangerResourceAccessCache.CacheType.MATCHED_CACHE);
+                    // update the cache with the result of the match
+                    if (result) {
+                        cache.add(resource, 
RangerResourceAccessCache.CacheType.MATCHED_CACHE);
+                    } else {
+                        cache.add(resource, 
RangerResourceAccessCache.CacheType.NOTMATCHED_CACHE);
+                    }
                 } else {
-                       cache.add(resource, 
RangerResourceAccessCache.CacheType.NOTMATCHED_CACHE);
+                    result = true;
                 }
-            } else {
-                result = true;
             }
         }
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("<== RangerCachedPolicyEvaluator.isMatch(" + resource + 
"): " + result);
+            LOG.debug("<== RangerCachedPolicyEvaluator.isMatch(" + resource + 
", " + evalContext + "): " + result);
         }
 
         return result;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java
----------------------------------------------------------------------
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 eb46353..867cd20 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
@@ -52,6 +52,7 @@ import 
org.apache.ranger.plugin.policyengine.RangerRowFilterResult;
 import 
org.apache.ranger.plugin.policyresourcematcher.RangerDefaultPolicyResourceMatcher;
 import 
org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
 import org.apache.ranger.plugin.resourcematcher.RangerResourceMatcher;
+import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
 import org.apache.ranger.plugin.util.RangerPerfTracer;
 import org.apache.ranger.plugin.util.ServiceDefUtil;
 
@@ -70,8 +71,11 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
        private int                             customConditionsCount    = 0;
        private List<RangerDataMaskPolicyItemEvaluator>  dataMaskEvaluators  = 
null;
        private List<RangerRowFilterPolicyItemEvaluator> rowFilterEvaluators = 
null;
+
        private String perfTag;
 
+       protected boolean needsDynamicEval() { return resourceMatcher != null ? 
resourceMatcher.getNeedsDynamicEval() : false; }
+
        @Override
        public int getCustomConditionsCount() {
                return customConditionsCount;
@@ -170,14 +174,14 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
             if (!result.getIsAuditedDetermined()) {
                 // Need to match request.resource first. If it matches (or 
head matches), then only more progress can be made
                 if (!isResourceMatchAttempted) {
-                    isResourceMatch = isMatch(request.getResource());
+                    isResourceMatch = isMatch(request.getResource(), 
request.getContext());
                     isResourceMatchAttempted = true;
                 }
 
                 // Try head match only if match was not found and ANY access 
was requested
                 if (!isResourceMatch) {
                     if (attemptResourceHeadMatch && 
!isResourceHeadMatchAttempted) {
-                        isResourceHeadMatch = 
matchResourceHead(request.getResource());
+                        isResourceHeadMatch = 
matchResourceHead(request.getResource(), request.getContext());
                         isResourceHeadMatchAttempted = true;
                     }
                 }
@@ -196,7 +200,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                 if (hasMatchablePolicyItem(request)) {
                     // Try Match only if it was not attempted as part of 
evaluating Audit requirement
                     if (!isResourceMatchAttempted) {
-                        isResourceMatch = isMatch(request.getResource());
+                        isResourceMatch = isMatch(request.getResource(), 
request.getContext());
                         isResourceMatchAttempted = true;
                     }
 
@@ -204,7 +208,7 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                     // Audit requirement
                     if (!isResourceMatch) {
                         if (attemptResourceHeadMatch && 
!isResourceHeadMatchAttempted) {
-                            isResourceHeadMatch = 
matchResourceHead(request.getResource());
+                            isResourceHeadMatch = 
matchResourceHead(request.getResource(), request.getContext());
                             isResourceHeadMatchAttempted = true;
                         }
                     }
@@ -245,13 +249,13 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
 
                        if (!result.getIsAuditedDetermined()) {
                                if (!isResourceMatchAttempted) {
-                                       isResourceMatch = 
isMatch(request.getResource());
+                                       isResourceMatch = 
isMatch(request.getResource(), request.getContext());
                                        isResourceMatchAttempted = true;
                                }
 
                                if (!isResourceMatch) {
                                        if (attemptResourceHeadMatch && 
!isResourceHeadMatchAttempted) {
-                                               isResourceHeadMatch = 
matchResourceHead(request.getResource());
+                                               isResourceHeadMatch = 
matchResourceHead(request.getResource(), request.getContext());
                                                isResourceHeadMatchAttempted = 
true;
                                        }
                                }
@@ -266,13 +270,13 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
 
                        if (!result.getIsAccessDetermined()) {
                                if (!isResourceMatchAttempted) {
-                                       isResourceMatch = 
isMatch(request.getResource());
+                                       isResourceMatch = 
isMatch(request.getResource(), request.getContext());
                                        isResourceMatchAttempted = true;
                                }
 
                                if (!isResourceMatch) {
                                        if (attemptResourceHeadMatch && 
!isResourceHeadMatchAttempted) {
-                                               isResourceHeadMatch = 
matchResourceHead(request.getResource());
+                                               isResourceHeadMatch = 
matchResourceHead(request.getResource(), request.getContext());
                                                isResourceHeadMatchAttempted = 
true;
                                        }
                                }
@@ -312,13 +316,13 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
 
                        if (!result.getIsAuditedDetermined()) {
                                if (!isResourceMatchAttempted) {
-                                       isResourceMatch = 
isMatch(request.getResource());
+                                       isResourceMatch = 
isMatch(request.getResource(), request.getContext());
                                        isResourceMatchAttempted = true;
                                }
 
                                if (!isResourceMatch) {
                                        if (attemptResourceHeadMatch && 
!isResourceHeadMatchAttempted) {
-                                               isResourceHeadMatch = 
matchResourceHead(request.getResource());
+                                               isResourceHeadMatch = 
matchResourceHead(request.getResource(), request.getContext());
                                                isResourceHeadMatchAttempted = 
true;
                                        }
                                }
@@ -333,13 +337,13 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
 
                        if (!result.getIsAccessDetermined()) {
                                if (!isResourceMatchAttempted) {
-                                       isResourceMatch = 
isMatch(request.getResource());
+                                       isResourceMatch = 
isMatch(request.getResource(), request.getContext());
                                        isResourceMatchAttempted = true;
                                }
 
                                if (!isResourceMatch) {
                                        if (attemptResourceHeadMatch && 
!isResourceHeadMatchAttempted) {
-                                               isResourceHeadMatch = 
matchResourceHead(request.getResource());
+                                               isResourceHeadMatch = 
matchResourceHead(request.getResource(), request.getContext());
                                                isResourceHeadMatchAttempted = 
true;
                                        }
                                }
@@ -358,9 +362,9 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
        }
 
        @Override
-       public boolean isMatch(RangerAccessResource resource) {
+       public boolean isMatch(RangerAccessResource resource, Map<String, 
Object> evalContext) {
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> RangerDefaultPolicyEvaluator.isMatch(" + 
resource + ")");
+                       LOG.debug("==> RangerDefaultPolicyEvaluator.isMatch(" + 
resource + ", " + evalContext + ")");
                }
 
                boolean ret = false;
@@ -368,32 +372,32 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                RangerPerfTracer perf = null;
 
                
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICY_REQUEST_LOG)) {
-                       perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, 
"RangerPolicyEvaluator.isMatch(resource=" + resource.getAsString() + "," + 
perfTag + ")");
+                       perf = 
RangerPerfTracer.getPerfTracer(PERF_POLICY_REQUEST_LOG, 
"RangerPolicyEvaluator.isMatch(resource=" + resource.getAsString() + "," + 
evalContext + "," + perfTag + ")");
                }
 
                if(resourceMatcher != null) {
-                       ret = resourceMatcher.isMatch(resource);
+                       ret = resourceMatcher.isMatch(resource, evalContext);
                }
 
                RangerPerfTracer.log(perf);
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== RangerDefaultPolicyEvaluator.isMatch(" + 
resource + "): " + ret);
+                       LOG.debug("<== RangerDefaultPolicyEvaluator.isMatch(" + 
resource + ", " + evalContext + "): " + ret);
                }
 
                return ret;
        }
 
        @Override
-       public boolean isCompleteMatch(RangerAccessResource resource) {
+       public boolean isCompleteMatch(RangerAccessResource resource, 
Map<String, Object> evalContext) {
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.isCompleteMatch(" + resource + ")");
+                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.isCompleteMatch(" + resource + ", " + evalContext 
+ ")");
                }
 
                boolean ret = false;
 
                if(resourceMatcher != null) {
-                       ret = resourceMatcher.isCompleteMatch(resource);
+                       ret = resourceMatcher.isCompleteMatch(resource, 
evalContext);
                }
 
                if(LOG.isDebugEnabled()) {
@@ -404,19 +408,19 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
        }
 
        @Override
-       public boolean isCompleteMatch(Map<String, RangerPolicyResource> 
resources) {
+       public boolean isCompleteMatch(Map<String, RangerPolicyResource> 
resources, Map<String, Object> evalContext) {
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.isCompleteMatch(" + resources + ")");
+                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.isCompleteMatch(" + resources + ", " + evalContext 
+ ")");
                }
 
                boolean ret = false;
 
                if(resourceMatcher != null) {
-                       ret = resourceMatcher.isCompleteMatch(resources);
+                       ret = resourceMatcher.isCompleteMatch(resources, 
evalContext);
                }
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerDefaultPolicyEvaluator.isCompleteMatch(" + resources + "): " + ret);
+                       LOG.debug("<== 
RangerDefaultPolicyEvaluator.isCompleteMatch(" + resources + ", " + evalContext 
+ "): " + ret);
                }
 
                return ret;
@@ -428,7 +432,10 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                        LOG.debug("==> 
RangerDefaultPolicyEvaluator.isAccessAllowed(" + resource + ", " + user + ", " 
+ userGroups + ", " + accessType + ")");
                }
 
-               boolean ret = isAccessAllowed(user, userGroups, accessType) && 
isMatch(resource);
+               Map<String, Object> evalContext = new HashMap<String, Object>();
+               RangerAccessRequestUtil.setCurrentUserInContext(evalContext, 
user);
+
+               boolean ret = isAccessAllowed(user, userGroups, accessType) && 
isMatch(resource, evalContext);
                
                if(LOG.isDebugEnabled()) {
                        LOG.debug("<== 
RangerDefaultPolicyEvaluator.isAccessAllowed(" + resource + ", " + user + ", " 
+ userGroups + ", " + accessType + "): " + ret);
@@ -443,7 +450,10 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                        LOG.debug("==> 
RangerDefaultPolicyEvaluator.isAccessAllowed(" + resources + ", " + user + ", " 
+ userGroups + ", " + accessType + ")");
                }
 
-               boolean ret = isAccessAllowed(user, userGroups, accessType) && 
isMatch(resources);
+               Map<String, Object> evalContext = new HashMap<String, Object>();
+               RangerAccessRequestUtil.setCurrentUserInContext(evalContext, 
user);
+
+               boolean ret = isAccessAllowed(user, userGroups, accessType) && 
isMatch(resources, evalContext);
                
                if(LOG.isDebugEnabled()) {
                        LOG.debug("<== 
RangerDefaultPolicyEvaluator.isAccessAllowed(" + resources + ", " + user + ", " 
+ userGroups + ", " + accessType + "): " + ret);
@@ -458,9 +468,9 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
                        LOG.debug("==> 
RangerDefaultPolicyEvaluator.getResourceAccessInfo(" + request + ", " + result 
+ ")");
                }
 
-               final boolean isResourceMatch          = 
isMatch(request.getResource());
+               final boolean isResourceMatch          = 
isMatch(request.getResource(), request.getContext());
                final boolean attemptResourceHeadMatch = 
request.isAccessTypeAny() || request.getResourceMatchingScope() == 
RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS;
-               final boolean isResourceHeadMatch      = (!isResourceMatch && 
attemptResourceHeadMatch) ? matchResourceHead(request.getResource()) : false;
+               final boolean isResourceHeadMatch      = (!isResourceMatch && 
attemptResourceHeadMatch) ? matchResourceHead(request.getResource(), 
request.getContext()) : false;
 
                if(isResourceMatch || isResourceHeadMatch) {
                        if (CollectionUtils.isNotEmpty(allowEvaluators)) {
@@ -643,37 +653,37 @@ public class RangerDefaultPolicyEvaluator extends 
RangerAbstractPolicyEvaluator
        }
 
 
-       protected boolean matchResourceHead(RangerAccessResource resource) {
+       protected boolean matchResourceHead(RangerAccessResource resource, 
Map<String, Object> evalContext) {
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.matchResourceHead(" + resource + ")");
+                       LOG.debug("==> 
RangerDefaultPolicyEvaluator.matchResourceHead(" + resource + ", " + 
evalContext + ")");
                }
 
                boolean ret = false;
 
                if(resourceMatcher != null) {
-                       ret = resourceMatcher.isHeadMatch(resource);
+                       ret = resourceMatcher.isHeadMatch(resource, 
evalContext);
                }
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerDefaultPolicyEvaluator.matchResourceHead(" + resource + "): " + ret);
+                       LOG.debug("<== 
RangerDefaultPolicyEvaluator.matchResourceHead(" + resource + ", " + 
evalContext + "): " + ret);
                }
 
                return ret;
        }
 
-       protected boolean isMatch(Map<String, RangerPolicyResource> resources) {
+       protected boolean isMatch(Map<String, RangerPolicyResource> resources, 
Map<String, Object> evalContext) {
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> RangerDefaultPolicyEvaluator.isMatch(" + 
resources + ")");
+                       LOG.debug("==> RangerDefaultPolicyEvaluator.isMatch(" + 
resources + ", " + evalContext + ")");
                }
 
                boolean ret = false;
 
                if(resourceMatcher != null) {
-                       ret = resourceMatcher.isMatch(resources);
+                       ret = resourceMatcher.isMatch(resources, evalContext);
                }
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== RangerDefaultPolicyEvaluator.isMatch(" + 
resources + "): " + ret);
+                       LOG.debug("<== RangerDefaultPolicyEvaluator.isMatch(" + 
resources + ", " + evalContext + "): " + ret);
                }
 
                return ret;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyItemEvaluator.java
----------------------------------------------------------------------
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 e2c715f..b899dd1 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
@@ -20,6 +20,7 @@ package org.apache.ranger.plugin.policyevaluator;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
 import org.apache.commons.collections.CollectionUtils;
@@ -48,6 +49,8 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
        private static final Log PERF_POLICYCONDITION_INIT_LOG = 
RangerPerfTracer.getPerfLogger("policycondition.init");
        private static final Log PERF_POLICYCONDITION_REQUEST_LOG = 
RangerPerfTracer.getPerfLogger("policycondition.request");
 
+       private boolean hasCurrentUser = false;
+
        public RangerDefaultPolicyItemEvaluator(RangerServiceDef serviceDef, 
RangerPolicy policy, RangerPolicyItem policyItem, int policyItemType, int 
policyItemIndex, RangerPolicyEngineOptions options) {
                super(serviceDef, policy, policyItem, policyItemType, 
policyItemIndex, options);
        }
@@ -100,6 +103,9 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
                        RangerPerfTracer.log(perf);
                }
 
+               List<String> users = policyItem != null ? policyItem.getUsers() 
: null;
+               this.hasCurrentUser = CollectionUtils.isNotEmpty(users) && 
users.contains(RangerPolicyEngine.USER_CURRENT);
+
                if(LOG.isDebugEnabled()) {
                        LOG.debug("<== 
RangerDefaultPolicyItemEvaluator(policyId=" + policyId + ", conditionsCount=" + 
getConditionEvaluators().size() + ")");
                }
@@ -172,7 +178,7 @@ public class RangerDefaultPolicyItemEvaluator extends 
RangerAbstractPolicyItemEv
 
                if(policyItem != null) {
                        if(!ret && user != null && policyItem.getUsers() != 
null) {
-                               ret = policyItem.getUsers().contains(user);
+                               ret = hasCurrentUser || 
policyItem.getUsers().contains(user);
                        }
 
                        if(!ret && userGroups != null && policyItem.getGroups() 
!= null) {

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
index 00b24d1..fb854d0 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerOptimizedPolicyEvaluator.java
@@ -40,7 +40,7 @@ public class RangerOptimizedPolicyEvaluator extends 
RangerDefaultPolicyEvaluator
     private boolean     delegateAdmin  = false;
     private boolean     hasAllPerms    = false;
     private boolean     hasPublicGroup = false;
-
+    private boolean     hasCurrentUser = false;
 
     // For computation of priority
     private static final String RANGER_POLICY_EVAL_MATCH_ANY_PATTERN_STRING   
= "*";
@@ -59,7 +59,7 @@ public class RangerOptimizedPolicyEvaluator extends 
RangerDefaultPolicyEvaluator
     private static final int 
RANGER_POLICY_EVAL_SCORE_RESOURCE_DISCOUNT_IS_EXCLUDES                      =  
5;
     private static final int 
RANGER_POLICY_EVAL_SCORE_RESORUCE_DISCOUNT_IS_RECURSIVE                     =  
5;
     private static final int RANGER_POLICY_EVAL_SCORE_CUSTOM_CONDITION_PENALTY 
                          =  5;
-
+    private static final int 
RANGER_POLICY_EVAL_SCORE_DYNAMIC_RESOURCE_EVAL_PENALTY                      =  
20;
 
     @Override
     public void init(RangerPolicy policy, RangerServiceDef serviceDef, 
RangerPolicyEngineOptions options) {
@@ -77,9 +77,17 @@ public class RangerOptimizedPolicyEvaluator extends 
RangerDefaultPolicyEvaluator
 
         hasAllPerms = checkIfHasAllPerms();
 
+        for (String user : users) {
+            if (user.equalsIgnoreCase(RangerPolicyEngine.USER_CURRENT)) {
+                hasCurrentUser = true;
+                break;
+            }
+        }
+
         for (String group : groups) {
             if (group.equalsIgnoreCase(RangerPolicyEngine.GROUP_PUBLIC)) {
                 hasPublicGroup = true;
+                break;
             }
         }
 
@@ -185,10 +193,13 @@ public class RangerOptimizedPolicyEvaluator extends 
RangerDefaultPolicyEvaluator
                 }
             }
         }
+        if (needsDynamicEval()) {
+            evalOrder += 
RANGER_POLICY_EVAL_SCORE_DYNAMIC_RESOURCE_EVAL_PENALTY;
+        }
 
         evalOrder -= Math.min(RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_RESOURCE, 
resourceDiscount);
 
-        if (hasPublicGroup) {
+        if (hasPublicGroup || hasCurrentUser) {
             evalOrder -= RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_USERSGROUPS;
         } else {
             evalOrder -= Math.min(groups.size() + users.size(), 
RANGER_POLICY_EVAL_SCORE_MAX_DISCOUNT_USERSGROUPS);
@@ -227,7 +238,7 @@ public class RangerOptimizedPolicyEvaluator extends 
RangerDefaultPolicyEvaluator
     protected boolean hasMatchablePolicyItem(RangerAccessRequest request) {
         boolean ret = false;
 
-        if (hasPublicGroup || users.contains(request.getUser()) || 
CollectionUtils.containsAny(groups, request.getUserGroups())) {
+        if (hasPublicGroup || hasCurrentUser || 
users.contains(request.getUser()) || CollectionUtils.containsAny(groups, 
request.getUserGroups())) {
             if(request.isAccessTypeDelegatedAdmin()) {
                 ret = delegateAdmin;
             } else if(hasAllPerms) {
@@ -243,7 +254,7 @@ public class RangerOptimizedPolicyEvaluator extends 
RangerDefaultPolicyEvaluator
     private boolean hasMatchablePolicyItem(String user, Set<String> 
userGroups, String accessType) {
         boolean ret = false;
 
-        if (hasPublicGroup || users.contains(user) || 
CollectionUtils.containsAny(groups, userGroups)) {
+        if (hasPublicGroup || hasCurrentUser || users.contains(user) || 
CollectionUtils.containsAny(groups, userGroups)) {
             boolean isAdminAccess = StringUtils.equals(accessType, 
RangerPolicyEngine.ADMIN_ACCESS);
 
             if(isAdminAccess) {
@@ -276,6 +287,7 @@ public class RangerOptimizedPolicyEvaluator extends 
RangerDefaultPolicyEvaluator
 
                    groups.addAll(item.getGroups());
                    users.addAll(item.getUsers());
+
                }
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
index b60e06e..92f1592 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java
@@ -71,11 +71,11 @@ public interface RangerPolicyEvaluator extends 
RangerPolicyResourceEvaluator {
 
        void evaluate(RangerAccessRequest request, RangerRowFilterResult 
result);
 
-       boolean isMatch(RangerAccessResource resource);
+       boolean isMatch(RangerAccessResource resource, Map<String, Object> 
evalContext);
 
-       boolean isCompleteMatch(RangerAccessResource resource);
+       boolean isCompleteMatch(RangerAccessResource resource, Map<String, 
Object> evalContext);
 
-       boolean isCompleteMatch(Map<String, RangerPolicyResource> resources);
+       boolean isCompleteMatch(Map<String, RangerPolicyResource> resources, 
Map<String, Object> evalContext);
 
        boolean isAccessAllowed(RangerAccessResource resource, String user, 
Set<String> userGroups, String accessType);
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
index 80e46f5..20b08c8 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyItemEvaluator.java
@@ -47,7 +47,6 @@ public interface RangerPolicyItemEvaluator extends 
Comparable<RangerPolicyItemEv
 
        int getEvalOrder();
 
-
        boolean isMatch(RangerAccessRequest request);
 
        boolean matchUserGroup(String user, Set<String> userGroups);

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/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 8bde807..5444e2b 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
@@ -48,6 +48,7 @@ public class RangerDefaultPolicyResourceMatcher implements 
RangerPolicyResourceM
        protected Map<String, RangerPolicyResource> policyResources = null;
 
        private Map<String, RangerResourceMatcher> matchers = null;
+       private boolean                            needsDynamicEval = false;
        private List<RangerResourceDef> firstValidResourceDefHierarchy;
 
        @Override
@@ -68,6 +69,11 @@ public class RangerDefaultPolicyResourceMatcher implements 
RangerPolicyResourceM
        }
 
        @Override
+       public boolean getNeedsDynamicEval() {
+               return needsDynamicEval;
+       }
+
+       @Override
        public void init() {
                if(LOG.isDebugEnabled()) {
                        LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.init()");
@@ -133,6 +139,9 @@ public class RangerDefaultPolicyResourceMatcher implements 
RangerPolicyResourceM
                                                        RangerResourceMatcher 
matcher = createResourceMatcher(resourceDef, policyResource);
 
                                                        if (matcher != null) {
+                                                               if 
(!needsDynamicEval && matcher.getNeedsDynamicEval()) {
+                                                                       
needsDynamicEval = true;
+                                                               }
                                                                
matchers.put(resourceName, matcher);
                                                        } else {
                                                                
LOG.error("failed to find matcher for resource " + resourceName);
@@ -189,10 +198,9 @@ public class RangerDefaultPolicyResourceMatcher implements 
RangerPolicyResourceM
                return matchers != null ? matchers.get(resourceName) : null;
        }
 
-       @Override
-       public boolean isMatch(RangerAccessResource resource) {
+       public boolean isMatch(RangerAccessResource resource, Map<String, 
Object> evalContext) {
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.isMatch(" + resource + ")");
+                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.isMatch(" + resource + ", " + evalContext + 
")");
                }
 
                boolean ret = false;
@@ -211,9 +219,9 @@ public class RangerDefaultPolicyResourceMatcher implements 
RangerPolicyResourceM
 
                                        // when no value exists for a 
resourceName, consider it a match only if: policy doesn't have a matcher OR 
matcher allows no-value resource
                                        if(StringUtils.isEmpty(resourceValue)) {
-                                               ret = matcher == null || 
matcher.isMatch(resourceValue);
+                                               ret = matcher == null || 
matcher.isMatch(resourceValue, evalContext);
                                        } else {
-                                               ret = matcher != null && 
matcher.isMatch(resourceValue);
+                                               ret = matcher != null && 
matcher.isMatch(resourceValue, evalContext);
                                        }
 
                                        if(! ret) {
@@ -228,7 +236,7 @@ public class RangerDefaultPolicyResourceMatcher implements 
RangerPolicyResourceM
                }
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.isMatch(" + resource + "): " + ret);
+                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.isMatch(" + resource  + ", " + evalContext + 
"): " + ret);
                }
 
                return ret;
@@ -236,9 +244,9 @@ public class RangerDefaultPolicyResourceMatcher implements 
RangerPolicyResourceM
 
 
        @Override
-       public boolean isMatch(Map<String, RangerPolicyResource> resources) {
+       public boolean isMatch(Map<String, RangerPolicyResource> resources, 
Map<String, Object> evalContext) {
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.isMatch(" + resources + ")");
+                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.isMatch(" + resources  + ", " + evalContext 
+ ")");
                }
 
                boolean ret = false;
@@ -257,10 +265,10 @@ public class RangerDefaultPolicyResourceMatcher 
implements RangerPolicyResourceM
 
                                        // when no value exists for a 
resourceName, consider it a match only if: policy doesn't have a matcher OR 
matcher allows no-value resource
                                        if(resourceValues == null || 
CollectionUtils.isEmpty(resourceValues.getValues())) {
-                                               ret = matcher == null || 
matcher.isMatch(null);
+                                               ret = matcher == null || 
matcher.isMatch(null, null);
                                        } else if(matcher != null) {
                                                for(String resourceValue : 
resourceValues.getValues()) {
-                                                       ret = 
matcher.isMatch(resourceValue);
+                                                       ret = 
matcher.isMatch(resourceValue, evalContext);
 
                                                        if(! ret) {
                                                                break;
@@ -280,16 +288,16 @@ public class RangerDefaultPolicyResourceMatcher 
implements RangerPolicyResourceM
                }
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.isMatch(" + resources + "): " + ret);
+                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.isMatch(" + resources  + ", " + evalContext 
+ "): " + ret);
                }
 
                return ret;
        }
 
        @Override
-       public boolean isCompleteMatch(RangerAccessResource resource) {
+       public boolean isCompleteMatch(RangerAccessResource resource, 
Map<String, Object> evalContext) {
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resource + ")");
+                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resource  + ", " + 
evalContext + ")");
                }
 
                boolean ret = false;
@@ -311,9 +319,9 @@ public class RangerDefaultPolicyResourceMatcher implements 
RangerPolicyResourceM
                                        RangerResourceMatcher matcher       = 
matchers == null ? null : matchers.get(resourceName);
 
                                        if(StringUtils.isEmpty(resourceValue)) {
-                                               ret = matcher == null || 
matcher.isCompleteMatch(resourceValue);
+                                               ret = matcher == null || 
matcher.isCompleteMatch(resourceValue, evalContext);
                                        } else {
-                                               ret = matcher != null && 
matcher.isCompleteMatch(resourceValue);
+                                               ret = matcher != null && 
matcher.isCompleteMatch(resourceValue, evalContext);
                                        }
 
                                        if(! ret) {
@@ -328,21 +336,21 @@ public class RangerDefaultPolicyResourceMatcher 
implements RangerPolicyResourceM
                }
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resource + "): " + ret);
+                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resource  + ", " + 
evalContext + "): " + ret);
                }
 
                return ret;
        }
 
        @Override
-       public boolean isHeadMatch(RangerAccessResource resource) {
+       public boolean isHeadMatch(RangerAccessResource resource, Map<String, 
Object> evalContext) {
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.isHeadMatch(" + resource + ")");
+                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.isHeadMatch(" + resource + ", " + 
evalContext + ")");
                }
 
                boolean ret = false;
-               
+
                if (matchers == null) {
 
                        
LOG.debug("RangerDefaultPolicyResourceMatcher.isHeadMatch(): 
PolicyResourceMatcher not initialized correctly!!!");
@@ -355,22 +363,22 @@ public class RangerDefaultPolicyResourceMatcher 
implements RangerPolicyResourceM
 
                } else {
 
-                       ret = newIsHeadMatch(resource);
+                       ret = newIsHeadMatch(resource, evalContext);
 
                }
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.matchResourceHead(" + resource + "): " + 
ret);
+                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.matchResourceHead(" + resource + ", " + 
evalContext  + "): " + ret);
                }
 
                return ret;
        }
 
        @Override
-       public boolean isExactHeadMatch(RangerAccessResource resource) {
+       public boolean isExactHeadMatch(RangerAccessResource resource, 
Map<String, Object> evalContext) {
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.isExactHeadMatch(" + resource + ")");
+                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.isExactHeadMatch(" + resource + ", " + 
evalContext + ")");
                }
 
                boolean ret = false;
@@ -392,21 +400,21 @@ public class RangerDefaultPolicyResourceMatcher 
implements RangerPolicyResourceM
 
                } else {
 
-                       ret = newIsHeadMatch(resource);
+                       ret = newIsHeadMatch(resource, evalContext);
 
                }
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.isExactHeadMatch(" + resource + ")" + ret);
+                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.isExactHeadMatch(" + resource + ", " + 
evalContext + ")" + ret);
                }
 
                return ret;
        }
 
-       private boolean newIsHeadMatch(RangerAccessResource resource) {
+       private boolean newIsHeadMatch(RangerAccessResource resource, 
Map<String, Object> evalContext) {
 
                if (LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.newIsHeadMatch(" + resource + ")");
+                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.newIsHeadMatch(" + resource + ", " + 
evalContext + ")");
                }
 
                boolean skipped = false;
@@ -424,7 +432,7 @@ public class RangerDefaultPolicyResourceMatcher implements 
RangerPolicyResourceM
 
                                        if (!skipped) {
 
-                                               matched = 
matcher.isMatch(resourceValue);
+                                               matched = 
matcher.isMatch(resourceValue, evalContext);
 
                                        } else {
 
@@ -444,7 +452,7 @@ public class RangerDefaultPolicyResourceMatcher implements 
RangerPolicyResourceM
                }
 
                if (LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.newIsHeadMatch(" + resource + "): " + 
matched);
+                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.newIsHeadMatch(" + resource + ", " + 
evalContext + "): " + matched);
                }
 
                return matched;
@@ -520,9 +528,9 @@ public class RangerDefaultPolicyResourceMatcher implements 
RangerPolicyResourceM
        }
 
        @Override
-       public boolean isCompleteMatch(Map<String, RangerPolicyResource> 
resources) {
+       public boolean isCompleteMatch(Map<String, RangerPolicyResource> 
resources, Map<String, Object> evalContext) {
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resources + ")");
+                       LOG.debug("==> 
RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resources + ", " + 
evalContext + ")");
                }
 
                boolean ret = false;
@@ -561,7 +569,7 @@ public class RangerDefaultPolicyResourceMatcher implements 
RangerPolicyResourceM
                }
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resources + "): " + ret);
+                       LOG.debug("<== 
RangerDefaultPolicyResourceMatcher.isCompleteMatch(" + resources + ", " + 
evalContext + "): " + ret);
                }
 
                return ret;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/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 a8810e5..ea0f36c 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
@@ -40,17 +40,19 @@ public interface RangerPolicyResourceMatcher {
 
        RangerResourceMatcher getResourceMatcher(String resourceName);
 
-       boolean isMatch(RangerAccessResource resource);
+       boolean isMatch(RangerAccessResource resource, Map<String, Object> 
evalContext);
 
-       boolean isMatch(Map<String, RangerPolicyResource> resources);
+       boolean isMatch(Map<String, RangerPolicyResource> resources, 
Map<String, Object> evalContext);
 
-       boolean isCompleteMatch(RangerAccessResource resource);
+       boolean isCompleteMatch(RangerAccessResource resource, Map<String, 
Object> evalContext);
 
-       boolean isHeadMatch(RangerAccessResource resource);
+       boolean isHeadMatch(RangerAccessResource resource, Map<String, Object> 
evalContext);
 
-       boolean isExactHeadMatch(RangerAccessResource resource);
+       boolean isExactHeadMatch(RangerAccessResource resource, Map<String, 
Object> evalContext);
 
-       boolean isCompleteMatch(Map<String, RangerPolicyResource> resources);
+       boolean isCompleteMatch(Map<String, RangerPolicyResource> resources, 
Map<String, Object> evalContext);
+
+       boolean getNeedsDynamicEval();
 
        StringBuilder toString(StringBuilder sb);
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
index 574f2eb..864709c 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java
@@ -32,18 +32,21 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.util.ServiceDefUtil;
 
 
 public abstract class RangerAbstractResourceMatcher implements 
RangerResourceMatcher {
        private static final Log LOG = 
LogFactory.getLog(RangerAbstractResourceMatcher.class);
 
        public final static String WILDCARD_ASTERISK = "*";
-       public final static String WILDCARDS = "*?";
 
-       public final static String OPTIONS_SEP        = ";";
-       public final static String OPTION_NV_SEP      = "=";
        public final static String OPTION_IGNORE_CASE = "ignoreCase";
        public final static String OPTION_WILD_CARD   = "wildCard";
+       public final static String OPTION_REPLACE_TOKENS         = 
"replaceTokens";
+       public final static String OPTION_TOKEN_DELIMITER_START  = 
"tokenDelimiterStart";
+       public final static String OPTION_TOKEN_DELIMITER_END    = 
"tokenDelimiterEnd";
+       public final static String OPTION_TOKEN_DELIMITER_ESCAPE = 
"tokenDelimiterEscape";
+       public final static String OPTION_TOKEN_DELIMITER_PREFIX = 
"tokenDelimiterPrefix";
 
        protected RangerResourceDef    resourceDef    = null;
        protected RangerPolicyResource policyResource = null;
@@ -51,10 +54,16 @@ public abstract class RangerAbstractResourceMatcher 
implements RangerResourceMat
        protected boolean      optIgnoreCase = false;
        protected boolean      optWildCard   = false;
 
-       protected List<String> policyValues     = null;
-       protected boolean      policyIsExcludes = false;
-       protected boolean      isMatchAny       = false;
-       protected List<ResourceMatcher> resourceMatchers = null;
+       protected List<String> policyValues = null;
+       protected boolean policyIsExcludes = false;
+       protected boolean isMatchAny = false;
+       protected ResourceMatcherWrapper resourceMatchers = null;
+
+       protected boolean optReplaceTokens   = false;
+       protected char    startDelimiterChar = '{';
+       protected char    endDelimiterChar   = '}';
+       protected char    escapeChar         = '\\';
+       protected String  tokenPrefix        = "";
 
        @Override
        public void setResourceDef(RangerResourceDef resourceDef) {
@@ -72,13 +81,15 @@ public abstract class RangerAbstractResourceMatcher 
implements RangerResourceMat
                        LOG.debug("==> RangerAbstractResourceMatcher.init()");
                }
 
-               optIgnoreCase = getBooleanOption(OPTION_IGNORE_CASE, true);
-               optWildCard   = getBooleanOption(OPTION_WILD_CARD, true);
+               Map<String, String> options = resourceDef != null ? 
resourceDef.getMatcherOptions() : null;
+
+               optIgnoreCase = getOptionIgnoreCase(options);
+               optWildCard   = getOptionWildCard(options);
 
-               policyValues     = new ArrayList<String>();
+               policyValues = new ArrayList<String>();
                policyIsExcludes = policyResource == null ? false : 
policyResource.getIsExcludes();
 
-               if(policyResource != null && policyResource.getValues() != 
null) {
+               if (policyResource != null && policyResource.getValues() != 
null) {
                        for (String policyValue : policyResource.getValues()) {
                                if (StringUtils.isEmpty(policyValue)) {
                                        continue;
@@ -86,8 +97,35 @@ public abstract class RangerAbstractResourceMatcher 
implements RangerResourceMat
                                policyValues.add(policyValue);
                        }
                }
+
+               optReplaceTokens = getOptionReplaceTokens(options);
+
+               if(optReplaceTokens) {
+                       startDelimiterChar = getOptionDelimiterStart(options);
+                       endDelimiterChar   = getOptionDelimiterEnd(options);
+                       escapeChar         = getOptionDelimiterEscape(options);
+                       tokenPrefix        = getOptionDelimiterPrefix(options);
+
+                       if(escapeChar == startDelimiterChar || escapeChar == 
endDelimiterChar ||
+                                       tokenPrefix.indexOf(escapeChar) != -1 
|| tokenPrefix.indexOf(startDelimiterChar) != -1 ||
+                                       tokenPrefix.indexOf(endDelimiterChar) 
!= -1) {
+                               String resouceName = resourceDef == null ? "" : 
resourceDef.getName();
+
+                               String msg = "Invalid token-replacement 
parameters for resource '" + resouceName + "': { ";
+                               msg += (OPTION_TOKEN_DELIMITER_START + "='" + 
startDelimiterChar + "'; ");
+                               msg += (OPTION_TOKEN_DELIMITER_END + "='" + 
endDelimiterChar + "'; ");
+                               msg += (OPTION_TOKEN_DELIMITER_ESCAPE + "='" + 
escapeChar + "'; ");
+                               msg += (OPTION_TOKEN_DELIMITER_PREFIX + "='" + 
tokenPrefix + "' }. ");
+                               msg += "Token replacement disabled";
+
+                               LOG.error(msg);
+
+                               optReplaceTokens = false;
+                       }
+               }
+
                resourceMatchers = buildResourceMatchers();
-               isMatchAny = CollectionUtils.isEmpty(resourceMatchers);
+               isMatchAny = resourceMatchers == null || 
CollectionUtils.isEmpty(resourceMatchers.getResourceMatchers());
 
                if(LOG.isDebugEnabled()) {
                        LOG.debug("<== RangerAbstractResourceMatcher.init()");
@@ -97,31 +135,66 @@ public abstract class RangerAbstractResourceMatcher 
implements RangerResourceMat
        @Override
        public boolean isMatchAny() { return isMatchAny; }
 
-       protected List<ResourceMatcher> buildResourceMatchers() {
-               List<ResourceMatcher> ret = new ArrayList<ResourceMatcher> ();
+       public boolean getNeedsDynamicEval() {
+               return resourceMatchers != null && 
resourceMatchers.getNeedsDynamicEval();
+       }
+
+       public static boolean getOptionIgnoreCase(Map<String, String> options) {
+               return ServiceDefUtil.getBooleanOption(options, 
OPTION_IGNORE_CASE, true);
+       }
+
+       public static boolean getOptionWildCard(Map<String, String> options) {
+               return ServiceDefUtil.getBooleanOption(options, 
OPTION_WILD_CARD, true);
+       }
+
+       public static boolean getOptionReplaceTokens(Map<String, String> 
options) {
+               return ServiceDefUtil.getBooleanOption(options, 
OPTION_REPLACE_TOKENS, true);
+       }
+
+       public static char getOptionDelimiterStart(Map<String, String> options) 
{
+               return ServiceDefUtil.getCharOption(options, 
OPTION_TOKEN_DELIMITER_START, '{');
+       }
+
+       public static char getOptionDelimiterEnd(Map<String, String> options) {
+               return ServiceDefUtil.getCharOption(options, 
OPTION_TOKEN_DELIMITER_END, '}');
+       }
+
+       public static char getOptionDelimiterEscape(Map<String, String> 
options) {
+               return ServiceDefUtil.getCharOption(options, 
OPTION_TOKEN_DELIMITER_ESCAPE, '\\');
+       }
+
+       public static String getOptionDelimiterPrefix(Map<String, String> 
options) {
+               return ServiceDefUtil.getOption(options, 
OPTION_TOKEN_DELIMITER_PREFIX, "");
+       }
+       protected ResourceMatcherWrapper buildResourceMatchers() {
+               List<ResourceMatcher> resourceMatchers = new 
ArrayList<ResourceMatcher>();
+               boolean needsDynamicEval = false;
 
                for (String policyValue : policyValues) {
                        ResourceMatcher matcher = getMatcher(policyValue);
 
                        if (matcher != null) {
                                if (matcher.isMatchAny()) {
-                                       ret.clear();
+                                       resourceMatchers.clear();
                                        break;
-                               } else {
-                                       ret.add(matcher);
                                }
+                               if (!needsDynamicEval && 
matcher.getNeedsDynamicEval()) {
+                                       needsDynamicEval = true;
+                               }
+                               resourceMatchers.add(matcher);
                        }
                }
 
-               Collections.sort(ret);
+               Collections.sort(resourceMatchers);
 
-               return ret;
+               return CollectionUtils.isNotEmpty(resourceMatchers) ?
+                               new ResourceMatcherWrapper(needsDynamicEval, 
resourceMatchers) : null;
        }
 
        @Override
-       public boolean isCompleteMatch(String resource) {
+       public boolean isCompleteMatch(String resource, Map<String, Object> 
evalContext) {
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> 
RangerAbstractResourceMatcher.isCompleteMatch(" + resource + ")");
+                       LOG.debug("==> 
RangerAbstractResourceMatcher.isCompleteMatch(" + resource + ", " + evalContext 
+ ")");
                }
 
                boolean ret = false;
@@ -130,7 +203,7 @@ public abstract class RangerAbstractResourceMatcher 
implements RangerResourceMat
                        ret = StringUtils.isEmpty(resource);
                } else if(policyValues.size() == 1) {
                        String policyValue = policyValues.get(0);
-                       
+
                        if(isMatchAny) {
                                ret = StringUtils.containsOnly(resource, 
WILDCARD_ASTERISK);
                        } else {
@@ -143,53 +216,7 @@ public abstract class RangerAbstractResourceMatcher 
implements RangerResourceMat
                }
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== 
RangerAbstractResourceMatcher.isCompleteMatch(" + resource + "): " + ret);
-               }
-
-               return ret;
-       }
-
-
-       public String getOption(String name) {
-               String ret = null;
-
-               Map<String, String> options = resourceDef != null ? 
resourceDef.getMatcherOptions() : null;
-
-               if(options != null && name != null) {
-                       ret = options.get(name);
-               }
-
-               return ret;
-       }
-
-       public String getOption(String name, String defaultValue) {
-               String ret = defaultValue;
-               String val = getOption(name);
-
-               if(val != null) {
-                       ret = val;
-               }
-
-               return ret;
-       }
-
-       public boolean getBooleanOption(String name, boolean defaultValue) {
-               boolean ret = defaultValue;
-               String  val = getOption(name);
-
-               if(val != null) {
-                       ret = Boolean.parseBoolean(val);
-               }
-
-               return ret;
-       }
-
-       public char getCharOption(String name, char defaultValue) {
-               char   ret = defaultValue;
-               String val = getOption(name);
-
-               if(! StringUtils.isEmpty(val)) {
-                       ret = val.charAt(0);
+                       LOG.debug("<== 
RangerAbstractResourceMatcher.isCompleteMatch(" + resource + ", " + evalContext 
+ "): " + ret);
                }
 
                return ret;
@@ -234,7 +261,7 @@ public abstract class RangerAbstractResourceMatcher 
implements RangerResourceMat
                sb.append("options={");
                if(resourceDef != null && resourceDef.getMatcherOptions() != 
null) {
                        for(Map.Entry<String, String> e : 
resourceDef.getMatcherOptions().entrySet()) {
-                               
sb.append(e.getKey()).append("=").append(e.getValue()).append(OPTIONS_SEP);
+                               
sb.append(e.getKey()).append("=").append(e.getValue()).append(';');
                        }
                }
                sb.append("} ");
@@ -320,6 +347,10 @@ public abstract class RangerAbstractResourceMatcher 
implements RangerResourceMat
                        ret = optIgnoreCase ? new 
CaseInsensitiveStartsWithMatcher(matchStr) : new 
CaseSensitiveStartsWithMatcher(matchStr);
                }
 
+               if(optReplaceTokens) {
+                       ret.setDelimiters(startDelimiterChar, endDelimiterChar, 
escapeChar, tokenPrefix);
+               }
+
                return ret;
        }
 }
@@ -329,19 +360,21 @@ final class CaseSensitiveStringMatcher extends 
ResourceMatcher {
                super(value);
        }
 
-       boolean isMatch(String str) {
-               return StringUtils.equals(str, value);
+       @Override
+       boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+               return StringUtils.equals(resourceValue, 
getExpandedValue(evalContext));
        }
-       int getPriority() { return 1;}
+       int getPriority() { return 1 + (getNeedsDynamicEval() ? 
DYNAMIC_EVALUATION_PENALTY : 0);}
 }
 
 final class CaseInsensitiveStringMatcher extends ResourceMatcher {
        CaseInsensitiveStringMatcher(String value) { super(value); }
 
-       boolean isMatch(String str) {
-               return StringUtils.equalsIgnoreCase(str, value);
+       @Override
+       boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+               return StringUtils.equalsIgnoreCase(resourceValue, 
getExpandedValue(evalContext));
        }
-       int getPriority() {return 2; }
+       int getPriority() {return 2 + (getNeedsDynamicEval() ? 
DYNAMIC_EVALUATION_PENALTY : 0); }
 }
 
 final class CaseSensitiveStartsWithMatcher extends ResourceMatcher {
@@ -349,19 +382,21 @@ final class CaseSensitiveStartsWithMatcher extends 
ResourceMatcher {
                super(value);
        }
 
-       boolean isMatch(String str) {
-               return StringUtils.startsWith(str, value);
+       @Override
+       boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+               return StringUtils.startsWith(resourceValue, 
getExpandedValue(evalContext));
        }
-       int getPriority() { return 3;}
+       int getPriority() { return 3 + (getNeedsDynamicEval() ? 
DYNAMIC_EVALUATION_PENALTY : 0);}
 }
 
 final class CaseInsensitiveStartsWithMatcher extends ResourceMatcher {
        CaseInsensitiveStartsWithMatcher(String value) { super(value); }
 
-       boolean isMatch(String str) {
-               return StringUtils.startsWithIgnoreCase(str, value);
+       @Override
+       boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+               return StringUtils.startsWithIgnoreCase(resourceValue, 
getExpandedValue(evalContext));
        }
-       int getPriority() { return 4; }
+       int getPriority() { return 4 + (getNeedsDynamicEval() ? 
DYNAMIC_EVALUATION_PENALTY : 0); }
 }
 
 final class CaseSensitiveEndsWithMatcher extends ResourceMatcher {
@@ -369,10 +404,11 @@ final class CaseSensitiveEndsWithMatcher extends 
ResourceMatcher {
                super(value);
        }
 
-       boolean isMatch(String str) {
-               return StringUtils.endsWith(str, value);
+       @Override
+       boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+               return StringUtils.endsWith(resourceValue, 
getExpandedValue(evalContext));
        }
-       int getPriority() { return 3; }
+       int getPriority() { return 3 + (getNeedsDynamicEval() ? 
DYNAMIC_EVALUATION_PENALTY : 0); }
 }
 
 final class CaseInsensitiveEndsWithMatcher extends ResourceMatcher {
@@ -380,10 +416,11 @@ final class CaseInsensitiveEndsWithMatcher extends 
ResourceMatcher {
                super(value);
        }
 
-       boolean isMatch(String str) {
-               return StringUtils.endsWithIgnoreCase(str, value);
+       @Override
+       boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+               return StringUtils.endsWithIgnoreCase(resourceValue, 
getExpandedValue(evalContext));
        }
-       int getPriority() { return 4; }
+       int getPriority() { return 4 + (getNeedsDynamicEval() ? 
DYNAMIC_EVALUATION_PENALTY : 0); }
 }
 
 final class CaseSensitiveWildcardMatcher extends ResourceMatcher {
@@ -391,10 +428,11 @@ final class CaseSensitiveWildcardMatcher extends 
ResourceMatcher {
                super(value);
        }
 
-       boolean isMatch(String str) {
-               return FilenameUtils.wildcardMatch(str, value, 
IOCase.SENSITIVE);
+       @Override
+       boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+               return FilenameUtils.wildcardMatch(resourceValue, 
getExpandedValue(evalContext), IOCase.SENSITIVE);
        }
-       int getPriority() { return 5; }
+       int getPriority() { return 5 + (getNeedsDynamicEval() ? 
DYNAMIC_EVALUATION_PENALTY : 0); }
 }
 
 
@@ -403,10 +441,32 @@ final class CaseInsensitiveWildcardMatcher extends 
ResourceMatcher {
                super(value);
        }
 
-       boolean isMatch(String str) {
-               return FilenameUtils.wildcardMatch(str, value, 
IOCase.INSENSITIVE);
+       @Override
+       boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+               return FilenameUtils.wildcardMatch(resourceValue, 
getExpandedValue(evalContext), IOCase.INSENSITIVE);
        }
-       int getPriority() {return 6; }
+       int getPriority() {return 6 + (getNeedsDynamicEval() ? 
DYNAMIC_EVALUATION_PENALTY : 0); }
+}
+
+final class ResourceMatcherWrapper {
+       private final boolean needsDynamicEval;
+       private final List<ResourceMatcher> resourceMatchers;
 
+       ResourceMatcherWrapper() {
+               this(false, null);
+       }
+
+       ResourceMatcherWrapper(boolean needsDynamicEval, List<ResourceMatcher> 
resourceMatchers) {
+               this.needsDynamicEval = needsDynamicEval;
+               this.resourceMatchers = resourceMatchers;
+       }
+
+       boolean getNeedsDynamicEval() {
+               return needsDynamicEval;
+       }
+
+       List<ResourceMatcher> getResourceMatchers() {
+               return resourceMatchers;
+       }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
index 0a11be0..c1508bf 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerDefaultResourceMatcher.java
@@ -20,18 +20,19 @@
 package org.apache.ranger.plugin.resourcematcher;
 
 
-import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+import java.util.Map;
+
 
 public class RangerDefaultResourceMatcher extends 
RangerAbstractResourceMatcher {
        private static final Log LOG = 
LogFactory.getLog(RangerDefaultResourceMatcher.class);
 
        @Override
-       public boolean isMatch(String resource) {
+       public boolean isMatch(String resource, Map<String, Object> 
evalContext) {
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("==> RangerDefaultResourceMatcher.isMatch(" + 
resource + ")");
+                       LOG.debug("==> RangerDefaultResourceMatcher.isMatch(" + 
resource + ", " + evalContext + ")");
                }
 
                boolean ret = false;
@@ -40,14 +41,13 @@ public class RangerDefaultResourceMatcher extends 
RangerAbstractResourceMatcher
                if(allValuesRequested || isMatchAny) {
                        ret = isMatchAny;
                } else {
-                       if (CollectionUtils.isNotEmpty(resourceMatchers)) {
-                               for (ResourceMatcher resourceMatcher : 
resourceMatchers) {
-                                       ret = resourceMatcher.isMatch(resource);
-                                       if (ret) {
-                                               break;
-                                       }
+                       for (ResourceMatcher resourceMatcher : 
resourceMatchers.getResourceMatchers()) {
+                               ret = resourceMatcher.isMatch(resource, 
evalContext);
+                               if (ret) {
+                                       break;
                                }
                        }
+
                }
 
                ret = applyExcludes(allValuesRequested, ret);
@@ -67,7 +67,7 @@ public class RangerDefaultResourceMatcher extends 
RangerAbstractResourceMatcher
                }
 
                if(LOG.isDebugEnabled()) {
-                       LOG.debug("<== RangerDefaultResourceMatcher.isMatch(" + 
resource + "): " + ret);
+                       LOG.debug("<== RangerDefaultResourceMatcher.isMatch(" + 
resource + ", " + evalContext + "): " + ret);
                }
 
                return ret;

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/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 d508f3f..fec527f 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
@@ -19,16 +19,19 @@
 
 package org.apache.ranger.plugin.resourcematcher;
 
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.io.IOCase;
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.util.ServiceDefUtil;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 
 public class RangerPathResourceMatcher extends RangerDefaultResourceMatcher {
@@ -46,8 +49,10 @@ public class RangerPathResourceMatcher extends 
RangerDefaultResourceMatcher {
                        LOG.debug("==> RangerPathResourceMatcher.init()");
                }
 
+               Map<String, String> options = resourceDef == null ? null : 
resourceDef.getMatcherOptions();
+
                policyIsRecursive = policyResource == null ? false : 
policyResource.getIsRecursive();
-               pathSeparatorChar = getCharOption(OPTION_PATH_SEPARATOR, 
DEFAULT_PATH_SEPARATOR_CHAR);
+               pathSeparatorChar = ServiceDefUtil.getCharOption(options, 
OPTION_PATH_SEPARATOR, DEFAULT_PATH_SEPARATOR_CHAR);
 
                super.init();
 
@@ -57,8 +62,10 @@ public class RangerPathResourceMatcher extends 
RangerDefaultResourceMatcher {
        }
 
        @Override
-       protected List<ResourceMatcher> buildResourceMatchers() {
-               List<ResourceMatcher> ret = new ArrayList<ResourceMatcher>();
+
+       protected ResourceMatcherWrapper buildResourceMatchers() {
+               List<ResourceMatcher> resourceMatchers = new 
ArrayList<ResourceMatcher>();
+               boolean needsDynamicEval = false;
 
                for (String policyValue : policyValues) {
                        if (optWildCard && policyIsRecursive) {
@@ -71,17 +78,20 @@ public class RangerPathResourceMatcher extends 
RangerDefaultResourceMatcher {
 
                        if (matcher != null) {
                                if (matcher.isMatchAny()) {
-                                       ret.clear();
+                                       resourceMatchers.clear();
                                        break;
-                               } else {
-                                       ret.add(matcher);
                                }
+                               if (!needsDynamicEval && 
matcher.getNeedsDynamicEval()) {
+                                       needsDynamicEval = true;
+                               }
+                               resourceMatchers.add(matcher);
                        }
                }
 
-               Collections.sort(ret);
+               Collections.sort(resourceMatchers);
 
-               return ret;
+               return CollectionUtils.isNotEmpty(resourceMatchers) ?
+                               new ResourceMatcherWrapper(needsDynamicEval, 
resourceMatchers) : null;
        }
 
        @Override
@@ -118,6 +128,8 @@ public class RangerPathResourceMatcher extends 
RangerDefaultResourceMatcher {
                        ret = optIgnoreCase ? new 
CaseInsensitiveStartsWithMatcher(policyValue) : new 
CaseSensitiveStartsWithMatcher(policyValue);
                }
 
+               ret.setDelimiters(startDelimiterChar, endDelimiterChar, 
escapeChar, tokenPrefix);
+
                return ret;
        }
 
@@ -152,7 +164,6 @@ public class RangerPathResourceMatcher extends 
RangerDefaultResourceMatcher {
                                ret = FilenameUtils.wildcardMatch(pathToCheck, 
wildcardPath, caseSensitivity) ;
                        }
                }
-
                return ret;
        }
 
@@ -177,10 +188,11 @@ final class CaseSensitiveRecursiveWildcardMatcher extends 
ResourceMatcher {
                this.levelSeparatorChar = levelSeparatorChar;
        }
 
-       boolean isMatch(String str) {
-               return RangerPathResourceMatcher.isRecursiveWildCardMatch(str, 
value, levelSeparatorChar, IOCase.SENSITIVE);
+       @Override
+       boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+               return 
RangerPathResourceMatcher.isRecursiveWildCardMatch(resourceValue, 
getExpandedValue(evalContext), levelSeparatorChar, IOCase.SENSITIVE);
        }
-       int getPriority() { return 7;}
+       int getPriority() { return 7 + (getNeedsDynamicEval() ? 
DYNAMIC_EVALUATION_PENALTY : 0);}
 }
 
 final class CaseInsensitiveRecursiveWildcardMatcher extends ResourceMatcher {
@@ -190,10 +202,10 @@ final class CaseInsensitiveRecursiveWildcardMatcher 
extends ResourceMatcher {
                this.levelSeparatorChar = levelSeparatorChar;
        }
 
-       boolean isMatch(String str) {
-               return RangerPathResourceMatcher.isRecursiveWildCardMatch(str, 
value, levelSeparatorChar, IOCase.INSENSITIVE);
+       @Override
+       boolean isMatch(String resourceValue, Map<String, Object> evalContext) {
+               return 
RangerPathResourceMatcher.isRecursiveWildCardMatch(resourceValue, 
getExpandedValue(evalContext), levelSeparatorChar, IOCase.INSENSITIVE);
        }
-       int getPriority() { return 8;}
+       int getPriority() { return 8 + (getNeedsDynamicEval() ? 
DYNAMIC_EVALUATION_PENALTY : 0);}
 
 }
-

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
index 8f1cebe..c1d8366 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java
@@ -22,6 +22,8 @@ package org.apache.ranger.plugin.resourcematcher;
 import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
 import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
 
+import java.util.Map;
+
 public interface RangerResourceMatcher {
        void setResourceDef(RangerResourceDef resourceDef);
 
@@ -31,8 +33,10 @@ public interface RangerResourceMatcher {
 
        boolean isMatchAny();
 
-       boolean isMatch(String resource);
+       boolean isMatch(String resource, Map<String, Object> evalContext);
+
+       boolean isCompleteMatch(String resource, Map<String, Object> 
evalContext);
 
-       boolean isCompleteMatch(String resource);
+       boolean getNeedsDynamicEval();
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ResourceMatcher.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ResourceMatcher.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ResourceMatcher.java
index 39eb339..853c525 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ResourceMatcher.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/ResourceMatcher.java
@@ -19,16 +19,31 @@
 
 package org.apache.ranger.plugin.resourcematcher;
 
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.util.StringTokenReplacer;
+
+import java.util.Map;
+
 abstract class ResourceMatcher implements Comparable<ResourceMatcher> {
+    private static final Log LOG = LogFactory.getLog(ResourceMatcher.class);
+
     protected final String value;
+    protected StringTokenReplacer tokenReplacer;
+
+    static final int DYNAMIC_EVALUATION_PENALTY = 8;
 
     ResourceMatcher(String value) { this.value = value; }
 
-    abstract boolean isMatch(String str);
+    abstract boolean isMatch(String resourceValue, Map<String, Object> 
evalContext);
     abstract int getPriority();
 
     boolean isMatchAny() { return value != null && value.length() == 0; }
 
+    boolean getNeedsDynamicEval() {
+        return tokenReplacer != null;
+    }
+
     @Override
     public int compareTo(ResourceMatcher other) { return 
Integer.compare(getPriority(), other.getPriority()); }
 
@@ -36,4 +51,32 @@ abstract class ResourceMatcher implements 
Comparable<ResourceMatcher> {
     public String toString() {
         return this.getClass().getName() + "(" + this.value + ")";
     }
-}
\ No newline at end of file
+
+    void setDelimiters(char startDelimiterChar, char endDelimiterChar, char 
escapeChar, String tokenPrefix) {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("==> setDelimiters(value= " + value + ", 
startDelimiter=" + startDelimiterChar +
+                    ", endDelimiter=" + endDelimiterChar + ", escapeChar=" + 
escapeChar + ", prefix=" + tokenPrefix);
+        }
+
+        if(value != null && (value.indexOf(escapeChar) != -1 || 
(value.indexOf(startDelimiterChar) != -1 && value.indexOf(endDelimiterChar) != 
-1))) {
+            tokenReplacer = new StringTokenReplacer(startDelimiterChar, 
endDelimiterChar, escapeChar, tokenPrefix);
+        }
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("<== setDelimiters(value= " + value + ", 
startDelimiter=" + startDelimiterChar +
+                    ", endDelimiter=" + endDelimiterChar + ", escapeChar=" + 
escapeChar + ", prefix=" + tokenPrefix);
+        }
+    }
+
+    String getExpandedValue(Map<String, Object> evalContext) {
+        final String ret;
+
+        if(tokenReplacer != null) {
+            ret = tokenReplacer.replaceTokens(value, evalContext);
+        } else {
+            ret = value;
+        }
+
+        return ret;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
index 0ce3721..2f3a39e 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerAccessRequestUtil.java
@@ -37,6 +37,8 @@ public class RangerAccessRequestUtil {
        public static final String KEY_CONTEXT_TAG_OBJECT          = 
"TAG_OBJECT";
        public static final String KEY_CONTEXT_RESOURCE            = "RESOURCE";
        public static final String KEY_CONTEXT_REQUESTED_RESOURCES = 
"REQUESTED_RESOURCES";
+       public static final String KEY_TOKEN_NAMESPACE = "token:";
+       public static final String KEY_USER = "USER";
 
        public static void setRequestTagsInContext(Map<String, Object> context, 
List<RangerTag> tags) {
                if(CollectionUtils.isEmpty(tags)) {
@@ -125,4 +127,22 @@ public class RangerAccessRequestUtil {
 
                return ret;
        }
+
+       public static void setCurrentUserInContext(Map<String, Object> context, 
String user) {
+               setTokenInContext(context, KEY_USER, user);
+       }
+
+       public static String getCurrentUserFromContext(Map<String, Object> 
context) {
+               Object ret = getTokenFromContext(context, KEY_USER);
+               return ret != null ? ret.toString() : "";
+       }
+
+       public static void setTokenInContext(Map<String, Object> context, 
String tokenName, Object tokenValue) {
+               String tokenNameWithNamespace = KEY_TOKEN_NAMESPACE + tokenName;
+               context.put(tokenNameWithNamespace, tokenValue);
+       }
+       public static Object getTokenFromContext(Map<String, Object> context, 
String tokenName) {
+               String tokenNameWithNamespace = KEY_TOKEN_NAMESPACE + tokenName;
+               return MapUtils.isNotEmpty(context) ? 
context.get(tokenNameWithNamespace) : null;
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/c659d9aa/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRequestedResources.java
----------------------------------------------------------------------
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRequestedResources.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRequestedResources.java
index 0f10deb..cb3b84a 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRequestedResources.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRequestedResources.java
@@ -31,6 +31,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 @JsonAutoDetect(getterVisibility= JsonAutoDetect.Visibility.NONE, 
setterVisibility= JsonAutoDetect.Visibility.NONE, fieldVisibility= 
JsonAutoDetect.Visibility.ANY)
 @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL )
@@ -67,7 +68,7 @@ public class RangerRequestedResources {
                }
        }
 
-       public boolean isMutuallyExcluded(final 
List<RangerPolicyResourceMatcher> matchers) {
+       public boolean isMutuallyExcluded(final 
List<RangerPolicyResourceMatcher> matchers, final Map<String, Object> 
evalContext) {
                boolean ret = true;
 
                int matchedCount = 0;
@@ -78,7 +79,7 @@ public class RangerRequestedResources {
 
                                for (RangerPolicyResourceMatcher matcher : 
matchers) {
 
-                                       if (matcher.isMatch(resource) && 
matchedCount++ > 0) {
+                                       if (matcher.isMatch(resource, 
evalContext) && matchedCount++ > 0) {
                                                ret = false;
                                                break;
                                        }


Reply via email to