[ldap] group search base_dn should not be null

JNDI will throw a NullPointerException when base_dn is not specified.
This should always be a non-null value that points to at least the base
of the directory or higher.

Closes elastic/elasticsearch#703

Original commit: elastic/x-pack-elasticsearch@825afcdd78
This commit is contained in:
jaymode 2015-02-10 11:28:13 -05:00
parent e7f141bd5c
commit 6a8d971df1
2 changed files with 36 additions and 6 deletions

View File

@ -9,6 +9,7 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.shield.ShieldSettingsException;
import org.elasticsearch.shield.authc.support.ldap.AbstractLdapConnection; import org.elasticsearch.shield.authc.support.ldap.AbstractLdapConnection;
import org.elasticsearch.shield.authc.support.ldap.ClosableNamingEnumeration; import org.elasticsearch.shield.authc.support.ldap.ClosableNamingEnumeration;
import org.elasticsearch.shield.authc.support.ldap.SearchScope; import org.elasticsearch.shield.authc.support.ldap.SearchScope;
@ -34,6 +35,9 @@ class SearchGroupsResolver implements AbstractLdapConnection.GroupsResolver {
public SearchGroupsResolver(Settings settings) { public SearchGroupsResolver(Settings settings) {
baseDn = settings.get("base_dn"); baseDn = settings.get("base_dn");
if (baseDn == null) {
throw new ShieldSettingsException("base_dn must be specified");
}
filter = settings.get("filter", GROUP_SEARCH_DEFAULT_FILTER); filter = settings.get("filter", GROUP_SEARCH_DEFAULT_FILTER);
userAttribute = filter == null ? null : settings.get("user_attribute"); userAttribute = filter == null ? null : settings.get("user_attribute");
scope = SearchScope.resolve(settings.get("scope"), SearchScope.SUB_TREE); scope = SearchScope.resolve(settings.get("scope"), SearchScope.SUB_TREE);

View File

@ -8,6 +8,7 @@ package org.elasticsearch.shield.authc.ldap;
import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.shield.ShieldSettingsException;
import org.elasticsearch.shield.authc.support.ldap.AbstractLdapSslSocketFactory; import org.elasticsearch.shield.authc.support.ldap.AbstractLdapSslSocketFactory;
import org.elasticsearch.shield.authc.support.ldap.ConnectionFactory; import org.elasticsearch.shield.authc.support.ldap.ConnectionFactory;
import org.elasticsearch.shield.authc.support.ldap.LdapSslSocketFactory; import org.elasticsearch.shield.authc.support.ldap.LdapSslSocketFactory;
@ -31,7 +32,7 @@ import java.util.List;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.*;
@Network @Network
public class SearchGroupsResolverTest extends ElasticsearchTestCase { public class SearchGroupsResolverTests extends ElasticsearchTestCase {
public static final String BRUCE_BANNER_DN = "uid=hulk,ou=people,dc=oldap,dc=test,dc=elasticsearch,dc=com"; public static final String BRUCE_BANNER_DN = "uid=hulk,ou=people,dc=oldap,dc=test,dc=elasticsearch,dc=com";
private InitialDirContext ldapContext; private InitialDirContext ldapContext;
@ -39,7 +40,7 @@ public class SearchGroupsResolverTest extends ElasticsearchTestCase {
@Before @Before
public void setup() throws Exception { public void setup() throws Exception {
super.setUp(); super.setUp();
Path keystore = Paths.get(SearchGroupsResolverTest.class.getResource("../support/ldap/ldaptrust.jks").toURI()).toAbsolutePath(); Path keystore = Paths.get(SearchGroupsResolverTests.class.getResource("../support/ldap/ldaptrust.jks").toURI()).toAbsolutePath();
/* /*
* Prior to each test we reinitialize the socket factory with a new SSLService so that we get a new SSLContext. * Prior to each test we reinitialize the socket factory with a new SSLService so that we get a new SSLContext.
@ -127,22 +128,44 @@ public class SearchGroupsResolverTest extends ElasticsearchTestCase {
assertThat(groups, hasItem(containsString("Geniuses"))); assertThat(groups, hasItem(containsString("Geniuses")));
} }
@Test
public void testSearchWithoutSpecifyingBaseDN() throws Exception {
Settings settings = ImmutableSettings.builder()
.put("scope", SearchScope.SUB_TREE)
.build();
try {
new SearchGroupsResolver(settings);
} catch (ShieldSettingsException e) {
assertThat(e.getMessage(), containsString("base_dn must be specified"));
}
}
@Test @Test
public void testReadUserAttribute() throws Exception { public void testReadUserAttribute() throws Exception {
{ {
Settings settings = ImmutableSettings.builder().put("user_attribute", "uid").build(); Settings settings = ImmutableSettings.builder()
.put("base_dn", "dc=oldap,dc=test,dc=elasticsearch,dc=com")
.put("user_attribute", "uid")
.build();
SearchGroupsResolver resolver = new SearchGroupsResolver(settings); SearchGroupsResolver resolver = new SearchGroupsResolver(settings);
assertThat(resolver.readUserAttribute(ldapContext, BRUCE_BANNER_DN), is("hulk")); assertThat(resolver.readUserAttribute(ldapContext, BRUCE_BANNER_DN), is("hulk"));
} }
{ {
Settings settings = ImmutableSettings.builder().put("user_attribute", "cn").build(); Settings settings = ImmutableSettings.builder()
.put("base_dn", "dc=oldap,dc=test,dc=elasticsearch,dc=com")
.put("user_attribute", "cn")
.build();
SearchGroupsResolver resolver = new SearchGroupsResolver(settings); SearchGroupsResolver resolver = new SearchGroupsResolver(settings);
assertThat(resolver.readUserAttribute(ldapContext, BRUCE_BANNER_DN), is("Bruce Banner")); assertThat(resolver.readUserAttribute(ldapContext, BRUCE_BANNER_DN), is("Bruce Banner"));
} }
try { try {
Settings settings = ImmutableSettings.builder().put("user_attribute", "doesntExists").build(); Settings settings = ImmutableSettings.builder()
.put("base_dn", "dc=oldap,dc=test,dc=elasticsearch,dc=com")
.put("user_attribute", "doesntExists")
.build();
SearchGroupsResolver resolver = new SearchGroupsResolver(settings); SearchGroupsResolver resolver = new SearchGroupsResolver(settings);
resolver.readUserAttribute(ldapContext, BRUCE_BANNER_DN); resolver.readUserAttribute(ldapContext, BRUCE_BANNER_DN);
fail("searching for a non-existing attribute should throw an LdapException"); fail("searching for a non-existing attribute should throw an LdapException");
@ -151,7 +174,10 @@ public class SearchGroupsResolverTest extends ElasticsearchTestCase {
} }
try { try {
Settings settings = ImmutableSettings.builder().put("user_attribute", "userPassword").build(); Settings settings = ImmutableSettings.builder()
.put("base_dn", "dc=oldap,dc=test,dc=elasticsearch,dc=com")
.put("user_attribute", "userPassword")
.build();
SearchGroupsResolver resolver = new SearchGroupsResolver(settings); SearchGroupsResolver resolver = new SearchGroupsResolver(settings);
resolver.readUserAttribute(ldapContext, BRUCE_BANNER_DN); resolver.readUserAttribute(ldapContext, BRUCE_BANNER_DN);
fail("searching for a binary attribute should throw an LdapException"); fail("searching for a binary attribute should throw an LdapException");