blob: 97da473a85e66dd89c20de85aecac130c8fbcb33 [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.service;
import java.util.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.ranger.admin.client.RangerAdminClient;
import org.apache.ranger.admin.client.RangerAdminRESTClient;
import org.apache.ranger.audit.provider.AuditHandler;
import org.apache.ranger.audit.provider.AuditProviderFactory;
import org.apache.ranger.audit.provider.StandAloneAuditProviderFactory;
import org.apache.ranger.authorization.hadoop.config.RangerAuditConfig;
import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
import org.apache.ranger.authorization.utils.StringUtil;
import org.apache.ranger.plugin.contextenricher.RangerAdminGdsInfoRetriever;
import org.apache.ranger.plugin.contextenricher.RangerAdminUserStoreRetriever;
import org.apache.ranger.plugin.contextenricher.RangerContextEnricher;
import org.apache.ranger.plugin.contextenricher.RangerGdsEnricher;
import org.apache.ranger.plugin.contextenricher.RangerTagEnricher;
import org.apache.ranger.plugin.contextenricher.RangerUserStoreEnricher;
import org.apache.ranger.plugin.policyengine.RangerRequestScriptEvaluator;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerRole;
import org.apache.ranger.plugin.model.RangerServiceDef;
import org.apache.ranger.plugin.policyengine.RangerAccessRequest;
import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
import org.apache.ranger.plugin.policyengine.RangerAccessResourceImpl;
import org.apache.ranger.plugin.policyengine.RangerAccessResult;
import org.apache.ranger.plugin.policyengine.RangerAccessResultProcessor;
import org.apache.ranger.plugin.policyengine.RangerPluginContext;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngineImpl;
import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
import org.apache.ranger.plugin.policyengine.RangerResourceAccessInfo;
import org.apache.ranger.plugin.policyengine.gds.GdsPolicyEngine;
import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.plugin.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RangerBasePlugin {
private static final Logger LOG = LoggerFactory.getLogger(RangerBasePlugin.class);
private final RangerPluginConfig pluginConfig;
private final RangerPluginContext pluginContext;
private final Map<String, LogHistory> logHistoryList = new Hashtable<>();
private final int logInterval = 30000; // 30 seconds
private final DownloadTrigger accessTrigger = new DownloadTrigger();
private PolicyRefresher refresher;
private RangerPolicyEngine policyEngine;
private RangerAuthContext currentAuthContext;
private RangerAccessResultProcessor resultProcessor;
private RangerRoles roles;
private final List<RangerChainedPlugin> chainedPlugins;
private final boolean dedupStrings;
private boolean isUserStoreEnricherAddedImplcitly = false;
public RangerBasePlugin(String serviceType, String appId) {
this(new RangerPluginConfig(serviceType, null, appId, null, null, null));
}
public RangerBasePlugin(String serviceType, String serviceName, String appId) {
this(new RangerPluginConfig(serviceType, serviceName, appId, null, null, null));
}
public RangerBasePlugin(RangerPluginConfig pluginConfig) {
this.pluginConfig = pluginConfig;
this.pluginContext = new RangerPluginContext(pluginConfig);
boolean usePerfDataRecorder = pluginConfig.getBoolean("ranger.perf.aggregate.data", false);
int perfDataDumpInterval = pluginConfig.getInt("ranger.perf.aggregate.data.dump.interval", 0);
boolean usePerfDataLock = pluginConfig.getBoolean("ranger.perf.aggregate.data.lock.enabled", false);
PerfDataRecorder.initialize(usePerfDataRecorder, perfDataDumpInterval, usePerfDataLock, null);
Set<String> superUsers = toSet(pluginConfig.get(pluginConfig.getPropertyPrefix() + ".super.users"));
Set<String> superGroups = toSet(pluginConfig.get(pluginConfig.getPropertyPrefix() + ".super.groups"));
Set<String> auditExcludeUsers = toSet(pluginConfig.get(pluginConfig.getPropertyPrefix() + ".audit.exclude.users"));
Set<String> auditExcludeGroups = toSet(pluginConfig.get(pluginConfig.getPropertyPrefix() + ".audit.exclude.groups"));
Set<String> auditExcludeRoles = toSet(pluginConfig.get(pluginConfig.getPropertyPrefix() + ".audit.exclude.roles"));
Set<String> serviceAdmins = toSet(pluginConfig.get(pluginConfig.getPropertyPrefix() + ".service.admins"));
setSuperUsersAndGroups(superUsers, superGroups);
setAuditExcludedUsersGroupsRoles(auditExcludeUsers, auditExcludeGroups, auditExcludeRoles);
setIsFallbackSupported(pluginConfig.getBoolean(pluginConfig.getPropertyPrefix() + ".is.fallback.supported", false));
setServiceAdmins(serviceAdmins);
RangerRequestScriptEvaluator.init(pluginConfig);
this.dedupStrings = pluginConfig.getBoolean(pluginConfig.getPropertyPrefix() + ".dedup.strings", true);
this.chainedPlugins = initChainedPlugins();
}
public RangerBasePlugin(RangerPluginConfig pluginConfig, ServicePolicies policies, ServiceTags tags, RangerRoles roles) {
this(pluginConfig, policies, tags, roles, null, null);
}
public RangerBasePlugin(RangerPluginConfig pluginConfig, ServicePolicies policies, ServiceTags tags, RangerRoles roles, RangerUserStore userStore) {
this(pluginConfig, policies, tags, roles, userStore, null);
}
public RangerBasePlugin(RangerPluginConfig pluginConfig, ServicePolicies policies, ServiceTags tags, RangerRoles roles, RangerUserStore userStore, ServiceGdsInfo gdsInfo) {
this(pluginConfig);
init();
setPolicies(policies);
setRoles(roles);
if (tags != null) {
RangerTagEnricher tagEnricher = getTagEnricher();
if (tagEnricher != null) {
tagEnricher.setServiceTags(tags);
} else {
LOG.warn("RangerBasePlugin(tagsVersion=" + tags.getTagVersion() + "): no tag enricher found. Plugin will not enforce tag-based policies");
}
}
if (userStore != null) {
RangerUserStoreEnricher userStoreEnricher = getUserStoreEnricher();
if (userStoreEnricher != null) {
userStoreEnricher.setRangerUserStore(userStore);
} else {
LOG.warn("RangerBasePlugin(userStoreVersion=" + userStore.getUserStoreVersion() + "): no userstore enricher found. Plugin will not enforce user/group attribute-based policies");
}
}
if (gdsInfo != null) {
RangerGdsEnricher gdsEnricher = getGdsEnricher();
if (gdsEnricher != null) {
gdsEnricher.setGdsInfo(gdsInfo);
} else {
LOG.warn("RangerBasePlugin(gdsInfo=" + gdsInfo.getGdsVersion() + "): no GDS enricher found. Plugin will not enforce GDS policies");
}
}
}
public static AuditHandler getAuditProvider(String serviceName) {
AuditProviderFactory providerFactory = RangerBasePlugin.getAuditProviderFactory(serviceName);
AuditHandler ret = providerFactory.getAuditProvider();
return ret;
}
public String getServiceType() {
return pluginConfig.getServiceType();
}
public String getAppId() {
return pluginConfig.getAppId();
}
public RangerPluginConfig getConfig() {
return pluginConfig;
}
public String getClusterName() {
return pluginConfig.getClusterName();
}
public RangerPluginContext getPluginContext() {
return pluginContext;
}
public RangerAuthContext getCurrentRangerAuthContext() { return currentAuthContext; }
public List<RangerChainedPlugin> getChainedPlugins() { return chainedPlugins; }
// For backward compatibility
public RangerAuthContext createRangerAuthContext() { return currentAuthContext; }
public RangerRoles getRoles() {
return this.roles;
}
public void setRoles(RangerRoles roles) {
this.roles = roles;
RangerPolicyEngine policyEngine = this.policyEngine;
if (policyEngine != null) {
policyEngine.setRoles(roles);
}
pluginContext.notifyAuthContextChanged();
}
public void setAuditExcludedUsersGroupsRoles(Set<String> users, Set<String> groups, Set<String> roles) {
pluginConfig.setAuditExcludedUsersGroupsRoles(users, groups, roles);
}
public void setSuperUsersAndGroups(Set<String> users, Set<String> groups) {
pluginConfig.setSuperUsersGroups(users, groups);
}
public void setIsFallbackSupported(boolean isFallbackSupported) {
pluginConfig.setIsFallbackSupported(isFallbackSupported);
}
public void setServiceAdmins(Set<String> users) {
pluginConfig.setServiceAdmins(users);
}
public RangerServiceDef getServiceDef() {
RangerPolicyEngine policyEngine = this.policyEngine;
return policyEngine != null ? policyEngine.getServiceDef() : null;
}
public int getServiceDefId() {
RangerServiceDef serviceDef = getServiceDef();
return serviceDef != null && serviceDef.getId() != null ? serviceDef.getId().intValue() : -1;
}
public String getServiceName() {
return pluginConfig.getServiceName();
}
public AuditProviderFactory getAuditProviderFactory() { return RangerBasePlugin.getAuditProviderFactory(getServiceName()); }
public void init() {
cleanup();
AuditProviderFactory providerFactory = AuditProviderFactory.getInstance();
if (!providerFactory.isInitDone()) {
if (pluginConfig.getProperties() != null) {
providerFactory.init(pluginConfig.getProperties(), getAppId());
} else {
LOG.error("Audit subsystem is not initialized correctly. Please check audit configuration. ");
LOG.error("No authorization audits will be generated. ");
}
}
if (!pluginConfig.getPolicyEngineOptions().disablePolicyRefresher) {
refresher = new PolicyRefresher(this);
LOG.info("Created PolicyRefresher Thread(" + refresher.getName() + ")");
refresher.setDaemon(true);
refresher.startRefresher();
}
for (RangerChainedPlugin chainedPlugin : chainedPlugins) {
chainedPlugin.init();
}
}
public long getPoliciesVersion() {
RangerPolicyEngine policyEngine = this.policyEngine;
Long ret = policyEngine != null ? policyEngine.getPolicyVersion() : null;
return ret != null ? ret : -1L;
}
public long getTagsVersion() {
RangerTagEnricher tagEnricher = getTagEnricher();
Long ret = tagEnricher != null ? tagEnricher.getServiceTagsVersion() : null;
return ret != null ? ret : -1L;
}
public long getRolesVersion() {
RangerPolicyEngine policyEngine = this.policyEngine;
Long ret = policyEngine != null ? policyEngine.getRoleVersion() : null;
return ret != null ? ret : -1L;
}
public long getUserStoreVersion() {
RangerUserStoreEnricher userStoreEnricher = getUserStoreEnricher();
Long ret = userStoreEnricher != null ? userStoreEnricher.getUserStoreVersion() : null;
return ret != null ? ret : -1L;
}
public void setPolicies(ServicePolicies policies) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> setPolicies(" + policies + ")");
}
if (pluginConfig.isEnableImplicitUserStoreEnricher() && policies != null && !ServiceDefUtil.isUserStoreEnricherPresent(policies)) {
String retrieverClassName = pluginConfig.get(RangerUserStoreEnricher.USERSTORE_RETRIEVER_CLASSNAME_OPTION, RangerAdminUserStoreRetriever.class.getCanonicalName());
String retrieverPollIntMs = pluginConfig.get(RangerUserStoreEnricher.USERSTORE_REFRESHER_POLLINGINTERVAL_OPTION, Integer.toString(60 * 1000));
// in case of delta, policies will only have changes; hence add userStoreEnricher if it was implicitly added previous calls to setPolicies()
if (RangerPolicyDeltaUtil.hasPolicyDeltas(policies) == Boolean.TRUE && isUserStoreEnricherAddedImplcitly) {
ServiceDefUtil.addUserStoreEnricher(policies, retrieverClassName, retrieverPollIntMs);
} else if (pluginConfig.isUseRangerGroups() || pluginConfig.isConvertEmailToUsername()) {
isUserStoreEnricherAddedImplcitly = ServiceDefUtil.addUserStoreEnricher(policies, retrieverClassName, retrieverPollIntMs);
} else {
isUserStoreEnricherAddedImplcitly = ServiceDefUtil.addUserStoreEnricherIfNeeded(policies, retrieverClassName, retrieverPollIntMs);
}
}
if (pluginConfig.isEnableImplicitGdsInfoEnricher() && policies != null && !ServiceDefUtil.isGdsInfoEnricherPresent(policies)) {
String retrieverClassName = pluginConfig.get(RangerGdsEnricher.RETRIEVER_CLASSNAME_OPTION, RangerAdminGdsInfoRetriever.class.getCanonicalName());
String retrieverPollIntMs = pluginConfig.get(RangerGdsEnricher.REFRESHER_POLLINGINTERVAL_OPTION, Integer.toString(60 * 1000));
ServiceDefUtil.addGdsInfoEnricher(policies, retrieverClassName, retrieverPollIntMs);
}
// guard against catastrophic failure during policy engine Initialization or
try {
RangerPolicyEngine oldPolicyEngine = this.policyEngine;
ServicePolicies servicePolicies = null;
boolean isNewEngineNeeded = true;
boolean usePolicyDeltas = false;
if (policies == null) {
policies = getDefaultSvcPolicies();
if (policies == null) {
LOG.error("Could not get default Service Policies. Keeping old policy-engine!");
isNewEngineNeeded = false;
}
} else {
if (dedupStrings) {
policies.dedupStrings();
}
Boolean hasPolicyDeltas = RangerPolicyDeltaUtil.hasPolicyDeltas(policies);
if (hasPolicyDeltas == null) {
LOG.info("Downloaded policies do not require policy change !! [" + policies + "]");
if (this.policyEngine == null) {
LOG.info("There are no material changes, and current policy-engine is null! Creating a policy-engine with default service policies");
ServicePolicies defaultSvcPolicies = getDefaultSvcPolicies();
if (defaultSvcPolicies == null) {
LOG.error("Could not get default Service Policies. Keeping old policy-engine! This is a FATAL error as the old policy-engine is null!");
isNewEngineNeeded = false;
} else {
defaultSvcPolicies.setPolicyVersion(policies.getPolicyVersion());
policies = defaultSvcPolicies;
isNewEngineNeeded = true;
}
} else {
LOG.info("Keeping old policy-engine!");
isNewEngineNeeded = false;
}
} else {
if (hasPolicyDeltas.equals(Boolean.TRUE)) {
// Rebuild policies from deltas
RangerPolicyEngineImpl policyEngine = (RangerPolicyEngineImpl) oldPolicyEngine;
servicePolicies = ServicePolicies.applyDelta(policies, policyEngine);
if (servicePolicies != null) {
usePolicyDeltas = true;
} else {
LOG.error("Could not apply deltas=" + Arrays.toString(policies.getPolicyDeltas().toArray()));
LOG.warn("Keeping old policy-engine!");
isNewEngineNeeded = false;
}
} else {
if (policies.getPolicies() == null) {
policies.setPolicies(new ArrayList<>());
}
if (MapUtils.isNotEmpty(policies.getSecurityZones())) {
for (ServicePolicies.SecurityZoneInfo element : policies.getSecurityZones().values()) {
if (element.getPolicies() == null) {
element.setPolicies(new ArrayList<>());
}
}
}
}
}
}
if (isNewEngineNeeded) {
RangerPolicyEngine newPolicyEngine = null;
boolean isPolicyEngineShared = false;
if (!usePolicyDeltas) {
if (LOG.isDebugEnabled()) {
LOG.debug("Creating engine from policies");
}
newPolicyEngine = new RangerPolicyEngineImpl(policies, pluginContext, roles);
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("policy-deltas are not null");
}
if (CollectionUtils.isNotEmpty(policies.getPolicyDeltas()) || MapUtils.isNotEmpty(policies.getSecurityZones())) {
if (LOG.isDebugEnabled()) {
LOG.debug("Non empty policy-deltas found. Cloning engine using policy-deltas");
}
if (oldPolicyEngine != null) {
RangerPolicyEngineImpl oldPolicyEngineImpl = (RangerPolicyEngineImpl) oldPolicyEngine;
newPolicyEngine = RangerPolicyEngineImpl.getPolicyEngine(oldPolicyEngineImpl, policies);
}
if (newPolicyEngine != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Applied policyDeltas=" + Arrays.toString(policies.getPolicyDeltas().toArray()) + ")");
}
isPolicyEngineShared = true;
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Failed to apply policyDeltas=" + Arrays.toString(policies.getPolicyDeltas().toArray()) + "), Creating engine from policies");
LOG.debug("Creating new engine from servicePolicies:[" + servicePolicies + "]");
}
newPolicyEngine = new RangerPolicyEngineImpl(servicePolicies, pluginContext, roles);
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Empty policy-deltas. No need to change policy engine");
}
}
}
if (newPolicyEngine != null) {
if (!isPolicyEngineShared) {
newPolicyEngine.setUseForwardedIPAddress(pluginConfig.isUseForwardedIPAddress());
newPolicyEngine.setTrustedProxyAddresses(pluginConfig.getTrustedProxyAddresses());
}
LOG.info("Switching policy engine from [" + getPolicyVersion() + "]");
this.policyEngine = newPolicyEngine;
LOG.info("Switched policy engine to [" + getPolicyVersion() + "]");
this.currentAuthContext = pluginContext.getAuthContext();
pluginContext.notifyAuthContextChanged();
if (oldPolicyEngine != null && oldPolicyEngine != newPolicyEngine) {
((RangerPolicyEngineImpl) oldPolicyEngine).releaseResources(!isPolicyEngineShared);
}
if (this.refresher != null) {
boolean doPreserveDeltas = pluginConfig.getBoolean (pluginConfig.getPropertyPrefix() + ".preserve.deltas", false);
if (!doPreserveDeltas) {
this.refresher.saveToCache(usePolicyDeltas ? servicePolicies : policies);
} else {
// Save both deltas and all policies to cache for verification
this.refresher.saveToCache(policies);
if (usePolicyDeltas) {
this.refresher.saveToCache(servicePolicies);
}
}
}
}
} else {
LOG.warn("Leaving current policy engine as-is");
LOG.warn("Policies are not saved to cache. policyVersion in the policy-cache may be different than in Ranger-admin, even though the policies are the same!");
LOG.warn("Ranger-PolicyVersion:[" + (policies != null ? policies.getPolicyVersion() : -1L) + "], Cached-PolicyVersion:[" + (this.policyEngine != null ? this.policyEngine.getPolicyVersion() : -1L) + "]");
}
} catch (Exception e) {
LOG.error("setPolicies: policy engine initialization failed! Leaving current policy engine as-is. Exception : ", e);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== setPolicies(" + policies + ")");
}
}
public void cleanup() {
PolicyRefresher refresher = this.refresher;
this.refresher = null;
RangerPolicyEngine policyEngine = this.policyEngine;
this.policyEngine = null;
if (refresher != null) {
refresher.stopRefresher();
}
if (policyEngine != null) {
((RangerPolicyEngineImpl) policyEngine).releaseResources(true);
}
}
public void setResultProcessor(RangerAccessResultProcessor resultProcessor) {
this.resultProcessor = resultProcessor;
}
public RangerAccessResultProcessor getResultProcessor() {
return this.resultProcessor;
}
public RangerAccessResult isAccessAllowed(RangerAccessRequest request) {
return isAccessAllowed(request, resultProcessor);
}
public Collection<RangerAccessResult> isAccessAllowed(Collection<RangerAccessRequest> requests) {
return isAccessAllowed(requests, resultProcessor);
}
public RangerAccessResult isAccessAllowed(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor) {
RangerAccessResult ret = null;
RangerPolicyEngine policyEngine = this.policyEngine;
if (policyEngine != null) {
ret = policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_ACCESS, null);
}
if (ret != null) {
for (RangerChainedPlugin chainedPlugin : chainedPlugins) {
if (LOG.isDebugEnabled()) {
LOG.debug("BasePlugin.isAccessAllowed result=[" + ret + "]");
LOG.debug("Calling chainedPlugin.isAccessAllowed for service:[" + chainedPlugin.plugin.pluginConfig.getServiceName() + "]");
}
RangerAccessResult chainedResult;
if (ret.getIsAccessDetermined() && chainedPlugin.skipAccessCheckIfAlreadyDetermined) {
chainedResult = null;
} else {
chainedResult = chainedPlugin.isAccessAllowed(request);
}
if (chainedResult != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("chainedPlugin.isAccessAllowed for service:[" + chainedPlugin.plugin.pluginConfig.getServiceName() + "] returned result=[" + chainedResult + "]");
}
updateResultFromChainedResult(ret, chainedResult);
if (LOG.isDebugEnabled()) {
LOG.debug("After updating result from chainedPlugin.isAccessAllowed for service:[" + chainedPlugin.plugin.pluginConfig.getServiceName() + "], result=" + ret + "]");
}
}
}
}
if (policyEngine != null) {
policyEngine.evaluateAuditPolicies(ret);
}
if (resultProcessor != null) {
resultProcessor.processResult(ret);
}
return ret;
}
public Collection<RangerAccessResult> isAccessAllowed(Collection<RangerAccessRequest> requests, RangerAccessResultProcessor resultProcessor) {
Collection<RangerAccessResult> ret = null;
RangerPolicyEngine policyEngine = this.policyEngine;
if (policyEngine != null) {
ret = policyEngine.evaluatePolicies(requests, RangerPolicy.POLICY_TYPE_ACCESS, null);
}
if (CollectionUtils.isNotEmpty(ret)) {
for (RangerChainedPlugin chainedPlugin : chainedPlugins) {
Collection<RangerAccessResult> chainedResults = chainedPlugin.isAccessAllowed(requests);
if (CollectionUtils.isNotEmpty(chainedResults)) {
Iterator<RangerAccessResult> iterRet = ret.iterator();
Iterator<RangerAccessResult> iterChainedResults = chainedResults.iterator();
while (iterRet.hasNext() && iterChainedResults.hasNext()) {
RangerAccessResult result = iterRet.next();
RangerAccessResult chainedResult = iterChainedResults.next();
if (result != null && chainedResult != null) {
updateResultFromChainedResult(result, chainedResult);
}
}
}
}
}
if (policyEngine != null && CollectionUtils.isNotEmpty(ret)) {
for (RangerAccessResult result : ret) {
policyEngine.evaluateAuditPolicies(result);
}
}
if (resultProcessor != null) {
resultProcessor.processResults(ret);
}
return ret;
}
public RangerAccessResult evalDataMaskPolicies(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor) {
RangerPolicyEngine policyEngine = this.policyEngine;
RangerAccessResult ret = null;
if(policyEngine != null) {
ret = policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_DATAMASK, resultProcessor);
if (ret != null) {
for (RangerChainedPlugin chainedPlugin : chainedPlugins) {
if (LOG.isDebugEnabled()) {
LOG.debug("BasePlugin.evalDataMaskPolicies result=[" + ret + "]");
LOG.debug("Calling chainedPlugin.evalDataMaskPolicies for service:[" + chainedPlugin.plugin.pluginConfig.getServiceName() + "]");
}
RangerAccessResult chainedResult = chainedPlugin.evalDataMaskPolicies(request);
if (chainedResult != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("chainedPlugin.evalDataMaskPolicies for service:[" + chainedPlugin.plugin.pluginConfig.getServiceName() + "] returned result=[" + chainedResult + "]");
}
updateResultFromChainedResult(ret, chainedResult);
if (LOG.isDebugEnabled()) {
LOG.debug("After updating result from chainedPlugin.evalDataMaskPolicies for service:[" + chainedPlugin.plugin.pluginConfig.getServiceName() + "], result=" + ret + "]");
}
}
}
}
policyEngine.evaluateAuditPolicies(ret);
}
return ret;
}
public RangerAccessResult evalRowFilterPolicies(RangerAccessRequest request, RangerAccessResultProcessor resultProcessor) {
RangerPolicyEngine policyEngine = this.policyEngine;
RangerAccessResult ret = null;
if(policyEngine != null) {
ret = policyEngine.evaluatePolicies(request, RangerPolicy.POLICY_TYPE_ROWFILTER, resultProcessor);
if (ret != null) {
for (RangerChainedPlugin chainedPlugin : chainedPlugins) {
if (LOG.isDebugEnabled()) {
LOG.debug("BasePlugin.evalRowFilterPolicies result=[" + ret + "]");
LOG.debug("Calling chainedPlugin.evalRowFilterPolicies for service:[" + chainedPlugin.plugin.pluginConfig.getServiceName() + "]");
}
RangerAccessResult chainedResult = chainedPlugin.evalRowFilterPolicies(request);
if (chainedResult != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("chainedPlugin.evalRowFilterPolicies for service:[" + chainedPlugin.plugin.pluginConfig.getServiceName() + "] returned result=[" + chainedResult + "]");
}
updateResultFromChainedResult(ret, chainedResult);
if (LOG.isDebugEnabled()) {
LOG.debug("After updating result from chainedPlugin.evalRowFilterPolicies for service:[" + chainedPlugin.plugin.pluginConfig.getServiceName() + "], result=" + ret + "]");
}
}
}
}
policyEngine.evaluateAuditPolicies(ret);
}
return ret;
}
public void evalAuditPolicies(RangerAccessResult result) {
RangerPolicyEngine policyEngine = this.policyEngine;
if (policyEngine != null) {
policyEngine.evaluateAuditPolicies(result);
}
}
public RangerResourceAccessInfo getResourceAccessInfo(RangerAccessRequest request) {
RangerPolicyEngine policyEngine = this.policyEngine;
if(policyEngine != null) {
return policyEngine.getResourceAccessInfo(request);
}
return null;
}
public RangerResourceACLs getResourceACLs(RangerAccessRequest request) {
return getResourceACLs(request, null);
}
public RangerResourceACLs getResourceACLs(RangerAccessRequest request, Integer policyType) {
RangerResourceACLs ret = null;
RangerPolicyEngine policyEngine = this.policyEngine;
if(policyEngine != null) {
ret = policyEngine.getResourceACLs(request, policyType);
}
for (RangerChainedPlugin chainedPlugin : chainedPlugins) {
RangerResourceACLs chainedResourceACLs = chainedPlugin.getResourceACLs(request, policyType);
if (chainedResourceACLs != null) {
if (LOG.isDebugEnabled()) {
LOG.debug("Chained-plugin returned non-null ACLs!!");
}
if (chainedPlugin.isAuthorizeOnlyWithChainedPlugin()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Chained-plugin is configured to ignore Base-plugin's ACLs");
}
ret = chainedResourceACLs;
break;
} else {
if (ret != null) {
ret = getMergedResourceACLs(ret, chainedResourceACLs);
}
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Chained-plugin returned null ACLs!!");
}
}
}
GdsPolicyEngine gdsPolicyEngine = getGdsPolicyEngine();
if (gdsPolicyEngine != null) {
RangerResourceACLs gdsACLs = gdsPolicyEngine.getResourceACLs(request);
if (gdsACLs != null) {
if (ret != null) {
ret = getMergedResourceACLs(ret, gdsACLs);
} else {
ret = gdsACLs;
}
}
}
return ret;
}
public Set<String> getRolesFromUserAndGroups(String user, Set<String> groups) {
RangerPolicyEngine policyEngine = this.policyEngine;
if(policyEngine != null) {
return policyEngine.getRolesFromUserAndGroups(user, groups);
}
return null;
}
public RangerRoles getRangerRoles() {
RangerPolicyEngine policyEngine = this.policyEngine;
if(policyEngine != null) {
return policyEngine.getRangerRoles();
}
return null;
}
public Set<RangerRole> getRangerRoleForPrincipal(String principal, String type) {
Set<RangerRole> ret = new HashSet<>();
Set<RangerRole> rangerRoles = null;
Map<String, Set<String>> roleMapping = null;
RangerRoles roles = getRangerRoles();
if (roles != null) {
rangerRoles = roles.getRangerRoles();
}
if (rangerRoles != null) {
RangerPluginContext rangerPluginContext = policyEngine.getPluginContext();
if (rangerPluginContext != null) {
RangerAuthContext rangerAuthContext = rangerPluginContext.getAuthContext();
if (rangerAuthContext != null) {
RangerRolesUtil rangerRolesUtil = rangerAuthContext.getRangerRolesUtil();
if (rangerRolesUtil != null) {
switch (type) {
case "USER":
roleMapping = rangerRolesUtil.getUserRoleMapping();
break;
case "GROUP":
roleMapping = rangerRolesUtil.getGroupRoleMapping();
break;
case "ROLE":
roleMapping = rangerRolesUtil.getRoleRoleMapping();
break;
}
}
}
}
if (roleMapping != null) {
Set<String> principalRoles = roleMapping.get(principal);
if (CollectionUtils.isNotEmpty(principalRoles)) {
for (String role : principalRoles) {
for (RangerRole rangerRole : rangerRoles) {
if (rangerRole.getName().equals(role)) {
ret.add(rangerRole);
}
}
}
}
}
}
return ret;
}
public boolean isServiceAdmin(String userName) {
boolean ret = false;
RangerPolicyEngine policyEngine = this.policyEngine;
if(policyEngine != null) {
RangerPolicyEngineImpl rangerPolicyEngine = (RangerPolicyEngineImpl) policyEngine;
ret = rangerPolicyEngine.isServiceAdmin(userName);
}
return ret;
}
public RangerRole createRole(RangerRole request, RangerAccessResultProcessor resultProcessor) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerBasePlugin.createRole(" + request + ")");
}
RangerRole ret = getAdminClient().createRole(request);
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerBasePlugin.createRole(" + request + ")");
}
return ret;
}
public void dropRole(String execUser, String roleName, RangerAccessResultProcessor resultProcessor) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerBasePlugin.dropRole(" + roleName + ")");
}
getAdminClient().dropRole(execUser, roleName);
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerBasePlugin.dropRole(" + roleName + ")");
}
}
public List<String> getUserRoles(String execUser, RangerAccessResultProcessor resultProcessor) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerBasePlugin.getUserRoleNames(" + execUser + ")");
}
final List<String> ret = getAdminClient().getUserRoles(execUser);
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerBasePlugin.getUserRoleNames(" + execUser + ")");
}
return ret;
}
public List<String> getAllRoles(String execUser, RangerAccessResultProcessor resultProcessor) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerBasePlugin.getAllRoles()");
}
final List<String> ret = getAdminClient().getAllRoles(execUser);
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerBasePlugin.getAllRoles()");
}
return ret;
}
public RangerRole getRole(String execUser, String roleName, RangerAccessResultProcessor resultProcessor) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerBasePlugin.getPrincipalsForRole(" + roleName + ")");
}
final RangerRole ret = getAdminClient().getRole(execUser, roleName);
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerBasePlugin.getPrincipalsForRole(" + roleName + ")");
}
return ret;
}
public void grantRole(GrantRevokeRoleRequest request, RangerAccessResultProcessor resultProcessor) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerBasePlugin.grantRole(" + request + ")");
}
getAdminClient().grantRole(request);
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerBasePlugin.grantRole(" + request + ")");
}
}
public void revokeRole(GrantRevokeRoleRequest request, RangerAccessResultProcessor resultProcessor) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerBasePlugin.revokeRole(" + request + ")");
}
getAdminClient().revokeRole(request);
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerBasePlugin.revokeRole(" + request + ")");
}
}
public void grantAccess(GrantRevokeRequest request, RangerAccessResultProcessor resultProcessor) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerBasePlugin.grantAccess(" + request + ")");
}
boolean isSuccess = false;
try {
RangerPolicyEngine policyEngine = this.policyEngine;
if (policyEngine != null) {
request.setZoneName(policyEngine.getUniquelyMatchedZoneName(request));
}
getAdminClient().grantAccess(request);
isSuccess = true;
} finally {
auditGrantRevoke(request, "grant", isSuccess, resultProcessor);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerBasePlugin.grantAccess(" + request + ")");
}
}
public void revokeAccess(GrantRevokeRequest request, RangerAccessResultProcessor resultProcessor) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerBasePlugin.revokeAccess(" + request + ")");
}
boolean isSuccess = false;
try {
RangerPolicyEngine policyEngine = this.policyEngine;
if (policyEngine != null) {
request.setZoneName(policyEngine.getUniquelyMatchedZoneName(request));
}
getAdminClient().revokeAccess(request);
isSuccess = true;
} finally {
auditGrantRevoke(request, "revoke", isSuccess, resultProcessor);
}
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerBasePlugin.revokeAccess(" + request + ")");
}
}
public void registerAuthContextEventListener(RangerAuthContextListener authContextListener) {
this.pluginContext.setAuthContextListener(authContextListener);
}
public static RangerAdminClient createAdminClient(RangerPluginConfig pluginConfig) {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerBasePlugin.createAdminClient(" + pluginConfig.getServiceName() + ", " + pluginConfig.getAppId() + ", " + pluginConfig.getPropertyPrefix() + ")");
}
RangerAdminClient ret = null;
String propertyName = pluginConfig.getPropertyPrefix() + ".policy.source.impl";
String policySourceImpl = pluginConfig.get(propertyName);
if(StringUtils.isEmpty(policySourceImpl)) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("Value for property[%s] was null or empty. Unexpected! Will use policy source of type[%s]", propertyName, RangerAdminRESTClient.class.getName()));
}
} else {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("Value for property[%s] was [%s].", propertyName, policySourceImpl));
}
try {
@SuppressWarnings("unchecked")
Class<RangerAdminClient> adminClass = (Class<RangerAdminClient>)Class.forName(policySourceImpl);
ret = adminClass.newInstance();
} catch (Exception excp) {
LOG.error("failed to instantiate policy source of type '" + policySourceImpl + "'. Will use policy source of type '" + RangerAdminRESTClient.class.getName() + "'", excp);
}
}
if(ret == null) {
ret = new RangerAdminRESTClient();
}
ret.init(pluginConfig.getServiceName(), pluginConfig.getAppId(), pluginConfig.getPropertyPrefix(), pluginConfig);
if(LOG.isDebugEnabled()) {
LOG.debug("<== RangerBasePlugin.createAdminClient(" + pluginConfig.getServiceName() + ", " + pluginConfig.getAppId() + ", " + pluginConfig.getPropertyPrefix() + "): policySourceImpl=" + policySourceImpl + ", client=" + ret);
}
return ret;
}
public void refreshPoliciesAndTags() {
if (LOG.isDebugEnabled()) {
LOG.debug("==> refreshPoliciesAndTags()");
}
try {
RangerPolicyEngine policyEngine = this.policyEngine;
// Synch-up policies
long oldPolicyVersion = policyEngine.getPolicyVersion();
if (refresher != null) {
refresher.syncPoliciesWithAdmin(accessTrigger);
}
policyEngine = this.policyEngine; // might be updated in syncPoliciesWithAdmin()
long newPolicyVersion = policyEngine.getPolicyVersion();
if (oldPolicyVersion == newPolicyVersion) {
// Synch-up tags
RangerTagEnricher tagEnricher = getTagEnricher();
if (tagEnricher != null) {
tagEnricher.syncTagsWithAdmin(accessTrigger);
}
}
} catch (InterruptedException exception) {
LOG.error("Failed to update policy-engine, continuing to use old policy-engine and/or tags", exception);
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== refreshPoliciesAndTags()");
}
}
private void auditGrantRevoke(GrantRevokeRequest request, String action, boolean isSuccess, RangerAccessResultProcessor resultProcessor) {
if(request != null && resultProcessor != null) {
RangerAccessRequestImpl accessRequest = new RangerAccessRequestImpl();
accessRequest.setResource(new RangerAccessResourceImpl(StringUtil.toStringObjectMap(request.getResource())));
accessRequest.setUser(request.getGrantor());
accessRequest.setAccessType(RangerPolicyEngine.ANY_ACCESS);
accessRequest.setAction(action);
accessRequest.setClientIPAddress(request.getClientIPAddress());
accessRequest.setClientType(request.getClientType());
accessRequest.setRequestData(request.getRequestData());
accessRequest.setSessionId(request.getSessionId());
// call isAccessAllowed() to determine if audit is enabled or not
RangerAccessResult accessResult = isAccessAllowed(accessRequest, null);
if(accessResult != null && accessResult.getIsAudited()) {
accessRequest.setAccessType(action);
accessResult.setIsAllowed(isSuccess);
if(! isSuccess) {
accessResult.setPolicyId(-1);
}
resultProcessor.processResult(accessResult);
}
}
}
private RangerServiceDef getDefaultServiceDef() {
RangerServiceDef ret = null;
if (StringUtils.isNotBlank(getServiceType())) {
try {
ret = EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(getServiceType());
} catch (Exception exp) {
LOG.error("Could not get embedded service-def for " + getServiceType());
}
}
return ret;
}
private ServicePolicies getDefaultSvcPolicies() {
ServicePolicies ret = null;
RangerServiceDef serviceDef = getServiceDef();
if (serviceDef == null) {
serviceDef = getDefaultServiceDef();
}
if (serviceDef != null) {
ret = new ServicePolicies();
ret.setServiceDef(serviceDef);
ret.setServiceName(getServiceName());
ret.setPolicies(new ArrayList<RangerPolicy>());
}
return ret;
}
public boolean logErrorMessage(String message) {
LogHistory log = logHistoryList.get(message);
if (log == null) {
log = new LogHistory();
logHistoryList.put(message, log);
}
if ((System.currentTimeMillis() - log.lastLogTime) > logInterval) {
log.lastLogTime = System.currentTimeMillis();
int counter = log.counter;
log.counter = 0;
if( counter > 0) {
message += ". Messages suppressed before: " + counter;
}
LOG.error(message);
return true;
} else {
log.counter++;
}
return false;
}
private Set<String> toSet(String value) {
return StringUtils.isNotBlank(value) ? StringUtil.toSet(value) : Collections.emptySet();
}
static private final class LogHistory {
long lastLogTime;
int counter;
}
public RangerTagEnricher getTagEnricher() {
RangerTagEnricher ret = null;
RangerAuthContext authContext = getCurrentRangerAuthContext();
if (authContext != null) {
Map<RangerContextEnricher, Object> contextEnricherMap = authContext.getRequestContextEnrichers();
if (MapUtils.isNotEmpty(contextEnricherMap)) {
Set<RangerContextEnricher> contextEnrichers = contextEnricherMap.keySet();
for (RangerContextEnricher enricher : contextEnrichers) {
if (enricher instanceof RangerTagEnricher) {
ret = (RangerTagEnricher) enricher;
break;
}
}
}
}
return ret;
}
public RangerUserStoreEnricher getUserStoreEnricher() {
RangerUserStoreEnricher ret = null;
RangerAuthContext authContext = getCurrentRangerAuthContext();
if (authContext != null) {
Map<RangerContextEnricher, Object> contextEnricherMap = authContext.getRequestContextEnrichers();
if (MapUtils.isNotEmpty(contextEnricherMap)) {
Set<RangerContextEnricher> contextEnrichers = contextEnricherMap.keySet();
for (RangerContextEnricher enricher : contextEnrichers) {
if (enricher instanceof RangerUserStoreEnricher) {
ret = (RangerUserStoreEnricher) enricher;
ret.getRangerUserStore();
break;
}
}
}
}
return ret;
}
public RangerGdsEnricher getGdsEnricher() {
RangerGdsEnricher ret = null;
RangerAuthContext authContext = getCurrentRangerAuthContext();
if (authContext != null) {
Map<RangerContextEnricher, Object> contextEnricherMap = authContext.getRequestContextEnrichers();
if (MapUtils.isNotEmpty(contextEnricherMap)) {
Set<RangerContextEnricher> contextEnrichers = contextEnricherMap.keySet();
for (RangerContextEnricher enricher : contextEnrichers) {
if (enricher instanceof RangerGdsEnricher) {
ret = (RangerGdsEnricher) enricher;
break;
}
}
}
}
return ret;
}
public GdsPolicyEngine getGdsPolicyEngine() {
RangerGdsEnricher gdsEnricher = getGdsEnricher();
return gdsEnricher != null ? gdsEnricher.getGdsPolicyEngine() : null;
}
public static RangerResourceACLs getMergedResourceACLs(RangerResourceACLs baseACLs, RangerResourceACLs chainedACLs) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerBasePlugin.getMergedResourceACLs()");
LOG.debug("baseACLs:[" + baseACLs + "]");
LOG.debug("chainedACLS:[" + chainedACLs + "]");
}
overrideACLs(chainedACLs, baseACLs, RangerRolesUtil.ROLES_FOR.USER);
overrideACLs(chainedACLs, baseACLs, RangerRolesUtil.ROLES_FOR.GROUP);
overrideACLs(chainedACLs, baseACLs, RangerRolesUtil.ROLES_FOR.ROLE);
baseACLs.getDatasets().addAll(chainedACLs.getDatasets());
baseACLs.getProjects().addAll(chainedACLs.getProjects());
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerBasePlugin.getMergedResourceACLs() : ret:[" + baseACLs + "]");
}
return baseACLs;
}
protected RangerPolicyEngine getPolicyEngine() {
return policyEngine;
}
private RangerAdminClient getAdminClient() throws Exception {
PolicyRefresher refresher = this.refresher;
RangerAdminClient admin = refresher == null ? null : refresher.getRangerAdminClient();
if(admin == null) {
throw new Exception("ranger-admin client is null");
}
return admin;
}
private List<RangerChainedPlugin> initChainedPlugins() {
List<RangerChainedPlugin> ret = new ArrayList<>();
String chainedServicePropPrefix = pluginConfig.getPropertyPrefix() + ".chained.services";
for (String chainedService : StringUtil.toList(pluginConfig.get(chainedServicePropPrefix))) {
if (StringUtils.isBlank(chainedService)) {
continue;
}
String className = pluginConfig.get(chainedServicePropPrefix + "." + chainedService + ".impl");
if (StringUtils.isBlank(className)) {
LOG.error("Ignoring chained service " + chainedService + ": no impl class specified");
continue;
}
try {
@SuppressWarnings("unchecked")
Class<RangerChainedPlugin> pluginClass = (Class<RangerChainedPlugin>) Class.forName(className);
RangerChainedPlugin chainedPlugin = pluginClass.getConstructor(RangerBasePlugin.class, String.class).newInstance(this, chainedService);
ret.add(chainedPlugin);
} catch (Throwable t) {
LOG.error("initChainedPlugins(): error instantiating plugin impl " + className, t);
}
}
return ret;
}
private void updateResultFromChainedResult(RangerAccessResult result, RangerAccessResult chainedResult) {
boolean overrideResult = false;
int policyType = result.getPolicyType();
if (chainedResult.getIsAccessDetermined()) { // only if chained-result is definitive
// override if chained-result is by a higher priority policy or result is not definitive or the result is not-allowed and no matching Ranger policy found
overrideResult = chainedResult.getPolicyPriority() > result.getPolicyPriority() || !result.getIsAccessDetermined() || (!result.getIsAllowed() && result.getPolicyId() == -1L);
if (!overrideResult) {
// override if chained-result is from the same policy priority, and if denies access with a specific policy id
if (chainedResult.getPolicyPriority() == result.getPolicyPriority() && (!chainedResult.getIsAllowed() && chainedResult.getPolicyId() != -1L)) {
// let's not override if result is already denied
if (result.getIsAllowed()) {
overrideResult = true;
}
}
}
}
if (overrideResult) {
result.setIsAllowed(chainedResult.getIsAllowed());
result.setIsAccessDetermined(chainedResult.getIsAccessDetermined());
result.setPolicyId(chainedResult.getPolicyId());
result.setPolicyVersion(chainedResult.getPolicyVersion());
result.setPolicyPriority(chainedResult.getPolicyPriority());
result.setZoneName(chainedResult.getZoneName());
if (policyType == RangerPolicy.POLICY_TYPE_DATAMASK) {
result.setMaskType(chainedResult.getMaskType());
result.setMaskCondition(chainedResult.getMaskCondition());
result.setMaskedValue(chainedResult.getMaskedValue());
} else if (policyType == RangerPolicy.POLICY_TYPE_ROWFILTER) {
result.setFilterExpr(chainedResult.getFilterExpr());
}
}
if (!result.getIsAuditedDetermined() && chainedResult.getIsAuditedDetermined()) {
result.setIsAudited(chainedResult.getIsAudited());
result.setAuditPolicyId(chainedResult.getAuditPolicyId());
}
}
private static void overrideACLs(final RangerResourceACLs chainedResourceACLs, RangerResourceACLs baseResourceACLs, final RangerRolesUtil.ROLES_FOR userType) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerBasePlugin.overrideACLs(isUser=" + userType.name() + ")");
}
Map<String, Map<String, RangerResourceACLs.AccessResult>> chainedACLs = null;
Map<String, Map<String, RangerResourceACLs.AccessResult>> baseACLs = null;
switch (userType) {
case USER:
chainedACLs = chainedResourceACLs.getUserACLs();
baseACLs = baseResourceACLs.getUserACLs();
break;
case GROUP:
chainedACLs = chainedResourceACLs.getGroupACLs();
baseACLs = baseResourceACLs.getGroupACLs();
break;
case ROLE:
chainedACLs = chainedResourceACLs.getRoleACLs();
baseACLs = baseResourceACLs.getRoleACLs();
break;
default:
break;
}
for (Map.Entry<String, Map<String, RangerResourceACLs.AccessResult>> chainedPermissionsMap : chainedACLs.entrySet()) {
String name = chainedPermissionsMap.getKey();
Map<String, RangerResourceACLs.AccessResult> chainedPermissions = chainedPermissionsMap.getValue();
Map<String, RangerResourceACLs.AccessResult> basePermissions = baseACLs.get(name);
for (Map.Entry<String, RangerResourceACLs.AccessResult> chainedPermission : chainedPermissions.entrySet()) {
String chainedAccessType = chainedPermission.getKey();
RangerResourceACLs.AccessResult chainedAccessResult = chainedPermission.getValue();
RangerResourceACLs.AccessResult baseAccessResult = basePermissions == null ? null : basePermissions.get(chainedAccessType);
final boolean useChainedAccessResult;
if (baseAccessResult == null) {
useChainedAccessResult = true;
} else {
if (chainedAccessResult.getPolicy().getPolicyPriority() > baseAccessResult.getPolicy().getPolicyPriority()) {
useChainedAccessResult = true;
} else if (chainedAccessResult.getPolicy().getPolicyPriority().equals(baseAccessResult.getPolicy().getPolicyPriority())) {
if (chainedAccessResult.getResult() == baseAccessResult.getResult()) {
useChainedAccessResult = true;
} else {
useChainedAccessResult = chainedAccessResult.getResult() == RangerPolicyEvaluator.ACCESS_DENIED;
}
} else { // chainedAccessResult.getPolicy().getPolicyPriority() < baseAccessResult.getPolicy().getPolicyPriority()
useChainedAccessResult = false;
}
}
final RangerResourceACLs.AccessResult finalAccessResult = useChainedAccessResult ? chainedAccessResult : baseAccessResult;
switch (userType) {
case USER:
baseResourceACLs.setUserAccessInfo(name, chainedAccessType, finalAccessResult.getResult(), finalAccessResult.getPolicy());
break;
case GROUP:
baseResourceACLs.setGroupAccessInfo(name, chainedAccessType, finalAccessResult.getResult(), finalAccessResult.getPolicy());
break;
case ROLE:
baseResourceACLs.setRoleAccessInfo(name, chainedAccessType, finalAccessResult.getResult(), finalAccessResult.getPolicy());
break;
default:
break;
}
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerBasePlugin.mergeACLsOneWay(isUser=" + userType.name() + ")");
}
}
private static AuditProviderFactory getAuditProviderFactory(String serviceName) {
AuditProviderFactory ret = AuditProviderFactory.getInstance();
if (!ret.isInitDone()) {
LOG.warn("RangerBasePlugin.getAuditProviderFactory(serviceName=" + serviceName + "): audit not initialized yet. Will use stand-alone audit factory");
ret = StandAloneAuditProviderFactory.getInstance();
if (!ret.isInitDone()) {
RangerAuditConfig conf = new RangerAuditConfig();
if (conf.isInitSuccess()) {
ret.init(conf.getProperties(), "StandAlone");
}
}
}
return ret;
}
public Long getPolicyVersion() {
return this.policyEngine == null ? -1L : this.policyEngine.getPolicyVersion();
}
}