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