HADOOP-12001. Fixed LdapGroupsMapping to include configurable Posix UID and GID attributes during the search. Contributed by Patrick White.
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/68cc034c Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/68cc034c Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/68cc034c Branch: refs/heads/YARN-2928 Commit: 68cc034c24683f24eb3fa6a9e0a2e4e9034555f3 Parents: e447ae3 Author: Vinod Kumar Vavilapalli <vino...@apache.org> Authored: Mon Jun 15 14:22:34 2015 -0700 Committer: Zhijie Shen <zjs...@apache.org> Committed: Thu Jun 18 11:10:05 2015 -0700 ---------------------------------------------------------------------- hadoop-common-project/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(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/68cc034c/hadoop-common-project/hadoop-common/CHANGES.txt ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 268b1db..cdd396f 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -899,6 +899,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 http://git-wip-us.apache.org/repos/asf/hadoop/blob/68cc034c/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/LdapGroupsMapping.java ---------------------------------------------------------------------- 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 df91b70..8f6203d 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 @@ -150,10 +150,17 @@ public class LdapGroupsMapping 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; } http://git-wip-us.apache.org/repos/asf/hadoop/blob/68cc034c/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml ---------------------------------------------------------------------- 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 ae23a75..13702ee 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 @@ -322,6 +322,24 @@ for ldap providers in the same way as above does. </property> <property> + <name>hadoop.security.group.mapping.ldap.posix.attr.uid.name</name> + <value>uidNumber</value> + <description> + 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. + </description> +</property> + +<property> + <name>hadoop.security.group.mapping.ldap.posix.attr.gid.name</name> + <value>gidNumber</value> + <description> + The attribute of posixAccount indicating the group id. + </description> +</property> + +<property> <name>hadoop.security.group.mapping.ldap.directory.search.timeout</name> <value>10000</value> <description> http://git-wip-us.apache.org/repos/asf/hadoop/blob/68cc034c/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestLdapGroupsMappingWithPosixGroup.java ---------------------------------------------------------------------- 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 1d1a354..247f6c4 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)); } }