You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by rm...@apache.org on 2020/12/01 22:13:04 UTC
[ranger] branch ranger-2.2 updated: RANGER-3000:Audit-filter
feature implementation to help reduce volume of audit logs generated
This is an automated email from the ASF dual-hosted git repository.
rmani pushed a commit to branch ranger-2.2
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/ranger-2.2 by this push:
new 75578f0 RANGER-3000:Audit-filter feature implementation to help reduce volume of audit logs generated
75578f0 is described below
commit 75578f0333cc8e1999704e3948715dba41309eb2
Author: Ramesh Mani <rm...@cloudera.com>
AuthorDate: Tue Dec 1 08:33:02 2020 -0800
RANGER-3000:Audit-filter feature implementation to help reduce volume of audit logs generated
---
.../ranger/authorization/utils/JsonUtils.java | 12 +
.../apache/ranger/plugin/model/AuditFilter.java | 130 +++++++
.../apache/ranger/plugin/model/RangerPolicy.java | 1 +
.../model/validation/RangerServiceDefHelper.java | 4 +
.../plugin/policyengine/RangerAccessResult.java | 2 +-
.../plugin/policyengine/RangerPolicyEngine.java | 3 +
.../policyengine/RangerPolicyEngineImpl.java | 109 ++++++
.../policyengine/RangerPolicyRepository.java | 123 ++++++-
.../RangerAuditPolicyEvaluator.java | 405 +++++++++++++++++++++
.../RangerDefaultPolicyEvaluator.java | 6 +-
.../RangerDefaultPolicyResourceMatcher.java | 2 +-
.../ranger/plugin/service/RangerBasePlugin.java | 32 +-
.../apache/ranger/plugin/util/ServicePolicies.java | 11 +
.../plugin/policyengine/TestPolicyEngine.java | 30 +-
.../test_policyengine_audit_filter_hdfs.json | 120 ++++++
.../test_policyengine_audit_filter_hive.json | 248 +++++++++++++
.../java/org/apache/ranger/rest/ServiceREST.java | 12 +
17 files changed, 1226 insertions(+), 24 deletions(-)
diff --git a/agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java b/agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java
index 994d394..ee4cef6 100644
--- a/agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java
+++ b/agents-common/src/main/java/org/apache/ranger/authorization/utils/JsonUtils.java
@@ -25,6 +25,7 @@ import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.model.AuditFilter;
import org.apache.ranger.plugin.model.RangerValidityRecurrence;
import org.apache.ranger.plugin.model.RangerValiditySchedule;
@@ -117,6 +118,17 @@ public class JsonUtils {
return null;
}
}
+
+ public static List<AuditFilter> jsonToAuditFilterList(String jsonStr) {
+ try {
+ Type listType = new TypeToken<List<AuditFilter>>() {}.getType();
+ return gson.fromJson(jsonStr, listType);
+ } catch (Exception e) {
+ LOG.error("failed to create audit filters from: " + jsonStr, e);
+ return null;
+ }
+ }
+
public static List<RangerValidityRecurrence> jsonToRangerValidityRecurringSchedule(String jsonStr) {
try {
Type listType = new TypeToken<List<RangerValidityRecurrence>>() {
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/AuditFilter.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/AuditFilter.java
new file mode 100644
index 0000000..b437e14
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/AuditFilter.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.plugin.model;
+
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+@JsonAutoDetect(fieldVisibility=Visibility.ANY)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.FIELD)
+public class AuditFilter {
+ public enum AccessResult { DENIED, ALLOWED, NOT_DETERMINED }
+
+ private AccessResult accessResult;
+ private Map<String, RangerPolicyResource> resources;
+ private List<String> accessTypes;
+ private List<String> actions;
+ private List<String> users;
+ private List<String> groups;
+ private List<String> roles;
+ private Boolean isAudited;
+
+ public AuditFilter() { }
+
+ public AccessResult getAccessResult() {
+ return accessResult;
+ }
+
+ public void setAccessResult(AccessResult accessResult) {
+ this.accessResult = accessResult;
+ }
+
+ public Map<String, RangerPolicyResource> getResources() {
+ return resources;
+ }
+
+ public void setResources(Map<String, RangerPolicyResource> resources) {
+ this.resources = resources;
+ }
+
+ public List<String> getAccessTypes() {
+ return accessTypes;
+ }
+
+ public void setAccessTypes(List<String> accessTypes) {
+ this.accessTypes = accessTypes;
+ }
+
+ public List<String> getActions() {
+ return actions;
+ }
+
+ public void setActions(List<String> actions) {
+ this.actions = actions;
+ }
+
+ public List<String> getUsers() {
+ return users;
+ }
+
+ public void setUsers(List<String> users) {
+ this.users = users;
+ }
+
+ public List<String> getGroups() {
+ return groups;
+ }
+
+ public void setGroups(List<String> groups) {
+ this.groups = groups;
+ }
+
+ public List<String> getRoles() {
+ return roles;
+ }
+
+ public void setRoles(List<String> roles) {
+ this.roles = roles;
+ }
+
+ public Boolean getIsAudited() {
+ return isAudited;
+ }
+
+ public void setAction(Boolean isAudited) {
+ this.isAudited = isAudited;
+ }
+
+ @Override
+ public String toString() {
+ return "{accessResult=" + accessResult
+ + ", resources=" + resources
+ + ", accessTypes=" + accessTypes
+ + ", actions=" + actions
+ + ", users=" + users
+ + ", groups=" + groups
+ + ", roles=" + roles
+ + ", isAudited=" + isAudited
+ + "}";
+ }
+}
\ No newline at end of file
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
index 04c6e75..6444fe9 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java
@@ -45,6 +45,7 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria
public static final int POLICY_TYPE_ACCESS = 0;
public static final int POLICY_TYPE_DATAMASK = 1;
public static final int POLICY_TYPE_ROWFILTER = 2;
+ public static final int POLICY_TYPE_AUDIT = 3;
public static final int[] POLICY_TYPES = new int[] {
POLICY_TYPE_ACCESS,
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
index 0d9a346..bbcf82f 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerServiceDefHelper.java
@@ -206,6 +206,10 @@ public class RangerServiceDefHelper {
Set<List<RangerResourceDef>> ret = new HashSet<List<RangerResourceDef>>();
+ if (policyType == RangerPolicy.POLICY_TYPE_AUDIT) {
+ policyType = RangerPolicy.POLICY_TYPE_ACCESS;
+ }
+
for (List<RangerResourceDef> hierarchy : getResourceHierarchies(policyType)) {
if (hierarchyHasAllResources(hierarchy, keys)) {
ret.add(hierarchy);
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
index c54ef17..407e3e7 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerAccessResult.java
@@ -155,7 +155,7 @@ public class RangerAccessResult {
public boolean getIsAuditedDetermined() { return isAuditedDetermined; }
- private void setIsAuditedDetermined(boolean value) { isAuditedDetermined = value; }
+ public void setIsAuditedDetermined(boolean value) { isAuditedDetermined = value; }
/**
* @return the isAudited
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 4e41adc..71f8dae 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
@@ -44,6 +44,7 @@ public interface RangerPolicyEngine {
String PLUGIN_AUDIT_EXCLUDE_ROLES = "ranger.plugin.audit.exclude.roles";
String PLUGIN_SUPER_USERS = "ranger.plugin.super.users";
String PLUGIN_SUPER_GROUPS = "ranger.plugin.super.groups";
+ String PLUGIN_AUDIT_FILTER = "ranger.plugin.audit.filters";
String USER_CURRENT = "{" + RangerAccessRequestUtil.KEY_USER + "}";
String RESOURCE_OWNER = "{OWNER}";
@@ -64,6 +65,8 @@ public interface RangerPolicyEngine {
Collection<RangerAccessResult> evaluatePolicies(Collection<RangerAccessRequest> requests, int policyType, RangerAccessResultProcessor resultProcessor);
+ void evaluateAuditPolicies(RangerAccessResult result);
+
RangerResourceACLs getResourceACLs(RangerAccessRequest request);
Set<String> getRolesFromUserAndGroups(String user, Set<String> groups);
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 b66d5a1..940cc65 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
@@ -162,6 +162,41 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
}
@Override
+ public void evaluateAuditPolicies(RangerAccessResult result) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerPolicyEngineImpl.evaluateAuditPolicies(result=" + result + ")");
+ }
+
+ RangerPolicyRepository tagPolicyRepository = policyEngine.getTagPolicyRepository();
+ RangerPolicyRepository policyRepository = policyEngine.getPolicyRepository();
+ RangerAccessRequest request = result.getAccessRequest();
+ boolean savedIsAuditedDetermined = result.getIsAuditedDetermined();
+ boolean savedIsAudited = result.getIsAudited();
+
+ result.setIsAudited(false);
+ result.setIsAuditedDetermined(false);
+
+ try {
+ if (tagPolicyRepository != null) {
+ evaluateTagAuditPolicies(request, result, tagPolicyRepository);
+ }
+
+ if (!result.getIsAuditedDetermined() && policyRepository != null) {
+ evaluateResourceAuditPolicies(request, result, policyRepository);
+ }
+ } finally {
+ if (!result.getIsAuditedDetermined()) {
+ result.setIsAudited(savedIsAudited);
+ result.setIsAuditedDetermined(savedIsAuditedDetermined);
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerPolicyEngineImpl.evaluateAuditPolicies(result=" + result + ")");
+ }
+ }
+
+ @Override
public RangerResourceACLs getResourceACLs(RangerAccessRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.getResourceACLs(request=" + request + ")");
@@ -861,6 +896,80 @@ public class RangerPolicyEngineImpl implements RangerPolicyEngine {
}
}
+ private void evaluateTagAuditPolicies(RangerAccessRequest request, RangerAccessResult result, RangerPolicyRepository tagPolicyRepository) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerPolicyEngineImpl.evaluateTagAuditPolicies(request=" + request + ", result=" + result + ")");
+ }
+
+ Set<RangerTagForEval> tags = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
+
+ if (CollectionUtils.isNotEmpty(tags)) {
+ Date accessTime = request.getAccessTime() != null ? request.getAccessTime() : new Date();
+ List<PolicyEvaluatorForTag> evaluators = tagPolicyRepository.getLikelyMatchPolicyEvaluators(tags, RangerPolicy.POLICY_TYPE_AUDIT, accessTime);
+
+ if (CollectionUtils.isNotEmpty(evaluators)) {
+ for (PolicyEvaluatorForTag policyEvaluator : evaluators) {
+ RangerPolicyEvaluator evaluator = policyEvaluator.getEvaluator();
+ RangerTagForEval tag = policyEvaluator.getTag();
+ RangerAccessRequest tagEvalRequest = new RangerTagAccessRequest(tag, tagPolicyRepository.getServiceDef(), request);
+ RangerAccessResult tagEvalResult = createAccessResult(tagEvalRequest, RangerPolicy.POLICY_TYPE_AUDIT);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("RangerPolicyEngineImpl.evaluateTagAuditPolicies: Evaluating Audit policies for tag (" + tag.getType() + ")" + "Tag Evaluator: " + policyEvaluator);
+ }
+
+ tagEvalResult.setAccessResultFrom(result);
+
+ result.incrementEvaluatedPoliciesCount();
+
+ evaluator.evaluate(tagEvalRequest, tagEvalResult);
+
+ if (tagEvalResult.getIsAuditedDetermined()) {
+ result.setIsAudited(tagEvalResult.getIsAudited());
+ break;
+ }
+ }
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerPolicyEngineImpl.evaluateTagAuditPolicies(request=" + request + ", result=" + result + ")");
+ }
+ }
+
+ private boolean evaluateResourceAuditPolicies(RangerAccessRequest request, RangerAccessResult result, RangerPolicyRepository policyRepository) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerPolicyEngineImpl.evaluateResourceAuditPolicies(request=" + request + ", result=" + result + ")");
+ }
+
+ boolean ret = false;
+ List<RangerPolicyEvaluator> evaluators = policyRepository.getLikelyMatchAuditPolicyEvaluators(request.getResource());
+
+ if (CollectionUtils.isNotEmpty(evaluators)) {
+ for (RangerPolicyEvaluator evaluator : evaluators) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerPolicyEngineImpl.evaluateResourceAuditPolicies(): Evaluating RangerPolicyEvaluator...: " + evaluator);
+ }
+
+ result.incrementEvaluatedPoliciesCount();
+
+ evaluator.evaluate(request, result);
+
+ if (result.getIsAuditedDetermined()) {
+ ret = true;
+
+ break;
+ }
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerPolicyEngineImpl.evaluateResourceAuditPolicies(request=" + request + ", result=" + result + "): ret=" + ret);
+ }
+
+ return ret;
+ }
+
private static class ServiceConfig {
private final Set<String> auditExcludedUsers;
private final Set<String> auditExcludedGroups;
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
index 169ed0f..0d6074f 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerPolicyRepository.java
@@ -23,16 +23,19 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.authorization.utils.JsonUtils;
import org.apache.ranger.plugin.contextenricher.RangerAbstractContextEnricher;
import org.apache.ranger.plugin.contextenricher.RangerContextEnricher;
import org.apache.ranger.plugin.contextenricher.RangerTagEnricher;
import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
+import org.apache.ranger.plugin.model.AuditFilter;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemDataMaskInfo;
import org.apache.ranger.plugin.model.RangerPolicyDelta;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper;
import org.apache.ranger.plugin.policyevaluator.RangerAbstractPolicyEvaluator;
+import org.apache.ranger.plugin.policyevaluator.RangerAuditPolicyEvaluator;
import org.apache.ranger.plugin.policyevaluator.RangerCachedPolicyEvaluator;
import org.apache.ranger.plugin.policyevaluator.RangerOptimizedPolicyEvaluator;
import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
@@ -52,6 +55,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import static org.apache.ranger.plugin.policyengine.RangerPolicyEngine.PLUGIN_AUDIT_FILTER;
+
public class RangerPolicyRepository {
private static final Log LOG = LogFactory.getLog(RangerPolicyRepository.class);
@@ -78,9 +83,11 @@ public class RangerPolicyRepository {
private final Map<String, RangerResourceTrie> policyResourceTrie;
private final Map<String, RangerResourceTrie> dataMaskResourceTrie;
private final Map<String, RangerResourceTrie> rowFilterResourceTrie;
+ private final Map<String, RangerResourceTrie> auditFilterResourceTrie;
private List<RangerPolicyEvaluator> policyEvaluators;
private List<RangerPolicyEvaluator> dataMaskPolicyEvaluators;
private List<RangerPolicyEvaluator> rowFilterPolicyEvaluators;
+ private final List<RangerPolicyEvaluator> auditPolicyEvaluators;
private Map<Long, RangerPolicyEvaluator> policyEvaluatorsMap;
private boolean isContextEnrichersShared = false;
private boolean isPreCleaned = false;
@@ -96,6 +103,7 @@ public class RangerPolicyRepository {
this.policyEvaluators = new ArrayList<>(other.policyEvaluators);
this.dataMaskPolicyEvaluators = new ArrayList<>(other.dataMaskPolicyEvaluators);
this.rowFilterPolicyEvaluators = new ArrayList<>(other.rowFilterPolicyEvaluators);
+ this.auditPolicyEvaluators = new ArrayList<>(other.auditPolicyEvaluators);
this.auditModeEnum = other.auditModeEnum;
this.componentServiceName = other.componentServiceName;
this.componentServiceDef = other.componentServiceDef;
@@ -131,6 +139,16 @@ public class RangerPolicyRepository {
this.rowFilterResourceTrie = null;
}
+ if (other.auditFilterResourceTrie != null) {
+ this.auditFilterResourceTrie = new HashMap<>();
+
+ for (Map.Entry<String, RangerResourceTrie> entry : other.auditFilterResourceTrie.entrySet()) {
+ auditFilterResourceTrie.put(entry.getKey(), new RangerResourceTrie(entry.getValue()));
+ }
+ } else {
+ this.auditFilterResourceTrie = null;
+ }
+
if (other.accessAuditCache != null) {
int auditResultCacheSize = other.accessAuditCache.size();
@@ -224,6 +242,12 @@ public class RangerPolicyRepository {
}
}
+ if (auditFilterResourceTrie != null) {
+ for (Map.Entry<String, RangerResourceTrie> entry : auditFilterResourceTrie.entrySet()) {
+ entry.getValue().wrapUpUpdate();
+ }
+ }
+
if (StringUtils.isEmpty(zoneName)) {
if (CollectionUtils.isNotEmpty(other.getPolicies())) {
if (CollectionUtils.isNotEmpty(this.getPolicies())) {
@@ -303,18 +327,22 @@ public class RangerPolicyRepository {
if (StringUtils.isEmpty(zoneName)) {
this.contextEnrichers = Collections.unmodifiableList(buildContextEnrichers(options));
+ this.auditPolicyEvaluators = buildAuditPolicyEvaluators(servicePolicies.getServiceConfig());
} else {
this.contextEnrichers = null;
+ this.auditPolicyEvaluators = Collections.emptyList();
}
if (options.disableTrieLookupPrefilter) {
- policyResourceTrie = null;
- dataMaskResourceTrie = null;
- rowFilterResourceTrie = null;
+ policyResourceTrie = null;
+ dataMaskResourceTrie = null;
+ rowFilterResourceTrie = null;
+ auditFilterResourceTrie = null;
} else {
- policyResourceTrie = createResourceTrieMap(policyEvaluators, options.optimizeTrieForRetrieval);
- dataMaskResourceTrie = createResourceTrieMap(dataMaskPolicyEvaluators, options.optimizeTrieForRetrieval);
- rowFilterResourceTrie = createResourceTrieMap(rowFilterPolicyEvaluators, options.optimizeTrieForRetrieval);
+ policyResourceTrie = createResourceTrieMap(policyEvaluators, options.optimizeTrieForRetrieval);
+ dataMaskResourceTrie = createResourceTrieMap(dataMaskPolicyEvaluators, options.optimizeTrieForRetrieval);
+ rowFilterResourceTrie = createResourceTrieMap(rowFilterPolicyEvaluators, options.optimizeTrieForRetrieval);
+ auditFilterResourceTrie = createResourceTrieMap(auditPolicyEvaluators, options.optimizeTrieForRetrieval);
}
}
@@ -353,19 +381,50 @@ public class RangerPolicyRepository {
if (StringUtils.isEmpty(zoneName)) {
this.contextEnrichers = Collections.unmodifiableList(buildContextEnrichers(options));
+ this.auditPolicyEvaluators = buildAuditPolicyEvaluators(tagPolicies.getServiceConfig());
} else {
this.contextEnrichers = null;
+ this.auditPolicyEvaluators = Collections.emptyList();
}
if (options.disableTrieLookupPrefilter) {
- policyResourceTrie = null;
- dataMaskResourceTrie = null;
- rowFilterResourceTrie = null;
+ policyResourceTrie = null;
+ dataMaskResourceTrie = null;
+ rowFilterResourceTrie = null;
+ auditFilterResourceTrie = null;
} else {
- policyResourceTrie = createResourceTrieMap(policyEvaluators, options.optimizeTrieForRetrieval);
- dataMaskResourceTrie = createResourceTrieMap(dataMaskPolicyEvaluators, options.optimizeTrieForRetrieval);
- rowFilterResourceTrie = createResourceTrieMap(rowFilterPolicyEvaluators, options.optimizeTrieForRetrieval);
+ policyResourceTrie = createResourceTrieMap(policyEvaluators, options.optimizeTrieForRetrieval);
+ dataMaskResourceTrie = createResourceTrieMap(dataMaskPolicyEvaluators, options.optimizeTrieForRetrieval);
+ rowFilterResourceTrie = createResourceTrieMap(rowFilterPolicyEvaluators, options.optimizeTrieForRetrieval);
+ auditFilterResourceTrie = createResourceTrieMap(auditPolicyEvaluators, options.optimizeTrieForRetrieval);
+ }
+ }
+
+ private List<RangerPolicyEvaluator> buildAuditPolicyEvaluators(Map<String, String> svcConfigs) {
+ List<RangerPolicyEvaluator> ret = Collections.emptyList();
+ String jsonStr = svcConfigs != null ? svcConfigs.get(PLUGIN_AUDIT_FILTER) : null;
+
+ if (StringUtils.isNotBlank(jsonStr)) {
+ List<AuditFilter> auditFilters = JsonUtils.jsonToAuditFilterList(jsonStr);
+ int filterCount = auditFilters != null ? auditFilters.size() : 0;
+
+ if (filterCount > 0) {
+ ret = new ArrayList<>(filterCount);
+
+ // set priority so that policies will be evaluated in the same order as in the list
+ int policyPriority = filterCount;
+
+ for (AuditFilter auditFilter : auditFilters) {
+ RangerAuditPolicyEvaluator evaluator = new RangerAuditPolicyEvaluator(auditFilter, policyPriority--);
+
+ evaluator.init(evaluator.getAuditPolicy(), serviceDef, options);
+
+ ret.add(evaluator);
+ }
+ }
}
+
+ return ret;
}
@Override
@@ -419,6 +478,16 @@ public class RangerPolicyRepository {
}
sb.append("} ");
+ sb.append("auditPolicyEvaluators={");
+ if (this.auditPolicyEvaluators != null) {
+ for (RangerPolicyEvaluator policyEvaluator : auditPolicyEvaluators) {
+ if (policyEvaluator != null) {
+ sb.append(policyEvaluator).append(" ");
+ }
+ }
+ }
+ sb.append("} ");
+
sb.append("contextEnrichers={");
if (contextEnrichers != null) {
for (RangerContextEnricher contextEnricher : contextEnrichers) {
@@ -599,6 +668,10 @@ public class RangerPolicyRepository {
return rowFilterPolicyEvaluators;
}
+ List<RangerPolicyEvaluator> getAuditPolicyEvaluators() {
+ return auditPolicyEvaluators;
+ }
+
String getAppId() { return appId; }
RangerPolicyEngineOptions getOptions() { return options; }
@@ -632,6 +705,7 @@ public class RangerPolicyRepository {
if (CollectionUtils.isNotEmpty(ret)) {
switch (policyType) {
case RangerPolicy.POLICY_TYPE_ACCESS:
+ case RangerPolicy.POLICY_TYPE_AUDIT:
Collections.sort(ret, PolicyEvaluatorForTag.EVAL_ORDER_COMPARATOR);
break;
case RangerPolicy.POLICY_TYPE_DATAMASK:
@@ -669,6 +743,8 @@ public class RangerPolicyRepository {
return getLikelyMatchDataMaskPolicyEvaluators(resource);
case RangerPolicy.POLICY_TYPE_ROWFILTER:
return getLikelyMatchRowFilterPolicyEvaluators(resource);
+ case RangerPolicy.POLICY_TYPE_AUDIT:
+ return getLikelyMatchAuditPolicyEvaluators(resource);
default:
return Collections.EMPTY_LIST;
}
@@ -699,6 +775,12 @@ public class RangerPolicyRepository {
return rowFilterResourceTrie == null || StringUtils.isEmpty(resourceStr) ? getRowFilterPolicyEvaluators() : getLikelyMatchPolicyEvaluators(rowFilterResourceTrie, resource);
}
+ List<RangerPolicyEvaluator> getLikelyMatchAuditPolicyEvaluators(RangerAccessResource resource) {
+ String resourceStr = resource == null ? null : resource.getAsString();
+
+ return auditFilterResourceTrie == null || StringUtils.isEmpty(resourceStr) ? getAuditPolicyEvaluators() : getLikelyMatchPolicyEvaluators(auditFilterResourceTrie, resource);
+ }
+
private List<RangerPolicyEvaluator> getLikelyMatchPolicyEvaluators(Map<String, RangerResourceTrie> resourceTrie, RangerAccessResource resource) {
List<RangerPolicyEvaluator> ret = Collections.EMPTY_LIST;
@@ -989,6 +1071,14 @@ public class RangerPolicyRepository {
LOG.debug("rowFilter policy evaluation order: #" + (++order) + " - policy id=" + policy.getId() + "; name=" + policy.getName() + "; evalOrder=" + policyEvaluator.getEvalOrder());
}
+
+ LOG.debug("audit policy evaluation order: " + this.auditPolicyEvaluators.size() + " policies");
+ order = 0;
+ for(RangerPolicyEvaluator policyEvaluator : this.auditPolicyEvaluators) {
+ RangerPolicy policy = policyEvaluator.getPolicy();
+
+ LOG.debug("rowFilter policy evaluation order: #" + (++order) + " - policy id=" + policy.getId() + "; name=" + policy.getName() + "; evalOrder=" + policyEvaluator.getEvalOrder());
+ }
}
}
@@ -1171,7 +1261,7 @@ public class RangerPolicyRepository {
return ret;
}
- private Map<String, RangerResourceTrie> createResourceTrieMap(List<RangerPolicyEvaluator> evaluators, boolean optimizeTrieForRetrieval) {
+ private Map<String, RangerResourceTrie> createResourceTrieMap(List<? extends RangerPolicyEvaluator> evaluators, boolean optimizeTrieForRetrieval) {
final Map<String, RangerResourceTrie> ret;
if (serviceDef != null && CollectionUtils.isNotEmpty(serviceDef.getResources())) {
@@ -1278,7 +1368,9 @@ public class RangerPolicyRepository {
LOG.warn("RangerPolicyEngine: ignoring policy id=" + policy.getId() + " - invalid policyType '" + policy.getPolicyType() + "'");
}
- policyEvaluatorsMap.put(policy.getId(), ret);
+ if (policy.getPolicyType() != RangerPolicy.POLICY_TYPE_AUDIT) {
+ policyEvaluatorsMap.put(policy.getId(), ret);
+ }
}
}
}
@@ -1401,6 +1493,9 @@ public class RangerPolicyRepository {
case RangerPolicy.POLICY_TYPE_ROWFILTER:
ret = rowFilterResourceTrie;
break;
+ case RangerPolicy.POLICY_TYPE_AUDIT:
+ ret = auditFilterResourceTrie;
+ break;
default:
ret = null;
}
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java
new file mode 100644
index 0000000..7e1b3b4
--- /dev/null
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerAuditPolicyEvaluator.java
@@ -0,0 +1,405 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ranger.plugin.policyevaluator;
+
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.model.AuditFilter;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef.RangerResourceDef;
+import org.apache.ranger.plugin.policyengine.*;
+import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
+import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+public class RangerAuditPolicyEvaluator extends RangerDefaultPolicyEvaluator {
+ private static final Log LOG = LogFactory.getLog(RangerAuditPolicyEvaluator.class);
+
+ private final RangerAuditPolicy auditPolicy;
+ private final boolean matchAnyResource;
+ private final List<RangerAuditPolicyItemEvaluator> auditItemEvaluators = new ArrayList<>();
+
+ public RangerAuditPolicyEvaluator(AuditFilter auditFilter, int priority) {
+ this.auditPolicy = new RangerAuditPolicy(auditFilter, priority);
+ this.matchAnyResource = MapUtils.isEmpty(auditFilter.getResources());
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("RangerAuditPolicyEvaluator(auditFilter=" + auditFilter + ", priority=" + priority + ", matchAnyResource=" + matchAnyResource + ")");
+ }
+ }
+
+ public RangerAuditPolicy getAuditPolicy() { return auditPolicy; }
+
+ @Override
+ public void init(RangerPolicy policy, RangerServiceDef serviceDef, RangerPolicyEngineOptions options) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerAuditPolicyEvaluator.init(" + auditPolicy.getId() + ")");
+ }
+
+ super.init(auditPolicy, serviceDef, options);
+
+ int policyItemIndex = 1;
+
+ for (RangerAuditPolicyItem policyItem : auditPolicy.getAuditPolicyItems()) {
+ RangerAuditPolicyItemEvaluator itemEvaluator = new RangerAuditPolicyItemEvaluator(serviceDef, auditPolicy, policyItem, policyItemIndex, options);
+ auditItemEvaluators.add(itemEvaluator);
+ policyItemIndex = policyItemIndex + 1;
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerAuditPolicyEvaluator.init(" + auditPolicy.getId() + ")");
+ }
+ }
+
+ @Override
+ public boolean isAncestorOf(RangerResourceDef resourceDef) {
+ return matchAnyResource ? true : super.isAncestorOf(resourceDef);
+ }
+
+ @Override
+ public void evaluate(RangerAccessRequest request, RangerAccessResult result) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerAuditPolicyEvaluator.evaluate(" + auditPolicy.getId() + ", " + request + ", " + result + ")");
+ }
+
+ if (request != null && result != null) {
+ if (!result.getIsAuditedDetermined()) {
+ if (matchResource(request)) {
+ evaluatePolicyItems(request, result);
+ }
+ }
+ }
+
+ if(LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerAuditPolicyEvaluator.evaluate(" + auditPolicy.getId() + ", " + request + ", " + result + ")");
+ }
+ }
+
+ @Override
+ protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef) {
+ super.preprocessPolicy(policy, serviceDef);
+
+ Map<String, Collection<String>> impliedAccessGrants = getImpliedAccessGrants(serviceDef);
+
+ if(impliedAccessGrants == null || impliedAccessGrants.isEmpty()) {
+ return;
+ }
+
+ preprocessPolicyItems(auditPolicy.getAuditPolicyItems(), impliedAccessGrants);
+ }
+
+ private boolean matchResource(RangerAccessRequest request) {
+ final boolean ret;
+
+ if (!matchAnyResource) {
+ RangerPolicyResourceMatcher.MatchType matchType;
+
+ if (RangerTagAccessRequest.class.isInstance(request)) {
+ matchType = ((RangerTagAccessRequest) request).getMatchType();
+
+ if (matchType == RangerPolicyResourceMatcher.MatchType.ANCESTOR) {
+ matchType = RangerPolicyResourceMatcher.MatchType.SELF;
+ }
+ } else {
+ RangerPolicyResourceMatcher resourceMatcher = getPolicyResourceMatcher();
+
+ if (resourceMatcher != null) {
+ matchType = resourceMatcher.getMatchType(request.getResource(), request.getContext());
+ } else {
+ matchType = RangerPolicyResourceMatcher.MatchType.NONE;
+ }
+ }
+
+ if (request.isAccessTypeAny()) {
+ ret = matchType != RangerPolicyResourceMatcher.MatchType.NONE;
+ } else if (request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
+ ret = matchType != RangerPolicyResourceMatcher.MatchType.NONE;
+ } else {
+ ret = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.SELF_AND_ALL_DESCENDANTS;
+ }
+ } else {
+ ret = true;
+ }
+
+ return ret;
+ }
+
+ private void evaluatePolicyItems(RangerAccessRequest request, RangerAccessResult result) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerAuditPolicyEvaluator.evaluatePolicyItems(" + auditPolicy.getId() + ", " + request + ", " + result + ")");
+ }
+
+ for (RangerAuditPolicyItemEvaluator itemEvaluator : auditItemEvaluators) {
+ if (itemEvaluator.isMatch(request, result)) {
+ Boolean isAudited = itemEvaluator.getIsAudited();
+
+ if (isAudited != null) {
+ result.setIsAudited(isAudited);
+
+ break;
+ }
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerAuditPolicyEvaluator.evaluatePolicyItems(" + auditPolicy.getId() + ", " + request + ", " + result + ")");
+ }
+ }
+
+ @Override
+ public StringBuilder toString(StringBuilder sb) {
+ sb.append("RangerAuditPolicyEvaluator={");
+
+ super.toString(sb);
+
+ sb.append("auditPolicy={");
+ auditPolicy.toString(sb);
+ sb.append("}");
+
+ sb.append(" matchAnyResource={").append(matchAnyResource).append("}");
+
+ sb.append("}");
+
+ return sb;
+ }
+
+
+ public static class RangerAuditPolicyItemEvaluator extends RangerDefaultPolicyItemEvaluator {
+ private final RangerAuditPolicyItem auditPolicyItem;
+ private final boolean matchAnyResult;
+ private final boolean matchAnyUser;
+ private final boolean matchAnyAction;
+ private final boolean hasResourceOwner;
+
+ public RangerAuditPolicyItemEvaluator(RangerServiceDef serviceDef, RangerPolicy policy, RangerAuditPolicyItem policyItem, int policyItemIndex, RangerPolicyEngineOptions options) {
+ super(serviceDef, policy, policyItem, POLICY_ITEM_TYPE_ALLOW, policyItemIndex, options);
+
+ this.auditPolicyItem = policyItem;
+ this.matchAnyResult = policyItem.getAccessResult() == null;
+
+ List<String> users = policyItem.getUsers();
+ List<String> groups = policyItem.getGroups();
+ List<String> roles = policyItem.getRoles();
+ this.matchAnyUser = (CollectionUtils.isEmpty(users) && CollectionUtils.isEmpty(groups) && CollectionUtils.isEmpty(roles)) ||
+ (CollectionUtils.isNotEmpty(groups) && groups.contains(RangerPolicyEngine.GROUP_PUBLIC)) ||
+ (CollectionUtils.isNotEmpty(users) && users.contains(RangerPolicyEngine.USER_CURRENT));
+ this.matchAnyAction = policyItem.getActions().isEmpty() && policyItem.getAccessTypes().isEmpty();
+ this.hasResourceOwner = CollectionUtils.isNotEmpty(users) && users.contains(RangerPolicyEngine.RESOURCE_OWNER);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("RangerAuditPolicyItemEvaluator(" + auditPolicyItem + ", matchAnyUser=" + matchAnyUser + ", matchAnyAction=" + matchAnyAction + ", hasResourceOwner=" + hasResourceOwner + ")");
+ }
+ }
+
+ public Boolean getIsAudited() { return auditPolicyItem.getIsAudited(); }
+
+ public boolean isMatch(RangerAccessRequest request, RangerAccessResult result) {
+ boolean ret = matchAccessResult(result) &&
+ matchUserGroupRole(request) &&
+ matchAction(request);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("RangerAuditPolicyItemEvaluator.isMatch(" + request + ", " + result + "): ret=" + ret);
+ }
+
+ return ret;
+ }
+
+ private boolean matchAccessResult(RangerAccessResult result) {
+ boolean ret = matchAnyResult;
+
+ if (!ret) {
+ switch (auditPolicyItem.getAccessResult()) {
+ case DENIED:
+ ret = result.getIsAccessDetermined() && !result.getIsAllowed();
+ break;
+
+ case ALLOWED:
+ ret = result.getIsAccessDetermined() && result.getIsAllowed();
+ break;
+
+ case NOT_DETERMINED:
+ ret = !result.getIsAccessDetermined();
+ break;
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("RangerAuditPolicyItemEvaluator.matchAccessResult(" + result + "): ret=" + ret);
+ }
+
+ return ret;
+ }
+
+ private boolean matchUserGroupRole(RangerAccessRequest request) {
+ boolean ret = matchAnyUser;
+
+ if (!ret) {
+
+ if (auditPolicyItem.getUsers() != null && request.getUser() != null) {
+ ret = auditPolicyItem.getUsers().contains(request.getUser());
+
+ if (!ret && hasResourceOwner) {
+ String owner = request.getResource() != null ? request.getResource().getOwnerUser() : null;
+ ret = request.getUser().equals(owner);
+ }
+ }
+
+ if (!ret && auditPolicyItem.getGroups() != null && request.getUserGroups() != null) {
+ ret = CollectionUtils.containsAny(auditPolicyItem.getGroups(), request.getUserGroups());
+ }
+
+ if (!ret && auditPolicyItem.getRoles() != null) {
+ ret = CollectionUtils.containsAny(auditPolicyItem.getRoles(), RangerAccessRequestUtil.getCurrentUserRolesFromContext(request.getContext()));
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("RangerAuditPolicyItemEvaluator.matchUserGroupRole(" + request + "): ret=" + ret);
+ }
+
+ return ret;
+ }
+
+ private boolean matchAction(RangerAccessRequest request) {
+ boolean ret = matchAnyAction;
+
+ if (!ret) {
+ if (request.getAction() != null) {
+ ret = auditPolicyItem.getActions().contains(request.getAction());
+ }
+
+ if (!ret && request.getAccessType() != null) {
+ ret = auditPolicyItem.getAccessTypes().contains(request.getAccessType());
+ }
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("RangerAuditPolicyItemEvaluator.matchAction(" + request + "): ret=" + ret);
+ }
+
+ return ret;
+ }
+ }
+
+ public static class RangerAuditPolicy extends RangerPolicy {
+ private final List<RangerAuditPolicyItem> auditPolicyItems;
+
+ public RangerAuditPolicy(AuditFilter auditFilter, int priority) {
+ setId((long)priority);
+ setResources(auditFilter.getResources());
+ setPolicyType(POLICY_TYPE_AUDIT);
+ setPolicyPriority(priority);
+
+ this.auditPolicyItems = Collections.singletonList(new RangerAuditPolicyItem(auditFilter));
+ }
+
+ public List<RangerAuditPolicyItem> getAuditPolicyItems() { return auditPolicyItems; }
+ }
+
+ public static class RangerAuditPolicyItem extends RangerPolicyItem {
+ private final AuditFilter.AccessResult accessResult;
+ private final Set<String> actions;
+ private final Set<String> accessTypes;
+ private final Boolean isAudited;
+
+ public RangerAuditPolicyItem(AuditFilter auditFilter) {
+ super(getPolicyItemAccesses(auditFilter.getAccessTypes()), auditFilter.getUsers(), auditFilter.getGroups(), auditFilter.getRoles(), null, null);
+
+ this.accessResult = auditFilter.getAccessResult();
+ this.actions = auditFilter.getActions() != null ? new HashSet<>(auditFilter.getActions()) : Collections.emptySet();
+ this.accessTypes = auditFilter.getAccessTypes() != null ? new HashSet<>(auditFilter.getAccessTypes()) : Collections.emptySet();
+ this.isAudited = auditFilter.getIsAudited();
+ }
+
+ public Set<String> getActions() { return actions; }
+
+ public Set<String> getAccessTypes() { return accessTypes; }
+
+ public AuditFilter.AccessResult getAccessResult() { return accessResult; }
+
+ public Boolean getIsAudited() { return isAudited; }
+
+ @Override
+ public StringBuilder toString(StringBuilder sb) {
+ if (sb == null) {
+ sb = new StringBuilder();
+ }
+
+ sb.append("RangerAuditPolicyItem={");
+ super.toString(sb);
+ sb.append(" accessResult={").append(accessResult).append("}");
+
+ sb.append(" actions={");
+ if (actions != null) {
+ for (String action : actions) {
+ if (action != null) {
+ sb.append(action).append(" ");
+ }
+ }
+ }
+ sb.append("}");
+
+ sb.append(" accessTypes={");
+ if (accessTypes != null) {
+ for (String accessTypes : accessTypes) {
+ if (accessTypes != null) {
+ sb.append(accessTypes).append(" ");
+ }
+ }
+ }
+ sb.append("}");
+
+ sb.append(" isAudited={").append(isAudited).append("}");
+ sb.append("}");
+
+ return sb;
+ }
+
+ private static List<RangerPolicyItemAccess> getPolicyItemAccesses(List<String> accessTypes) {
+ final List<RangerPolicyItemAccess> ret;
+
+ if (accessTypes != null) {
+ ret = new ArrayList<>(accessTypes.size());
+
+ for (String accessType : accessTypes) {
+ ret.add(new RangerPolicyItemAccess(accessType));
+ }
+ } else {
+ ret = Collections.emptyList();
+ }
+
+ return ret;
+ }
+ }
+}
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 07fb638..d64d226 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
@@ -856,7 +856,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
return sb;
}
- private void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef) {
+ protected void preprocessPolicy(RangerPolicy policy, RangerServiceDef serviceDef) {
if(policy == null || (!hasAllow() && !hasDeny()) || serviceDef == null) {
return;
}
@@ -875,7 +875,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
preprocessPolicyItems(policy.getRowFilterPolicyItems(), impliedAccessGrants);
}
- private void preprocessPolicyItems(List<? extends RangerPolicyItem> policyItems, Map<String, Collection<String>> impliedAccessGrants) {
+ protected void preprocessPolicyItems(List<? extends RangerPolicyItem> policyItems, Map<String, Collection<String>> impliedAccessGrants) {
for(RangerPolicyItem policyItem : policyItems) {
if(CollectionUtils.isEmpty(policyItem.getAccesses())) {
continue;
@@ -910,7 +910,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator
}
}
- private Map<String, Collection<String>> getImpliedAccessGrants(RangerServiceDef serviceDef) {
+ protected Map<String, Collection<String>> getImpliedAccessGrants(RangerServiceDef serviceDef) {
Map<String, Collection<String>> ret = null;
if(serviceDef != null && !CollectionUtils.isEmpty(serviceDef.getAccessTypes())) {
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 9794881..f218900 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
@@ -202,7 +202,7 @@ public class RangerDefaultPolicyResourceMatcher implements RangerPolicyResourceM
errorText = "policyResources is null or empty, or serviceDef is null.";
}
- if (allMatchers == null) {
+ if (allMatchers == null && policyType != RangerPolicy.POLICY_TYPE_AUDIT) {
serviceDefHelper = null;
validResourceHierarchy = null;
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
index 2d9bc73..873553a 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java
@@ -364,6 +364,10 @@ public class RangerBasePlugin {
}
+ if (policyEngine != null) {
+ policyEngine.evaluateAuditPolicies(ret);
+ }
+
if (resultProcessor != null) {
resultProcessor.processResult(ret);
}
@@ -399,6 +403,12 @@ public class RangerBasePlugin {
}
}
+ if (policyEngine != null && CollectionUtils.isNotEmpty(ret)) {
+ for (RangerAccessResult result : ret) {
+ policyEngine.evaluateAuditPolicies(result);
+ }
+ }
+
if (resultProcessor != null) {
resultProcessor.processResults(ret);
}
@@ -408,22 +418,36 @@ public class RangerBasePlugin {
public RangerAccessResult evalDataMaskPolicies(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor) {
RangerPolicyEngine policyEngine = this.policyEngine;
+ RangerAccessResult ret = null;
if(policyEngine != null) {
- return policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_DATAMASK, resultProcessor);
+ ret = policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_DATAMASK, resultProcessor);
+
+ policyEngine.evaluateAuditPolicies(ret);
}
- return null;
+ return ret;
}
public RangerAccessResult evalRowFilterPolicies(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor) {
RangerPolicyEngine policyEngine = this.policyEngine;
+ RangerAccessResult ret = null;
if(policyEngine != null) {
- return policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_ROWFILTER, resultProcessor);
+ ret = policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_ROWFILTER, resultProcessor);
+
+ policyEngine.evaluateAuditPolicies(ret);
}
- return null;
+ return ret;
+ }
+
+ public void evalAuditPolicies(RangerAccessResult result) {
+ RangerPolicyEngine policyEngine = this.policyEngine;
+
+ if (policyEngine != null) {
+ policyEngine.evaluateAuditPolicies(result);
+ }
}
public RangerResourceAccessInfo getResourceAccessInfo(RangerAccessRequest request) {
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java
index 6ab068f..c3d7816 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/ServicePolicies.java
@@ -201,6 +201,8 @@ public class ServicePolicies implements java.io.Serializable {
private List<RangerPolicy> policies;
private RangerServiceDef serviceDef;
private String auditMode = RangerPolicyEngine.AUDIT_DEFAULT;
+ private Map<String, String> serviceConfig;
+
/**
* @return the serviceName
*/
@@ -282,6 +284,14 @@ public class ServicePolicies implements java.io.Serializable {
this.auditMode = auditMode;
}
+ public Map<String, String> getServiceConfig() {
+ return serviceConfig;
+ }
+
+ public void setServiceConfig(Map<String, String> serviceConfig) {
+ this.serviceConfig = serviceConfig;
+ }
+
@Override
public String toString() {
return "serviceName=" + serviceName + ", "
@@ -291,6 +301,7 @@ public class ServicePolicies implements java.io.Serializable {
+ "policies=" + policies + ", "
+ "serviceDef=" + serviceDef + ", "
+ "auditMode=" + auditMode
+ + "serviceConfig=" + serviceConfig
;
}
}
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
index 63fccd0..046e15f 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
@@ -430,6 +430,21 @@ public class TestPolicyEngine {
runTestsFromResourceFiles(resourceFiles);
}
+ @Test
+ public void testPolicyEngine_auditFilterHdfs() {
+ String[] resourceFiles = {"/policyengine/test_policyengine_audit_filter_hdfs.json"};
+
+ runTestsFromResourceFiles(resourceFiles);
+ }
+
+
+ @Test
+ public void testPolicyEngine_auditFilterHive() {
+ String[] resourceFiles = {"/policyengine/test_policyengine_audit_filter_hive.json"};
+
+ runTestsFromResourceFiles(resourceFiles);
+ }
+
private void runTestsFromResourceFiles(String[] resourceNames) {
for(String resourceName : resourceNames) {
InputStream inStream = this.getClass().getResourceAsStream(resourceName);
@@ -461,6 +476,7 @@ public class TestPolicyEngine {
tagPolicies.setServiceName(testCase.tagPolicyInfo.serviceName);
tagPolicies.setServiceDef(testCase.tagPolicyInfo.serviceDef);
tagPolicies.setPolicies(testCase.tagPolicyInfo.tagPolicies);
+ tagPolicies.setServiceConfig(testCase.tagPolicyInfo.serviceConfig);
if (StringUtils.isNotBlank(testCase.auditMode)) {
tagPolicies.setAuditMode(testCase.auditMode);
@@ -563,7 +579,6 @@ public class TestPolicyEngine {
}
private void runTestCaseTests(RangerPolicyEngine policyEngine, RangerPolicyEngine policyEngineForEvaluatingWithACLs, RangerServiceDef serviceDef, String testName, List<TestData> tests) {
-
RangerAccessRequest request = null;
for(TestData test : tests) {
@@ -643,12 +658,16 @@ public class TestPolicyEngine {
result = policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_ACCESS, auditHandler);
+ policyEngine.evaluateAuditPolicies(result);
+
assertNotNull("result was null! - " + test.name, result);
assertEquals("isAllowed mismatched! - " + test.name, expected.getIsAllowed(), result.getIsAllowed());
assertEquals("isAudited mismatched! - " + test.name, expected.getIsAudited(), result.getIsAudited());
result = policyEngineForEvaluatingWithACLs.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_ACCESS, auditHandler);
+ policyEngine.evaluateAuditPolicies(result);
+
assertNotNull("result was null! - " + test.name, result);
assertEquals("isAllowed mismatched! - " + test.name, expected.getIsAllowed(), result.getIsAllowed());
assertEquals("isAudited mismatched! - " + test.name, expected.getIsAudited(), result.getIsAudited());
@@ -660,6 +679,8 @@ public class TestPolicyEngine {
result = policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_DATAMASK, auditHandler);
+ policyEngine.evaluateAuditPolicies(result);
+
assertNotNull("result was null! - " + test.name, result);
assertEquals("maskType mismatched! - " + test.name, expected.getMaskType(), result.getMaskType());
assertEquals("maskCondition mismatched! - " + test.name, expected.getMaskCondition(), result.getMaskCondition());
@@ -668,6 +689,8 @@ public class TestPolicyEngine {
result = policyEngineForEvaluatingWithACLs.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_DATAMASK, auditHandler);
+ policyEngine.evaluateAuditPolicies(result);
+
assertNotNull("result was null! - " + test.name, result);
assertEquals("maskType mismatched! - " + test.name, expected.getMaskType(), result.getMaskType());
assertEquals("maskCondition mismatched! - " + test.name, expected.getMaskCondition(), result.getMaskCondition());
@@ -682,12 +705,16 @@ public class TestPolicyEngine {
result = policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_ROWFILTER, auditHandler);
+ policyEngine.evaluateAuditPolicies(result);
+
assertNotNull("result was null! - " + test.name, result);
assertEquals("filterExpr mismatched! - " + test.name, expected.getFilterExpr(), result.getFilterExpr());
assertEquals("policyId mismatched! - " + test.name, expected.getPolicyId(), result.getPolicyId());
result = policyEngineForEvaluatingWithACLs.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_ROWFILTER, auditHandler);
+ policyEngine.evaluateAuditPolicies(result);
+
assertNotNull("result was null! - " + test.name, result);
assertEquals("filterExpr mismatched! - " + test.name, expected.getFilterExpr(), result.getFilterExpr());
assertEquals("policyId mismatched! - " + test.name, expected.getPolicyId(), result.getPolicyId());
@@ -745,6 +772,7 @@ public class TestPolicyEngine {
class TagPolicyInfo {
public String serviceName;
public RangerServiceDef serviceDef;
+ public Map<String, String> serviceConfig;
public List<RangerPolicy> tagPolicies;
}
}
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_audit_filter_hdfs.json b/agents-common/src/test/resources/policyengine/test_policyengine_audit_filter_hdfs.json
new file mode 100644
index 0000000..153b39b
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_audit_filter_hdfs.json
@@ -0,0 +1,120 @@
+{
+ "serviceName":"hdfsdev",
+
+ "serviceDef":{ "name":"hdfs", "id":1,
+ "resources":[
+ {"name":"path","type":"path","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Resource Path","description":"HDFS file or directory path"}
+ ],
+
+ "accessTypes":[
+ {"name":"read","label":"Read"},
+ {"name":"write","label":"Write"},
+ {"name":"execute","label":"Execute"}
+ ]
+ },
+
+ "serviceConfig": {
+ "ranger.plugin.audit.filters": "[ {'accessResult': 'DENIED', 'isAudited': true}, {'users': ['unaudited-user1'], 'groups': ['unaudited-group1'], 'roles': ['unaudited-role1'], 'isAudited': false}, {'actions': [ 'listStatus', 'getfileinfo' ], 'accessTypes':['execute'], 'isAudited': false}, {'resources':{'path':{'values':['/audited'], 'isRecursive': true}},'isAudited': true}, {'resources':{'path':{'values':['/unaudited'], 'isRecursive': true}},'isAudited': false} ]"
+ },
+
+ "policies":[
+ { "id":10,"name":"/audited/","isEnabled":true,"isAuditEnabled":true,
+ "isDenyAllElse": true,
+ "resources":{"path":{"values":["/audited"],"isRecursive":true}},
+ "policyItems":[
+ {"accesses":[{"type":"write","isAllowed":true},{"type":"read","isAllowed":true},{"type":"execute","isAllowed":true}],"users":["allowed-user1", "unaudited-user1"], "groups": ["unaudited-group1"], "roles": ["unaudited-role1"] }
+ ]
+ },
+ { "id":11,"name":"/unaudited/","isEnabled":true,"isAuditEnabled":true,
+ "isDenyAllElse": true,
+ "resources":{"path":{"values":["/unaudited"],"isRecursive":true}},
+ "policyItems":[
+ {"accesses":[{"type":"write","isAllowed":true},{"type":"read","isAllowed":true},{"type":"execute","isAllowed":true}],"users":["allowed-user1"]}
+ ]
+ }
+ ],
+
+ "tagPolicyInfo": {
+ "serviceName":"tagdev",
+
+ "serviceDef": { "name": "tag", "id": 100,
+ "resources": [
+ { "name": "tag", "type": "string", "level": 1, "mandatory": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard": false, "ignoreCase": false }, "label": "TAG", "description": "TAG" }
+ ],
+ "accessTypes": [
+ { "name": "hdfs:read", "label": "hdfs:Read" },
+ { "name": "hdfs:write", "label": "hdfs:Write" },
+ { "name": "hdfs:execute", "label": "hdfs:Execute" }
+ ]
+ },
+
+ "serviceConfig": {
+ "ranger.plugin.audit.filters": "[ {'resources':{'tag':{'values':['AUDIT_ALL_ACCESS']}},'isAudited': true}, {'resources':{'tag':{'values':['NO_AUDIT_ACCESS']}},'isAudited': false} ]"
+ },
+
+ "tagPolicies":[
+ { "id":101, "name":"PII", "isEnabled":true, "isAuditEnabled":true,
+ "resources":{"tag":{"values":["PII"]}},
+ "policyItems":[
+ { "accesses":[{"type":"hdfs:read", "isAllowed":true},{"type":"hdfs:write", "isAllowed":true}], "users":["allowed-user1", "unaudited-user1"], "groups":["unaudited-group1"], "roles":["unaudited-role1"]}
+ ]
+ }
+ ]
+ },
+
+ "tests":[
+ { "name":"audit denied access: resource=/audited/test.txt, accessType=read, action=null, user=denied-user1",
+ "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"read", "user":"denied-user1" },
+ "result":{"isAudited":true,"isAllowed":false,"policyId":-1}
+ },
+ { "name":"audit denied access: resource=/unaudited/test.txt, accessType=read, action=null, user=denied-user1",
+ "request":{ "resource":{"elements":{"path":"/unaudited/test.txt"}}, "accessType":"read","user":"denied-user1" },
+ "result":{"isAudited":true,"isAllowed":false,"policyId":-1}
+ },
+ { "name":"audit read access to /audited: resource=/audited/test.txt, accessType=read, action=null, user=allowed-user1",
+ "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"read","user":"allowed-user1" },
+ "result":{"isAudited":true,"isAllowed":true,"policyId":10}
+ },
+ { "name":"audit write access to /audited: resource=/audited/test.txt, accessType=write, action=null, user=allowed-user1",
+ "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"write","user":"allowed-user1" },
+ "result":{"isAudited":true,"isAllowed":true,"policyId":10}
+ },
+ { "name":"no audit for access to /unaudited: resource=/unaudited/test.txt, accessType=read, action=null, user=allowed-user1",
+ "request":{ "resource":{"elements":{"path":"/unaudited/test.txt"}}, "accessType":"read","user":"allowed-user1" },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":11}
+ },
+ { "name":"no audit for listStatus action: resource=/audited/test.txt', accessType=read, action=listStatus, user=allowed-user1",
+ "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"read","action":"listStatus","user":"allowed-user1" },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":10}
+ },
+ { "name":"no audit for getfileinfo action: resource=/audited/test.txt, accessType=read, action=getfileinfo, user=allowed-user1",
+ "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"read","action":"getfileinfo","user":"allowed-user1" },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":10}
+ },
+ { "name":"no audit for execute access: resource=/audited/test.txt, accessType=execute, action=null, user=allowed-user1",
+ "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"execute","user":"allowed-user1" },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":10}
+ },
+ { "name":"no audit for unaudited-user1 user: resource=/audited/test.txt, accessType=execute, action=null, user=unaudited-user1",
+ "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"write","user":"unaudited-user1" },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":10}
+ },
+ { "name":"no audit for unaudited-group1 group: resource=/audited/test.txt, accessType=execute, action=null, group=unaudited-group1",
+ "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"write","user":"nonexisting-user1", "userGroups":["unaudited-group1"] },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":10}
+ },
+ { "name":"no audit for unaudited-role1 role: resource=/audited/test.txt, accessType=execute, action=null, role=unaudited-role1",
+ "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"write","user":"nonexisting-user1", "userGroups":["nonexisting-group1"], "userRoles":["unaudited-role1"] },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":10}
+ },
+ { "name":"audit access to AUDIT_ALL_ACCESS tagged: resource=/unaudited/test.txt, accessType=write, action=null, user=allowed-user1, tags=AUDIT_ALL_ACCESS",
+ "request":{ "resource":{"elements":{"path":"/unaudited/test.txt"}}, "accessType":"write", "user":"allowed-user1", "context":{"TAGS": "[{'type':'AUDIT_ALL_ACCESS'}]"}},
+ "result":{"isAudited":true,"isAllowed":true,"policyId":10}
+ },
+ { "name":"no audit access to NO_AUDIT_ACCESS tagged: resource=/audited/test.txt, accessType=write, action=null, user=allowed-user1, tags=NO_AUDIT_ACCESS",
+ "request":{ "resource":{"elements":{"path":"/audited/test.txt"}}, "accessType":"write", "user":"allowed-user1", "context":{"TAGS": "[{'type':'NO_AUDIT_ACCESS'}]"}},
+ "result":{"isAudited":false,"isAllowed":true,"policyId":10}
+ }
+ ]
+}
+
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_audit_filter_hive.json b/agents-common/src/test/resources/policyengine/test_policyengine_audit_filter_hive.json
new file mode 100644
index 0000000..3225f15
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_audit_filter_hive.json
@@ -0,0 +1,248 @@
+{
+ "serviceName":"hivedev",
+
+ "serviceDef":{
+ "name":"hive",
+ "id":3,
+ "resources":[
+ {"name":"database","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Database","description":"Hive Database"},
+ {"name":"global","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Global","description":"Global"},
+ {"name":"url","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"URL","description":"URL"},
+ {"name":"hiveservice","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Service","description":"Hive Service"},
+ {"name":"table","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Table","description":"Hive Table"},
+ {"name":"udf","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive UDF","description":"Hive UDF"},
+ {"name":"column","level":3,"parent":"table","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true, "ignoreCase":true},"label":"Hive Column","description":"Hive Column"}
+ ],
+ "accessTypes":[
+ {"name":"select","label":"Select"},
+ {"name":"update","label":"Update"},
+ {"name":"create","label":"Create"},
+ {"name":"drop","label":"Drop"},
+ {"name":"alter","label":"Alter"},
+ {"name":"index","label":"Index"},
+ {"name":"lock","label":"Lock"},
+ {"name":"all","label":"All",
+ "impliedGrants": [
+ "select",
+ "update",
+ "create",
+ "drop",
+ "alter",
+ "index",
+ "lock"
+ ]
+ }
+ ]
+ },
+
+ "serviceConfig": {
+ "ranger.plugin.audit.filters": "[ {'accessResult': 'DENIED', 'isAudited': true}, {'resources':{'database':{'values':['temp']},'table':{'values':['tempdata']},'column':{'values':['*']}},'isAudited' : false}, {'resources':{'database':{'values':['sys']},'table':{'values':['dump']}},'users':['user2'],'isAudited': false }, {'actions':['METADATA OPERATION'], 'isAudited': false}, {'users':['superuser1'],'groups':['supergroup1'], 'isAudited': false} ]"
+ },
+
+"policies": [
+ {"id":1,"name":"db=*:table=*,column=*","isEnabled":true,"isAuditEnabled":true,"policyType":0,
+ "resources":{"database":{"values":["*"]},"table":{"values":["*"]},"column":{"values":["*"]}},
+ "policyItems":[
+ {"accesses":[{"type":"select","isAllowed":true}],"users":["hive", "user1", "user2", "superuser1"],"groups":["supergroup1"],"delegateAdmin":false}
+ ]
+ }
+ ],
+ "tagPolicyInfo": {
+
+ "serviceName":"tagdev",
+ "serviceDef": {
+ "name": "tag",
+ "id": 100,
+ "resources": [
+ {
+ "itemId": 1,
+ "name": "tag",
+ "type": "string",
+ "level": 1,
+ "parent": "",
+ "mandatory": true,
+ "lookupSupported": true,
+ "recursiveSupported": false,
+ "excludesSupported": false,
+ "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+ "matcherOptions": {
+ "wildCard": true,
+ "ignoreCase": false
+ },
+ "validationRegEx": "",
+ "validationMessage": "",
+ "uiHint": "",
+ "label": "TAG",
+ "description": "TAG"
+ }
+ ],
+ "accessTypes": [
+ {
+ "itemId": 1,
+ "name": "hive:select",
+ "label": "hive:select"
+ },
+ {
+ "itemId": 2,
+ "name": "hive:update",
+ "label": "hive:update"
+ },
+ {
+ "itemId": 3,
+ "name": "hive:create",
+ "label": "hive:create"
+ }
+ ,
+ {
+ "itemId": 4,
+ "name": "hive:grant",
+ "label": "hive:grant"
+ }
+ ,
+ {
+ "itemId": 5,
+ "name": "hive:drop",
+ "label": "hive:drop"
+ }
+ ,
+ {
+ "itemId": 6,
+ "name": "hive:alter",
+ "label": "hive:alter"
+ },
+ {
+ "itemId": 7,
+ "name": "hive:index",
+ "label": "hive:index"
+ },
+ {
+ "itemId": 8,
+ "name": "hive:lock",
+ "label": "hive:lock"
+ },
+ {
+ "itemId": 9,
+ "name": "hive:all",
+ "label": "hive:all",
+ "impliedGrants":
+ [
+ "hive:select",
+ "hive:update",
+ "hive:create",
+ "hive:grant",
+ "hive:drop",
+ "hive:alter",
+ "hive:index",
+ "hive:lock"
+ ]
+ }
+ ],
+ "contextEnrichers": [],
+ "policyConditions": []
+ },
+
+ "serviceConfig": {
+ "ranger.plugin.audit.filters": "[ {'resources':{'tag':{'values':['NO_AUDIT']}},'isAudited': false}, {'resources':{'tag':{'values':['SYS_DATA']}},'users':['user1'],'isAudited': false}, {'resources':{'tag':{'values':['HIPPA']}},'users':['user1'], 'isAudited': true} ]"
+ },
+
+ "tagPolicies":[
+ {"id":1001,"name":"DEFAULT","isEnabled":true,"isAuditEnabled":true,
+ "resources":{"tag":{"values":["DEFAULT"],"isRecursive":false}},
+ "policyItems":[{"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive", "user1"],"groups":[],"delegateAdmin":false}]
+ },
+ {"id":1002,"name":"HIPPA","isEnabled":true,"isAuditEnabled":true,
+ "resources":{"tag":{"values":["HIPPA"],"isRecursive":false}},
+ "policyItems":[{"accesses":[{"type":"hive:select","isAllowed":true}],"users":["hive", "user1","user2"],"groups":[],"delegateAdmin":false}]
+ }
+ ]
+ },
+
+ "tests": [
+ {"name":"cmd -> select * from temp.tempdata, discard access audit for user1 to table -> temp.tempdata",
+ "request":{
+ "resource":{"elements":{"database":"temp","table":"tempdata", "column": "*"}},
+ "accessType":"select","user":"user1","userGroups":["user1"],"requestData":"select * from temp.tempdata"
+ },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+ },
+ {"name":"cmd -> use temp, discard access audit for user1 to database -> temp" ,
+ "request":{
+ "resource":{"elements":{"database":"temp"},
+ "accessType":"_any","user":"user1","userGroups":["user1"],"requestData":"use temp"
+ },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+ }
+ },
+ {"name":"cmd -> select * from sys.dump, discard access audit for user2 to table -> sys.dump",
+ "request":{
+ "resource":{"elements":{"database":"sys","table":"dump"}},
+ "accessType":"select","user":"user2","userGroups":[],"requestData":"select * from sys.dump"
+ },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+ },
+ {"name":"cmd -> select * from hr.emp, discard access audit for superuser1 for access to table -> hr.emp",
+ "request":{
+ "resource":{"elements":{"database":"hr"}},
+ "accessType":"select","user":"superuser1","userGroups":[],"requestData":"select * from hr.emp"
+ },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+ },
+ {"name":"cmd -> select * from hr.emp, discard access audit for supergroup1 to table -> hr.emp",
+ "request":{
+ "resource":{"elements":{"database":"hr","table":"emp"}},
+ "accessType":"select","user":"","userGroups":["supergroup1"],"requestData":"select * from hr.emp"
+ },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+ },
+ {"name":"cmd -> select * from hr.emp;', Audit access for user4 to table hr.emp",
+ "request":{
+ "resource":{"elements":{"database":"hr","table":"emp"}},
+ "accessType":"select","user":"user4","userGroups":[],"requestData":"select * from hr.emp"
+ },
+ "result":{"isAudited":true,"isAllowed":false,"policyId":-1}
+ },
+ {"name":"cmd -> select * from sys.scheduled_queries, discard access audit for hive operation = METADATA OPERATION",
+ "request":{
+ "resource":{"elements":{"database":"sys","table":"scheduled_queries"}},
+ "accessType":"select","user":"hive","userGroups":[],"requestData":"select * from sys.scheduled_queries","action": "METADATA OPERATION"
+ },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+ },
+
+ {"name":"cmd -> select name from medical.data, Audit access of resources with TAG = HIPPA",
+ "request":{
+ "resource":{"elements":{"database":"medical", "table":"data", "column":"name"}},
+ "accessType":"select","user":"user2","userGroups":[],"requestData":"select name from medical.data for user1",
+ "context": {"TAGS": "[{\"type\":\"HIPPA\"}]"}
+ },
+ "result":{"isAudited":true,"isAllowed":true,"policyId":-1}
+ },
+
+ {"name":"cmd -> select name from temp.data, discard access audit of resources with TAG = NO_AUDIT",
+ "request":{
+ "resource":{"elements":{"database":"temp", "table":"data", "column":"name"}},
+ "accessType":"select","user":"user1","userGroups":[],"requestData":"select name from temp.data for user1",
+ "context": {"TAGS": "[{\"type\":\"NO_AUDIT\"}]"}
+ },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+ },
+
+ {"name":"cmd -> select name from sysdb.data, discard access audit of resources with TAG = SYS_DATA",
+ "request":{
+ "resource":{"elements":{"database":"sysdb", "table":"data", "column":"name"}},
+ "accessType":"select","user":"user1","userGroups":[],"requestData":"select name from sysdb.data for user1",
+ "context": {"TAGS": "[{\"type\":\"SYS_DATA\"}]"}
+ },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+ },
+
+ {"name":"cmd -> use sysdb, discard access audit of resource with TAG = SYS_DATA",
+ "request":{
+ "resource":{"elements":{"database":"sysdb"}},
+ "accessType":"_any","user":"user1","userGroups":[],"requestData":"use sysdb",
+ "context": {"TAGS": "[{\"type\":\"SYS_DATA\"}]"}
+ },
+ "result":{"isAudited":false,"isAllowed":true,"policyId":-1}
+ }
+ ]
+}
\ No newline at end of file
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
index 9aad6db..5e20091 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
@@ -3119,7 +3119,13 @@ public class ServiceREST {
} else {
ret = updatedServicePolicies;
}
+
ret.setServiceConfig(svcStore.getServiceConfigForPlugin(ret.getServiceId()));
+
+ if (ret.getTagPolicies() != null && ret.getTagPolicies().getServiceId() != null) {
+ ret.getTagPolicies().setServiceConfig(svcStore.getServiceConfigForPlugin(ret.getTagPolicies().getServiceId()));
+ }
+
httpCode = HttpServletResponse.SC_OK;
logMsg = "Returning " + (ret.getPolicies() != null ? ret.getPolicies().size() : (ret.getPolicyDeltas() != null ? ret.getPolicyDeltas().size() : 0)) + " policies. Policy version=" + ret.getPolicyVersion();
}
@@ -3241,7 +3247,13 @@ public class ServiceREST {
} else {
ret = updatedServicePolicies;
}
+
ret.setServiceConfig(svcStore.getServiceConfigForPlugin(ret.getServiceId()));
+
+ if (ret.getTagPolicies() != null && ret.getTagPolicies().getServiceId() != null) {
+ ret.getTagPolicies().setServiceConfig(svcStore.getServiceConfigForPlugin(ret.getTagPolicies().getServiceId()));
+ }
+
httpCode = HttpServletResponse.SC_OK;
logMsg = "Returning " + (ret.getPolicies() != null ? ret.getPolicies().size() : (ret.getPolicyDeltas() != null ? ret.getPolicyDeltas().size() : 0)) + " policies. Policy version=" + ret.getPolicyVersion();
}