-
Notifications
You must be signed in to change notification settings - Fork 9.2k
HADOOP-18074 - Partial/Incomplete groups list can be returned in LDAP… #4503
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
918b3c8
b29ff8a
44e0fef
f6415f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,10 +20,12 @@ | |
|
|
||
| import java.util.Arrays; | ||
| import java.util.List; | ||
| import java.util.Set; | ||
|
|
||
| import javax.naming.NamingEnumeration; | ||
| import javax.naming.NamingException; | ||
| import javax.naming.directory.Attribute; | ||
| import javax.naming.directory.DirContext; | ||
| import javax.naming.directory.SearchControls; | ||
| import javax.naming.directory.SearchResult; | ||
|
|
||
|
|
@@ -72,6 +74,9 @@ public void testGetGroups() throws NamingException { | |
| // properties, return an array of strings representing its groups. | ||
| String[] testGroups = new String[] {"abc", "xyz", "sss"}; | ||
| doTestGetGroups(Arrays.asList(testGroups)); | ||
|
|
||
| // test fallback triggered by NamingException | ||
| doTestGetGroupsWithFallback(); | ||
| } | ||
|
|
||
| private void doTestGetGroups(List<String> expectedGroups) | ||
|
|
@@ -81,16 +86,72 @@ private void doTestGetGroups(List<String> expectedGroups) | |
| // enable single-query lookup | ||
| conf.set(LdapGroupsMapping.MEMBEROF_ATTR_KEY, "memberOf"); | ||
|
|
||
| LdapGroupsMapping groupsMapping = getGroupsMapping(); | ||
| TestLdapGroupsMapping groupsMapping = new TestLdapGroupsMapping(); | ||
| groupsMapping.setConf(conf); | ||
| // Username is arbitrary, since the spy is mocked to respond the same, | ||
| // regardless of input | ||
| List<String> groups = groupsMapping.getGroups("some_user"); | ||
|
|
||
| Assert.assertEquals(expectedGroups, groups); | ||
| Assert.assertFalse(groupsMapping.isSecondaryQueryCalled()); | ||
|
||
|
|
||
| // We should have only made one query because single-query lookup is enabled | ||
| verify(getContext(), times(1)).search(anyString(), anyString(), | ||
| any(Object[].class), any(SearchControls.class)); | ||
| } | ||
| } | ||
|
|
||
| private void doTestGetGroupsWithFallback() | ||
steveloughran marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| throws NamingException { | ||
| Attribute groupDN = mock(Attribute.class); | ||
|
|
||
| NamingEnumeration<SearchResult> groupNames = getGroupNames(); | ||
| doReturn(groupNames).when(groupDN).getAll(); | ||
| String groupName1 = "CN=abc,DC=foo,DC=bar,DC=com"; | ||
| String groupName2 = "CN=xyz,DC=foo,DC=bar,DC=com"; | ||
| String groupName3 = "ipaUniqueID=e4a9a634-bb24-11ec-aec1-06ede52b5fe1," + | ||
| "CN=sudo,DC=foo,DC=bar,DC=com"; | ||
| doReturn(groupName1).doReturn(groupName2).doReturn(groupName3). | ||
| when(groupNames).next(); | ||
| when(groupNames.hasMore()).thenReturn(true).thenReturn(true). | ||
| thenReturn(true).thenReturn(false); | ||
|
|
||
| when(getAttributes().get(eq("memberOf"))).thenReturn(groupDN); | ||
|
|
||
| String ldapUrl = "ldap://test"; | ||
| Configuration conf = getBaseConf(ldapUrl); | ||
| // enable single-query lookup | ||
| conf.set(LdapGroupsMapping.MEMBEROF_ATTR_KEY, "memberOf"); | ||
| conf.set(LdapGroupsMapping.LDAP_NUM_ATTEMPTS_KEY, "1"); | ||
|
|
||
| TestLdapGroupsMapping groupsMapping = new TestLdapGroupsMapping(); | ||
| groupsMapping.setConf(conf); | ||
| // Username is arbitrary, since the spy is mocked to respond the same, | ||
| // regardless of input | ||
| List<String> groups = groupsMapping.getGroups("some_user"); | ||
|
|
||
| // expected to be empty due to invalid memberOf | ||
| Assert.assertEquals(0, groups.size()); | ||
|
|
||
| // expect secondary query to be called: getGroups() | ||
| Assert.assertTrue(groupsMapping.isSecondaryQueryCalled()); | ||
|
||
|
|
||
| // We should have fallen back to the second query because first threw | ||
| // NamingException expected count is 3 since testGetGroups calls | ||
| // doTestGetGroups and doTestGetGroupsWithFallback in succession and | ||
| // the count is across both test scenarios. | ||
| verify(getContext(), times(3)).search(anyString(), anyString(), | ||
| any(Object[].class), any(SearchControls.class)); | ||
| } | ||
|
|
||
| class TestLdapGroupsMapping extends LdapGroupsMapping { | ||
|
||
| private boolean secondaryQueryCalled = false; | ||
| public boolean isSecondaryQueryCalled() { | ||
| return secondaryQueryCalled; | ||
| } | ||
| Set<String> lookupGroup(SearchResult result, DirContext c, | ||
| int goUpHierarchy) throws NamingException { | ||
| secondaryQueryCalled = true; | ||
| return super.lookupGroup(result, c, goUpHierarchy); | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.