blob: 7c48ef763a01bb31649c130320cd7165b7dbf329 [file] [log] [blame]
/*
* 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.policyengine;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.ListUtils;
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.contextenricher.RangerContextEnricher;
import org.apache.ranger.plugin.contextenricher.RangerTagForEval;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerPolicyDelta;
import org.apache.ranger.plugin.model.RangerRole;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
import org.apache.ranger.plugin.model.validation.RangerZoneResourceMatcher;
import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator.PolicyACLSummary;
import org.apache.ranger.plugin.policyresourcematcher.RangerPolicyResourceMatcher;
import org.apache.ranger.plugin.service.RangerAuthContext;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.util.GrantRevokeRequest;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
import org.apache.ranger.plugin.util.RangerPerfTracer;
import org.apache.ranger.plugin.util.RangerResourceTrie;
import org.apache.ranger.plugin.util.RangerPolicyDeltaUtil;
import org.apache.ranger.plugin.util.RangerRoles;
import org.apache.ranger.plugin.util.RangerRolesUtil;
import org.apache.ranger.plugin.util.ServicePolicies;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator.ACCESS_CONDITIONAL;
public class RangerPolicyEngineImpl implements RangerPolicyEngine {
private static final Log LOG = LogFactory.getLog(RangerPolicyEngineImpl.class);
private static final Log PERF_POLICYENGINE_INIT_LOG = RangerPerfTracer.getPerfLogger("policyengine.init");
private static final Log PERF_POLICYENGINE_REQUEST_LOG = RangerPerfTracer.getPerfLogger("policyengine.request");
private static final Log PERF_POLICYENGINE_AUDIT_LOG = RangerPerfTracer.getPerfLogger("policyengine.audit");
private static final Log PERF_CONTEXTENRICHER_REQUEST_LOG = RangerPerfTracer.getPerfLogger("contextenricher.request");
private static final Log PERF_POLICYENGINE_REBALANCE_LOG = RangerPerfTracer.getPerfLogger("policyengine.rebalance");
private static final Log PERF_POLICYENGINE_USAGE_LOG = RangerPerfTracer.getPerfLogger("policyengine.usage");
private static final Log PERF_POLICYENGINE_GET_ACLS_LOG = RangerPerfTracer.getPerfLogger("policyengine.getResourceACLs");
private static final int MAX_POLICIES_FOR_CACHE_TYPE_EVALUATOR = 100;
private final RangerPolicyRepository policyRepository;
private final RangerPolicyRepository tagPolicyRepository;
private List<RangerContextEnricher> allContextEnrichers;
private RangerRoles rangerRoles;
private boolean useForwardedIPAddress;
private String[] trustedProxyAddresses;
private Map<String, RangerPolicyRepository> policyRepositories = new HashMap<>();
private Map<String, RangerResourceTrie> trieMap;
private Map<String, String> zoneTagServiceMap;
private Map<String, Set<String>> userRoleMapping;
private Map<String, Set<String>> groupRoleMapping;
private final RangerPluginContext pluginContext;
public RangerPolicyEngineImpl(final RangerPolicyEngineImpl other, ServicePolicies servicePolicies) {
this(other,servicePolicies, null);
}
public RangerPolicyEngineImpl(final RangerPolicyEngineImpl other, ServicePolicies servicePolicies, RangerRoles rangerRoles) {
long policyVersion = servicePolicies.getPolicyVersion() != null ? servicePolicies.getPolicyVersion() : -1L;
this.useForwardedIPAddress = other.useForwardedIPAddress;
this.trustedProxyAddresses = other.trustedProxyAddresses;
if (rangerRoles != null) {
this.rangerRoles = rangerRoles;
setUserGroupRoleMapping(rangerRoles);
}
this.pluginContext = other.pluginContext;
List<RangerPolicyDelta> defaultZoneDeltas = new ArrayList<>();
List<RangerPolicyDelta> defaultZoneDeltasForTagPolicies = new ArrayList<>();
if (MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
buildZoneTrie(servicePolicies);
Map<String, List<RangerPolicyDelta>> zoneDeltasMap = new HashMap<>();
for (Map.Entry<String, ServicePolicies.SecurityZoneInfo> zone : servicePolicies.getSecurityZones().entrySet()) {
List<RangerPolicyDelta> deltas = zone.getValue().getPolicyDeltas();
for (RangerPolicyDelta delta : deltas) {
String zoneName = delta.getZoneName();
if (StringUtils.isNotEmpty(zoneName)) {
List<RangerPolicyDelta> zoneDeltas = zoneDeltasMap.get(zoneName);
if (zoneDeltas == null) {
zoneDeltas = new ArrayList<>();
zoneDeltasMap.put(zoneName, zoneDeltas);
}
zoneDeltas.add(delta);
} else {
LOG.warn("policyDelta : [" + delta + "] does not belong to any zone. Should not have come here.");
}
}
}
for (Map.Entry<String, List<RangerPolicyDelta>> entry : zoneDeltasMap.entrySet()) {
final String zoneName = entry.getKey();
List<RangerPolicyDelta> zoneDeltas = entry.getValue();
RangerPolicyRepository otherRepository = other.policyRepositories.get(zoneName);
final RangerPolicyRepository policyRepository;
if (CollectionUtils.isNotEmpty(zoneDeltas)) {
if (otherRepository == null) {
List<RangerPolicy> policies = new ArrayList<>();
for (RangerPolicyDelta delta : zoneDeltas) {
if (delta.getChangeType() == RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE) {
policies.add(delta.getPolicy());
} else {
LOG.warn("Expected changeType:[" + RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE + "], found policy-change-delta:[" + delta +"]");
}
}
servicePolicies.getSecurityZones().get(zoneName).setPolicies(policies);
policyRepository = new RangerPolicyRepository(other.policyRepository.getAppId(), servicePolicies, other.policyRepository.getOptions(), this.pluginContext, zoneName);
} else {
policyRepository = new RangerPolicyRepository(otherRepository, zoneDeltas, policyVersion);
}
} else {
policyRepository = shareWith(otherRepository);
}
policyRepositories.put(zoneName, policyRepository);
}
}
List<RangerPolicyDelta> unzonedDeltas = servicePolicies.getPolicyDeltas();
for (RangerPolicyDelta delta : unzonedDeltas) {
if (servicePolicies.getServiceDef().getName().equals(delta.getServiceType())) {
defaultZoneDeltas.add(delta);
} else {
defaultZoneDeltasForTagPolicies.add(delta);
}
}
if (CollectionUtils.isNotEmpty(defaultZoneDeltas)) {
if (other.policyRepository == null) {
LOG.warn("Current policy-engine's policy-repository is null! Should not have happened!!");
this.policyRepository = other.policyRepository;
} else {
this.policyRepository = new RangerPolicyRepository(other.policyRepository, defaultZoneDeltas, policyVersion);
}
} else {
this.policyRepository = shareWith(other.policyRepository);
}
if (servicePolicies.getTagPolicies() != null && CollectionUtils.isNotEmpty(defaultZoneDeltasForTagPolicies)) {
if (other.tagPolicyRepository == null) {
// Only creates are expected
List<RangerPolicy> tagPolicies = new ArrayList<>();
for (RangerPolicyDelta delta : defaultZoneDeltasForTagPolicies) {
if (delta.getChangeType() == RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE) {
tagPolicies.add(delta.getPolicy());
} else {
LOG.warn("Expected changeType:[" + RangerPolicyDelta.CHANGE_TYPE_POLICY_CREATE + "], found policy-change-delta:[" + delta + "]");
}
}
servicePolicies.getTagPolicies().setPolicies(tagPolicies);
this.tagPolicyRepository = new RangerPolicyRepository(other.policyRepository.getAppId(), servicePolicies.getTagPolicies(), other.policyRepository.getOptions(), this.pluginContext, servicePolicies.getServiceDef(), servicePolicies.getServiceName());
} else {
this.tagPolicyRepository = new RangerPolicyRepository(other.tagPolicyRepository, defaultZoneDeltasForTagPolicies, policyVersion);
}
} else {
this.tagPolicyRepository = shareWith(other.tagPolicyRepository);
}
List<RangerContextEnricher> tmpList;
List<RangerContextEnricher> tagContextEnrichers = tagPolicyRepository == null ? null :tagPolicyRepository.getContextEnrichers();
List<RangerContextEnricher> resourceContextEnrichers = policyRepository.getContextEnrichers();
if (CollectionUtils.isEmpty(tagContextEnrichers)) {
tmpList = resourceContextEnrichers;
} else if (CollectionUtils.isEmpty(resourceContextEnrichers)) {
tmpList = tagContextEnrichers;
} else {
tmpList = new ArrayList<>(tagContextEnrichers);
tmpList.addAll(resourceContextEnrichers);
}
this.allContextEnrichers = tmpList;
reorderPolicyEvaluators();
RangerAuthContext oldContext = pluginContext.getAuthContext();
this.pluginContext.setAuthContext(new RangerAuthContext(this, oldContext));
}
public RangerPolicyEngineImpl(String appId, ServicePolicies servicePolicies, RangerPolicyEngineOptions options) {
this(appId, servicePolicies, options, null);
}
public RangerPolicyEngineImpl(String appId, ServicePolicies servicePolicies, RangerPolicyEngineOptions options, RangerPluginContext rangerPluginContext) {
this(appId, servicePolicies, options, rangerPluginContext, null);
}
public RangerPolicyEngineImpl(String appId, ServicePolicies servicePolicies, RangerPolicyEngineOptions options, RangerPluginContext rangerPluginContext, RangerRoles rangerRoles) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl(" + appId + ", " + servicePolicies + ", " + options + ", " + rangerPluginContext + ")");
}
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_INIT_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_INIT_LOG, "RangerPolicyEngine.init(appId=" + appId + ",hashCode=" + Integer.toHexString(System.identityHashCode(this)) + ")");
long freeMemory = Runtime.getRuntime().freeMemory();
long totalMemory = Runtime.getRuntime().totalMemory();
PERF_POLICYENGINE_INIT_LOG.debug("In-Use memory: " + (totalMemory - freeMemory) + ", Free memory:" + freeMemory);
}
if (options == null) {
options = new RangerPolicyEngineOptions();
}
this.pluginContext = (rangerPluginContext != null) ? rangerPluginContext : new RangerPluginContext(servicePolicies.getServiceDef().getName());
if (rangerRoles != null) {
this.rangerRoles = rangerRoles;
setUserGroupRoleMapping(rangerRoles);
}
RangerAuthContext authContext = new RangerAuthContext(this, null, this.pluginContext);
this.pluginContext.setAuthContext(authContext);
if(StringUtils.isBlank(options.evaluatorType) || StringUtils.equalsIgnoreCase(options.evaluatorType, RangerPolicyEvaluator.EVALUATOR_TYPE_AUTO)) {
String serviceType = servicePolicies.getServiceDef().getName();
String propertyName = "ranger.plugin." + serviceType + ".policyengine.evaluator.auto.maximum.policycount.for.cache.type";
int thresholdForUsingOptimizedEvaluator = pluginContext.getConfig().getInt(propertyName, MAX_POLICIES_FOR_CACHE_TYPE_EVALUATOR);
int servicePoliciesCount = servicePolicies.getPolicies().size() + (servicePolicies.getTagPolicies() != null ? servicePolicies.getTagPolicies().getPolicies().size() : 0);
if (servicePoliciesCount > thresholdForUsingOptimizedEvaluator) {
options.evaluatorType = RangerPolicyEvaluator.EVALUATOR_TYPE_OPTIMIZED;
} else {
options.evaluatorType = RangerPolicyEvaluator.EVALUATOR_TYPE_CACHED;
}
} else if (StringUtils.equalsIgnoreCase(options.evaluatorType, RangerPolicyEvaluator.EVALUATOR_TYPE_CACHED)) {
options.evaluatorType = RangerPolicyEvaluator.EVALUATOR_TYPE_CACHED;
} else {
// All other cases
options.evaluatorType = RangerPolicyEvaluator.EVALUATOR_TYPE_OPTIMIZED;
}
policyRepository = new RangerPolicyRepository(appId, servicePolicies, options, this.pluginContext);
ServicePolicies.TagPolicies tagPolicies = servicePolicies.getTagPolicies();
if (!options.disableTagPolicyEvaluation
&& tagPolicies != null
&& !StringUtils.isEmpty(tagPolicies.getServiceName())
&& tagPolicies.getServiceDef() != null
&& !CollectionUtils.isEmpty(tagPolicies.getPolicies())) {
if (LOG.isDebugEnabled()) {
LOG.debug("RangerPolicyEngineImpl : Building tag-policy-repository for tag-service " + tagPolicies.getServiceName());
}
tagPolicyRepository = new RangerPolicyRepository(appId, tagPolicies, options, this.pluginContext, servicePolicies.getServiceDef(), servicePolicies.getServiceName());
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("RangerPolicyEngineImpl : No tag-policy-repository for service " + servicePolicies.getServiceName());
}
tagPolicyRepository = null;
}
List<RangerContextEnricher> tmpList;
List<RangerContextEnricher> tagContextEnrichers = tagPolicyRepository == null ? null :tagPolicyRepository.getContextEnrichers();
List<RangerContextEnricher> resourceContextEnrichers = policyRepository.getContextEnrichers();
if (CollectionUtils.isEmpty(tagContextEnrichers)) {
tmpList = resourceContextEnrichers;
} else if (CollectionUtils.isEmpty(resourceContextEnrichers)) {
tmpList = tagContextEnrichers;
} else {
tmpList = new ArrayList<>(tagContextEnrichers);
tmpList.addAll(resourceContextEnrichers);
}
this.allContextEnrichers = tmpList;
if (MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
buildZoneTrie(servicePolicies);
for (Map.Entry<String, ServicePolicies.SecurityZoneInfo> zone : servicePolicies.getSecurityZones().entrySet()) {
RangerPolicyRepository policyRepository = new RangerPolicyRepository(appId, servicePolicies, options, this.pluginContext, zone.getKey());
policyRepositories.put(zone.getKey(), policyRepository);
}
}
RangerPerfTracer.log(perf);
if (PERF_POLICYENGINE_INIT_LOG.isDebugEnabled()) {
long freeMemory = Runtime.getRuntime().freeMemory();
long totalMemory = Runtime.getRuntime().totalMemory();
PERF_POLICYENGINE_INIT_LOG.debug("In-Use memory: " + (totalMemory - freeMemory) + ", Free memory:" + freeMemory);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl()");
}
}
@Override
public RangerPolicyEngine cloneWithDelta(ServicePolicies servicePolicies, RangerRoles rangerRoles) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> cloneWithDelta(" + Arrays.toString(servicePolicies.getPolicyDeltas().toArray()) + ", " + servicePolicies.getPolicyVersion() + ")");
}
final RangerPolicyEngineImpl ret;
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_INIT_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_INIT_LOG, "RangerPolicyEngine.cloneWithDelta()");
}
RangerServiceDef serviceDef = this.getServiceDef();
String serviceType = (serviceDef != null) ? serviceDef.getName() : "";
boolean isValidDeltas = false;
if (CollectionUtils.isNotEmpty(servicePolicies.getPolicyDeltas()) || MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
isValidDeltas = CollectionUtils.isEmpty(servicePolicies.getPolicyDeltas()) || RangerPolicyDeltaUtil.isValidDeltas(servicePolicies.getPolicyDeltas(), serviceType);
if (isValidDeltas) {
if (MapUtils.isNotEmpty(servicePolicies.getSecurityZones())) {
for (Map.Entry<String, ServicePolicies.SecurityZoneInfo> entry : servicePolicies.getSecurityZones().entrySet()) {
if (!RangerPolicyDeltaUtil.isValidDeltas(entry.getValue().getPolicyDeltas(), serviceType)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Invalid policy-deltas for security zone:[" + entry.getKey() + "]");
}
isValidDeltas = false;
break;
}
}
}
}
}
if (isValidDeltas) {
ret = new RangerPolicyEngineImpl(this, servicePolicies, rangerRoles);
} else {
ret = null;
}
RangerPerfTracer.log(perf);
if (LOG.isDebugEnabled()) {
LOG.debug("<== cloneWithDelta(" + Arrays.toString(servicePolicies.getPolicyDeltas().toArray()) + ", " + servicePolicies.getPolicyVersion() + ")");
}
return ret;
}
public void setIsShared(boolean isShared) {
this.policyRepository.setIsShared(isShared);
if (this.tagPolicyRepository != null) {
this.tagPolicyRepository.setIsShared(isShared);
}
for (RangerPolicyRepository repository : policyRepositories.values()) {
repository.setIsShared(isShared);
}
}
@Override
protected void finalize() throws Throwable {
try {
cleanup();
}
finally {
super.finalize();
}
}
@Override
public String toString( ) {
StringBuilder sb = new StringBuilder();
sb.append("RangerPolicyEngineImpl={");
sb.append("serviceName={").append(this.getServiceName()).append("} ");
sb.append(policyRepository);
sb.append("}");
return sb.toString();
}
@Override
public void setUseForwardedIPAddress(boolean useForwardedIPAddress) {
this.useForwardedIPAddress = useForwardedIPAddress;
}
@Override
public void setTrustedProxyAddresses(String[] trustedProxyAddresses) {
this.trustedProxyAddresses = trustedProxyAddresses;
}
@Override
public boolean getUseForwardedIPAddress() {
return useForwardedIPAddress;
}
@Override
public String[] getTrustedProxyAddresses() {
return trustedProxyAddresses;
}
@Override
public RangerServiceDef getServiceDef() {
return policyRepository.getServiceDef();
}
@Override
public long getPolicyVersion() {
return policyRepository.getPolicyVersion();
}
@Override
public void preProcess(RangerAccessRequest request) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.preProcess(" + request + ")");
}
setResourceServiceDef(request);
if (request instanceof RangerAccessRequestImpl) {
RangerAccessRequestImpl reqImpl = (RangerAccessRequestImpl) request;
reqImpl.extractAndSetClientIPAddress(useForwardedIPAddress, trustedProxyAddresses);
if(pluginContext != null) {
reqImpl.setClusterName(pluginContext.getClusterName());
reqImpl.setClusterType(pluginContext.getClusterType());
}
}
RangerAccessRequestUtil.setCurrentUserInContext(request.getContext(), request.getUser());
Set<String> roles = getRolesFromUserAndGroups(request.getUser(), request.getUserGroups());
if (CollectionUtils.isNotEmpty(roles)) {
RangerAccessRequestUtil.setCurrentUserRolesInContext(request.getContext(), roles);
}
String owner = request.getResource() != null ? request.getResource().getOwnerUser() : null;
if (StringUtils.isNotEmpty(owner)) {
RangerAccessRequestUtil.setOwnerInContext(request.getContext(), owner);
}
List<RangerContextEnricher> enrichers = allContextEnrichers;
if(!CollectionUtils.isEmpty(enrichers)) {
for(RangerContextEnricher enricher : enrichers) {
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_CONTEXTENRICHER_REQUEST_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_CONTEXTENRICHER_REQUEST_LOG, "RangerContextEnricher.enrich(requestHashCode=" + Integer.toHexString(System.identityHashCode(request)) + ", enricherName=" + enricher.getName() + ")");
}
enricher.enrich(request);
RangerPerfTracer.log(perf);
}
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.preProcess(" + request + ")");
}
}
@Override
public void preProcess(Collection<RangerAccessRequest> requests) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.preProcess(" + requests + ")");
}
if(CollectionUtils.isNotEmpty(requests)) {
for(RangerAccessRequest request : requests) {
preProcess(request);
}
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.preProcess(" + requests + ")");
}
}
@Override
public RangerAccessResult evaluatePolicies(RangerAccessRequest request, int policyType, RangerAccessResultProcessor resultProcessor) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.evaluatePolicies(" + request + ", policyType=" + policyType + ")");
}
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_REQUEST_LOG)) {
String requestHashCode = Integer.toHexString(System.identityHashCode(request)) + "_" + Integer.toString(policyType);
perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_REQUEST_LOG, "RangerPolicyEngine.evaluatePolicies(requestHashCode=" + requestHashCode + ")");
LOG.info("RangerPolicyEngineImpl.evaluatePolicies(" + requestHashCode + ", " + request + ")");
}
RangerAccessResult ret = zoneAwareAccessEvaluationWithNoAudit(request, policyType);
updatePolicyUsageCounts(request, ret);
if (resultProcessor != null) {
RangerPerfTracer perfAuditTracer = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_AUDIT_LOG)) {
String requestHashCode = Integer.toHexString(System.identityHashCode(request)) + "_" + Integer.toString(policyType);
perfAuditTracer = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_AUDIT_LOG, "RangerPolicyEngine.processAudit(requestHashCode=" + requestHashCode + ")");
}
resultProcessor.processResult(ret);
RangerPerfTracer.log(perfAuditTracer);
}
RangerPerfTracer.log(perf);
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.evaluatePolicies(" + request + ", policyType=" + policyType + "): " + ret);
}
return ret;
}
@Override
public Collection<RangerAccessResult> evaluatePolicies(Collection<RangerAccessRequest> requests, int policyType, RangerAccessResultProcessor resultProcessor) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.evaluatePolicies(" + requests + ", policyType=" + policyType + ")");
}
Collection<RangerAccessResult> ret = new ArrayList<>();
if (requests != null) {
for (RangerAccessRequest request : requests) {
RangerAccessResult result = zoneAwareAccessEvaluationWithNoAudit(request, policyType);
ret.add(result);
}
}
if (resultProcessor != null) {
resultProcessor.processResults(ret);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.evaluatePolicies(" + requests + ", policyType=" + policyType + "): " + ret);
}
return ret;
}
@Override
public RangerResourceACLs getResourceACLs(RangerAccessRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.getResourceACLs(request=" + request + ")");
}
RangerResourceACLs ret = new RangerResourceACLs();
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_GET_ACLS_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_GET_ACLS_LOG, "RangerPolicyEngine.getResourceACLs(requestHashCode=" + request.getResource().getAsString() + ")");
}
String zoneName = trieMap == null ? null : getMatchedZoneName(request.getResource());
if (LOG.isDebugEnabled()) {
LOG.debug("zoneName:[" + zoneName + "]");
}
Collection<RangerPolicyRepository> matchedRepositories = new ArrayList<>();
if (StringUtils.isNotEmpty(zoneName)) {
RangerPolicyRepository policyRepository = policyRepositories.get(zoneName);
if (policyRepository == null) {
LOG.error("policyRepository for zoneName:[" + zoneName + "] is null!! ERROR!");
} else {
matchedRepositories.add(policyRepository);
}
} else {
// Search all security zones
matchedRepositories.add(this.policyRepository);
matchedRepositories.addAll(this.policyRepositories.values());
}
List<RangerPolicyEvaluator> allEvaluators = new ArrayList<>();
Map<Long, RangerPolicyResourceMatcher.MatchType> tagMatchTypeMap = null;
Set<Long> policyIdForTemporalTags = null;
Set<RangerTagForEval> tags = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
List<PolicyEvaluatorForTag> tagPolicyEvaluators = tagPolicyRepository == null ? null : tagPolicyRepository.getLikelyMatchPolicyEvaluators(tags, RangerPolicy.POLICY_TYPE_ACCESS, null);
if (CollectionUtils.isNotEmpty(tagPolicyEvaluators)) {
tagMatchTypeMap = new HashMap<>();
for (PolicyEvaluatorForTag tagEvaluator : tagPolicyEvaluators) {
RangerPolicyEvaluator evaluator = tagEvaluator.getEvaluator();
RangerTagForEval tag = tagEvaluator.getTag();
allEvaluators.add(evaluator);
tagMatchTypeMap.put(evaluator.getId(), tag.getMatchType());
if (CollectionUtils.isNotEmpty(tag.getValidityPeriods())) {
if (policyIdForTemporalTags == null) {
policyIdForTemporalTags = new HashSet<>();
}
policyIdForTemporalTags.add(evaluator.getId());
}
}
}
for (RangerPolicyRepository policyRepository : matchedRepositories) {
List<RangerPolicyEvaluator> resourcePolicyEvaluators = policyRepository.getLikelyMatchPolicyEvaluators(request.getResource(), RangerPolicy.POLICY_TYPE_ACCESS);
allEvaluators.addAll(resourcePolicyEvaluators);
}
allEvaluators.sort(RangerPolicyEvaluator.EVAL_ORDER_COMPARATOR);
if (CollectionUtils.isNotEmpty(allEvaluators)) {
Integer policyPriority = null;
for (RangerPolicyEvaluator evaluator : allEvaluators) {
if (policyPriority == null) {
policyPriority = evaluator.getPolicyPriority();
}
if (policyPriority != evaluator.getPolicyPriority()) {
ret.finalizeAcls();
policyPriority = evaluator.getPolicyPriority();
}
RangerPolicyResourceMatcher.MatchType matchType = tagMatchTypeMap != null ? tagMatchTypeMap.get(evaluator.getId()) : null;
if (matchType == null) {
matchType = evaluator.getPolicyResourceMatcher().getMatchType(request.getResource(), request.getContext());
}
final boolean isMatched;
if (request.getResourceMatchingScope() == RangerAccessRequest.ResourceMatchingScope.SELF_OR_DESCENDANTS) {
isMatched = matchType != RangerPolicyResourceMatcher.MatchType.NONE;
} else {
isMatched = matchType == RangerPolicyResourceMatcher.MatchType.SELF || matchType == RangerPolicyResourceMatcher.MatchType.ANCESTOR_WITH_WILDCARDS;
}
if (!isMatched) {
continue;
}
PolicyACLSummary aclSummary = evaluator.getPolicyACLSummary();
if (aclSummary != null) {
boolean isConditional = (policyIdForTemporalTags != null && policyIdForTemporalTags.contains(evaluator.getId())) || evaluator.getValidityScheduleEvaluatorsCount() != 0;
Integer accessResult;
for (Map.Entry<String, Map<String, PolicyACLSummary.AccessResult>> userAccessInfo : aclSummary.getUsersAccessInfo().entrySet()) {
final String userName = userAccessInfo.getKey();
for (Map.Entry<String, PolicyACLSummary.AccessResult> accessInfo : userAccessInfo.getValue().entrySet()) {
if (isConditional) {
accessResult = ACCESS_CONDITIONAL;
} else {
accessResult = accessInfo.getValue().getResult();
if (accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
}
}
RangerPolicy policy = evaluator.getPolicy();
ret.setUserAccessInfo(userName, accessInfo.getKey(), accessResult, policy);
}
}
for (Map.Entry<String, Map<String, PolicyACLSummary.AccessResult>> groupAccessInfo : aclSummary.getGroupsAccessInfo().entrySet()) {
final String groupName = groupAccessInfo.getKey();
for (Map.Entry<String, PolicyACLSummary.AccessResult> accessInfo : groupAccessInfo.getValue().entrySet()) {
if (isConditional) {
accessResult = ACCESS_CONDITIONAL;
} else {
accessResult = accessInfo.getValue().getResult();
if (accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
}
}
RangerPolicy policy = evaluator.getPolicy();
ret.setGroupAccessInfo(groupName, accessInfo.getKey(), accessResult, policy);
}
}
for (Map.Entry<String, Map<String, PolicyACLSummary.AccessResult>> roleAccessInfo : aclSummary.getRolesAccessInfo().entrySet()) {
final String roleName = roleAccessInfo.getKey();
for (Map.Entry<String, PolicyACLSummary.AccessResult> accessInfo : roleAccessInfo.getValue().entrySet()) {
if (isConditional) {
accessResult = ACCESS_CONDITIONAL;
} else {
accessResult = accessInfo.getValue().getResult();
if (accessResult.equals(RangerPolicyEvaluator.ACCESS_UNDETERMINED)) {
accessResult = RangerPolicyEvaluator.ACCESS_DENIED;
}
}
RangerPolicy policy = evaluator.getPolicy();
ret.setRoleAccessInfo(roleName, accessInfo.getKey(), accessResult, policy);
}
}
}
}
ret.finalizeAcls();
}
RangerPerfTracer.logAlways(perf);
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.getResourceACLs(request=" + request + ") : ret=" + ret);
}
return ret;
}
@Override
public boolean preCleanup() {
boolean ret = true;
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.preCleanup()");
}
if (policyRepository != null) {
policyRepository.preCleanup();
}
if (tagPolicyRepository != null) {
tagPolicyRepository.preCleanup();
}
if (MapUtils.isNotEmpty(this.policyRepositories)) {
for (Map.Entry<String, RangerPolicyRepository> entry : this.policyRepositories.entrySet()) {
entry.getValue().preCleanup();
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.preCleanup() : result=" + ret);
}
return ret;
}
@Override
public void cleanup() {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.cleanup()");
}
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_INIT_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_INIT_LOG, "RangerPolicyEngine.cleanUp(hashCode=" + Integer.toHexString(System.identityHashCode(this)) + ")");
}
preCleanup();
if (policyRepository != null) {
policyRepository.cleanup();
}
if (tagPolicyRepository != null) {
tagPolicyRepository.cleanup();
}
if (MapUtils.isNotEmpty(this.policyRepositories)) {
for (Map.Entry<String, RangerPolicyRepository> entry : this.policyRepositories.entrySet()) {
entry.getValue().cleanup();
}
}
RangerPerfTracer.log(perf);
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.cleanup()");
}
}
@Override
public void reorderPolicyEvaluators() {
if (LOG.isDebugEnabled()) {
LOG.debug("==> reorderEvaluators()");
}
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_REBALANCE_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_REBALANCE_LOG, "RangerPolicyEngine.reorderEvaluators()");
}
if (tagPolicyRepository != null && MapUtils.isNotEmpty(tagPolicyRepository.getPolicyEvaluatorsMap())) {
for (Map.Entry<Long, RangerPolicyEvaluator> entry : tagPolicyRepository.getPolicyEvaluatorsMap().entrySet()) {
entry.getValue().setUsageCountImmutable();
}
}
if (policyRepository != null && MapUtils.isNotEmpty(policyRepository.getPolicyEvaluatorsMap())) {
for (Map.Entry<Long, RangerPolicyEvaluator> entry : policyRepository.getPolicyEvaluatorsMap().entrySet()) {
entry.getValue().setUsageCountImmutable();
}
}
if (tagPolicyRepository != null) {
tagPolicyRepository.reorderPolicyEvaluators();
}
if (policyRepository != null) {
policyRepository.reorderPolicyEvaluators();
}
if (tagPolicyRepository != null && MapUtils.isNotEmpty(tagPolicyRepository.getPolicyEvaluatorsMap())) {
for (Map.Entry<Long, RangerPolicyEvaluator> entry : tagPolicyRepository.getPolicyEvaluatorsMap().entrySet()) {
entry.getValue().resetUsageCount();
}
}
if (policyRepository != null && MapUtils.isNotEmpty(policyRepository.getPolicyEvaluatorsMap())) {
for (Map.Entry<Long, RangerPolicyEvaluator> entry : policyRepository.getPolicyEvaluatorsMap().entrySet()) {
entry.getValue().resetUsageCount();
}
}
RangerPerfTracer.log(perf);
if (LOG.isDebugEnabled()) {
LOG.debug("<== reorderEvaluators()");
}
}
/*
* This API is used by ranger-admin
*/
@Override
public boolean isAccessAllowed(RangerAccessResource resource, String user, Set<String> userGroups, String accessType) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.isAccessAllowed(" + resource + ", " + user + ", " + userGroups + ", " + accessType + ")");
}
boolean ret = false;
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_REQUEST_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_REQUEST_LOG, "RangerPolicyEngine.isAccessAllowed(user=" + user + ",accessType=" + accessType + "resource=" + resource.getAsString() + ")");
}
String zoneName = trieMap == null ? null : getMatchedZoneName(resource);
if (LOG.isDebugEnabled()) {
LOG.debug("zoneName:[" + zoneName + "]");
}
Collection<RangerPolicyRepository> matchedRepositories = new ArrayList<>();
if (StringUtils.isNotEmpty(zoneName)) {
RangerPolicyRepository policyRepository = policyRepositories.get(zoneName);
if (policyRepository == null) {
LOG.error("policyRepository for zoneName:[" + zoneName + "] is null!! ERROR!");
} else {
matchedRepositories.add(policyRepository);
}
} else {
// Search unzoned security zone
matchedRepositories.add(this.policyRepository);
}
Set<String> roles = getRolesFromUserAndGroups(user, userGroups);
for (RangerPolicyRepository policyRepository : matchedRepositories) {
for (RangerPolicyEvaluator evaluator : policyRepository.getLikelyMatchPolicyEvaluators(resource, RangerPolicy.POLICY_TYPE_ACCESS)) {
ret = evaluator.isAccessAllowed(resource, user, userGroups, roles, accessType);
if (ret) {
break;
}
}
if (ret) {
break;
}
}
RangerPerfTracer.log(perf);
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.isAccessAllowed(" + resource + ", " + user + ", " + userGroups + ", " + accessType + "): " + ret);
}
return ret;
}
/*
* This API is used by ranger-admin - kept for backward compatibility
*/
@Override
public boolean isAccessAllowed(RangerPolicy policy, String user, Set<String> userGroups, String accessType) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.isAccessAllowed(" + policy.getId() + ", " + user + ", " + userGroups + ", " + accessType + ")");
}
boolean ret = isAccessAllowed(policy, user, userGroups, null, accessType);
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.isAccessAllowed(" + policy.getId() + ", " + user + ", " + userGroups + ", " + accessType + ") : " + ret);
}
return ret;
}
/*
* This API is used by ranger-admin
*/
@Override
public boolean isAccessAllowed(RangerPolicy policy, String user, Set<String> userGroups, Set<String> roles, String accessType) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.isAccessAllowed(" + policy.getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + accessType + ")");
}
boolean ret = false;
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_REQUEST_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_REQUEST_LOG, "RangerPolicyEngine.isAccessAllowed(user=" + user + "," + userGroups + ", roles=" + roles + ",accessType=" + accessType + ")");
}
String zoneName = trieMap == null ? null : policy.getZoneName();
if (LOG.isDebugEnabled()) {
LOG.debug("zoneName:[" + zoneName + "]");
}
Collection<RangerPolicyRepository> matchedRepositories = new ArrayList<>();
if (StringUtils.isNotEmpty(zoneName)) {
RangerPolicyRepository policyRepository = policyRepositories.get(zoneName);
if (policyRepository == null) {
LOG.error("policyRepository for zoneName:[" + zoneName + "] is null!! ERROR!");
} else {
matchedRepositories.add(policyRepository);
}
} else {
// Search unzoned security zone
matchedRepositories.add(this.policyRepository);
}
for (RangerPolicyRepository policyRepository : matchedRepositories) {
for (RangerPolicyEvaluator evaluator : policyRepository.getPolicyEvaluators()) {
ret = evaluator.isAccessAllowed(policy, user, userGroups, roles, accessType);
if (ret) {
break;
}
}
if (ret) {
break;
}
}
RangerPerfTracer.log(perf);
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.isAccessAllowed(" + policy.getId() + ", " + user + ", " + userGroups + ", " + roles + ", " + accessType + "): " + ret);
}
return ret;
}
/*
* This API is used by ranger-admin
*/
@Override
public List<RangerPolicy> getExactMatchPolicies(RangerAccessResource resource, Map<String, Object> evalContext) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.getExactMatchPolicies(" + resource + ", " + evalContext + ")");
}
List<RangerPolicy> ret = null;
RangerPolicyRepository policyRepository = this.policyRepository;
String zoneName = trieMap == null ? null : getMatchedZoneName(resource);
if (LOG.isDebugEnabled()) {
LOG.debug("zoneName:[" + zoneName + "]");
}
if (StringUtils.isNotEmpty(zoneName)) {
policyRepository = policyRepositories.get(zoneName);
if (policyRepository == null) {
LOG.error("policyRepository for zoneName:[" + zoneName + "] is null!! ERROR!");
}
}
if (policyRepository != null) {
for (RangerPolicyEvaluator evaluator : policyRepository.getPolicyEvaluators()) {
if (evaluator.isCompleteMatch(resource, evalContext)) {
if (ret == null) {
ret = new ArrayList<>();
}
ret.add(evaluator.getPolicy());
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.getExactMatchPolicies(" + resource + ", " + evalContext + "): " + ret);
}
return ret;
}
/*
* This API is used by ranger-admin
*/
@Override
public List<RangerPolicy> getExactMatchPolicies(RangerPolicy policy, Map<String, Object> evalContext) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.getExactMatchPolicies(" + policy + ", " + evalContext + ")");
}
List<RangerPolicy> ret = null;
RangerPolicyRepository policyRepository = this.policyRepository;
String zoneName = trieMap == null ? null : policy.getZoneName();
if (LOG.isDebugEnabled()) {
LOG.debug("zoneName:[" + zoneName + "]");
}
if (StringUtils.isNotEmpty(zoneName)) {
policyRepository = policyRepositories.get(zoneName);
if (policyRepository == null) {
LOG.error("policyRepository for zoneName:[" + zoneName + "] is null!! ERROR!");
}
}
if (policyRepository != null) {
Map<String, RangerPolicyResource> resources = policy.getResources();
for (RangerPolicyEvaluator evaluator : policyRepository.getPolicyEvaluators()) {
if (evaluator.isCompleteMatch(resources, evalContext)) {
if (ret == null) {
ret = new ArrayList<>();
}
ret.add(evaluator.getPolicy());
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.getExactMatchPolicies(" + policy + ", " + evalContext + "): " + ret);
}
return ret;
}
/*
* This API is used by ranger-admin
*/
@Override
public List<RangerPolicy> getMatchingPolicies(RangerAccessResource resource) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.getMatchingPolicies(" + resource + ")");
}
RangerAccessRequestImpl request = new RangerAccessRequestImpl(resource, RangerPolicyEngine.ANY_ACCESS, null, null);
preProcess(request);
List<RangerPolicy> ret = getMatchingPolicies(request);
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.getMatchingPolicies(" + resource + ") : " + ret.size());
}
return ret;
}
/*
* This API is used by ranger-admin
*/
@Override
public List<RangerPolicy> getMatchingPolicies(RangerAccessRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.getMatchingPolicies(" + request + ")");
}
List<RangerPolicy> ret = new ArrayList<>();
String zoneName = trieMap == null ? null : getMatchedZoneName(request.getResource());
if (LOG.isDebugEnabled()) {
LOG.debug("zoneName:[" + zoneName + "]");
}
Collection<RangerPolicyRepository> matchedRepositories = new ArrayList<>();
if (StringUtils.isNotEmpty(zoneName)) {
RangerPolicyRepository policyRepository = policyRepositories.get(zoneName);
if (policyRepository == null) {
LOG.error("policyRepository for zoneName:[" + zoneName + "] is null!! ERROR!");
} else {
matchedRepositories.add(policyRepository);
}
} else {
// Search all security zones
matchedRepositories.add(this.policyRepository);
matchedRepositories.addAll(this.policyRepositories.values());
}
if (hasTagPolicies(tagPolicyRepository)) {
Set<RangerTagForEval> tags = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
if (CollectionUtils.isNotEmpty(tags)) {
for (RangerTagForEval tag : tags) {
RangerAccessRequest tagEvalRequest = new RangerTagAccessRequest(tag, tagPolicyRepository.getServiceDef(), request);
RangerAccessResource tagResource = tagEvalRequest.getResource();
List<RangerPolicyEvaluator> likelyEvaluators = tagPolicyRepository.getLikelyMatchPolicyEvaluators(tagResource);
for (RangerPolicyEvaluator evaluator : likelyEvaluators) {
RangerPolicyResourceMatcher matcher = evaluator.getPolicyResourceMatcher();
if (matcher != null &&
(request.isAccessTypeAny() ? matcher.isMatch(tagResource, RangerPolicyResourceMatcher.MatchScope.ANY, null) : matcher.isMatch(tagResource, null))) {
ret.add(evaluator.getPolicy());
}
}
}
}
}
for (RangerPolicyRepository policyRepository : matchedRepositories) {
if (hasResourcePolicies(policyRepository)) {
List<RangerPolicyEvaluator> likelyEvaluators = policyRepository.getLikelyMatchPolicyEvaluators(request.getResource());
for (RangerPolicyEvaluator evaluator : likelyEvaluators) {
RangerPolicyResourceMatcher matcher = evaluator.getPolicyResourceMatcher();
if (matcher != null &&
(request.isAccessTypeAny() ? matcher.isMatch(request.getResource(), RangerPolicyResourceMatcher.MatchScope.ANY, null) : matcher.isMatch(request.getResource(), null))) {
ret.add(evaluator.getPolicy());
}
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.getMatchingPolicies(" + request + ") : " + ret.size());
}
return ret;
}
/*
* This API is used by plugin code, but never used
*/
@Override
public RangerResourceAccessInfo getResourceAccessInfo(RangerAccessRequest request) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.getResourceAccessInfo(" + request + ")");
}
RangerResourceAccessInfo ret = new RangerResourceAccessInfo(request);
String zoneName = trieMap == null ? null : getMatchedZoneName(request.getResource());
if (LOG.isDebugEnabled()) {
LOG.debug("zoneName:[" + zoneName + "]");
}
Collection<RangerPolicyRepository> matchedRepositories = new ArrayList<>();
if (StringUtils.isNotEmpty(zoneName)) {
RangerPolicyRepository policyRepository = policyRepositories.get(zoneName);
if (policyRepository == null) {
LOG.error("policyRepository for zoneName:[" + zoneName + "] is null!! ERROR!");
} else {
matchedRepositories.add(policyRepository);
}
} else {
// Search all security zones
matchedRepositories.add(this.policyRepository);
matchedRepositories.addAll(this.policyRepositories.values());
}
List<RangerPolicyEvaluator> tagPolicyEvaluators = tagPolicyRepository == null ? null : tagPolicyRepository.getPolicyEvaluators();
if (CollectionUtils.isNotEmpty(tagPolicyEvaluators)) {
Set<RangerTagForEval> tags = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
if (CollectionUtils.isNotEmpty(tags)) {
for (RangerTagForEval tag : tags) {
RangerAccessRequest tagEvalRequest = new RangerTagAccessRequest(tag, tagPolicyRepository.getServiceDef(), request);
List<RangerPolicyEvaluator> evaluators = tagPolicyRepository.getLikelyMatchPolicyEvaluators(tagEvalRequest.getResource(), RangerPolicy.POLICY_TYPE_ACCESS);
for (RangerPolicyEvaluator evaluator : evaluators) {
evaluator.getResourceAccessInfo(tagEvalRequest, ret);
}
}
}
}
for (RangerPolicyRepository policyRepository : matchedRepositories) {
List<RangerPolicyEvaluator> resPolicyEvaluators = policyRepository.getLikelyMatchPolicyEvaluators(request.getResource(), RangerPolicy.POLICY_TYPE_ACCESS);
if (CollectionUtils.isNotEmpty(resPolicyEvaluators)) {
for (RangerPolicyEvaluator evaluator : resPolicyEvaluators) {
evaluator.getResourceAccessInfo(request, ret);
}
}
ret.getAllowedUsers().removeAll(ret.getDeniedUsers());
ret.getAllowedGroups().removeAll(ret.getDeniedGroups());
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.getResourceAccessInfo(" + request + "): " + ret);
}
return ret;
}
/*
* This API is used only by test-code; checks only policies within default security-zone
*/
@Override
public boolean isAccessAllowed(Map<String, RangerPolicyResource> resources, String user, Set<String> userGroups, String accessType) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.isAccessAllowed(" + resources + ", " + user + ", " + userGroups + ", " + accessType + ")");
}
boolean ret = false;
RangerPerfTracer perf = null;
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_REQUEST_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_REQUEST_LOG, "RangerPolicyEngine.isAccessAllowed(user=" + user + "," + userGroups + ",accessType=" + accessType + ")");
}
for (RangerPolicyEvaluator evaluator : policyRepository.getPolicyEvaluators()) {
ret = evaluator.isAccessAllowed(resources, user, userGroups, accessType);
if (ret) {
break;
}
}
RangerPerfTracer.log(perf);
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.isAccessAllowed(" + resources + ", " + user + ", " + userGroups + ", " + accessType + "): " + ret);
}
return ret;
}
/*
* This API is used only by test-code; checks only policies within default security-zone
*/
@Override
public List<RangerPolicy> getAllowedPolicies(String user, Set<String> userGroups, String accessType) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.getAllowedPolicies(" + user + ", " + userGroups + ", " + accessType + ")");
}
List<RangerPolicy> ret = new ArrayList<>();
// TODO: run through evaluator in tagPolicyRepository as well
for (RangerPolicyEvaluator evaluator : policyRepository.getPolicyEvaluators()) {
RangerPolicy policy = evaluator.getPolicy();
boolean isAccessAllowed = isAccessAllowed(policy.getResources(), user, userGroups, accessType);
if (isAccessAllowed) {
ret.add(policy);
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.getAllowedPolicies(" + user + ", " + userGroups + ", " + accessType + "): policyCount=" + ret.size());
}
return ret;
}
@Override
public Set<String> getRolesFromUserAndGroups(String user, Set<String> groups) {
Set<String> allRoles = new HashSet<>();
if (MapUtils.isNotEmpty(userRoleMapping) && StringUtils.isNotEmpty(user)) {
Set<String> userRoles = userRoleMapping.get(user);
if (CollectionUtils.isNotEmpty(userRoles)) {
allRoles.addAll(userRoles);
}
}
if (MapUtils.isNotEmpty(groupRoleMapping)) {
if (CollectionUtils.isNotEmpty(groups)) {
for (String group : groups) {
Set<String> groupRoles = groupRoleMapping.get(group);
if (CollectionUtils.isNotEmpty(groupRoles)) {
allRoles.addAll(groupRoles);
}
}
}
Set<String> publicGroupRoles = groupRoleMapping.get(RangerPolicyEngine.GROUP_PUBLIC);
if (CollectionUtils.isNotEmpty(publicGroupRoles)) {
allRoles.addAll(publicGroupRoles);
}
}
return allRoles;
}
public RangerRoles getRangerRoles() {
return this.rangerRoles;
}
public void setRangerRoles(RangerRoles rangerRoles) {
this.rangerRoles = rangerRoles;
}
public List<RangerPolicy> getResourcePolicies(String zoneName) {
RangerPolicyRepository zoneResourceRepository = policyRepositories.get(zoneName);
return zoneResourceRepository == null ? ListUtils.EMPTY_LIST : zoneResourceRepository.getPolicies();
}
public List<RangerPolicy> getResourcePolicies() { return policyRepository == null ? ListUtils.EMPTY_LIST : policyRepository.getPolicies(); }
public List<RangerPolicy> getTagPolicies() { return tagPolicyRepository == null ? ListUtils.EMPTY_LIST : tagPolicyRepository.getPolicies(); }
private RangerAccessResult zoneAwareAccessEvaluationWithNoAudit(RangerAccessRequest request, int policyType) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.zoneAwareAccessEvaluationWithNoAudit(" + request + ", policyType =" + policyType + ")");
}
RangerAccessResult ret = null;
RangerPolicyRepository policyRepository = this.policyRepository;
RangerPolicyRepository tagPolicyRepository = this.tagPolicyRepository;
// Evaluate zone-name from request
String zoneName = trieMap == null ? null : getMatchedZoneName(request.getResource());
if (LOG.isDebugEnabled()) {
LOG.debug("zoneName:[" + zoneName + "]");
}
if (StringUtils.isNotEmpty(zoneName)) {
policyRepository = policyRepositories.get(zoneName);
if (policyRepository == null) {
LOG.error("policyRepository for zoneName:[" + zoneName + "] is null!! ERROR!");
}
}
if (policyRepository != null) {
ret = evaluatePoliciesNoAudit(request, policyType, zoneName, policyRepository, tagPolicyRepository);
ret.setZoneName(zoneName);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.zoneAwareAccessEvaluationWithNoAudit(" + request + ", policyType =" + policyType + "): " + ret);
}
return ret;
}
private RangerAccessResult evaluatePoliciesNoAudit(RangerAccessRequest request, int policyType, String zoneName, RangerPolicyRepository policyRepository, RangerPolicyRepository tagPolicyRepository) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.evaluatePoliciesNoAudit(" + request + ", policyType =" + policyType + ", zoneName=" + zoneName + ")");
}
RangerAccessResult ret = createAccessResult(request, policyType);
Date accessTime = request.getAccessTime() != null ? request.getAccessTime() : new Date();
if (ret != null && request != null) {
evaluateTagPolicies(request, policyType, zoneName, tagPolicyRepository, ret);
if (LOG.isDebugEnabled()) {
if (ret.getIsAccessDetermined() && ret.getIsAuditedDetermined()) {
if (!ret.getIsAllowed()) {
LOG.debug("RangerPolicyEngineImpl.evaluatePoliciesNoAudit() - audit determined and access denied by a tag policy. Higher priority resource policies will be evaluated to check for allow, request=" + request + ", result=" + ret);
} else {
LOG.debug("RangerPolicyEngineImpl.evaluatePoliciesNoAudit() - audit determined and access allowed by a tag policy. Same or higher priority resource policies will be evaluated to check for deny, request=" + request + ", result=" + ret);
}
}
}
boolean isAllowedByTags = ret.getIsAccessDetermined() && ret.getIsAllowed();
boolean isDeniedByTags = ret.getIsAccessDetermined() && !ret.getIsAllowed();
boolean evaluateResourcePolicies = hasResourcePolicies(policyRepository);
if (evaluateResourcePolicies) {
boolean findAuditByResource = !ret.getIsAuditedDetermined();
boolean foundInCache = findAuditByResource && policyRepository.setAuditEnabledFromCache(request, ret);
ret.setIsAccessDetermined(false); // discard result by tag-policies, to evaluate resource policies for possible override
List<RangerPolicyEvaluator> evaluators = policyRepository.getLikelyMatchPolicyEvaluators(request.getResource(), policyType);
for (RangerPolicyEvaluator evaluator : evaluators) {
if (!evaluator.isApplicable(accessTime)) {
continue;
}
if (isDeniedByTags) {
if (ret.getPolicyPriority() >= evaluator.getPolicyPriority()) {
ret.setIsAccessDetermined(true);
}
} else if (isAllowedByTags) {
if (ret.getPolicyPriority() > evaluator.getPolicyPriority()) {
ret.setIsAccessDetermined(true);
}
}
ret.incrementEvaluatedPoliciesCount();
evaluator.evaluate(request, ret);
if (ret.getIsAllowed()) {
if (!evaluator.hasDeny()) { // No more deny policies left
ret.setIsAccessDetermined(true);
}
}
if (ret.getIsAuditedDetermined() && ret.getIsAccessDetermined()) {
break; // Break out of policy-evaluation loop
}
}
if (!ret.getIsAccessDetermined()) {
if (isDeniedByTags) {
ret.setIsAllowed(false);
} else if (isAllowedByTags) {
ret.setIsAllowed(true);
}
}
if(ret.getIsAllowed()) {
ret.setIsAccessDetermined(true);
}
if (findAuditByResource && !foundInCache) {
policyRepository.storeAuditEnabledInCache(request, ret);
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.evaluatePoliciesNoAudit(" + request + ", policyType =" + policyType + ", zoneName=" + zoneName + "): " + ret);
}
return ret;
}
private void evaluateTagPolicies(final RangerAccessRequest request, int policyType, String zoneName, RangerPolicyRepository tagPolicyRepository, RangerAccessResult result) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.evaluateTagPolicies(" + request + ", policyType =" + policyType + ", zoneName=" + zoneName + ", " + result + ")");
}
if (StringUtils.isNotEmpty(zoneName) && tagPolicyRepository != null && (zoneTagServiceMap == null || zoneTagServiceMap.get(zoneName) == null)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Accessed resource is in a zone:[" + zoneName + "] which is not associated with the tag-service:[" + tagPolicyRepository.getServiceName() + "]. Evaluating unzoned tag policies of this service");
}
zoneName = null;
}
Date accessTime = request.getAccessTime() != null ? request.getAccessTime() : new Date();
Set<RangerTagForEval> tags = RangerAccessRequestUtil.getRequestTagsFromContext(request.getContext());
List<PolicyEvaluatorForTag> policyEvaluators = tagPolicyRepository == null ? null : tagPolicyRepository.getLikelyMatchPolicyEvaluators(tags, policyType, accessTime);
if (CollectionUtils.isNotEmpty(policyEvaluators)) {
for (PolicyEvaluatorForTag policyEvaluator : policyEvaluators) {
RangerPolicyEvaluator evaluator = policyEvaluator.getEvaluator();
String policyZoneName = evaluator.getPolicy().getZoneName();
if (!(StringUtils.isEmpty(policyZoneName) && StringUtils.isEmpty(zoneName)) && !StringUtils.equals(zoneName, policyZoneName)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Tag policy [zone:" + policyZoneName + "] does not belong to the zone:[" + zoneName + "] of the accessed resource. Not evaluating this policy:[" + evaluator.getPolicy() + "]");
}
continue;
}
RangerTagForEval tag = policyEvaluator.getTag();
RangerAccessRequest tagEvalRequest = new RangerTagAccessRequest(tag, tagPolicyRepository.getServiceDef(), request);
RangerAccessResult tagEvalResult = createAccessResult(tagEvalRequest, policyType);
if (LOG.isDebugEnabled()) {
LOG.debug("RangerPolicyEngineImpl.evaluateTagPolicies: Evaluating policies for tag (" + tag.getType() + ")");
}
tagEvalResult.setAccessResultFrom(result);
tagEvalResult.setAuditResultFrom(result);
result.incrementEvaluatedPoliciesCount();
evaluator.evaluate(tagEvalRequest, tagEvalResult);
if (tagEvalResult.getIsAllowed()) {
if (!evaluator.hasDeny()) { // No Deny policies left now
tagEvalResult.setIsAccessDetermined(true);
}
}
if (tagEvalResult.getIsAudited()) {
result.setAuditResultFrom(tagEvalResult);
}
if (!result.getIsAccessDetermined()) {
if (tagEvalResult.getIsAccessDetermined()) {
result.setAccessResultFrom(tagEvalResult);
} else {
if (!result.getIsAllowed() && tagEvalResult.getIsAllowed()) {
result.setAccessResultFrom(tagEvalResult);
}
}
}
if (result.getIsAuditedDetermined() && result.getIsAccessDetermined()) {
break; // Break out of policy-evaluation loop
}
}
}
if (result.getIsAllowed()) {
result.setIsAccessDetermined(true);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.evaluateTagPolicies(" + request + ", policyType =" + policyType + ", zoneName=" + zoneName + ", " + result + ")");
}
}
private String getServiceName() {
return policyRepository.getServiceName();
}
private RangerPolicyEvaluator getPolicyEvaluator(Long id) {
RangerPolicyEvaluator ret = policyRepository.getPolicyEvaluator(id);
if (ret == null && tagPolicyRepository != null) {
ret = tagPolicyRepository.getPolicyEvaluator(id);
}
return ret;
}
private RangerAccessResult createAccessResult(RangerAccessRequest request, int policyType) {
RangerAccessResult ret = new RangerAccessResult(policyType, this.getServiceName(), policyRepository.getServiceDef(), request);
switch (policyRepository.getAuditModeEnum()) {
case AUDIT_ALL:
ret.setIsAudited(true);
break;
case AUDIT_NONE:
ret.setIsAudited(false);
break;
default:
if (CollectionUtils.isEmpty(policyRepository.getPolicies()) && tagPolicyRepository == null) {
ret.setIsAudited(true);
}
break;
}
return ret;
}
private void setResourceServiceDef(RangerAccessRequest request) {
RangerAccessResource resource = request.getResource();
if (resource.getServiceDef() == null) {
if (resource instanceof RangerMutableResource) {
RangerMutableResource mutable = (RangerMutableResource) resource;
mutable.setServiceDef(getServiceDef());
} else {
LOG.debug("RangerPolicyEngineImpl.setResourceServiceDef(): Cannot set ServiceDef in RangerMutableResource.");
}
}
}
private boolean hasTagPolicies(RangerPolicyRepository tagPolicyRepository) {
return tagPolicyRepository != null && CollectionUtils.isNotEmpty(tagPolicyRepository.getPolicies());
}
private boolean hasResourcePolicies(RangerPolicyRepository policyRepository) {
return policyRepository != null && CollectionUtils.isNotEmpty(policyRepository.getPolicies());
}
private void updatePolicyUsageCounts(RangerAccessRequest accessRequest, RangerAccessResult accessResult) {
boolean auditCountUpdated = false;
if (accessResult.getIsAccessDetermined()) {
RangerPolicyEvaluator accessPolicy = getPolicyEvaluator(accessResult.getPolicyId());
if (accessPolicy != null) {
if (accessPolicy.getPolicy().getIsAuditEnabled()) {
updateUsageCount(accessPolicy, 2);
accessResult.setAuditPolicyId(accessResult.getPolicyId());
auditCountUpdated = true;
} else {
updateUsageCount(accessPolicy, 1);
}
}
}
if (!auditCountUpdated && accessResult.getIsAuditedDetermined()) {
long auditPolicyId = accessResult.getAuditPolicyId();
RangerPolicyEvaluator auditPolicy = auditPolicyId == -1 ? null : getPolicyEvaluator(auditPolicyId);
updateUsageCount(auditPolicy, 1);
}
if(RangerPerfTracer.isPerfTraceEnabled(PERF_POLICYENGINE_USAGE_LOG)) {
RangerAccessRequestImpl rangerAccessRequest = (RangerAccessRequestImpl) accessRequest;
RangerPerfTracer perf = RangerPerfTracer.getPerfTracer(PERF_POLICYENGINE_USAGE_LOG,
"RangerPolicyEngine.usage(accessingUser=" + rangerAccessRequest.getUser()
+ ",accessedResource=" + rangerAccessRequest.getResource().getAsString()
+ ",accessType=" + rangerAccessRequest.getAccessType()
+ ",evaluatedPoliciesCount=" + accessResult.getEvaluatedPoliciesCount() + ")");
RangerPerfTracer.logAlways(perf);
}
}
private void updateUsageCount(RangerPolicyEvaluator evaluator, int number) {
if (evaluator != null) {
evaluator.incrementUsageCount(number);
}
}
private void buildZoneTrie(ServicePolicies servicePolicies) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.buildZoneTrie()");
}
Map<String, ServicePolicies.SecurityZoneInfo> securityZones = servicePolicies.getSecurityZones();
if (MapUtils.isNotEmpty(securityZones)) {
RangerServiceDef serviceDef = servicePolicies.getServiceDef();
List<RangerZoneResourceMatcher> matchers = new ArrayList<>();
zoneTagServiceMap = new HashMap<>();
for (Map.Entry<String, ServicePolicies.SecurityZoneInfo> securityZone : securityZones.entrySet()) {
String zoneName = securityZone.getKey();
ServicePolicies.SecurityZoneInfo zoneDetails = securityZone.getValue();
if (LOG.isDebugEnabled()) {
LOG.debug("Building matchers for zone:[" + zoneName +"]");
}
for (Map<String, List<String>> resource : zoneDetails.getResources()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Building matcher for resource:[" + resource + "] in zone:[" + zoneName +"]");
}
Map<String, RangerPolicy.RangerPolicyResource> policyResources = new HashMap<>();
for (Map.Entry<String, List<String>> entry : resource.entrySet()) {
String resourceDefName = entry.getKey();
List<String> resourceValues = entry.getValue();
RangerPolicy.RangerPolicyResource policyResource = new RangerPolicy.RangerPolicyResource();
policyResource.setIsExcludes(false);
policyResource.setIsRecursive(StringUtils.equals(serviceDef.getName(), EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_HDFS_NAME));
policyResource.setValues(resourceValues);
policyResources.put(resourceDefName, policyResource);
}
matchers.add(new RangerZoneResourceMatcher(zoneName, policyResources, serviceDef));
if (LOG.isDebugEnabled()) {
LOG.debug("Built matcher for resource:[" + resource +"] in zone:[" + zoneName + "]");
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("Built all matchers for zone:[" + zoneName +"]");
}
if (zoneDetails.getContainsAssociatedTagService()) {
zoneTagServiceMap.put(zoneName, zoneName);
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("Built matchers for all Zones");
}
trieMap = new HashMap<>();
for (RangerServiceDef.RangerResourceDef resourceDef : serviceDef.getResources()) {
trieMap.put(resourceDef.getName(), new RangerResourceTrie<>(resourceDef, matchers));
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.buildZoneTrie()");
}
}
@Override
public String getMatchedZoneName(GrantRevokeRequest grantRevokeRequest) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.getMatchedZoneName(" + grantRevokeRequest + ")");
}
String ret = null;
if (this.trieMap != null) {
Map<String, ? extends Object> resource = grantRevokeRequest.getResource();
Map<String, List<String>> resourceForZoneMatch = convertFromSingleResource(resource);
RangerAccessResource accessResource = convertToAccessResource(resource);
ret = getMatchedZoneName(resourceForZoneMatch, accessResource);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.getMatchedZoneName(" + grantRevokeRequest + ") : " + ret);
}
return ret;
}
public boolean compare(RangerPolicyEngineImpl other) {
// Compare zones, policyRepositories and tagRepository
boolean ret;
if (policyRepository != null && other.policyRepository != null) {
ret = policyRepository .compare(other.policyRepository);
} else {
ret = policyRepository == other.policyRepository;
}
if (ret) {
if (tagPolicyRepository != null && other.tagPolicyRepository != null) {
ret = tagPolicyRepository.compare(other.tagPolicyRepository);
} else {
ret = tagPolicyRepository == other.tagPolicyRepository;
}
if (ret) {
if (trieMap != null && other.trieMap != null) {
//check trieMap
ret = trieMap.size() == other.trieMap.size();
if (ret) {
for (Map.Entry<String, RangerResourceTrie> entry : trieMap.entrySet()) {
ret = entry.getValue().compareSubtree(other.trieMap.get(entry.getKey()));
if (!ret) {
break;
}
}
}
ret = true;
} else {
ret = trieMap == other.trieMap;
}
if (ret) {
// Check policyRepositories
ret = policyRepositories.size() == other.policyRepositories.size();
if (ret) {
for (Map.Entry<String, RangerPolicyRepository> entry : policyRepositories.entrySet()) {
ret = entry.getValue().compare(other.policyRepositories.get(entry.getKey()));
if (!ret) {
break;
}
}
}
}
}
}
return ret;
}
private String getMatchedZoneName(RangerAccessResource accessResource) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.getMatchedZoneName(" + accessResource + ")");
}
String ret = null;
if (this.trieMap != null) {
Map<String, List<String>> resource = convertFromAccessResource(accessResource);
ret = getMatchedZoneName(resource, accessResource);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.getMatchedZoneName(" + accessResource + ") : " + ret);
}
return ret;
}
private String getMatchedZoneName(Map<String, List<String>> resource, RangerAccessResource accessResource) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerPolicyEngineImpl.getMatchedZoneName(" + resource + ", " + accessResource + ")");
}
String ret = null;
if (this.trieMap != null) {
List<List<RangerZoneResourceMatcher>> zoneMatchersList = null;
List<RangerZoneResourceMatcher> smallestList = null;
for (Map.Entry<String, List<String>> entry : resource.entrySet()) {
String resourceDefName = entry.getKey();
List<String> resourceValues = entry.getValue();
RangerResourceTrie<RangerZoneResourceMatcher> trie = trieMap.get(resourceDefName);
if (trie == null) {
continue;
}
List<RangerZoneResourceMatcher> matchedZones = trie.getEvaluatorsForResource(resourceValues);
if (LOG.isDebugEnabled()) {
LOG.debug("ResourceDefName:[" + resourceDefName + "], values:[" + resourceValues + "], matched-zones:[" + matchedZones + "]");
}
if (CollectionUtils.isEmpty(matchedZones)) { // no policies for this resource, bail out
zoneMatchersList = null;
smallestList = null;
break;
}
if (smallestList == null) {
smallestList = matchedZones;
} else {
if (zoneMatchersList == null) {
zoneMatchersList = new ArrayList<>();
zoneMatchersList.add(smallestList);
}
zoneMatchersList.add(matchedZones);
if (smallestList.size() > matchedZones.size()) {
smallestList = matchedZones;
}
}
}
if (smallestList != null) {
final List<RangerZoneResourceMatcher> intersection;
if (zoneMatchersList != null) {
intersection = new ArrayList<>(smallestList);
for (List<RangerZoneResourceMatcher> zoneMatchers : zoneMatchersList) {
if (zoneMatchers != smallestList) {
// remove zones from intersection that are not in zoneMatchers
intersection.retainAll(zoneMatchers);
if (CollectionUtils.isEmpty(intersection)) { // if no zoneMatcher exists, bail out and return empty list
break;
}
}
}
} else {
intersection = smallestList;
}
if (LOG.isDebugEnabled()) {
LOG.debug("Resource:[" + resource + "], matched-zones:[" + intersection + "]");
}
if (intersection.size() > 0) {
Set<String> matchedZoneNames = new HashSet<>();
for (RangerZoneResourceMatcher zoneMatcher : intersection) {
if (LOG.isDebugEnabled()) {
LOG.debug("Trying to match resource:[" + accessResource + "] using zoneMatcher:[" + zoneMatcher + "]");
}
// These are potential matches. Try to really match them
if (zoneMatcher.getPolicyResourceMatcher().isMatch(accessResource, RangerPolicyResourceMatcher.MatchScope.ANY, null)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Matched resource:[" + accessResource + "] using zoneMatcher:[" + zoneMatcher + "]");
}
// Actual match happened
matchedZoneNames.add(zoneMatcher.getSecurityZoneName());
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Did not match resource:[" + accessResource + "] using zoneMatcher:[" + zoneMatcher + "]");
}
}
}
LOG.info("The following zone-names matched resource:[" + accessResource + "]: " + matchedZoneNames);
if (matchedZoneNames.size() == 1) {
String[] zones = new String[1];
matchedZoneNames.toArray(zones);
ret = zones[0];
} else {
LOG.error("Internal error, multiple zone-names are matched. The following zone-names matched resource:[" + resource + "]: " + matchedZoneNames);
}
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerPolicyEngineImpl.getMatchedZoneName(" + resource + ", " + accessResource + ") : " + ret);
}
return ret;
}
private static Map<String, List<String>> convertFromAccessResource(RangerAccessResource accessResource) {
return convertFromSingleResource(accessResource.getAsMap());
}
private static Map<String, List<String>> convertFromSingleResource(Map<String, ? extends Object> resource) {
Map<String, List<String>> ret = new HashMap<>();
for (Map.Entry<String, ? extends Object> entry : resource.entrySet()) {
List<String> value;
if (entry.getValue() instanceof Collection && CollectionUtils.isNotEmpty((Collection) entry.getValue())) {
value = new ArrayList((Collection) entry.getValue());
} else if (entry.getValue() instanceof String) {
value = new ArrayList<>();
value.add((String) entry.getValue());
} else {
LOG.error("access-resource contains value of unknown type : [" + entry.getValue().getClass().getCanonicalName() + "]");
value = new ArrayList<>();
}
ret.put(entry.getKey(), value);
}
return ret;
}
private RangerAccessResource convertToAccessResource(Map<String, ? extends Object> resource) {
RangerAccessResourceImpl ret = new RangerAccessResourceImpl();
ret.setServiceDef(getServiceDef());
for (Map.Entry<String, ? extends Object> entry : resource.entrySet()) {
ret.setValue(entry.getKey(), entry.getValue());
}
return ret;
}
private static RangerPolicyRepository shareWith(RangerPolicyRepository other) {
if (other != null) {
other.setIsShared(true);
}
return other;
}
private void setUserGroupRoleMapping(RangerRoles rangerRoles) {
Set<RangerRole> rangerRoleSet = rangerRoles.getRangerRoles();
if (CollectionUtils.isNotEmpty(rangerRoleSet)) {
RangerRolesUtil rangerRolesUtil = new RangerRolesUtil();
rangerRolesUtil.init(rangerRoleSet);
userRoleMapping = rangerRolesUtil.getUserRoleMapping();
groupRoleMapping = rangerRolesUtil.getGroupRoleMapping();
} else {
userRoleMapping = null;
groupRoleMapping = null;
}
}
}