[LDAP] Support explicit "dn" attribute in group search (elastic/x-pack-elasticsearch#1995)

The default for group_search.attribute is to search by DN, but explicitly setting that to dn
wouldn't work because the DN is returned in a special value in the result, and not in the attributes list.

This change detects when user_attribute is set to dn and treats it the same way as the default value.

Original commit: elastic/x-pack-elasticsearch@1933410a0b
This commit is contained in:
Tim Vernum 2017-07-14 13:12:28 +10:00 committed by GitHub
parent 44a104cb26
commit d57e38fbed
2 changed files with 60 additions and 7 deletions

View File

@ -110,7 +110,7 @@ class SearchGroupsResolver implements GroupsResolver {
private void getUserId(String dn, Collection<Attribute> attributes, LDAPInterface connection,
TimeValue timeout, ActionListener<String> listener) {
if (isNullOrEmpty(userAttribute)) {
if (isNullOrEmpty(userAttribute) || userAttribute.equals("dn")) {
listener.onResponse(dn);
} else if (attributes != null) {
final String value = attributes.stream()

View File

@ -21,11 +21,14 @@ import org.elasticsearch.xpack.security.authc.ldap.support.LdapTestCase;
import org.elasticsearch.xpack.security.authc.ldap.support.LdapUtils;
import org.junit.After;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.iterableWithSize;
public class SearchGroupsResolverInMemoryTests extends LdapTestCase {
private static final String WILLIAM_BUSH = "cn=William Bush,ou=people,o=sevenSeas";
private LDAPConnection connection;
@After
@ -53,11 +56,7 @@ public class SearchGroupsResolverInMemoryTests extends LdapTestCase {
.build();
final SearchGroupsResolver resolver = new SearchGroupsResolver(settings);
final PlainActionFuture<List<String>> future = new PlainActionFuture<>();
resolver.resolve(connection,
"cn=William Bush,ou=people,o=sevenSeas",
TimeValue.timeValueSeconds(30),
logger,
null, future);
resolver.resolve(connection, WILLIAM_BUSH, TimeValue.timeValueSeconds(30), logger, null, future);
final ExecutionException exception = expectThrows(ExecutionException.class, future::get);
final Throwable cause = exception.getCause();
@ -65,6 +64,53 @@ public class SearchGroupsResolverInMemoryTests extends LdapTestCase {
assertThat(((LDAPException) cause).getResultCode(), is(ResultCode.TIMEOUT));
}
/**
* Tests searching for groups when the "user_attribute" field is not set
*/
public void testResolveWithDefaultUserAttribute() throws Exception {
connect(new LDAPConnectionOptions());
Settings settings = Settings.builder()
.put("group_search.base_dn", "ou=groups,o=sevenSeas")
.put("group_search.scope", LdapSearchScope.SUB_TREE)
.build();
final List<String> groups = resolveGroups(settings, WILLIAM_BUSH);
assertThat(groups, iterableWithSize(1));
assertThat(groups.get(0), containsString("HMS Lydia"));
}
/**
* Tests searching for groups when the "user_attribute" field is set to "dn" (which is special)
*/
public void testResolveWithExplicitDnAttribute() throws Exception {
connect(new LDAPConnectionOptions());
Settings settings = Settings.builder()
.put("group_search.base_dn", "ou=groups,o=sevenSeas")
.put("group_search.user_attribute", "dn")
.build();
final List<String> groups = resolveGroups(settings, WILLIAM_BUSH);
assertThat(groups, iterableWithSize(1));
assertThat(groups.get(0), containsString("HMS Lydia"));
}
/**
* Tests searching for groups when the "user_attribute" field is set to a missing value
*/
public void testResolveWithMissingAttribute() throws Exception {
connect(new LDAPConnectionOptions());
Settings settings = Settings.builder()
.put("group_search.base_dn", "ou=groups,o=sevenSeas")
.put("group_search.user_attribute", "no-such-attribute")
.build();
final List<String> groups = resolveGroups(settings, WILLIAM_BUSH);
assertThat(groups, iterableWithSize(0));
}
private void connect(LDAPConnectionOptions options) throws LDAPException {
if (connection != null) {
throw new IllegalStateException("Already connected (" + connection.getConnectionName() + ' '
@ -74,4 +120,11 @@ public class SearchGroupsResolverInMemoryTests extends LdapTestCase {
this.connection = LdapUtils.privilegedConnect(() -> new LDAPConnection(options, ldapurl.getHost(), ldapurl.getPort()));
}
}
private List<String> resolveGroups(Settings settings, String userDn) {
final SearchGroupsResolver resolver = new SearchGroupsResolver(settings);
final PlainActionFuture<List<String>> future = new PlainActionFuture<>();
resolver.resolve(connection, userDn, TimeValue.timeValueSeconds(30), logger, null, future);
return future.actionGet();
}
}