浏览代码

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 年之前
父节点
当前提交
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
     HADOOP-15206. BZip2 drops and duplicates records when input split size
     is small. (Aki Tanaka via jlowe)
     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
 Release 2.7.5 - 2017-12-14
 
 
   INCOMPATIBLE CHANGES
   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_KEY = LDAP_CONFIG_PREFIX + ".search.attr.group.name";
   public static final String GROUP_NAME_ATTR_DEFAULT = "cn";
   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
    * 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_GROUP = "posixGroup";
   public static final String POSIX_ACCOUNT = "posixAccount";
   public static final String POSIX_ACCOUNT = "posixAccount";
 
 
@@ -184,6 +191,8 @@ public class LdapGroupsMapping
   private String userSearchFilter;
   private String userSearchFilter;
   private String groupMemberAttr;
   private String groupMemberAttr;
   private String groupNameAttr;
   private String groupNameAttr;
+  private String posixUidAttr;
+  private String posixGidAttr;
   private boolean isPosix;
   private boolean isPosix;
 
 
   public static final int RECONNECT_RETRY_COUNT = 3;
   public static final int RECONNECT_RETRY_COUNT = 3;
@@ -240,8 +249,8 @@ public class LdapGroupsMapping
       if (isPosix) {
       if (isPosix) {
         String gidNumber = null;
         String gidNumber = null;
         String uidNumber = 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) {
         if (gidAttribute != null) {
           gidNumber = gidAttribute.get().toString();
           gidNumber = gidAttribute.get().toString();
         }
         }
@@ -251,7 +260,7 @@ public class LdapGroupsMapping
         if (uidNumber != null && gidNumber != null) {
         if (uidNumber != null && gidNumber != null) {
           groupResults =
           groupResults =
               ctx.search(baseDN,
               ctx.search(baseDN,
-                  "(&"+ groupSearchFilter + "(|(" + POSIX_GIDNUMBER + "={0})" +
+                  "(&"+ groupSearchFilter + "(|(" + posixGidAttr + "={0})" +
                       "(" + groupMemberAttr + "={1})))",
                       "(" + groupMemberAttr + "={1})))",
                   new Object[] { gidNumber, uidNumber },
                   new Object[] { gidNumber, uidNumber },
                   SEARCH_CONTROLS);
                   SEARCH_CONTROLS);
@@ -361,11 +370,17 @@ public class LdapGroupsMapping
         conf.get(GROUP_MEMBERSHIP_ATTR_KEY, GROUP_MEMBERSHIP_ATTR_DEFAULT);
         conf.get(GROUP_MEMBERSHIP_ATTR_KEY, GROUP_MEMBERSHIP_ATTR_DEFAULT);
     groupNameAttr =
     groupNameAttr =
         conf.get(GROUP_NAME_ATTR_KEY, GROUP_NAME_ATTR_DEFAULT);
         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);
     int dirSearchTimeout = conf.getInt(DIRECTORY_SEARCH_TIMEOUT, DIRECTORY_SEARCH_TIMEOUT_DEFAULT);
     SEARCH_CONTROLS.setTimeLimit(dirSearchTimeout);
     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;
     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>
   </description>
 </property>
 </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>
 <property>
   <name>hadoop.security.group.mapping.ldap.directory.search.timeout</name>
   <name>hadoop.security.group.mapping.ldap.directory.search.timeout</name>
   <value>10000</value>
   <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);
     SearchResult mockUserResult = mock(SearchResult.class);
     when(mockUserNamingEnum.nextElement()).thenReturn(mockUserResult);
     when(mockUserNamingEnum.nextElement()).thenReturn(mockUserResult);
 
 
+    Attribute mockUidNumberAttr = mock(Attribute.class);
+    Attribute mockGidNumberAttr = mock(Attribute.class);
     Attribute mockUidAttr = mock(Attribute.class);
     Attribute mockUidAttr = mock(Attribute.class);
-    Attribute mockGidAttr = mock(Attribute.class);
     Attributes mockAttrs = mock(Attributes.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);
     when(mockUserResult.getAttributes()).thenReturn(mockAttrs);
   }
   }
@@ -85,6 +88,8 @@ public class TestLdapGroupsMappingWithPosixGroup
     conf.set(LdapGroupsMapping.USER_SEARCH_FILTER_KEY,
     conf.set(LdapGroupsMapping.USER_SEARCH_FILTER_KEY,
         "(objectClass=posixAccount)");
         "(objectClass=posixAccount)");
     conf.set(LdapGroupsMapping.GROUP_MEMBERSHIP_ATTR_KEY, "memberUid");
     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");
     conf.set(LdapGroupsMapping.GROUP_NAME_ATTR_KEY, "cn");
 
 
     mappingSpy.setConf(conf);
     mappingSpy.setConf(conf);
@@ -94,10 +99,14 @@ public class TestLdapGroupsMappingWithPosixGroup
 
 
     Assert.assertEquals(expectedGroups, groups);
     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
     // We should have searched for a user, and then two groups
     verify(mockContext, times(searchTimes)).search(anyString(),
     verify(mockContext, times(searchTimes)).search(anyString(),
-                                         anyString(),
-                                         any(Object[].class),
-                                         any(SearchControls.class));
+        anyString(),
+        any(Object[].class),
+        any(SearchControls.class));
   }
   }
 }
 }