Skip to content

Commit a5d5234

Browse files
authored
Fix building AD URL from domain name (#31849)
The steps to read the settings and build URLs happen in a non-obvious order, which meant that we would build the default URL (from the domain name, and port) before we'd actually read the port settings. This would cause the URL to always have a port of `0`. Relates: bccf988
1 parent dd21ad0 commit a5d5234

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ldap/ActiveDirectorySessionFactory.java

+8-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.unboundid.ldap.sdk.LDAPException;
1212
import com.unboundid.ldap.sdk.LDAPInterface;
1313
import com.unboundid.ldap.sdk.SearchResultEntry;
14+
import com.unboundid.ldap.sdk.ServerSet;
1415
import com.unboundid.ldap.sdk.SimpleBindRequest;
1516
import com.unboundid.ldap.sdk.controls.AuthorizationIdentityRequestControl;
1617
import org.apache.logging.log4j.Logger;
@@ -62,8 +63,6 @@ class ActiveDirectorySessionFactory extends PoolingSessionFactory {
6263
final DownLevelADAuthenticator downLevelADAuthenticator;
6364
final UpnADAuthenticator upnADAuthenticator;
6465

65-
private final int ldapPort;
66-
6766
ActiveDirectorySessionFactory(RealmConfig config, SSLService sslService, ThreadPool threadPool) throws LDAPException {
6867
super(config, sslService, new ActiveDirectoryGroupsResolver(config.settings()),
6968
ActiveDirectorySessionFactorySettings.POOL_ENABLED,
@@ -85,7 +84,7 @@ class ActiveDirectorySessionFactory extends PoolingSessionFactory {
8584
+ "] setting for active directory");
8685
}
8786
String domainDN = buildDnFromDomain(domainName);
88-
ldapPort = ActiveDirectorySessionFactorySettings.AD_LDAP_PORT_SETTING.get(settings);
87+
final int ldapPort = ActiveDirectorySessionFactorySettings.AD_LDAP_PORT_SETTING.get(settings);
8988
final int ldapsPort = ActiveDirectorySessionFactorySettings.AD_LDAPS_PORT_SETTING.get(settings);
9089
final int gcLdapPort = ActiveDirectorySessionFactorySettings.AD_GC_LDAP_PORT_SETTING.get(settings);
9190
final int gcLdapsPort = ActiveDirectorySessionFactorySettings.AD_GC_LDAPS_PORT_SETTING.get(settings);
@@ -102,7 +101,7 @@ class ActiveDirectorySessionFactory extends PoolingSessionFactory {
102101
@Override
103102
protected List<String> getDefaultLdapUrls(Settings settings) {
104103
return Collections.singletonList("ldap://" + settings.get(ActiveDirectorySessionFactorySettings.AD_DOMAIN_NAME_SETTING) +
105-
":" + ldapPort);
104+
":" + ActiveDirectorySessionFactorySettings.AD_LDAP_PORT_SETTING.get(settings));
106105
}
107106

108107
@Override
@@ -197,6 +196,11 @@ static String getBindDN(Settings settings) {
197196
return bindDN;
198197
}
199198

199+
// Exposed for testing
200+
ServerSet getServerSet() {
201+
return super.serverSet;
202+
}
203+
200204
ADAuthenticator getADAuthenticator(String username) {
201205
if (username.indexOf('\\') > 0) {
202206
return downLevelADAuthenticator;

x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ldap/ActiveDirectoryRealmTests.java

+47
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
import com.unboundid.ldap.listener.InMemoryDirectoryServer;
99
import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig;
1010
import com.unboundid.ldap.sdk.Attribute;
11+
import com.unboundid.ldap.sdk.FailoverServerSet;
1112
import com.unboundid.ldap.sdk.LDAPException;
1213
import com.unboundid.ldap.sdk.LDAPURL;
14+
import com.unboundid.ldap.sdk.SingleServerSet;
1315
import com.unboundid.ldap.sdk.schema.Schema;
1416
import org.elasticsearch.action.ActionListener;
1517
import org.elasticsearch.action.support.PlainActionFuture;
@@ -28,6 +30,7 @@
2830
import org.elasticsearch.xpack.core.security.authc.ldap.ActiveDirectorySessionFactorySettings;
2931
import org.elasticsearch.xpack.core.security.authc.ldap.LdapRealmSettings;
3032
import org.elasticsearch.xpack.core.security.authc.ldap.PoolingSessionFactorySettings;
33+
import org.elasticsearch.xpack.core.security.authc.ldap.support.SessionFactorySettings;
3134
import org.elasticsearch.xpack.core.security.authc.support.CachingUsernamePasswordRealmSettings;
3235
import org.elasticsearch.xpack.core.security.authc.support.DnRoleMapperSettings;
3336
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
@@ -51,9 +54,11 @@
5154
import static org.elasticsearch.xpack.core.security.authc.ldap.support.SessionFactorySettings.URLS_SETTING;
5255
import static org.hamcrest.Matchers.arrayContaining;
5356
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
57+
import static org.hamcrest.Matchers.arrayWithSize;
5458
import static org.hamcrest.Matchers.containsString;
5559
import static org.hamcrest.Matchers.equalTo;
5660
import static org.hamcrest.Matchers.hasEntry;
61+
import static org.hamcrest.Matchers.instanceOf;
5762
import static org.hamcrest.Matchers.is;
5863
import static org.hamcrest.Matchers.notNullValue;
5964
import static org.mockito.Matchers.any;
@@ -355,6 +360,48 @@ public void testCustomSearchFilters() throws Exception {
355360
assertEquals("(objectClass=down level)", sessionFactory.downLevelADAuthenticator.getUserSearchFilter());
356361
}
357362

363+
public void testBuildUrlFromDomainNameAndDefaultPort() throws Exception {
364+
Settings settings = Settings.builder()
365+
.put(ActiveDirectorySessionFactorySettings.AD_DOMAIN_NAME_SETTING, "ad.test.elasticsearch.com")
366+
.build();
367+
RealmConfig config = new RealmConfig("testBuildUrlFromDomainNameAndDefaultPort", settings, globalSettings,
368+
TestEnvironment.newEnvironment(globalSettings), new ThreadContext(globalSettings));
369+
ActiveDirectorySessionFactory sessionFactory = new ActiveDirectorySessionFactory(config, sslService, threadPool);
370+
assertSingleLdapServer(sessionFactory, "ad.test.elasticsearch.com", 389);
371+
}
372+
373+
public void testBuildUrlFromDomainNameAndCustomPort() throws Exception {
374+
Settings settings = Settings.builder()
375+
.put(ActiveDirectorySessionFactorySettings.AD_DOMAIN_NAME_SETTING, "ad.test.elasticsearch.com")
376+
.put(ActiveDirectorySessionFactorySettings.AD_LDAP_PORT_SETTING.getKey(), 10389)
377+
.build();
378+
RealmConfig config = new RealmConfig("testBuildUrlFromDomainNameAndCustomPort", settings, globalSettings,
379+
TestEnvironment.newEnvironment(globalSettings), new ThreadContext(globalSettings));
380+
ActiveDirectorySessionFactory sessionFactory = new ActiveDirectorySessionFactory(config, sslService, threadPool);
381+
assertSingleLdapServer(sessionFactory, "ad.test.elasticsearch.com", 10389);
382+
}
383+
384+
public void testUrlConfiguredInSettings() throws Exception {
385+
Settings settings = Settings.builder()
386+
.put(ActiveDirectorySessionFactorySettings.AD_DOMAIN_NAME_SETTING, "ad.test.elasticsearch.com")
387+
.put(SessionFactorySettings.URLS_SETTING, "ldap://ad01.testing.elastic.co:20389/")
388+
.build();
389+
RealmConfig config = new RealmConfig("testBuildUrlFromDomainNameAndCustomPort", settings, globalSettings,
390+
TestEnvironment.newEnvironment(globalSettings), new ThreadContext(globalSettings));
391+
ActiveDirectorySessionFactory sessionFactory = new ActiveDirectorySessionFactory(config, sslService, threadPool);
392+
assertSingleLdapServer(sessionFactory, "ad01.testing.elastic.co", 20389);
393+
}
394+
395+
private void assertSingleLdapServer(ActiveDirectorySessionFactory sessionFactory, String hostname, int port) {
396+
assertThat(sessionFactory.getServerSet(), instanceOf(FailoverServerSet.class));
397+
FailoverServerSet fss = (FailoverServerSet) sessionFactory.getServerSet();
398+
assertThat(fss.getServerSets(), arrayWithSize(1));
399+
assertThat(fss.getServerSets()[0], instanceOf(SingleServerSet.class));
400+
SingleServerSet sss = (SingleServerSet) fss.getServerSets()[0];
401+
assertThat(sss.getAddress(), equalTo(hostname));
402+
assertThat(sss.getPort(), equalTo(port));
403+
}
404+
358405
private Settings settings() throws Exception {
359406
return settings(Settings.EMPTY);
360407
}

0 commit comments

Comments
 (0)