You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ol...@apache.org on 2016/06/28 13:16:26 UTC
ambari git commit: AMBARI-17444. LDAP sync: force to use uid and cn
in patterns to check a member is a dn or not (oleewere)
Repository: ambari
Updated Branches:
refs/heads/trunk 56c8bf661 -> 740c6caa9
AMBARI-17444. LDAP sync: force to use uid and cn in patterns to check a member is a dn or not (oleewere)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/740c6caa
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/740c6caa
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/740c6caa
Branch: refs/heads/trunk
Commit: 740c6caa9be975da87084f4c5b6d5ce4e4c9b543
Parents: 56c8bf6
Author: oleewere <ol...@gmail.com>
Authored: Tue Jun 28 15:11:51 2016 +0200
Committer: oleewere <ol...@gmail.com>
Committed: Tue Jun 28 15:11:51 2016 +0200
----------------------------------------------------------------------
.../server/configuration/Configuration.java | 5 +-
.../AmbariLdapBindAuthenticator.java | 90 +++++++++++---------
.../authorization/LdapServerProperties.java | 12 ++-
.../security/ldap/AmbariLdapDataPopulator.java | 2 +-
.../ldap/AmbariLdapDataPopulatorTest.java | 19 +++++
5 files changed, 86 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/740c6caa/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
index 3743220..153289e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
@@ -195,6 +195,7 @@ public class Configuration {
public static final String LDAP_GROUP_NAMING_ATTR_KEY = "authentication.ldap.groupNamingAttr";
public static final String LDAP_GROUP_MEMEBERSHIP_ATTR_KEY = "authentication.ldap.groupMembershipAttr";
public static final String LDAP_ADMIN_GROUP_MAPPING_RULES_KEY = "authorization.ldap.adminGroupMappingRules";
+ public static final String LDAP_ADMIN_GROUP_MAPPING_MEMBER_ATTR_KEY = "authorization.ldap.adminGroupMappingMemberAttr";
/**
* When authentication through LDAP is enabled then Ambari Server uses this filter to lookup
* the user in LDAP based on the provided ambari user name.
@@ -509,7 +510,7 @@ public class Configuration {
private static final String LDAP_GROUP_NAMING_ATTR_DEFAULT = "cn";
private static final String LDAP_GROUP_MEMBERSHIP_ATTR_DEFAULT = "member";
private static final String LDAP_ADMIN_GROUP_MAPPING_RULES_DEFAULT = "Ambari Administrators";
-
+ private static final String LDAP_ADMIN_GROUP_MAPPING_MEMBER_ATTR_DEFAULT = "";
/**
* If the default LDAP user search filter is not able to find the authenticating user
* in LDAP than Ambari can fall back an alternative user search filter if this
@@ -1879,6 +1880,8 @@ public class Configuration {
getProperty(LDAP_GROUP_NAMING_ATTR_KEY, LDAP_GROUP_NAMING_ATTR_DEFAULT));
ldapServerProperties.setAdminGroupMappingRules(properties.getProperty(
LDAP_ADMIN_GROUP_MAPPING_RULES_KEY, LDAP_ADMIN_GROUP_MAPPING_RULES_DEFAULT));
+ ldapServerProperties.setAdminGroupMappingMemberAttr(properties.getProperty(
+ LDAP_ADMIN_GROUP_MAPPING_MEMBER_ATTR_KEY, LDAP_ADMIN_GROUP_MAPPING_MEMBER_ATTR_DEFAULT));
ldapServerProperties.setUserSearchFilter(properties.getProperty(
LDAP_USER_SEARCH_FILTER_KEY, LDAP_USER_SEARCH_FILTER_DEFAULT));
ldapServerProperties.setAlternateUserSearchFilter(properties.getProperty(
http://git-wip-us.apache.org/repos/asf/ambari/blob/740c6caa/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticator.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticator.java
index c63ea92..917471b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticator.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticator.java
@@ -24,6 +24,7 @@ import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import org.apache.ambari.server.configuration.Configuration;
+import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ldap.core.AttributesMapper;
@@ -55,11 +56,15 @@ public class AmbariLdapBindAuthenticator extends BindAuthenticator {
public DirContextOperations authenticate(Authentication authentication) {
DirContextOperations user = super.authenticate(authentication);
- setAmbariAdminAttr(user);
+ LdapServerProperties ldapServerProperties =
+ configuration.getLdapServerProperties();
+ if (StringUtils.isNotEmpty(ldapServerProperties.getAdminGroupMappingRules())) {
+ setAmbariAdminAttr(user, ldapServerProperties);
+ }
// Users stored locally in ambari are matched against LDAP users by the ldap attribute configured to be used as user name.
// (e.g. uid, sAMAccount -> ambari user name )
- String ldapUserName = user.getStringAttribute(configuration.getLdapServerProperties().getUsernameAttribute());
+ String ldapUserName = user.getStringAttribute(ldapServerProperties.getUsernameAttribute());
String loginName = authentication.getName(); // user login name the user has logged in
if (!ldapUserName.equals(loginName)) {
@@ -80,51 +85,23 @@ public class AmbariLdapBindAuthenticator extends BindAuthenticator {
* @param user
* @return
*/
- private DirContextOperations setAmbariAdminAttr(DirContextOperations user) {
- LdapServerProperties ldapServerProperties =
- configuration.getLdapServerProperties();
-
+ private DirContextOperations setAmbariAdminAttr(DirContextOperations user, LdapServerProperties ldapServerProperties) {
String baseDn = ldapServerProperties.getBaseDN().toLowerCase();
String groupBase = ldapServerProperties.getGroupBase().toLowerCase();
- String groupObjectClass = ldapServerProperties.getGroupObjectClass();
- String groupMembershipAttr = ldapServerProperties.getGroupMembershipAttr();
- String adminGroupMappingRules =
- ldapServerProperties.getAdminGroupMappingRules();
final String groupNamingAttribute =
ldapServerProperties.getGroupNamingAttr();
- String groupSearchFilter = ldapServerProperties.getGroupSearchFilter();
+ final String adminGroupMappingMemberAttr = ldapServerProperties.getAdminGroupMappingMemberAttr();
//If groupBase is set incorrectly or isn't set - search in BaseDn
int indexOfBaseDn = groupBase.indexOf(baseDn);
groupBase = indexOfBaseDn <= 0 ? "" : groupBase.substring(0,indexOfBaseDn - 1);
- StringBuilder filterBuilder = new StringBuilder();
-
- filterBuilder.append("(&(");
- filterBuilder.append(groupMembershipAttr);
- filterBuilder.append("=");
- filterBuilder.append(user.getNameInNamespace());//DN
-
- if ((groupSearchFilter == null) || groupSearchFilter.equals("") ) {
- //If groupSearchFilter is not specified, build it from other authorization
- // group properties
- filterBuilder.append(")(objectclass=");
- filterBuilder.append(groupObjectClass);
- filterBuilder.append(")(|");
- String[] adminGroupMappingRegexs = adminGroupMappingRules.split(",");
- for (String adminGroupMappingRegex : adminGroupMappingRegexs) {
- filterBuilder.append("(");
- filterBuilder.append(groupNamingAttribute);
- filterBuilder.append("=");
- filterBuilder.append(adminGroupMappingRegex);
- filterBuilder.append(")");
- }
- filterBuilder.append(")");
- } else {
- filterBuilder.append(")");
- filterBuilder.append(groupSearchFilter);
- }
- filterBuilder.append(")");
+ String memberValue = StringUtils.isNotEmpty(adminGroupMappingMemberAttr)
+ ? user.getStringAttribute(adminGroupMappingMemberAttr) : user.getNameInNamespace();
+ LOG.debug("LDAP login - set '{}' as member attribute for adminGroupMappingRules", memberValue);
+
+ String setAmbariAdminAttrFilter = resolveAmbariAdminAttrFilter(ldapServerProperties, memberValue);
+ LOG.debug("LDAP login - set admin attr filter: {}", setAmbariAdminAttrFilter);
AttributesMapper attributesMapper = new AttributesMapper() {
public Object mapFromAttributes(Attributes attrs)
@@ -138,7 +115,7 @@ public class AmbariLdapBindAuthenticator extends BindAuthenticator {
ldapTemplate.setIgnoreNameNotFoundException(true);
List<String> ambariAdminGroups = ldapTemplate.search(
- groupBase,filterBuilder.toString(),attributesMapper);
+ groupBase, setAmbariAdminAttrFilter, attributesMapper);
//user has admin role granted, if user is a member of at least 1 group,
// which matches the rules in configuration
@@ -149,4 +126,39 @@ public class AmbariLdapBindAuthenticator extends BindAuthenticator {
return user;
}
+ private String resolveAmbariAdminAttrFilter(LdapServerProperties ldapServerProperties, String memberValue) {
+ String groupMembershipAttr = ldapServerProperties.getGroupMembershipAttr();
+ String groupObjectClass = ldapServerProperties.getGroupObjectClass();
+ String adminGroupMappingRules =
+ ldapServerProperties.getAdminGroupMappingRules();
+ final String groupNamingAttribute =
+ ldapServerProperties.getGroupNamingAttr();
+ String groupSearchFilter = ldapServerProperties.getGroupSearchFilter();
+
+ String setAmbariAdminAttrFilter;
+ if (StringUtils.isEmpty(groupSearchFilter)) {
+ String adminGroupMappingRegex = createAdminGroupMappingRegex(adminGroupMappingRules, groupNamingAttribute);
+ setAmbariAdminAttrFilter = String.format("(&(%s=%s)(objectclass=%s)(|%s))",
+ groupMembershipAttr,
+ memberValue,
+ groupObjectClass,
+ adminGroupMappingRegex);
+ } else {
+ setAmbariAdminAttrFilter = String.format("(&(%s=%s)%s)",
+ groupMembershipAttr,
+ memberValue,
+ groupSearchFilter);
+ }
+ return setAmbariAdminAttrFilter;
+ }
+
+ private String createAdminGroupMappingRegex(String adminGroupMappingRules, String groupNamingAttribute) {
+ String[] adminGroupMappingRegexs = adminGroupMappingRules.split(",");
+ StringBuilder builder = new StringBuilder("");
+ for (String adminGroupMappingRegex : adminGroupMappingRegexs) {
+ builder.append(String.format("(%s=%s)", groupNamingAttribute, adminGroupMappingRegex));
+ }
+ return builder.toString();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/740c6caa/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java
index d0cafa8..a3086693 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java
@@ -63,6 +63,7 @@ public class LdapServerProperties {
private String syncGroupMemberFilter = "";
//LDAP pagination properties
private boolean paginationEnabled = true;
+ private String adminGroupMappingMemberAttr = ""; // custom group search filter for admin mappings
public List<String> getLdapUrls() {
String protocol = useSsl ? "ldaps://" : "ldap://";
@@ -301,6 +302,14 @@ public class LdapServerProperties {
this.syncGroupMemberFilter = syncGroupMemberFilter;
}
+ public String getAdminGroupMappingMemberAttr() {
+ return adminGroupMappingMemberAttr;
+ }
+
+ public void setAdminGroupMappingMemberAttr(String adminGroupMappingMemberAttr) {
+ this.adminGroupMappingMemberAttr = adminGroupMappingMemberAttr;
+ }
+
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
@@ -352,6 +361,7 @@ public class LdapServerProperties {
if (userSearchFilter != null ? !userSearchFilter.equals(that.userSearchFilter) : that.userSearchFilter != null) return false;
if (alternateUserSearchFilter != null ? !alternateUserSearchFilter.equals(that.alternateUserSearchFilter) : that.alternateUserSearchFilter != null) return false;
+ if (adminGroupMappingMemberAttr != null ? !adminGroupMappingMemberAttr.equals(that.adminGroupMappingMemberAttr) : that.adminGroupMappingMemberAttr != null) return false;
return true;
@@ -383,6 +393,7 @@ public class LdapServerProperties {
result = 31 * result + (referralMethod != null ? referralMethod.hashCode() : 0);
result = 31 * result + (userSearchFilter != null ? userSearchFilter.hashCode() : 0);
result = 31 * result + (alternateUserSearchFilter != null ? alternateUserSearchFilter.hashCode() : 0);
+ result = 31 * result + (adminGroupMappingMemberAttr != null ? adminGroupMappingMemberAttr.hashCode() : 0);
return result;
}
@@ -396,5 +407,4 @@ public class LdapServerProperties {
.replace("{usernameAttribute}", usernameAttribute)
.replace("{userObjectClass}", userObjectClass);
}
-
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/740c6caa/ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java b/ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java
index 53ff16d..d38ec69 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulator.java
@@ -101,7 +101,7 @@ public class AmbariLdapDataPopulator {
private static final int USERS_PAGE_SIZE = 500;
// REGEXP to check member attribute starts with "cn=" or "uid=" - case insensitive
- private static final String IS_MEMBER_DN_REGEXP = "^(?i)(%s|%s)=.*$";
+ private static final String IS_MEMBER_DN_REGEXP = "^(?i)(uid|cn|%s|%s)=.*$";
private static final String MEMBER_ATTRIBUTE_REPLACE_STRING = "${member}";
private static final String MEMBER_ATTRIBUTE_VALUE_PLACEHOLDER = "{member}";
http://git-wip-us.apache.org/repos/asf/ambari/blob/740c6caa/ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java
index 2265eec..34eadad 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/security/ldap/AmbariLdapDataPopulatorTest.java
@@ -1809,6 +1809,25 @@ public class AmbariLdapDataPopulatorTest {
}
@Test
+ public void testIsMemberAttributeBaseDn_withDifferentUserAndGroupNameAttribute() {
+ // GIVEN
+ Configuration configuration = createNiceMock(Configuration.class);
+ Users users = createNiceMock(Users.class);
+ LdapServerProperties ldapServerProperties = createNiceMock(LdapServerProperties.class);
+ expect(configuration.getLdapServerProperties()).andReturn(ldapServerProperties).anyTimes();
+ expect(ldapServerProperties.getUsernameAttribute()).andReturn("sAMAccountName");
+ expect(ldapServerProperties.getGroupNamingAttr()).andReturn("groupOfNames");
+
+ replay(configuration, users, ldapServerProperties);
+
+ // WHEN
+ AmbariLdapDataPopulatorTestInstance populator = new AmbariLdapDataPopulatorTestInstance(configuration, users);
+ boolean result = populator.isMemberAttributeBaseDn("cn=mygroupname,OU=myOrganizationUnit,DC=apache,DC=org");
+ // THEN
+ assertTrue(result);
+ }
+
+ @Test
public void testGetUniqueIdMemberPattern() {
// GIVEN
Configuration configuration = createNiceMock(Configuration.class);