From 98cdc150382828147efa7ddf00283db9911cf385 Mon Sep 17 00:00:00 2001 From: Tim Vernum Date: Tue, 6 Jun 2017 14:07:07 +1000 Subject: [PATCH] [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@b2c7703fb03d1d4725c13c0714d51796c68bb4b2 --- .../ldap/LdapUserSearchSessionFactory.java | 9 ++--- .../LdapUserSearchSessionFactoryTests.java | 33 +++++++++++++++++-- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/plugin/src/main/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactory.java b/plugin/src/main/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactory.java index a1d50a18aee..3290189430d 100644 --- a/plugin/src/main/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactory.java +++ b/plugin/src/main/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactory.java @@ -146,11 +146,11 @@ class LdapUserSearchSessionFactory extends SessionFactory { } static SimpleBindRequest bindRequest(Settings settings) { - SimpleBindRequest request = null; 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) { @@ -206,7 +206,8 @@ class LdapUserSearchSessionFactory extends SessionFactory { LDAPConnection connection = null; try { connection = LdapUtils.privilegedConnect(serverSet::getConnection); - connection.bind(bindRequest(config.settings())); + final SimpleBindRequest bind = bindRequest(config.settings()); + connection.bind(bind); final LDAPConnection finalConnection = connection; 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 diff --git a/plugin/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactoryTests.java b/plugin/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactoryTests.java index d37ba555d3f..a4e60c5fed4 100644 --- a/plugin/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactoryTests.java +++ b/plugin/src/test/java/org/elasticsearch/xpack/security/authc/ldap/LdapUserSearchSessionFactoryTests.java @@ -13,6 +13,7 @@ import com.unboundid.ldap.sdk.LDAPConnectionPoolHealthCheck; import com.unboundid.ldap.sdk.LDAPURL; import com.unboundid.ldap.sdk.SimpleBindRequest; import com.unboundid.ldap.sdk.SingleServerSet; +import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.SecureString; 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.hasItem; import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; public class LdapUserSearchSessionFactoryTests extends LdapTestCase { @@ -468,9 +471,33 @@ public class LdapUserSearchSessionFactoryTests extends LdapTestCase { } } - public void testEmptyBindDNReturnsNullBindRequest() { - BindRequest request = LdapUserSearchSessionFactory.bindRequest(Settings.builder().put("bind_password", "password").build()); - assertThat(request, is(nullValue())); + public void testThatEmptyBindDNAndDisabledPoolingDoesNotThrow() throws Exception { + String groupSearchBase = "o=sevenSeas"; + 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 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() {