Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions agents-common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,25 @@
<artifactId>ranger-plugins-cred</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.ranger</groupId>
<artifactId>ugsync-util</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>*</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>*</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
import org.apache.ranger.plugin.util.ServiceDefUtil;
import org.apache.ranger.plugin.util.ServicePolicies;
import org.apache.ranger.plugin.util.StringTokenReplacer;
import org.apache.ranger.plugin.util.RangerUserStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -213,9 +212,7 @@ public PolicyEngine(ServicePolicies servicePolicies, RangerPluginContext pluginC
}
}

RangerAuthContext currAuthContext = pluginContext.getAuthContext();
RangerUserStore userStore = currAuthContext != null ? currAuthContext.getUserStoreUtil().getUserStore() : null;
RangerAuthContext authContext = new RangerAuthContext(null, zoneMatcher, roles, userStore);
RangerAuthContext authContext = new RangerAuthContext(pluginContext.getAuthContext(), zoneMatcher, roles);

this.pluginContext.setAuthContext(authContext);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,47 @@
import org.apache.ranger.plugin.contextenricher.RangerContextEnricher;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
import org.apache.ranger.plugin.policyengine.RangerSecurityZoneMatcher;
import org.apache.ranger.plugin.util.RangerCommonConstants;
import org.apache.ranger.plugin.util.RangerRoles;
import org.apache.ranger.plugin.util.RangerRolesUtil;
import org.apache.ranger.plugin.util.RangerUserStore;
import org.apache.ranger.plugin.util.RangerUserStoreUtil;
import org.apache.ranger.ugsyncutil.transform.Mapper;
import org.apache.ranger.ugsyncutil.util.UgsyncCommonConstants.CaseConversion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import static org.apache.ranger.ugsyncutil.util.UgsyncCommonConstants.toCaseConversion;

public class RangerAuthContext {
private static final Logger LOG = LoggerFactory.getLogger(RangerAuthContext.class);

private final Map<RangerContextEnricher, Object> requestContextEnrichers;
private final RangerSecurityZoneMatcher zoneMatcher;
private RangerRolesUtil rolesUtil;
private RangerUserStoreUtil userStoreUtil;
private Mapper userNameTransformer;
private Mapper groupNameTransformer;
private CaseConversion userNameCaseConversion;
private CaseConversion groupNameCaseConversion;

public RangerAuthContext(RangerAuthContext prevContext, RangerSecurityZoneMatcher zoneMatcher, RangerRoles roles) {
this(null, zoneMatcher, roles, prevContext != null ? prevContext.getUserStoreUtil().getUserStore() : null);

if (prevContext != null) {
this.userNameTransformer = prevContext.userNameTransformer;
this.groupNameTransformer = prevContext.groupNameTransformer;
this.userNameCaseConversion = prevContext.userNameCaseConversion;
this.groupNameCaseConversion = prevContext.groupNameCaseConversion;
}
}

public RangerAuthContext(Map<RangerContextEnricher, Object> requestContextEnrichers, RangerSecurityZoneMatcher zoneMatcher, RangerRoles roles, RangerUserStore userStore) {
this.requestContextEnrichers = requestContextEnrichers != null ? requestContextEnrichers : new ConcurrentHashMap<>();
Expand Down Expand Up @@ -127,4 +153,118 @@ public RangerUserStoreUtil getUserStoreUtil() {
public void setUserStore(RangerUserStore userStore) {
this.userStoreUtil = new RangerUserStoreUtil(userStore);
}

public Mapper getUserNameTransformer() {
return userNameTransformer;
}

public Mapper getGroupNameTransformer() {
return groupNameTransformer;
}

public CaseConversion getUserNameCaseConversion() {
return userNameCaseConversion;
}

public CaseConversion getGroupNameCaseConversion() {
return groupNameCaseConversion;
}

public void onServiceConfigsUpdate(Map<String, String> serviceConfigs) {
String userNameCaseConversion = null;
String groupNameCaseConversion = null;
Mapper userNameTransformer = null;
Mapper groupNameTransformer = null;

if (MapUtils.isNotEmpty(serviceConfigs)) {
LOG.debug("==> onServiceConfigsUpdate({})", serviceConfigs.keySet());

userNameCaseConversion = serviceConfigs.get(RangerCommonConstants.PLUGINS_CONF_USERNAME_CASE_CONVERSION_PARAM);
groupNameCaseConversion = serviceConfigs.get(RangerCommonConstants.PLUGINS_CONF_GROUPNAME_CASE_CONVERSION_PARAM);

String mappingUserNameHandler = serviceConfigs.get(RangerCommonConstants.PLUGINS_CONF_MAPPING_USERNAME_HANDLER);

if (mappingUserNameHandler != null) {
try {
Class<Mapper> regExClass = (Class<Mapper>) Class.forName(mappingUserNameHandler);

userNameTransformer = regExClass.newInstance();

String baseProperty = RangerCommonConstants.PLUGINS_CONF_MAPPING_USERNAME;

userNameTransformer.init(baseProperty, getAllRegexPatterns(baseProperty, serviceConfigs), serviceConfigs.get(RangerCommonConstants.PLUGINS_CONF_MAPPING_SEPARATOR));
} catch (ClassNotFoundException cne) {
LOG.error("Failed to load {}", mappingUserNameHandler, cne);
} catch (Throwable te) {
LOG.error("Failed to instantiate {}", mappingUserNameHandler, te);
}
}

String mappingGroupNameHandler = serviceConfigs.get(RangerCommonConstants.PLUGINS_CONF_MAPPING_GROUPNAME_HANDLER);

if (mappingGroupNameHandler != null) {
try {
Class<Mapper> regExClass = (Class<Mapper>) Class.forName(mappingGroupNameHandler);

groupNameTransformer = regExClass.newInstance();

String baseProperty = RangerCommonConstants.PLUGINS_CONF_MAPPING_GROUPNAME;

groupNameTransformer.init(baseProperty, getAllRegexPatterns(baseProperty, serviceConfigs), serviceConfigs.get(RangerCommonConstants.PLUGINS_CONF_MAPPING_SEPARATOR));
} catch (ClassNotFoundException cne) {
LOG.error("Failed to load {}", mappingGroupNameHandler, cne);
} catch (Throwable te) {
LOG.error("Failed to instantiate {}", mappingGroupNameHandler, te);
}
}
}

setUserNameCaseConversion(userNameCaseConversion);
setGroupNameCaseConversion(groupNameCaseConversion);
setUserNameTransformer(userNameTransformer);
setGroupNameTransformer(groupNameTransformer);
}

private void setUserNameTransformer(Mapper userNameTransformer) {
this.userNameTransformer = userNameTransformer;
}

private void setGroupNameTransformer(Mapper groupNameTransformer) {
this.groupNameTransformer = groupNameTransformer;
}

private void setUserNameCaseConversion(String userNameCaseConversion) {
this.userNameCaseConversion = toCaseConversion(userNameCaseConversion);
}

private void setGroupNameCaseConversion(String groupNameCaseConversion) {
this.groupNameCaseConversion = toCaseConversion(groupNameCaseConversion);
}

private List<String> getAllRegexPatterns(String baseProperty, Map<String, String> serviceConfig) {
LOG.debug("==> getAllRegexPatterns({})", baseProperty);

List<String> regexPatterns = new ArrayList<>();
String baseRegex = serviceConfig != null ? serviceConfig.get(baseProperty) : null;

LOG.debug("baseRegex = {}, pluginConfig = {}", baseRegex, serviceConfig == null ? null : serviceConfig.keySet());

if (baseRegex != null) {
regexPatterns.add(baseRegex);

for (int i = 1; true; i++) {
String nextRegex = serviceConfig.get(baseProperty + "." + i);

if (nextRegex == null) {
break;
}

regexPatterns.add(nextRegex);
}
}

LOG.debug("<== getAllRegexPatterns({}): ret={}", baseProperty, regexPatterns);

return regexPatterns;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,6 @@ public void setPolicies(ServicePolicies policies) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> setPolicies(" + policies + ")");
}
this.serviceConfigs = (policies != null && policies.getServiceConfig() != null) ? policies.getServiceConfig() : new HashMap<>();
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));
Expand All @@ -370,8 +369,8 @@ public void setPolicies(ServicePolicies policies) {
isUserStoreEnricherAddedImplcitly = ServiceDefUtil.addUserStoreEnricherIfNeeded(policies, retrieverClassName, retrieverPollIntMs);
}
}

String isSyncPolicyRefresh = this.pluginConfig == null ? null : this.serviceConfigs.get(this.pluginConfig.getPropertyPrefix() + ".policy.refresh.synchronous");
// String isSyncPolicyRefresh = this.pluginConfig == null ? null : this.serviceConfigs.get(this.pluginConfig.getPropertyPrefix() + ".policy.refresh.synchronous");
String isSyncPolicyRefresh = this.pluginConfig == null ? null : (this.serviceConfigs == null ? null : this.serviceConfigs.get(this.pluginConfig.getPropertyPrefix() + ".policy.refresh.synchronous"));
this.synchronousPolicyRefresh = Boolean.parseBoolean(isSyncPolicyRefresh);
if (this.synchronousPolicyRefresh) {
LOG.info("synchronousPolicyRefresh = {}", this.synchronousPolicyRefresh);
Expand Down Expand Up @@ -500,6 +499,8 @@ public void setPolicies(ServicePolicies policies) {
newPolicyEngine.setTrustedProxyAddresses(pluginConfig.getTrustedProxyAddresses());
}

setServiceConfigs(policies.getServiceConfig());

LOG.info("Switching policy engine from [" + getPolicyVersion() + "]");
this.policyEngine = newPolicyEngine;
LOG.info("Switched policy engine to [" + getPolicyVersion() + "]");
Expand Down Expand Up @@ -1422,6 +1423,18 @@ private static void overrideACLs(final RangerResourceACLs chainedResourceACLs, R
}
}

private void setServiceConfigs(Map<String, String> serviceConfigs) {
Map<String, String> oldServiceConfigs = this.serviceConfigs;

this.serviceConfigs = serviceConfigs != null ? serviceConfigs : new HashMap<>();

RangerAuthContext authContext = this.pluginContext.getAuthContext();

if (authContext != null && !Objects.equals(oldServiceConfigs, this.serviceConfigs)) {
authContext.onServiceConfigsUpdate(this.serviceConfigs);
}
}

private static AuditProviderFactory getAuditProviderFactory(String serviceName) {
AuditProviderFactory ret = AuditProviderFactory.getInstance();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,20 @@
import org.apache.ranger.plugin.policyengine.RangerMutableResource;
import org.apache.ranger.plugin.policyengine.RangerPluginContext;
import org.apache.ranger.plugin.util.RangerAccessRequestUtil;
import org.apache.ranger.plugin.util.RangerCommonConstants;
import org.apache.ranger.plugin.util.RangerPerfTracer;
import org.apache.ranger.plugin.util.RangerUserStoreUtil;
import org.apache.ranger.ugsyncutil.transform.Mapper;
import org.apache.ranger.ugsyncutil.util.UgsyncCommonConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

public class RangerDefaultRequestProcessor implements RangerAccessRequestProcessor {

Expand Down Expand Up @@ -103,6 +108,17 @@ public void preProcess(RangerAccessRequest request) {
reqImpl.setClusterType(pluginContext.getClusterType());
}

RangerPluginConfig config = policyEngine.getPluginContext().getConfig();

boolean isNameTransformationSupported = config.getBoolean(config.getPropertyPrefix() + RangerCommonConstants.PLUGIN_CONFIG_SUFFIX_NAME_TRANSFORMATION, false);

LOG.debug("isNameTransformationSupported = {}", isNameTransformationSupported);

if (isNameTransformationSupported) {
reqImpl.setUser(getTransformedUser(policyEngine, request));
reqImpl.setUserGroups(getTransformedGroups(policyEngine, request));
}

convertEmailToUsername(reqImpl);

updateUserGroups(reqImpl);
Expand Down Expand Up @@ -166,6 +182,65 @@ public void enrich(RangerAccessRequest request) {
}
}

private String getTransformedUser(PolicyEngine policyEngine, RangerAccessRequest request) {
RangerAuthContext authContext = policyEngine.getPluginContext().getAuthContext();
boolean toLowerCase = authContext.getUserNameCaseConversion() == UgsyncCommonConstants.CaseConversion.TO_LOWER;
boolean toUpperCase = authContext.getUserNameCaseConversion() == UgsyncCommonConstants.CaseConversion.TO_UPPER;
Mapper nameTransformer = authContext.getUserNameTransformer();

if (toLowerCase || toUpperCase || nameTransformer != null) {
String user = request.getUser();

if (toLowerCase) {
user = user.toLowerCase();
} else if (toUpperCase) {
user = user.toUpperCase();
}

if (nameTransformer != null) {
user = nameTransformer.transform(user);
}

LOG.debug("Original username = {}, Transformed username = {}", request.getUser(), user);

return user;
}

return request.getUser();
}

private Set<String> getTransformedGroups(PolicyEngine policyEngine, RangerAccessRequest request) {
if (CollectionUtils.isNotEmpty(request.getUserGroups())) {
RangerAuthContext authContext = policyEngine.getPluginContext().getAuthContext();
boolean toLowerCase = authContext.getGroupNameCaseConversion() == UgsyncCommonConstants.CaseConversion.TO_LOWER;
boolean toUpperCase = authContext.getGroupNameCaseConversion() == UgsyncCommonConstants.CaseConversion.TO_UPPER;
Mapper nameTransformer = authContext.getGroupNameTransformer();

if (toLowerCase || toUpperCase || nameTransformer != null) {
return request.getUserGroups().stream()
.filter(Objects::nonNull)
.map(group -> {
String originalGroup = group;

if (toLowerCase) {
group = group.toLowerCase();
} else if (toUpperCase) {
group = group.toUpperCase();
}

String transformedGroup = nameTransformer.transform(group);

LOG.debug("Original group name = {}, Transformed group name = {}", originalGroup, transformedGroup);

return transformedGroup;
})
.collect(Collectors.toSet());
}
}

return request.getUserGroups();
}

private void setResourceServiceDef(RangerAccessRequest request) {
RangerAccessResource resource = request.getResource();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ private RangerCommonConstants() {

public static final String RANGER_ADMIN_SUFFIX_IN_PLACE_TAG_UPDATES = ".supports.in.place.tag.updates";
public static final String PLUGIN_CONFIG_SUFFIX_IN_PLACE_TAG_UPDATES = ".supports.in.place.tag.updates";
public static final String PLUGIN_CONFIG_SUFFIX_NAME_TRANSFORMATION = ".supports.name.transformation";

public static final String PLUGINS_CONF_USERNAME_CASE_CONVERSION_PARAM = "ranger.plugins.conf.ldap.username.caseconversion";
public static final String PLUGINS_CONF_GROUPNAME_CASE_CONVERSION_PARAM = "ranger.plugins.conf.ldap.groupname.caseconversion";
public static final String PLUGINS_CONF_MAPPING_USERNAME = "ranger.plugins.conf.mapping.username.regex";
public static final String PLUGINS_CONF_MAPPING_GROUPNAME = "ranger.plugins.conf.mapping.groupname.regex";
public static final String PLUGINS_CONF_MAPPING_USERNAME_HANDLER = "ranger.plugins.conf.mapping.username.handler";
public static final String PLUGINS_CONF_MAPPING_GROUPNAME_HANDLER = "ranger.plugins.conf.mapping.groupname.handler";
public static final String PLUGINS_CONF_MAPPING_SEPARATOR = "ranger.plugins.conf.mapping.regex.separator";

public static final String RANGER_SUPPORTS_TAGS_DEDUP = ".supports.tags.dedup";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@ static public ServicePolicies copyHeader(ServicePolicies source) {
ret.setPolicyVersion(source.getPolicyVersion());
ret.setAuditMode(source.getAuditMode());
ret.setServiceDef(source.getServiceDef());
ret.setServiceConfig(source.getServiceConfig() != null ? new HashMap<>(source.getServiceConfig()) : null);
ret.setPolicyUpdateTime(source.getPolicyUpdateTime());
ret.setSecurityZones(source.getSecurityZones());
ret.setPolicies(Collections.emptyList());
Expand Down
1 change: 1 addition & 0 deletions distro/src/main/assembly/admin-web.xml
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@
<include>org.eclipse.jdt.core.compiler:ecj:jar:P20140317-1600</include>
<include>org.apache.hadoop:hadoop-auth:jar:${hadoop.version}</include>
<include>org.apache.ranger:ranger-plugins-common</include>
<include>org.apache.ranger:ugsync-util</include>
<include>org.slf4j:slf4j-api:jar:${slf4j.version}</include>
<include>org.apache.hadoop:hadoop-common</include>
<include>commons-logging:commons-logging</include>
Expand Down
Loading
Loading