Repository: ambari Updated Branches: refs/heads/trunk f98c2b4ed -> 593234b76
Revert "AMBARI-19632. Ldap sync fails when there are special characters in distinguished names (rlevas)" This reverts commit 7e0097501daa5177ee38450b3a9f0e47d7ebf1a7. Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/274969b4 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/274969b4 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/274969b4 Branch: refs/heads/trunk Commit: 274969b4d927aa654b98e75d8277c76d102908a7 Parents: f98c2b4 Author: Robert Levas <[email protected]> Authored: Sun Jan 22 09:24:18 2017 -0500 Committer: Robert Levas <[email protected]> Committed: Sun Jan 22 09:24: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, 126 insertions(+), 211 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/274969b4/ambari-project/pom.xml ---------------------------------------------------------------------- diff --git a/ambari-project/pom.xml b/ambari-project/pom.xml index 0eab275..16ea2af 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>4.0.4.RELEASE</version> + <version>3.1.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.ldap</groupId> <artifactId>spring-ldap-core</artifactId> - <version>2.0.4.RELEASE</version> + <version>1.3.1.RELEASE</version> </dependency> <dependency> <groupId>org.apache.directory.server</groupId> http://git-wip-us.apache.org/repos/asf/ambari/blob/274969b4/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 a6ffa81..b4ef889 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,7 +20,6 @@ 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; @@ -34,6 +33,7 @@ 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,8 +234,9 @@ public class AmbariLdapBindAuthenticator extends AbstractLdapAuthenticator { } BaseLdapPathContextSource baseLdapPathContextSource = (BaseLdapPathContextSource) contextSource; - Name userDistinguishedName = user.getDn(); - Name fullDn = AmbariLdapUtils.getFullDn(userDistinguishedName, baseLdapPathContextSource.getBaseLdapName()); + DistinguishedName userDistinguishedName = new DistinguishedName(user.getDn()); + DistinguishedName fullDn = new DistinguishedName(userDistinguishedName); + fullDn.prepend(baseLdapPathContextSource.getBaseLdapPath()); LOG.debug("Attempting to bind as {}", fullDn); @@ -251,7 +252,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.getBaseLdapName()); + return new DirContextAdapter(user.getAttributes(), userDistinguishedName, baseLdapPathContextSource.getBaseLdapPath()); } 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/274969b4/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 2854dbb..a64ab3d 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,15 +20,13 @@ 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.support.LdapUtils; +import org.springframework.ldap.core.DistinguishedName; +import org.springframework.security.ldap.LdapUtils; import com.google.common.base.Preconditions; @@ -46,9 +44,8 @@ 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 true if the given user name contains domain name as well; false otherwise + * @return */ public static boolean isUserPrincipalNameFormat(String loginName) { return UPN_FORMAT.matcher(loginName).matches(); @@ -57,10 +54,9 @@ 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 the base distinguished name - * @return true if the object is out of scope; false otherwise + * @param baseDn + * @return */ public static boolean isLdapObjectOutOfScopeFromBaseDn(DirContextAdapter adapter, String baseDn) { boolean isOutOfScope = true; @@ -68,9 +64,9 @@ public class AmbariLdapUtils { Name dn = adapter.getDn(); Preconditions.checkArgument(dn != null, "DN cannot be null in LDAP response object"); - Name fullDn = getFullDn(dn, adapter); - Name base = LdapUtils.newLdapName(baseDn); - if (fullDn.startsWith(base)) { + DistinguishedName full = LdapUtils.getFullDn((DistinguishedName) dn, adapter); + DistinguishedName base = new DistinguishedName(baseDn); + if (full.startsWith(base)) { isOutOfScope = false; } } catch (Exception e) { @@ -78,49 +74,4 @@ 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/274969b4/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 c134c51..2dccf11 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,8 +89,13 @@ 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; @@ -103,8 +108,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) { @@ -215,7 +220,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 { @@ -292,7 +297,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 { @@ -359,11 +364,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, @@ -375,7 +380,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()); @@ -394,7 +399,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) { @@ -423,7 +428,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())); } @@ -432,7 +437,8 @@ 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) { @@ -445,7 +451,8 @@ 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) { @@ -457,30 +464,31 @@ 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; + Set<LdapUserDto> filteredLdapUsers = new HashSet<LdapUserDto>(); 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(); @@ -489,20 +497,21 @@ 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; + Set<LdapGroupDto> filteredLdapGroups = new HashSet<LdapGroupDto>(); 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); @@ -511,8 +520,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(); @@ -561,7 +570,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); } @@ -591,7 +600,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(); } @@ -611,10 +620,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); @@ -627,7 +636,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; } @@ -642,7 +651,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); @@ -663,15 +672,15 @@ public class AmbariLdapDataPopulator { do { LOG.trace("LDAP User Query - Base DN: '{}' ; Filter: '{}'", baseDn, encodedFilter); List dtos = configuration.getLdapServerProperties().isPaginationEnabled() ? - ldapTemplate.search(LdapUtils.newLdapName(baseDn), encodedFilter, searchControls, ldapUserContextMapper, processor) : - ldapTemplate.search(LdapUtils.newLdapName(baseDn), encodedFilter, searchControls, ldapUserContextMapper); + ldapTemplate.search(baseDn, encodedFilter, searchControls, ldapUserContextMapper, processor) : + ldapTemplate.search(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; } @@ -735,7 +744,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); @@ -775,7 +784,6 @@ public class AmbariLdapDataPopulator { /** * PagedResultsDirContextProcessor factory method. - * * @return new processor; */ protected PagedResultsDirContextProcessor createPagingProcessor() { @@ -785,7 +793,8 @@ 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) { @@ -820,7 +829,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()); } } @@ -840,7 +849,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); @@ -858,7 +867,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/274969b4/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 1b58173..5629913 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,32 +15,33 @@ * 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.Name; +import javax.naming.Context; import javax.naming.NamingException; -import junit.framework.Assert; - import org.apache.ambari.server.security.authorization.AmbariLdapUtils; 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.support.LdapUtils; +import org.springframework.ldap.core.DistinguishedName; +import org.springframework.security.ldap.LdapUtils; +@RunWith(PowerMockRunner.class) +@PrepareForTest(LdapUtils.class) public class AmbariLdapUtilsTest { - 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; + private static final String USER_DN = "uid=myuser,ou=hdp,ou=Users,dc=apache,dc=org"; @Test public void testIsUserPrincipalNameFormat_True() throws Exception { @@ -105,101 +106,46 @@ public class AmbariLdapUtilsTest { @Test public void testIsLdapObjectOutOfScopeFromBaseDn() throws NamingException { // GIVEN - Name fullDn = LdapUtils.newLdapName(USER_DN); - + 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(); + expect(adapter.getDn()).andReturn(fullDn); - expect(adapter.getNameInNamespace()).andReturn(USER_DN); + expect(context.getNameInNamespace()).andReturn(USER_DN); - replay(adapter); + replay(adapter, context); + PowerMock.replayAll(); // WHEN boolean isOutOfScopeFromBaseDN = AmbariLdapUtils.isLdapObjectOutOfScopeFromBaseDn(adapter, "dc=apache,dc=org"); // THEN assertFalse(isOutOfScopeFromBaseDN); - - verify(adapter); } @Test public void testIsLdapObjectOutOfScopeFromBaseDn_dnOutOfScope() throws NamingException { // GIVEN - Name fullDn = LdapUtils.newLdapName(USER_DN); + 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(); + expect(adapter.getDn()).andReturn(fullDn); - expect(adapter.getNameInNamespace()).andReturn(USER_DN); + expect(context.getNameInNamespace()).andReturn(USER_DN); - replay(adapter); + replay(adapter, context); + PowerMock.replayAll(); // 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/274969b4/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 385666a..fcaae37 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); - LdapName basePath = LdapUtils.newLdapName(basePathString); + DistinguishedName basePath = new DistinguishedName(basePathString); LdapContextSource ldapCtxSource = createMock(LdapContextSource.class); - expect(ldapCtxSource.getBaseLdapName()) + expect(ldapCtxSource.getBaseLdapPath()) .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); - LdapName basePath = LdapUtils.newLdapName(basePathString); + DistinguishedName basePath = new DistinguishedName(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.getBaseLdapName()) + expect(ldapCtxSource.getBaseLdapPath()) .andReturn(basePath) .atLeastOnce(); expect(ldapCtxSource.getContext(ldapUserDNString, "password")) @@ -146,7 +146,16 @@ public class AmbariLdapBindAuthenticatorTest extends EasyMockSupport { .andReturn(boundUserContext) .once(); - Attributes searchedAttributes = new BasicAttributes("uid", ldapUsername); + 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(); DirContextOperations searchedUserContext = createMock(DirContextOperations.class); expect(searchedUserContext.getDn()) http://git-wip-us.apache.org/repos/asf/ambari/blob/274969b4/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 46fe33a..6143cf8 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,7 +76,6 @@ 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; @@ -1657,12 +1656,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("cn=testUser,ou=Ambari,dc=SME,dc=support,dc=com").anyTimes(); + expect(ldapServerProperties.getBaseDN()).andReturn("baseDN").anyTimes(); expect(ldapServerProperties.getUsernameAttribute()).andReturn("uid").anyTimes(); expect(processor.getCookie()).andReturn(cookie).anyTimes(); expect(cookie.getCookie()).andReturn(null).anyTimes(); - 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); + expect(ldapTemplate.search(eq("baseDN"), eq("(&(objectClass=objectClass)(uid=foo))"), anyObject(SearchControls.class), capture(contextMapperCapture), eq(processor))).andReturn(list); replay(ldapTemplate, ldapServerProperties, users, configuration, processor, cookie); @@ -1697,9 +1696,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("cn=testUser,ou=Ambari,dc=SME,dc=support,dc=com").anyTimes(); + expect(ldapServerProperties.getBaseDN()).andReturn("baseDN").anyTimes(); - 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); + expect(ldapTemplate.search(eq("baseDN"), eq("(&(objectClass=objectClass)(uid=foo))"), anyObject(SearchControls.class), capture(contextMapperCapture))).andReturn(list); replay(ldapTemplate, ldapServerProperties, users, configuration, processor, cookie);
