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