[Security] Support anon-bind without pooling (elastic/x-pack-elasticsearch#1491)

Make LDAP User-Search work with anonymous bind (bind_dn not set) and connection pooling disabled.

Original commit: elastic/x-pack-elasticsearch@b2c7703fb0
This commit is contained in:
Tim Vernum 2017-06-06 14:07:07 +10:00 committed by GitHub
parent 2fd3526203
commit 98cdc15038
2 changed files with 35 additions and 7 deletions

View File

@ -146,11 +146,11 @@ class LdapUserSearchSessionFactory extends SessionFactory {
} }
static SimpleBindRequest bindRequest(Settings settings) { static SimpleBindRequest bindRequest(Settings settings) {
SimpleBindRequest request = null;
if (BIND_DN.exists(settings)) { if (BIND_DN.exists(settings)) {
request = new SimpleBindRequest(BIND_DN.get(settings), BIND_PASSWORD.get(settings)); return new SimpleBindRequest(BIND_DN.get(settings), BIND_PASSWORD.get(settings));
} else {
return new SimpleBindRequest();
} }
return request;
} }
public static boolean hasUserSearchSettings(RealmConfig config) { public static boolean hasUserSearchSettings(RealmConfig config) {
@ -206,7 +206,8 @@ class LdapUserSearchSessionFactory extends SessionFactory {
LDAPConnection connection = null; LDAPConnection connection = null;
try { try {
connection = LdapUtils.privilegedConnect(serverSet::getConnection); connection = LdapUtils.privilegedConnect(serverSet::getConnection);
connection.bind(bindRequest(config.settings())); final SimpleBindRequest bind = bindRequest(config.settings());
connection.bind(bind);
final LDAPConnection finalConnection = connection; final LDAPConnection finalConnection = connection;
findUser(user, connection, ActionListener.wrap((entry) -> { findUser(user, connection, ActionListener.wrap((entry) -> {
// close the existing connection since we are executing in this handler of the previous request and cannot bind here // close the existing connection since we are executing in this handler of the previous request and cannot bind here

View File

@ -13,6 +13,7 @@ import com.unboundid.ldap.sdk.LDAPConnectionPoolHealthCheck;
import com.unboundid.ldap.sdk.LDAPURL; import com.unboundid.ldap.sdk.LDAPURL;
import com.unboundid.ldap.sdk.SimpleBindRequest; import com.unboundid.ldap.sdk.SimpleBindRequest;
import com.unboundid.ldap.sdk.SingleServerSet; import com.unboundid.ldap.sdk.SingleServerSet;
import org.elasticsearch.action.support.PlainActionFuture;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.SecureString; import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
@ -39,6 +40,8 @@ import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isEmptyString;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.nullValue;
public class LdapUserSearchSessionFactoryTests extends LdapTestCase { public class LdapUserSearchSessionFactoryTests extends LdapTestCase {
@ -468,9 +471,33 @@ public class LdapUserSearchSessionFactoryTests extends LdapTestCase {
} }
} }
public void testEmptyBindDNReturnsNullBindRequest() { public void testThatEmptyBindDNAndDisabledPoolingDoesNotThrow() throws Exception {
BindRequest request = LdapUserSearchSessionFactory.bindRequest(Settings.builder().put("bind_password", "password").build()); String groupSearchBase = "o=sevenSeas";
assertThat(request, is(nullValue())); String userSearchBase = "o=sevenSeas";
RealmConfig config = new RealmConfig("ldap_realm", Settings.builder()
.put(buildLdapSettings(ldapUrls(), Strings.EMPTY_ARRAY, groupSearchBase, LdapSearchScope.SUB_TREE))
.put("user_search.base_dn", userSearchBase)
.put("user_search.pool.enabled", false)
.put("bind_password", "pass")
.build(), globalSettings, new Environment(globalSettings), new ThreadContext(globalSettings));
LdapUserSearchSessionFactory searchSessionFactory = null;
try {
searchSessionFactory = new LdapUserSearchSessionFactory(config, sslService);
final PlainActionFuture<LdapSession> future = new PlainActionFuture<>();
searchSessionFactory.session("cn=ironman", new SecureString("password".toCharArray()), future);
future.get();
} finally {
if (searchSessionFactory != null) {
searchSessionFactory.shutdown();
}
}
}
public void testEmptyBindDNReturnsAnonymousBindRequest() {
SimpleBindRequest request = LdapUserSearchSessionFactory.bindRequest(Settings.builder().put("bind_password", "password").build());
assertThat(request, is(notNullValue()));
assertThat(request.getBindDN(), isEmptyString());
} }
public void testThatBindRequestReturnsSimpleBindRequest() { public void testThatBindRequestReturnsSimpleBindRequest() {