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);