You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2017/01/22 15:44:32 UTC

[2/2] ambari git commit: AMBARI-19632. Ldap sync fails when there are special characters in distinguished names (rlevas)

AMBARI-19632. Ldap sync fails when there are special characters in distinguished names (rlevas)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/593234b7
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/593234b7
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/593234b7

Branch: refs/heads/trunk
Commit: 593234b76ab8f9ec67f27f504b03285286120358
Parents: 274969b
Author: Robert Levas <rl...@hortonworks.com>
Authored: Sun Jan 22 10:44:18 2017 -0500
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Sun Jan 22 10:44:18 2017 -0500

----------------------------------------------------------------------
 ambari-project/pom.xml                          |   4 +-
 .../AmbariLdapBindAuthenticator.java            |   9 +-
 .../security/authorization/AmbariLdapUtils.java |  69 +++++++++--
 .../security/ldap/AmbariLdapDataPopulator.java  | 105 ++++++++---------
 .../server/security/AmbariLdapUtilsTest.java    | 118 ++++++++++++++-----
 .../AmbariLdapBindAuthenticatorTest.java        |  23 ++--
 .../ldap/AmbariLdapDataPopulatorTest.java       |   9 +-
 7 files changed, 211 insertions(+), 126 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/593234b7/ambari-project/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-project/pom.xml b/ambari-project/pom.xml
index 16ea2af..0eab275 100644
--- a/ambari-project/pom.xml
+++ b/ambari-project/pom.xml
@@ -146,12 +146,12 @@
       <dependency>
         <groupId>org.springframework.security</groupId>
         <artifactId>spring-security-ldap</artifactId>
-        <version>3.1.2.RELEASE</version>
+        <version>4.0.4.RELEASE</version>
       </dependency>
       <dependency>
         <groupId>org.springframework.ldap</groupId>
         <artifactId>spring-ldap-core</artifactId>
-        <version>1.3.1.RELEASE</version>
+        <version>2.0.4.RELEASE</version>
       </dependency>
       <dependency>
         <groupId>org.apache.directory.server</groupId>

http://git-wip-us.apache.org/repos/asf/ambari/blob/593234b7/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 b4ef889..a6ffa81 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
@@ -20,6 +20,7 @@ package org.apache.ambari.server.security.authorization;
 
 import java.util.List;
 
+import javax.naming.Name;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
 import javax.naming.directory.Attributes;
@@ -33,7 +34,6 @@ import org.springframework.ldap.core.AttributesMapper;
 import org.springframework.ldap.core.ContextSource;
 import org.springframework.ldap.core.DirContextAdapter;
 import org.springframework.ldap.core.DirContextOperations;
-import org.springframework.ldap.core.DistinguishedName;
 import org.springframework.ldap.core.LdapTemplate;
 import org.springframework.ldap.core.support.BaseLdapPathContextSource;
 import org.springframework.ldap.support.LdapUtils;
@@ -234,9 +234,8 @@ public class AmbariLdapBindAuthenticator extends AbstractLdapAuthenticator {
     }
 
     BaseLdapPathContextSource baseLdapPathContextSource = (BaseLdapPathContextSource) contextSource;
-    DistinguishedName userDistinguishedName = new DistinguishedName(user.getDn());
-    DistinguishedName fullDn = new DistinguishedName(userDistinguishedName);
-    fullDn.prepend(baseLdapPathContextSource.getBaseLdapPath());
+    Name userDistinguishedName = user.getDn();
+    Name fullDn = AmbariLdapUtils.getFullDn(userDistinguishedName, baseLdapPathContextSource.getBaseLdapName());
 
     LOG.debug("Attempting to bind as {}", fullDn);
 
@@ -252,7 +251,7 @@ public class AmbariLdapBindAuthenticator extends AbstractLdapAuthenticator {
       // is expected these details will be more complete of querying for them from the bound context.
       // Some LDAP server implementations will no return all attributes to the bound context due to
       // the filter being used in the query.
-      return new DirContextAdapter(user.getAttributes(), userDistinguishedName, baseLdapPathContextSource.getBaseLdapPath());
+      return new DirContextAdapter(user.getAttributes(), userDistinguishedName, baseLdapPathContextSource.getBaseLdapName());
     } catch (org.springframework.ldap.AuthenticationException e) {
       String message = String.format("Failed to bind as %s - %s", user.getDn().toString(), e.getMessage());
       if (LOG.isTraceEnabled()) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/593234b7/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapUtils.java
index a64ab3d..2854dbb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapUtils.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapUtils.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -7,7 +7,7 @@
  * "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
+ *     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,
@@ -20,13 +20,15 @@ package org.apache.ambari.server.security.authorization;
 
 import java.util.regex.Pattern;
 
+import javax.naming.Context;
+import javax.naming.InvalidNameException;
 import javax.naming.Name;
+import javax.naming.NamingException;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.ldap.core.DirContextAdapter;
-import org.springframework.ldap.core.DistinguishedName;
-import org.springframework.security.ldap.LdapUtils;
+import org.springframework.ldap.support.LdapUtils;
 
 import com.google.common.base.Preconditions;
 
@@ -44,8 +46,9 @@ public class AmbariLdapUtils {
 
   /**
    * Returns true if the given user name contains domain name as well (e.g. username@domain)
+   *
    * @param loginName the login name to verify if it contains domain information.
-   * @return
+   * @return true if the given user name contains domain name as well; false otherwise
    */
   public static boolean isUserPrincipalNameFormat(String loginName) {
     return UPN_FORMAT.matcher(loginName).matches();
@@ -54,9 +57,10 @@ public class AmbariLdapUtils {
 
   /**
    * Determine that the full DN of an LDAP object is in/out of the base DN scope.
+   *
    * @param adapter used for get the full dn from the ldap query response
-   * @param baseDn
-   * @return
+   * @param baseDn  the base distinguished name
+   * @return true if the object is out of scope; false otherwise
    */
   public static boolean isLdapObjectOutOfScopeFromBaseDn(DirContextAdapter adapter, String baseDn) {
     boolean isOutOfScope = true;
@@ -64,9 +68,9 @@ public class AmbariLdapUtils {
       Name dn = adapter.getDn();
       Preconditions.checkArgument(dn != null, "DN cannot be null in LDAP response object");
 
-      DistinguishedName full = LdapUtils.getFullDn((DistinguishedName) dn, adapter);
-      DistinguishedName base = new DistinguishedName(baseDn);
-      if (full.startsWith(base)) {
+      Name fullDn = getFullDn(dn, adapter);
+      Name base = LdapUtils.newLdapName(baseDn);
+      if (fullDn.startsWith(base)) {
         isOutOfScope = false;
       }
     } catch (Exception e) {
@@ -74,4 +78,49 @@ public class AmbariLdapUtils {
     }
     return isOutOfScope;
   }
+
+  /**
+   * Ensures the given distinguished name is an absolute value rather than a name relative to the context.
+   *
+   * @param dn      a distinguished name
+   * @param context the context containing the base distinguished name
+   * @return the absolute distinguished name
+   */
+  public static Name getFullDn(String dn, Context context) throws NamingException {
+    return getFullDn(LdapUtils.newLdapName(dn), context);
+  }
+
+  /**
+   * Ensures the given distinguished name is an absolute value rather than a name relative to the context.
+   *
+   * @param dn      a distinguished name
+   * @param context the context containing the base distinguished name
+   * @return the absolute distinguished name
+   */
+  public static Name getFullDn(Name dn, Context context) throws NamingException {
+    return getFullDn(LdapUtils.newLdapName(dn), LdapUtils.newLdapName(context.getNameInNamespace()));
+  }
+
+  /**
+   * Ensures the given distinguished name is an absolute value rather than a name relative to the context.
+   *
+   * @param dn     a distinguished name
+   * @param baseDn the base distinguished name
+   * @return the absolute distinguished name
+   */
+  public static Name getFullDn(Name dn, Name baseDn) {
+
+    if (dn.startsWith(baseDn)) {
+      return dn;
+    } else {
+      try {
+        //Copy the baseDN so we do not change the one that is passed in...
+        baseDn = LdapUtils.newLdapName(baseDn);
+        baseDn.addAll(dn);
+      } catch (InvalidNameException e) {
+        LOG.error(e.getMessage());
+      }
+      return baseDn;
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/593234b7/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 2dccf11..c134c51 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
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -54,9 +54,9 @@ import org.springframework.ldap.filter.Filter;
 import org.springframework.ldap.filter.HardcodedFilter;
 import org.springframework.ldap.filter.LikeFilter;
 import org.springframework.ldap.filter.OrFilter;
+import org.springframework.ldap.support.LdapUtils;
 import org.springframework.security.core.userdetails.UsernameNotFoundException;
 
-import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import com.google.inject.Inject;
 
@@ -89,13 +89,8 @@ public class AmbariLdapDataPopulator {
    */
   private LdapTemplate ldapTemplate;
 
-  /**
-   * List for organizationUnits from the base DN
-   */
-  private List<String> baseOrganizationUnits = Lists.newArrayList();
-
   // Constants
-  private static final String UID_ATTRIBUTE          = "uid";
+  private static final String UID_ATTRIBUTE = "uid";
   private static final String OBJECT_CLASS_ATTRIBUTE = "objectClass";
   private static final int USERS_PAGE_SIZE = 500;
 
@@ -108,8 +103,8 @@ public class AmbariLdapDataPopulator {
   /**
    * Construct an AmbariLdapDataPopulator.
    *
-   * @param configuration  the Ambari configuration
-   * @param users          utility that provides access to Users
+   * @param configuration the Ambari configuration
+   * @param users         utility that provides access to Users
    */
   @Inject
   public AmbariLdapDataPopulator(Configuration configuration, Users users) {
@@ -220,7 +215,7 @@ public class AmbariLdapDataPopulator {
       if (internalUsersMap.containsKey(userName)) {
         final User user = internalUsersMap.get(userName);
         if (user != null && !user.isLdapUser()) {
-          if (Configuration.LdapUsernameCollisionHandlingBehavior.SKIP == configuration.getLdapSyncCollisionHandlingBehavior()){
+          if (Configuration.LdapUsernameCollisionHandlingBehavior.SKIP == configuration.getLdapSyncCollisionHandlingBehavior()) {
             LOG.info("User '{}' skipped because it is local user", userName);
             batchInfo.getUsersSkipped().add(userName);
           } else {
@@ -297,7 +292,7 @@ public class AmbariLdapDataPopulator {
       if (internalUsersMap.containsKey(userName)) {
         final User user = internalUsersMap.get(userName);
         if (user != null && !user.isLdapUser()) {
-          if (Configuration.LdapUsernameCollisionHandlingBehavior.SKIP == configuration.getLdapSyncCollisionHandlingBehavior()){
+          if (Configuration.LdapUsernameCollisionHandlingBehavior.SKIP == configuration.getLdapSyncCollisionHandlingBehavior()) {
             LOG.info("User '{}' skipped because it is local user", userName);
             batchInfo.getUsersSkipped().add(userName);
           } else {
@@ -364,11 +359,11 @@ public class AmbariLdapDataPopulator {
   /**
    * Check group members of the synced group: add missing ones and remove the ones absent in external LDAP.
    *
-   * @param batchInfo batch update object
-   * @param group ldap group
-   * @param internalUsers map of internal users
-   * @param groupMemberAttributes  set of group member attributes that have already been refreshed
-   * @param recursive if disabled, it won't refresh members recursively (its not needed in case of all groups are processed)
+   * @param batchInfo             batch update object
+   * @param group                 ldap group
+   * @param internalUsers         map of internal users
+   * @param groupMemberAttributes set of group member attributes that have already been refreshed
+   * @param recursive             if disabled, it won't refresh members recursively (its not needed in case of all groups are processed)
    * @throws AmbariException if group refresh failed
    */
   protected void refreshGroupMembers(LdapBatchDto batchInfo, LdapGroupDto group, Map<String, User> internalUsers,
@@ -380,7 +375,7 @@ public class AmbariLdapDataPopulator {
       groupMemberAttributes = new HashSet<String>();
     }
 
-    for (String memberAttributeValue: group.getMemberAttributes()) {
+    for (String memberAttributeValue : group.getMemberAttributes()) {
       LdapUserDto groupMember = getLdapUserByMemberAttr(memberAttributeValue);
       if (groupMember != null) {
         externalMembers.add(groupMember.getUserName());
@@ -399,7 +394,7 @@ public class AmbariLdapDataPopulator {
     }
     String groupName = group.getGroupName();
     final Map<String, User> internalMembers = getInternalMembers(groupName);
-    for (String externalMember: externalMembers) {
+    for (String externalMember : externalMembers) {
       if (internalUsers.containsKey(externalMember)) {
         final User user = internalUsers.get(externalMember);
         if (user == null) {
@@ -428,7 +423,7 @@ public class AmbariLdapDataPopulator {
         batchInfo.getMembershipToAdd().add(new LdapUserGroupMemberDto(groupName, externalMember));
       }
     }
-    for (Entry<String, User> userToBeUnsynced: internalMembers.entrySet()) {
+    for (Entry<String, User> userToBeUnsynced : internalMembers.entrySet()) {
       final User user = userToBeUnsynced.getValue();
       batchInfo.getMembershipToRemove().add(new LdapUserGroupMemberDto(groupName, user.getUserName()));
     }
@@ -437,8 +432,7 @@ public class AmbariLdapDataPopulator {
   /**
    * Get the set of LDAP groups for the given group name.
    *
-   * @param groupName  the group name
-   *
+   * @param groupName the group name
    * @return the set of LDAP groups for the given name
    */
   protected Set<LdapGroupDto> getLdapGroups(String groupName) {
@@ -451,8 +445,7 @@ public class AmbariLdapDataPopulator {
   /**
    * Get the set of LDAP users for the given user name.
    *
-   * @param username  the user name
-   *
+   * @param username the user name
    * @return the set of LDAP users for the given name
    */
   protected Set<LdapUserDto> getLdapUsers(String username) {
@@ -464,31 +457,30 @@ public class AmbariLdapDataPopulator {
   /**
    * Get the LDAP user member for the given member attribute.
    *
-   * @param memberAttributeValue  the member attribute value
-   *
+   * @param memberAttributeValue the member attribute value
    * @return the user for the given member attribute; null if not found
    */
   protected LdapUserDto getLdapUserByMemberAttr(String memberAttributeValue) {
-    Set<LdapUserDto> filteredLdapUsers = new HashSet<LdapUserDto>();
+    Set<LdapUserDto> filteredLdapUsers;
 
     memberAttributeValue = getUniqueIdByMemberPattern(memberAttributeValue,
-      ldapServerProperties.getSyncUserMemberReplacePattern());
+        ldapServerProperties.getSyncUserMemberReplacePattern());
     Filter syncMemberFilter = createCustomMemberFilter(memberAttributeValue,
-      ldapServerProperties.getSyncUserMemberFilter());
+        ldapServerProperties.getSyncUserMemberFilter());
 
     if (memberAttributeValue != null && syncMemberFilter != null) {
       LOG.trace("Use custom filter '{}' for getting member user with default baseDN ('{}')",
-        syncMemberFilter.encode(), ldapServerProperties.getBaseDN());
+          syncMemberFilter.encode(), ldapServerProperties.getBaseDN());
       filteredLdapUsers = getFilteredLdapUsers(ldapServerProperties.getBaseDN(), syncMemberFilter);
-    } else if (memberAttributeValue!= null && isMemberAttributeBaseDn(memberAttributeValue)) {
+    } else if (memberAttributeValue != null && isMemberAttributeBaseDn(memberAttributeValue)) {
       LOG.trace("Member can be used as baseDn: {}", memberAttributeValue);
       Filter filter = new EqualsFilter(OBJECT_CLASS_ATTRIBUTE, ldapServerProperties.getUserObjectClass());
       filteredLdapUsers = getFilteredLdapUsers(memberAttributeValue, filter);
     } else {
       LOG.trace("Member cannot be used as baseDn: {}", memberAttributeValue);
       Filter filter = new AndFilter()
-        .and(new EqualsFilter(OBJECT_CLASS_ATTRIBUTE, ldapServerProperties.getUserObjectClass()))
-        .and(new EqualsFilter(ldapServerProperties.getUsernameAttribute(), memberAttributeValue));
+          .and(new EqualsFilter(OBJECT_CLASS_ATTRIBUTE, ldapServerProperties.getUserObjectClass()))
+          .and(new EqualsFilter(ldapServerProperties.getUsernameAttribute(), memberAttributeValue));
       filteredLdapUsers = getFilteredLdapUsers(ldapServerProperties.getBaseDN(), filter);
     }
     return (filteredLdapUsers.isEmpty()) ? null : filteredLdapUsers.iterator().next();
@@ -497,21 +489,20 @@ public class AmbariLdapDataPopulator {
   /**
    * Get the LDAP group member for the given member attribute.
    *
-   * @param memberAttributeValue  the member attribute value
-   *
+   * @param memberAttributeValue the member attribute value
    * @return the group for the given member attribute; null if not found
    */
   protected LdapGroupDto getLdapGroupByMemberAttr(String memberAttributeValue) {
-    Set<LdapGroupDto> filteredLdapGroups = new HashSet<LdapGroupDto>();
+    Set<LdapGroupDto> filteredLdapGroups;
 
     memberAttributeValue = getUniqueIdByMemberPattern(memberAttributeValue,
-      ldapServerProperties.getSyncGroupMemberReplacePattern());
+        ldapServerProperties.getSyncGroupMemberReplacePattern());
     Filter syncMemberFilter = createCustomMemberFilter(memberAttributeValue,
-      ldapServerProperties.getSyncGroupMemberFilter());
+        ldapServerProperties.getSyncGroupMemberFilter());
 
     if (memberAttributeValue != null && syncMemberFilter != null) {
       LOG.trace("Use custom filter '{}' for getting member group with default baseDN ('{}')",
-        syncMemberFilter.encode(), ldapServerProperties.getBaseDN());
+          syncMemberFilter.encode(), ldapServerProperties.getBaseDN());
       filteredLdapGroups = getFilteredLdapGroups(ldapServerProperties.getBaseDN(), syncMemberFilter);
     } else if (memberAttributeValue != null && isMemberAttributeBaseDn(memberAttributeValue)) {
       LOG.trace("Member can be used as baseDn: {}", memberAttributeValue);
@@ -520,8 +511,8 @@ public class AmbariLdapDataPopulator {
     } else {
       LOG.trace("Member cannot be used as baseDn: {}", memberAttributeValue);
       filteredLdapGroups = getFilteredLdapGroups(ldapServerProperties.getBaseDN(),
-        new EqualsFilter(OBJECT_CLASS_ATTRIBUTE, ldapServerProperties.getGroupObjectClass()),
-        getMemberFilter(memberAttributeValue));
+          new EqualsFilter(OBJECT_CLASS_ATTRIBUTE, ldapServerProperties.getGroupObjectClass()),
+          getMemberFilter(memberAttributeValue));
     }
 
     return (filteredLdapGroups.isEmpty()) ? null : filteredLdapGroups.iterator().next();
@@ -570,7 +561,7 @@ public class AmbariLdapDataPopulator {
    */
   protected void cleanUpLdapUsersWithoutGroup() throws AmbariException {
     final List<User> allUsers = users.getAllUsers();
-    for (User user: allUsers) {
+    for (User user : allUsers) {
       if (user.isLdapUser() && user.getGroups().isEmpty()) {
         users.removeUser(user);
       }
@@ -600,7 +591,7 @@ public class AmbariLdapDataPopulator {
    */
   protected boolean isMemberAttributeBaseDn(String memberAttributeValue) {
     Pattern pattern = Pattern.compile(String.format(IS_MEMBER_DN_REGEXP,
-      ldapServerProperties.getUsernameAttribute(), ldapServerProperties.getGroupNamingAttr()));
+        ldapServerProperties.getUsernameAttribute(), ldapServerProperties.getGroupNamingAttr()));
     return pattern.matcher(memberAttributeValue).find();
   }
 
@@ -620,10 +611,10 @@ public class AmbariLdapDataPopulator {
     String dnAttribute = ldapServerProperties.getDnAttribute();
 
     return new OrFilter().or(new EqualsFilter(dnAttribute, memberAttributeValue)).
-            or(new EqualsFilter(UID_ATTRIBUTE, memberAttributeValue));
+        or(new EqualsFilter(UID_ATTRIBUTE, memberAttributeValue));
   }
 
-  private Set<LdapGroupDto> getFilteredLdapGroups(String baseDn, Filter...filters) {
+  private Set<LdapGroupDto> getFilteredLdapGroups(String baseDn, Filter... filters) {
     AndFilter andFilter = new AndFilter();
     for (Filter filter : filters) {
       andFilter.and(filter);
@@ -636,7 +627,7 @@ public class AmbariLdapDataPopulator {
     final LdapTemplate ldapTemplate = loadLdapTemplate();
     LOG.trace("LDAP Group Query - Base DN: '{}' ; Filter: '{}'", baseDn, filter.encode());
     ldapTemplate.search(baseDn, filter.encode(),
-      new LdapGroupContextMapper(groups, ldapServerProperties));
+        new LdapGroupContextMapper(groups, ldapServerProperties));
     return groups;
   }
 
@@ -651,7 +642,7 @@ public class AmbariLdapDataPopulator {
     return getFilteredLdapUsers(ldapServerProperties.getBaseDN(), userObjectFilter);
   }
 
-  private Set<LdapUserDto> getFilteredLdapUsers(String baseDn, Filter...filters) {
+  private Set<LdapUserDto> getFilteredLdapUsers(String baseDn, Filter... filters) {
     AndFilter andFilter = new AndFilter();
     for (Filter filter : filters) {
       andFilter.and(filter);
@@ -672,15 +663,15 @@ public class AmbariLdapDataPopulator {
     do {
       LOG.trace("LDAP User Query - Base DN: '{}' ; Filter: '{}'", baseDn, encodedFilter);
       List dtos = configuration.getLdapServerProperties().isPaginationEnabled() ?
-        ldapTemplate.search(baseDn, encodedFilter, searchControls, ldapUserContextMapper, processor) :
-        ldapTemplate.search(baseDn, encodedFilter, searchControls, ldapUserContextMapper);
+          ldapTemplate.search(LdapUtils.newLdapName(baseDn), encodedFilter, searchControls, ldapUserContextMapper, processor) :
+          ldapTemplate.search(LdapUtils.newLdapName(baseDn), encodedFilter, searchControls, ldapUserContextMapper);
       for (Object dto : dtos) {
         if (dto != null) {
-          users.add((LdapUserDto)dto);
+          users.add((LdapUserDto) dto);
         }
       }
     } while (configuration.getLdapServerProperties().isPaginationEnabled()
-      && processor.getCookie().getCookie() != null);
+        && processor.getCookie().getCookie() != null);
     return users;
   }
 
@@ -744,7 +735,7 @@ public class AmbariLdapDataPopulator {
       ldapServerProperties = properties;
 
       final LdapContextSource ldapContextSource = createLdapContextSource();
-	  
+
       // The LdapTemplate by design will close the connection after each call to the LDAP Server
       // In order to have the interaction work with large/paged results, said connection must be pooled and reused
       ldapContextSource.setPooled(true);
@@ -784,6 +775,7 @@ public class AmbariLdapDataPopulator {
 
   /**
    * PagedResultsDirContextProcessor factory method.
+   *
    * @return new processor;
    */
   protected PagedResultsDirContextProcessor createPagingProcessor() {
@@ -793,8 +785,7 @@ public class AmbariLdapDataPopulator {
   /**
    * LdapTemplate factory method.
    *
-   * @param ldapContextSource  the LDAP context source
-   *
+   * @param ldapContextSource the LDAP context source
    * @return new LDAP template
    */
   protected LdapTemplate createLdapTemplate(LdapContextSource ldapContextSource) {
@@ -829,7 +820,7 @@ public class AmbariLdapDataPopulator {
         group.setGroupName(groupNameAttribute.toLowerCase());
         final String[] uniqueMembers = adapter.getStringAttributes(ldapServerProperties.getGroupMembershipAttr());
         if (uniqueMembers != null) {
-          for (String uniqueMember: uniqueMembers) {
+          for (String uniqueMember : uniqueMembers) {
             group.getMemberAttributes().add(uniqueMember.toLowerCase());
           }
         }
@@ -849,7 +840,7 @@ public class AmbariLdapDataPopulator {
 
     @Override
     public Object mapFromContext(Object ctx) {
-      final DirContextAdapter adapter  = (DirContextAdapter) ctx;
+      final DirContextAdapter adapter = (DirContextAdapter) ctx;
       final String usernameAttribute = adapter.getStringAttribute(ldapServerProperties.getUsernameAttribute());
       final String uidAttribute = adapter.getStringAttribute(UID_ATTRIBUTE);
 
@@ -867,7 +858,7 @@ public class AmbariLdapDataPopulator {
         return user;
       } else {
         LOG.warn("Ignoring LDAP user " + adapter.getNameInNamespace() + " as it doesn't have required" +
-                " attributes uid and " + ldapServerProperties.getUsernameAttribute());
+            " attributes uid and " + ldapServerProperties.getUsernameAttribute());
       }
       return null;
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/593234b7/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariLdapUtilsTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariLdapUtilsTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariLdapUtilsTest.java
index 5629913..46f9689 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariLdapUtilsTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/security/AmbariLdapUtilsTest.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -7,7 +7,7 @@
  * "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
+ *     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,
@@ -15,33 +15,32 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.ambari.server.security;
 
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
-import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.createStrictMock;
 import static org.easymock.EasyMock.expect;
 import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
 
-import javax.naming.Context;
+import javax.naming.Name;
 import javax.naming.NamingException;
 
+
 import org.apache.ambari.server.security.authorization.AmbariLdapUtils;
+import org.junit.Assert;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.powermock.api.easymock.PowerMock;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
 import org.springframework.ldap.core.DirContextAdapter;
-import org.springframework.ldap.core.DistinguishedName;
-import org.springframework.security.ldap.LdapUtils;
+import org.springframework.ldap.support.LdapUtils;
 
-@RunWith(PowerMockRunner.class)
-@PrepareForTest(LdapUtils.class)
 public class AmbariLdapUtilsTest {
 
-  private static final String USER_DN = "uid=myuser,ou=hdp,ou=Users,dc=apache,dc=org";
+  private static final String USER_BASE_DN = "ou=hdp,ou=Users,dc=apache,dc=org";
+  private static final String USER_RELATIVE_DN = "uid=myuser";
+  private static final String USER_DN = USER_RELATIVE_DN + "," + USER_BASE_DN;
 
   @Test
   public void testIsUserPrincipalNameFormat_True() throws Exception {
@@ -106,46 +105,101 @@ public class AmbariLdapUtilsTest {
   @Test
   public void testIsLdapObjectOutOfScopeFromBaseDn() throws NamingException {
     // GIVEN
-    DistinguishedName fullDn = new DistinguishedName(USER_DN);
-    Context context = createNiceMock(Context.class);
-    DirContextAdapter adapter = createNiceMock(DirContextAdapter.class);
-
-    PowerMock.mockStatic(LdapUtils.class);
-    expect(LdapUtils.getFullDn(anyObject(DistinguishedName.class), anyObject(Context.class)))
-      .andReturn(fullDn).anyTimes();
+    Name fullDn = LdapUtils.newLdapName(USER_DN);
 
+    DirContextAdapter adapter = createNiceMock(DirContextAdapter.class);
     expect(adapter.getDn()).andReturn(fullDn);
-    expect(context.getNameInNamespace()).andReturn(USER_DN);
+    expect(adapter.getNameInNamespace()).andReturn(USER_DN);
 
-    replay(adapter, context);
-    PowerMock.replayAll();
+    replay(adapter);
 
     // WHEN
     boolean isOutOfScopeFromBaseDN = AmbariLdapUtils.isLdapObjectOutOfScopeFromBaseDn(adapter, "dc=apache,dc=org");
     // THEN
     assertFalse(isOutOfScopeFromBaseDN);
+
+    verify(adapter);
   }
 
   @Test
   public void testIsLdapObjectOutOfScopeFromBaseDn_dnOutOfScope() throws NamingException {
     // GIVEN
-    DistinguishedName fullDn = new DistinguishedName(USER_DN);
-    Context context = createNiceMock(Context.class);
+    Name fullDn = LdapUtils.newLdapName(USER_DN);
     DirContextAdapter adapter = createNiceMock(DirContextAdapter.class);
 
-    PowerMock.mockStatic(LdapUtils.class);
-    expect(LdapUtils.getFullDn(anyObject(DistinguishedName.class), anyObject(Context.class)))
-      .andReturn(fullDn).anyTimes();
-
     expect(adapter.getDn()).andReturn(fullDn);
-    expect(context.getNameInNamespace()).andReturn(USER_DN);
+    expect(adapter.getNameInNamespace()).andReturn(USER_DN);
 
-    replay(adapter, context);
-    PowerMock.replayAll();
+    replay(adapter);
 
     // WHEN
     boolean isOutOfScopeFromBaseDN = AmbariLdapUtils.isLdapObjectOutOfScopeFromBaseDn(adapter, "dc=apache,dc=org,ou=custom");
     // THEN
     assertTrue(isOutOfScopeFromBaseDN);
+
+    verify(adapter);
+  }
+
+  @Test
+  public void testGetFullDn() throws Exception {
+
+    DirContextAdapter adapterFullDn = createStrictMock(DirContextAdapter.class);
+    expect(adapterFullDn.getNameInNamespace()).andReturn(USER_DN).anyTimes();
+
+    DirContextAdapter adapterBaseDn = createStrictMock(DirContextAdapter.class);
+    expect(adapterBaseDn.getNameInNamespace()).andReturn(USER_BASE_DN).anyTimes();
+
+    Name absoluteDn = LdapUtils.newLdapName(USER_DN);
+    Name relativeDn = LdapUtils.newLdapName(USER_RELATIVE_DN);
+
+    replay(adapterFullDn, adapterBaseDn);
+
+    Name fullDn;
+
+    // ****************************
+    // getFullDn(Name, Context)
+    fullDn = AmbariLdapUtils.getFullDn(absoluteDn, adapterFullDn);
+    Assert.assertEquals(absoluteDn, fullDn);
+
+    fullDn = AmbariLdapUtils.getFullDn(absoluteDn, adapterBaseDn);
+    Assert.assertEquals(absoluteDn, fullDn);
+
+    fullDn = AmbariLdapUtils.getFullDn(relativeDn, adapterBaseDn);
+    Assert.assertEquals(absoluteDn, fullDn);
+    // ****************************
+
+
+    // ****************************
+    // getFullDn(String, Context)
+    fullDn = AmbariLdapUtils.getFullDn(absoluteDn.toString(), adapterFullDn);
+    Assert.assertEquals(absoluteDn, fullDn);
+
+    fullDn = AmbariLdapUtils.getFullDn(absoluteDn.toString(), adapterBaseDn);
+    Assert.assertEquals(absoluteDn, fullDn);
+
+    fullDn = AmbariLdapUtils.getFullDn(relativeDn.toString(), adapterBaseDn);
+    Assert.assertEquals(absoluteDn, fullDn);
+    // ****************************
+
+    // ****************************
+    // getFullDn(Name, Name)
+    Name nameInNamespaceFullDn = LdapUtils.newLdapName(adapterFullDn.getNameInNamespace());
+    Name nameInNamespaceBaseDn = LdapUtils.newLdapName(adapterBaseDn.getNameInNamespace());
+
+    fullDn = AmbariLdapUtils.getFullDn(absoluteDn, nameInNamespaceFullDn);
+    Assert.assertEquals(absoluteDn, fullDn);
+
+    fullDn = AmbariLdapUtils.getFullDn(absoluteDn, nameInNamespaceBaseDn);
+    Assert.assertEquals(absoluteDn, fullDn);
+
+    fullDn = AmbariLdapUtils.getFullDn(relativeDn, nameInNamespaceBaseDn);
+    Assert.assertEquals(absoluteDn, fullDn);
+
+    // Make sure nameInNamespace was not altered
+    Assert.assertEquals(adapterFullDn.getNameInNamespace(), nameInNamespaceFullDn.toString());
+    Assert.assertEquals(adapterBaseDn.getNameInNamespace(), nameInNamespaceBaseDn.toString());
+    // ****************************
+
+    verify(adapterFullDn, adapterBaseDn);
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/593234b7/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticatorTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticatorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticatorTest.java
index fcaae37..385666a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticatorTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/security/authorization/AmbariLdapBindAuthenticatorTest.java
@@ -28,8 +28,8 @@ import static org.junit.Assert.fail;
 import java.util.Properties;
 
 import javax.naming.NamingEnumeration;
-import javax.naming.directory.Attribute;
 import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttributes;
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 import javax.naming.ldap.LdapName;
@@ -39,8 +39,8 @@ import org.apache.commons.lang.StringUtils;
 import org.easymock.EasyMockSupport;
 import org.junit.Test;
 import org.springframework.ldap.core.DirContextOperations;
-import org.springframework.ldap.core.DistinguishedName;
 import org.springframework.ldap.core.support.LdapContextSource;
+import org.springframework.ldap.support.LdapUtils;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.ldap.search.FilterBasedLdapUserSearch;
 import org.springframework.web.context.request.RequestAttributes;
@@ -75,10 +75,10 @@ public class AmbariLdapBindAuthenticatorTest extends EasyMockSupport {
     String ldapUserRelativeDNString = String.format("uid=%s,ou=people,ou=dev", "ldapUsername");
     LdapName ldapUserRelativeDN = new LdapName(ldapUserRelativeDNString);
     String ldapUserDNString = String.format("%s,%s", ldapUserRelativeDNString, basePathString);
-    DistinguishedName basePath = new DistinguishedName(basePathString);
+    LdapName basePath = LdapUtils.newLdapName(basePathString);
 
     LdapContextSource ldapCtxSource = createMock(LdapContextSource.class);
-    expect(ldapCtxSource.getBaseLdapPath())
+    expect(ldapCtxSource.getBaseLdapName())
         .andReturn(basePath)
         .atLeastOnce();
     expect(ldapCtxSource.getContext(ldapUserDNString, "password"))
@@ -117,7 +117,7 @@ public class AmbariLdapBindAuthenticatorTest extends EasyMockSupport {
     String ldapUserRelativeDNString = String.format("uid=%s,ou=people,ou=dev", ldapUsername);
     LdapName ldapUserRelativeDN = new LdapName(ldapUserRelativeDNString);
     String ldapUserDNString = String.format("%s,%s", ldapUserRelativeDNString, basePathString);
-    DistinguishedName basePath = new DistinguishedName(basePathString);
+    LdapName basePath = LdapUtils.newLdapName(basePathString);
 
     @SuppressWarnings("unchecked")
     NamingEnumeration<SearchResult> adminGroups = createMock(NamingEnumeration.class);
@@ -136,7 +136,7 @@ public class AmbariLdapBindAuthenticatorTest extends EasyMockSupport {
 
 
     LdapContextSource ldapCtxSource = createMock(LdapContextSource.class);
-    expect(ldapCtxSource.getBaseLdapPath())
+    expect(ldapCtxSource.getBaseLdapName())
         .andReturn(basePath)
         .atLeastOnce();
     expect(ldapCtxSource.getContext(ldapUserDNString, "password"))
@@ -146,16 +146,7 @@ public class AmbariLdapBindAuthenticatorTest extends EasyMockSupport {
         .andReturn(boundUserContext)
         .once();
 
-    Attribute uidAttribute = createMock(Attribute.class);
-    expect(uidAttribute.size())
-        .andReturn(1)
-        .atLeastOnce();
-    expect(uidAttribute.get()).andReturn(ldapUsername).atLeastOnce();
-
-    Attributes searchedAttributes = createMock(Attributes.class);
-    expect(searchedAttributes.get("uid"))
-        .andReturn(uidAttribute)
-        .atLeastOnce();
+    Attributes searchedAttributes = new BasicAttributes("uid", ldapUsername);
 
     DirContextOperations searchedUserContext = createMock(DirContextOperations.class);
     expect(searchedUserContext.getDn())

http://git-wip-us.apache.org/repos/asf/ambari/blob/593234b7/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 6143cf8..46fe33a 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
@@ -76,6 +76,7 @@ import org.springframework.ldap.core.DirContextAdapter;
 import org.springframework.ldap.core.LdapTemplate;
 import org.springframework.ldap.core.support.LdapContextSource;
 import org.springframework.ldap.filter.Filter;
+import org.springframework.ldap.support.LdapUtils;
 
 import com.google.common.collect.Sets;
 
@@ -1656,12 +1657,12 @@ public class AmbariLdapDataPopulatorTest {
     expect(ldapServerProperties.isPaginationEnabled()).andReturn(true).anyTimes();
     expect(ldapServerProperties.getUserObjectClass()).andReturn("objectClass").anyTimes();
     expect(ldapServerProperties.getDnAttribute()).andReturn("dn").anyTimes();
-    expect(ldapServerProperties.getBaseDN()).andReturn("baseDN").anyTimes();
+    expect(ldapServerProperties.getBaseDN()).andReturn("cn=testUser,ou=Ambari,dc=SME,dc=support,dc=com").anyTimes();
     expect(ldapServerProperties.getUsernameAttribute()).andReturn("uid").anyTimes();
     expect(processor.getCookie()).andReturn(cookie).anyTimes();
     expect(cookie.getCookie()).andReturn(null).anyTimes();
 
-    expect(ldapTemplate.search(eq("baseDN"), eq("(&(objectClass=objectClass)(uid=foo))"), anyObject(SearchControls.class), capture(contextMapperCapture), eq(processor))).andReturn(list);
+    expect(ldapTemplate.search(eq(LdapUtils.newLdapName("cn=testUser,ou=Ambari,dc=SME,dc=support,dc=com")), eq("(&(objectClass=objectClass)(uid=foo))"), anyObject(SearchControls.class), capture(contextMapperCapture), eq(processor))).andReturn(list);
 
     replay(ldapTemplate, ldapServerProperties, users, configuration, processor, cookie);
 
@@ -1696,9 +1697,9 @@ public class AmbariLdapDataPopulatorTest {
     expect(ldapServerProperties.getUserObjectClass()).andReturn("objectClass").anyTimes();
     expect(ldapServerProperties.getUsernameAttribute()).andReturn("uid").anyTimes();
     expect(ldapServerProperties.getDnAttribute()).andReturn("dn").anyTimes();
-    expect(ldapServerProperties.getBaseDN()).andReturn("baseDN").anyTimes();
+    expect(ldapServerProperties.getBaseDN()).andReturn("cn=testUser,ou=Ambari,dc=SME,dc=support,dc=com").anyTimes();
 
-    expect(ldapTemplate.search(eq("baseDN"), eq("(&(objectClass=objectClass)(uid=foo))"), anyObject(SearchControls.class), capture(contextMapperCapture))).andReturn(list);
+    expect(ldapTemplate.search(eq(LdapUtils.newLdapName("cn=testUser,ou=Ambari,dc=SME,dc=support,dc=com") ), eq("(&(objectClass=objectClass)(uid=foo))"), anyObject(SearchControls.class), capture(contextMapperCapture))).andReturn(list);
 
     replay(ldapTemplate, ldapServerProperties, users, configuration, processor, cookie);