Bladeren bron

HADOOP-12001. Fixed LdapGroupsMapping to include configurable Posix UID and GID attributes during the search. Contributed by Patrick White.

(cherry picked from commit 722aa1db1f2ac3db0e70063022436a90f90643f3)
Vinod Kumar Vavilapalli 10 jaren geleden
bovenliggende
commit
98f9d6fee1

+ 3 - 0
hadoop-common-project/hadoop-common/CHANGES.txt

@@ -55,6 +55,9 @@ Release 2.7.6 - UNRELEASED
     HADOOP-15206. BZip2 drops and duplicates records when input split size
     is small. (Aki Tanaka via jlowe)
 
+    HADOOP-12001. Fixed LdapGroupsMapping to include configurable Posix UID and
+    GID attributes during the search. (Patrick White via vinodkv)
+
 Release 2.7.5 - 2017-12-14
 
   INCOMPATIBLE CHANGES

+ 22 - 7
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/LdapGroupsMapping.java

@@ -147,11 +147,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";
 
@@ -184,6 +191,8 @@ public class LdapGroupsMapping
   private String userSearchFilter;
   private String groupMemberAttr;
   private String groupNameAttr;
+  private String posixUidAttr;
+  private String posixGidAttr;
   private boolean isPosix;
 
   public static final int RECONNECT_RETRY_COUNT = 3;
@@ -240,8 +249,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();
         }
@@ -251,7 +260,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);
@@ -361,11 +370,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;
   }

+ 18 - 0
hadoop-common-project/hadoop-common/src/main/resources/core-default.xml

@@ -359,6 +359,24 @@ for ldap providers in the same way as above does.
   </description>
 </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>

+ 17 - 8
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));
   }
 }