From 58d3a9aaf65310aba9b4300ef0cacd58ebfdb6eb Mon Sep 17 00:00:00 2001 From: Vinod Kumar Vavilapalli Date: Mon, 15 Jun 2015 14:22:34 -0700 Subject: [PATCH] HADOOP-12001. Fixed LdapGroupsMapping to include configurable Posix UID and GID attributes during the search. Contributed by Patrick White. (cherry picked from commit 722aa1db1f2ac3db0e70063022436a90f90643f3) --- .../hadoop-common/CHANGES.txt | 3 ++ .../hadoop/security/LdapGroupsMapping.java | 29 ++++++++++++++----- .../src/main/resources/core-default.xml | 18 ++++++++++++ .../TestLdapGroupsMappingWithPosixGroup.java | 25 +++++++++++----- 4 files changed, 60 insertions(+), 15 deletions(-) diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 70f7da5b2f4..46cd5a323a7 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -415,6 +415,9 @@ Release 2.7.1 - UNRELEASED HADOOP-12078. The default retry policy does not handle RetriableException correctly. (Arpit Agarwal) + HADOOP-12001. Fixed LdapGroupsMapping to include configurable Posix UID and + GID attributes during the search. (Patrick White via vinodkv) + Release 2.7.0 - 2015-04-20 INCOMPATIBLE CHANGES diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/LdapGroupsMapping.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/LdapGroupsMapping.java index df91b701bcd..8f6203de45b 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/LdapGroupsMapping.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/LdapGroupsMapping.java @@ -149,11 +149,18 @@ public class LdapGroupsMapping public static final String GROUP_NAME_ATTR_KEY = LDAP_CONFIG_PREFIX + ".search.attr.group.name"; public static final String GROUP_NAME_ATTR_DEFAULT = "cn"; + /* + * LDAP attribute names to use when doing posix-like lookups + */ + public static final String POSIX_UID_ATTR_KEY = LDAP_CONFIG_PREFIX + ".posix.attr.uid.name"; + public static final String POSIX_UID_ATTR_DEFAULT = "uidNumber"; + + public static final String POSIX_GID_ATTR_KEY = LDAP_CONFIG_PREFIX + ".posix.attr.gid.name"; + public static final String POSIX_GID_ATTR_DEFAULT = "gidNumber"; + /* * Posix attributes */ - public static final String POSIX_UIDNUMBER = "uidNumber"; - public static final String POSIX_GIDNUMBER = "gidNumber"; public static final String POSIX_GROUP = "posixGroup"; public static final String POSIX_ACCOUNT = "posixAccount"; @@ -186,6 +193,8 @@ public class LdapGroupsMapping private String userSearchFilter; private String groupMemberAttr; private String groupNameAttr; + private String posixUidAttr; + private String posixGidAttr; private boolean isPosix; public static int RECONNECT_RETRY_COUNT = 3; @@ -256,8 +265,8 @@ public class LdapGroupsMapping if (isPosix) { String gidNumber = null; String uidNumber = null; - Attribute gidAttribute = result.getAttributes().get(POSIX_GIDNUMBER); - Attribute uidAttribute = result.getAttributes().get(POSIX_UIDNUMBER); + Attribute gidAttribute = result.getAttributes().get(posixGidAttr); + Attribute uidAttribute = result.getAttributes().get(posixUidAttr); if (gidAttribute != null) { gidNumber = gidAttribute.get().toString(); } @@ -267,7 +276,7 @@ public class LdapGroupsMapping if (uidNumber != null && gidNumber != null) { groupResults = ctx.search(baseDN, - "(&"+ groupSearchFilter + "(|(" + POSIX_GIDNUMBER + "={0})" + + "(&"+ groupSearchFilter + "(|(" + posixGidAttr + "={0})" + "(" + groupMemberAttr + "={1})))", new Object[] { gidNumber, uidNumber }, SEARCH_CONTROLS); @@ -374,11 +383,17 @@ public class LdapGroupsMapping conf.get(GROUP_MEMBERSHIP_ATTR_KEY, GROUP_MEMBERSHIP_ATTR_DEFAULT); groupNameAttr = conf.get(GROUP_NAME_ATTR_KEY, GROUP_NAME_ATTR_DEFAULT); + posixUidAttr = + conf.get(POSIX_UID_ATTR_KEY, POSIX_UID_ATTR_DEFAULT); + posixGidAttr = + conf.get(POSIX_GID_ATTR_KEY, POSIX_GID_ATTR_DEFAULT); int dirSearchTimeout = conf.getInt(DIRECTORY_SEARCH_TIMEOUT, DIRECTORY_SEARCH_TIMEOUT_DEFAULT); SEARCH_CONTROLS.setTimeLimit(dirSearchTimeout); - // Limit the attributes returned to only those required to speed up the search. See HADOOP-10626 for more details. - SEARCH_CONTROLS.setReturningAttributes(new String[] {groupNameAttr}); + // Limit the attributes returned to only those required to speed up the search. + // See HADOOP-10626 and HADOOP-12001 for more details. + SEARCH_CONTROLS.setReturningAttributes( + new String[] {groupNameAttr, posixUidAttr, posixGidAttr}); this.conf = conf; } diff --git a/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml b/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml index 0f2952b2cc5..8643a0e2a0b 100644 --- a/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml +++ b/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml @@ -330,6 +330,24 @@ for ldap providers in the same way as above does. + + hadoop.security.group.mapping.ldap.posix.attr.uid.name + uidNumber + + The attribute of posixAccount to use when groups for membership. + Mostly useful for schemas wherein groups have memberUids that use an + attribute other than uidNumber. + + + + + hadoop.security.group.mapping.ldap.posix.attr.gid.name + gidNumber + + The attribute of posixAccount indicating the group id. + + + hadoop.security.group.mapping.ldap.directory.search.timeout 10000 diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestLdapGroupsMappingWithPosixGroup.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestLdapGroupsMappingWithPosixGroup.java index 1d1a354b11f..247f6c440db 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestLdapGroupsMappingWithPosixGroup.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestLdapGroupsMappingWithPosixGroup.java @@ -52,14 +52,17 @@ public class TestLdapGroupsMappingWithPosixGroup SearchResult mockUserResult = mock(SearchResult.class); when(mockUserNamingEnum.nextElement()).thenReturn(mockUserResult); + Attribute mockUidNumberAttr = mock(Attribute.class); + Attribute mockGidNumberAttr = mock(Attribute.class); Attribute mockUidAttr = mock(Attribute.class); - Attribute mockGidAttr = mock(Attribute.class); Attributes mockAttrs = mock(Attributes.class); - when(mockUidAttr.get()).thenReturn("700"); - when(mockGidAttr.get()).thenReturn("600"); - when(mockAttrs.get(eq("uidNumber"))).thenReturn(mockUidAttr); - when(mockAttrs.get(eq("gidNumber"))).thenReturn(mockGidAttr); + when(mockUidAttr.get()).thenReturn("some_user"); + when(mockUidNumberAttr.get()).thenReturn("700"); + when(mockGidNumberAttr.get()).thenReturn("600"); + when(mockAttrs.get(eq("uid"))).thenReturn(mockUidAttr); + when(mockAttrs.get(eq("uidNumber"))).thenReturn(mockUidNumberAttr); + when(mockAttrs.get(eq("gidNumber"))).thenReturn(mockGidNumberAttr); when(mockUserResult.getAttributes()).thenReturn(mockAttrs); } @@ -85,6 +88,8 @@ public class TestLdapGroupsMappingWithPosixGroup conf.set(LdapGroupsMapping.USER_SEARCH_FILTER_KEY, "(objectClass=posixAccount)"); conf.set(LdapGroupsMapping.GROUP_MEMBERSHIP_ATTR_KEY, "memberUid"); + conf.set(LdapGroupsMapping.POSIX_UID_ATTR_KEY, "uidNumber"); + conf.set(LdapGroupsMapping.POSIX_GID_ATTR_KEY, "gidNumber"); conf.set(LdapGroupsMapping.GROUP_NAME_ATTR_KEY, "cn"); mappingSpy.setConf(conf); @@ -94,10 +99,14 @@ public class TestLdapGroupsMappingWithPosixGroup Assert.assertEquals(expectedGroups, groups); + mappingSpy.getConf().set(LdapGroupsMapping.POSIX_UID_ATTR_KEY, "uid"); + + Assert.assertEquals(expectedGroups, groups); + // We should have searched for a user, and then two groups verify(mockContext, times(searchTimes)).search(anyString(), - anyString(), - any(Object[].class), - any(SearchControls.class)); + anyString(), + any(Object[].class), + any(SearchControls.class)); } }