Run active directory tests against a samba4 fixture (elastic/x-pack-elasticsearch#4067)
This commit adds a Samba4 test fixture that acts as a domain controller and has the same contents as the cloud active directory instance that we previously used for tests. The tests also support reading information from environment variables so that they can be run against a real active directory instance in our CI builds. In addition, this commit also fixes a few issues that surfaced when making this change. The first is a change in the base DN that is searched when performing down-level authentication. The base DN is now the configuration object instead of the domain DN. This change was required due to the original producing unnecessary referrals, which we cannot easily follow when running against this test figure. Referrals cannot easily be followed as they are returned by the ldap server with an unresolvable DNS name unless the host points to the samba4 instance for DNS. The port returned in the referral url is the one samba is bound to, which differs from the port that is forwarded to the host by the test fixture. The other issue that is resolved by this change is the addition of settings that allow specifying non-standard ports for active directory. This is needed for down-level authentication as we may need to query the regular port of active directory instead of the global catalog port as the configuration object is not replicated to the global catalog. relates elastic/x-pack-elasticsearch#185 Relates elastic/x-pack-elasticsearch#3800 Original commit: elastic/x-pack-elasticsearch@883c742fba
This commit is contained in:
parent
4c78ede9c1
commit
bccf988e9d
|
@ -20,6 +20,10 @@ public final class ActiveDirectorySessionFactorySettings {
|
||||||
public static final String AD_UPN_USER_SEARCH_FILTER_SETTING = "user_search.upn_filter";
|
public static final String AD_UPN_USER_SEARCH_FILTER_SETTING = "user_search.upn_filter";
|
||||||
public static final String AD_DOWN_LEVEL_USER_SEARCH_FILTER_SETTING = "user_search.down_level_filter";
|
public static final String AD_DOWN_LEVEL_USER_SEARCH_FILTER_SETTING = "user_search.down_level_filter";
|
||||||
public static final String AD_USER_SEARCH_SCOPE_SETTING = "user_search.scope";
|
public static final String AD_USER_SEARCH_SCOPE_SETTING = "user_search.scope";
|
||||||
|
public static final Setting<Integer> AD_LDAP_PORT_SETTING = Setting.intSetting("port.ldap", 389, Setting.Property.NodeScope);
|
||||||
|
public static final Setting<Integer> AD_LDAPS_PORT_SETTING = Setting.intSetting("port.ldaps", 636, Setting.Property.NodeScope);
|
||||||
|
public static final Setting<Integer> AD_GC_LDAP_PORT_SETTING = Setting.intSetting("port.gc_ldap", 3268, Setting.Property.NodeScope);
|
||||||
|
public static final Setting<Integer> AD_GC_LDAPS_PORT_SETTING = Setting.intSetting("port.gc_ldaps", 3269, Setting.Property.NodeScope);
|
||||||
public static final Setting<Boolean> POOL_ENABLED = Setting.boolSetting("user_search.pool.enabled",
|
public static final Setting<Boolean> POOL_ENABLED = Setting.boolSetting("user_search.pool.enabled",
|
||||||
settings -> Boolean.toString(PoolingSessionFactorySettings.BIND_DN.exists(settings)), Setting.Property.NodeScope);
|
settings -> Boolean.toString(PoolingSessionFactorySettings.BIND_DN.exists(settings)), Setting.Property.NodeScope);
|
||||||
|
|
||||||
|
@ -36,6 +40,10 @@ public final class ActiveDirectorySessionFactorySettings {
|
||||||
settings.add(Setting.simpleString(AD_UPN_USER_SEARCH_FILTER_SETTING, Setting.Property.NodeScope));
|
settings.add(Setting.simpleString(AD_UPN_USER_SEARCH_FILTER_SETTING, Setting.Property.NodeScope));
|
||||||
settings.add(Setting.simpleString(AD_DOWN_LEVEL_USER_SEARCH_FILTER_SETTING, Setting.Property.NodeScope));
|
settings.add(Setting.simpleString(AD_DOWN_LEVEL_USER_SEARCH_FILTER_SETTING, Setting.Property.NodeScope));
|
||||||
settings.add(Setting.simpleString(AD_USER_SEARCH_SCOPE_SETTING, Setting.Property.NodeScope));
|
settings.add(Setting.simpleString(AD_USER_SEARCH_SCOPE_SETTING, Setting.Property.NodeScope));
|
||||||
|
settings.add(AD_LDAP_PORT_SETTING);
|
||||||
|
settings.add(AD_LDAPS_PORT_SETTING);
|
||||||
|
settings.add(AD_GC_LDAP_PORT_SETTING);
|
||||||
|
settings.add(AD_GC_LDAPS_PORT_SETTING);
|
||||||
settings.add(POOL_ENABLED);
|
settings.add(POOL_ENABLED);
|
||||||
settings.addAll(PoolingSessionFactorySettings.getSettings());
|
settings.addAll(PoolingSessionFactorySettings.getSettings());
|
||||||
return settings;
|
return settings;
|
||||||
|
|
|
@ -128,7 +128,7 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
|
||||||
assertThat(aliases[0], is("key"));
|
assertThat(aliases[0], is("key"));
|
||||||
};
|
};
|
||||||
final BiConsumer<X509ExtendedTrustManager, SSLConfiguration> trustManagerPostChecks = (updatedTrustManager, config) -> {
|
final BiConsumer<X509ExtendedTrustManager, SSLConfiguration> trustManagerPostChecks = (updatedTrustManager, config) -> {
|
||||||
assertThat(trustedCount.get() - updatedTrustManager.getAcceptedIssuers().length, is(4));
|
assertThat(trustedCount.get() - updatedTrustManager.getAcceptedIssuers().length, is(5));
|
||||||
};
|
};
|
||||||
validateSSLConfigurationIsReloaded(settings, env, keyManagerPreChecks, trustManagerPreChecks, modifier, keyManagerPostChecks,
|
validateSSLConfigurationIsReloaded(settings, env, keyManagerPreChecks, trustManagerPreChecks, modifier, keyManagerPostChecks,
|
||||||
trustManagerPostChecks);
|
trustManagerPostChecks);
|
||||||
|
@ -244,7 +244,7 @@ public class SSLConfigurationReloaderTests extends ESTestCase {
|
||||||
};
|
};
|
||||||
|
|
||||||
final BiConsumer<X509ExtendedTrustManager, SSLConfiguration> trustManagerPostChecks = (updatedTrustManager, config) -> {
|
final BiConsumer<X509ExtendedTrustManager, SSLConfiguration> trustManagerPostChecks = (updatedTrustManager, config) -> {
|
||||||
assertThat(trustedCount.get() - updatedTrustManager.getAcceptedIssuers().length, is(5));
|
assertThat(trustedCount.get() - updatedTrustManager.getAcceptedIssuers().length, is(6));
|
||||||
};
|
};
|
||||||
|
|
||||||
validateTrustConfigurationIsReloaded(settings, env, trustManagerPreChecks, modifier, trustManagerPostChecks);
|
validateTrustConfigurationIsReloaded(settings, env, trustManagerPreChecks, modifier, trustManagerPostChecks);
|
||||||
|
|
|
@ -485,7 +485,7 @@ public class SSLServiceTests extends ESTestCase {
|
||||||
|
|
||||||
final SSLService sslService = new SSLService(settings, env);
|
final SSLService sslService = new SSLService(settings, env);
|
||||||
final List<CertificateInfo> certificates = new ArrayList<>(sslService.getLoadedCertificates());
|
final List<CertificateInfo> certificates = new ArrayList<>(sslService.getLoadedCertificates());
|
||||||
assertThat(certificates, iterableWithSize(7));
|
assertThat(certificates, iterableWithSize(8));
|
||||||
Collections.sort(certificates,
|
Collections.sort(certificates,
|
||||||
Comparator.comparing((CertificateInfo c) -> c.alias() == null ? "" : c.alias()).thenComparing(CertificateInfo::path));
|
Comparator.comparing((CertificateInfo c) -> c.alias() == null ? "" : c.alias()).thenComparing(CertificateInfo::path));
|
||||||
|
|
||||||
|
@ -508,6 +508,15 @@ public class SSLServiceTests extends ESTestCase {
|
||||||
assertThat(cert.expiry(), equalTo(DateTime.parse("2029-08-27T16:32:42Z")));
|
assertThat(cert.expiry(), equalTo(DateTime.parse("2029-08-27T16:32:42Z")));
|
||||||
assertThat(cert.hasPrivateKey(), equalTo(false));
|
assertThat(cert.hasPrivateKey(), equalTo(false));
|
||||||
|
|
||||||
|
cert = iterator.next();
|
||||||
|
assertThat(cert.alias(), equalTo("mykey"));
|
||||||
|
assertThat(cert.path(), equalTo(jksPath.toString()));
|
||||||
|
assertThat(cert.format(), equalTo("jks"));
|
||||||
|
assertThat(cert.serialNumber(), equalTo("3151a81eec8d4e34c56a8466a8510bcfbe63cc31"));
|
||||||
|
assertThat(cert.subjectDn(), equalTo("CN=samba4"));
|
||||||
|
assertThat(cert.expiry(), equalTo(DateTime.parse("2021-02-14T17:49:11.000Z")));
|
||||||
|
assertThat(cert.hasPrivateKey(), equalTo(false));
|
||||||
|
|
||||||
cert = iterator.next();
|
cert = iterator.next();
|
||||||
assertThat(cert.alias(), equalTo("openldap"));
|
assertThat(cert.alias(), equalTo("openldap"));
|
||||||
assertThat(cert.path(), equalTo(jksPath.toString()));
|
assertThat(cert.path(), equalTo(jksPath.toString()));
|
||||||
|
|
Binary file not shown.
|
@ -62,6 +62,8 @@ class ActiveDirectorySessionFactory extends PoolingSessionFactory {
|
||||||
final DownLevelADAuthenticator downLevelADAuthenticator;
|
final DownLevelADAuthenticator downLevelADAuthenticator;
|
||||||
final UpnADAuthenticator upnADAuthenticator;
|
final UpnADAuthenticator upnADAuthenticator;
|
||||||
|
|
||||||
|
private final int ldapPort;
|
||||||
|
|
||||||
ActiveDirectorySessionFactory(RealmConfig config, SSLService sslService, ThreadPool threadPool) throws LDAPException {
|
ActiveDirectorySessionFactory(RealmConfig config, SSLService sslService, ThreadPool threadPool) throws LDAPException {
|
||||||
super(config, sslService, new ActiveDirectoryGroupsResolver(config.settings()),
|
super(config, sslService, new ActiveDirectoryGroupsResolver(config.settings()),
|
||||||
ActiveDirectorySessionFactorySettings.POOL_ENABLED, () -> {
|
ActiveDirectorySessionFactorySettings.POOL_ENABLED, () -> {
|
||||||
|
@ -88,10 +90,15 @@ class ActiveDirectorySessionFactory extends PoolingSessionFactory {
|
||||||
+ "] setting for active directory");
|
+ "] setting for active directory");
|
||||||
}
|
}
|
||||||
String domainDN = buildDnFromDomain(domainName);
|
String domainDN = buildDnFromDomain(domainName);
|
||||||
|
ldapPort = ActiveDirectorySessionFactorySettings.AD_LDAP_PORT_SETTING.get(settings);
|
||||||
|
final int ldapsPort = ActiveDirectorySessionFactorySettings.AD_LDAPS_PORT_SETTING.get(settings);
|
||||||
|
final int gcLdapPort = ActiveDirectorySessionFactorySettings.AD_GC_LDAP_PORT_SETTING.get(settings);
|
||||||
|
final int gcLdapsPort = ActiveDirectorySessionFactorySettings.AD_GC_LDAPS_PORT_SETTING.get(settings);
|
||||||
|
|
||||||
defaultADAuthenticator = new DefaultADAuthenticator(config, timeout, ignoreReferralErrors, logger, groupResolver,
|
defaultADAuthenticator = new DefaultADAuthenticator(config, timeout, ignoreReferralErrors, logger, groupResolver,
|
||||||
metaDataResolver, domainDN, threadPool);
|
metaDataResolver, domainDN, threadPool);
|
||||||
downLevelADAuthenticator = new DownLevelADAuthenticator(config, timeout, ignoreReferralErrors, logger, groupResolver,
|
downLevelADAuthenticator = new DownLevelADAuthenticator(config, timeout, ignoreReferralErrors, logger, groupResolver,
|
||||||
metaDataResolver, domainDN, sslService, threadPool);
|
metaDataResolver, domainDN, sslService, threadPool, ldapPort, ldapsPort, gcLdapPort, gcLdapsPort);
|
||||||
upnADAuthenticator = new UpnADAuthenticator(config, timeout, ignoreReferralErrors, logger, groupResolver,
|
upnADAuthenticator = new UpnADAuthenticator(config, timeout, ignoreReferralErrors, logger, groupResolver,
|
||||||
metaDataResolver, domainDN, threadPool);
|
metaDataResolver, domainDN, threadPool);
|
||||||
|
|
||||||
|
@ -99,7 +106,8 @@ class ActiveDirectorySessionFactory extends PoolingSessionFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<String> getDefaultLdapUrls(Settings settings) {
|
protected List<String> getDefaultLdapUrls(Settings settings) {
|
||||||
return Collections.singletonList("ldap://" + settings.get(ActiveDirectorySessionFactorySettings.AD_DOMAIN_NAME_SETTING) + ":389");
|
return Collections.singletonList("ldap://" + settings.get(ActiveDirectorySessionFactorySettings.AD_DOMAIN_NAME_SETTING) +
|
||||||
|
":" + ldapPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -361,16 +369,24 @@ class ActiveDirectorySessionFactory extends PoolingSessionFactory {
|
||||||
final Settings settings;
|
final Settings settings;
|
||||||
final SSLService sslService;
|
final SSLService sslService;
|
||||||
final RealmConfig config;
|
final RealmConfig config;
|
||||||
|
private final int ldapPort;
|
||||||
|
private final int ldapsPort;
|
||||||
|
private final int gcLdapPort;
|
||||||
|
private final int gcLdapsPort;
|
||||||
|
|
||||||
DownLevelADAuthenticator(RealmConfig config, TimeValue timeout, boolean ignoreReferralErrors, Logger logger,
|
DownLevelADAuthenticator(RealmConfig config, TimeValue timeout, boolean ignoreReferralErrors, Logger logger,
|
||||||
GroupsResolver groupsResolver, LdapMetaDataResolver metaDataResolver, String domainDN, SSLService sslService,
|
GroupsResolver groupsResolver, LdapMetaDataResolver metaDataResolver, String domainDN, SSLService sslService,
|
||||||
ThreadPool threadPool) {
|
ThreadPool threadPool, int ldapPort, int ldapsPort, int gcLdapPort, int gcLdapsPort) {
|
||||||
super(config, timeout, ignoreReferralErrors, logger, groupsResolver, metaDataResolver, domainDN,
|
super(config, timeout, ignoreReferralErrors, logger, groupsResolver, metaDataResolver, domainDN,
|
||||||
ActiveDirectorySessionFactorySettings.AD_DOWN_LEVEL_USER_SEARCH_FILTER_SETTING, DOWN_LEVEL_FILTER, threadPool);
|
ActiveDirectorySessionFactorySettings.AD_DOWN_LEVEL_USER_SEARCH_FILTER_SETTING, DOWN_LEVEL_FILTER, threadPool);
|
||||||
this.domainDN = domainDN;
|
this.domainDN = domainDN;
|
||||||
this.settings = config.settings();
|
this.settings = config.settings();
|
||||||
this.sslService = sslService;
|
this.sslService = sslService;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
this.ldapPort = ldapPort;
|
||||||
|
this.ldapsPort = ldapsPort;
|
||||||
|
this.gcLdapPort = gcLdapPort;
|
||||||
|
this.gcLdapsPort = gcLdapsPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -400,7 +416,8 @@ class ActiveDirectorySessionFactory extends PoolingSessionFactory {
|
||||||
if (cachedName != null) {
|
if (cachedName != null) {
|
||||||
listener.onResponse(cachedName);
|
listener.onResponse(cachedName);
|
||||||
} else if (usingGlobalCatalog(ldapInterface) == false) {
|
} else if (usingGlobalCatalog(ldapInterface) == false) {
|
||||||
search(ldapInterface, domainDN, LdapSearchScope.SUB_TREE.scope(), filter, timeLimitSeconds, ignoreReferralErrors,
|
search(ldapInterface, "CN=Configuration," + domainDN, LdapSearchScope.SUB_TREE.scope(), filter, timeLimitSeconds,
|
||||||
|
ignoreReferralErrors,
|
||||||
ActionListener.wrap((results) -> handleSearchResults(results, netBiosDomainName, domainNameCache, listener),
|
ActionListener.wrap((results) -> handleSearchResults(results, netBiosDomainName, domainNameCache, listener),
|
||||||
listener::onFailure),
|
listener::onFailure),
|
||||||
"ncname");
|
"ncname");
|
||||||
|
@ -417,7 +434,8 @@ class ActiveDirectorySessionFactory extends PoolingSessionFactory {
|
||||||
final LDAPConnection finalLdapConnection = ldapConnection;
|
final LDAPConnection finalLdapConnection = ldapConnection;
|
||||||
final LDAPConnection searchConnection = LdapUtils.privilegedConnect(
|
final LDAPConnection searchConnection = LdapUtils.privilegedConnect(
|
||||||
() -> new LDAPConnection(finalLdapConnection.getSocketFactory(), connectionOptions(config, sslService, logger),
|
() -> new LDAPConnection(finalLdapConnection.getSocketFactory(), connectionOptions(config, sslService, logger),
|
||||||
finalLdapConnection.getConnectedAddress(), finalLdapConnection.getSSLSession() != null ? 636 : 389));
|
finalLdapConnection.getConnectedAddress(),
|
||||||
|
finalLdapConnection.getSSLSession() != null ? ldapsPort : ldapPort));
|
||||||
final byte[] passwordBytes = CharArrays.toUtf8Bytes(password.getChars());
|
final byte[] passwordBytes = CharArrays.toUtf8Bytes(password.getChars());
|
||||||
final SimpleBindRequest bind = bindDN.isEmpty()
|
final SimpleBindRequest bind = bindDN.isEmpty()
|
||||||
? new SimpleBindRequest(username, passwordBytes)
|
? new SimpleBindRequest(username, passwordBytes)
|
||||||
|
@ -425,8 +443,8 @@ class ActiveDirectorySessionFactory extends PoolingSessionFactory {
|
||||||
LdapUtils.maybeForkThenBind(searchConnection, bind, threadPool, new ActionRunnable<String>(listener) {
|
LdapUtils.maybeForkThenBind(searchConnection, bind, threadPool, new ActionRunnable<String>(listener) {
|
||||||
@Override
|
@Override
|
||||||
protected void doRun() throws Exception {
|
protected void doRun() throws Exception {
|
||||||
search(searchConnection, domainDN, LdapSearchScope.SUB_TREE.scope(), filter, timeLimitSeconds,
|
search(searchConnection, "CN=Configuration," + domainDN, LdapSearchScope.SUB_TREE.scope(), filter,
|
||||||
ignoreReferralErrors,
|
timeLimitSeconds, ignoreReferralErrors,
|
||||||
ActionListener.wrap(
|
ActionListener.wrap(
|
||||||
results -> {
|
results -> {
|
||||||
IOUtils.close(searchConnection);
|
IOUtils.close(searchConnection);
|
||||||
|
@ -473,7 +491,7 @@ class ActiveDirectorySessionFactory extends PoolingSessionFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean usingGlobalCatalog(LDAPInterface ldap) throws LDAPException {
|
boolean usingGlobalCatalog(LDAPInterface ldap) throws LDAPException {
|
||||||
if (ldap instanceof LDAPConnection) {
|
if (ldap instanceof LDAPConnection) {
|
||||||
return usingGlobalCatalog((LDAPConnection) ldap);
|
return usingGlobalCatalog((LDAPConnection) ldap);
|
||||||
} else {
|
} else {
|
||||||
|
@ -490,8 +508,8 @@ class ActiveDirectorySessionFactory extends PoolingSessionFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean usingGlobalCatalog(LDAPConnection ldapConnection) {
|
private boolean usingGlobalCatalog(LDAPConnection ldapConnection) {
|
||||||
return ldapConnection.getConnectedPort() == 3268 || ldapConnection.getConnectedPort() == 3269;
|
return ldapConnection.getConnectedPort() == gcLdapPort || ldapConnection.getConnectedPort() == gcLdapsPort;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,6 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.common.util.concurrent.UncategorizedExecutionException;
|
import org.elasticsearch.common.util.concurrent.UncategorizedExecutionException;
|
||||||
import org.elasticsearch.env.TestEnvironment;
|
import org.elasticsearch.env.TestEnvironment;
|
||||||
import org.elasticsearch.test.junit.annotations.Network;
|
|
||||||
import org.elasticsearch.threadpool.TestThreadPool;
|
import org.elasticsearch.threadpool.TestThreadPool;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
|
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
|
||||||
|
@ -28,12 +27,10 @@ import org.junit.Before;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.anyOf;
|
|
||||||
import static org.hamcrest.Matchers.contains;
|
import static org.hamcrest.Matchers.contains;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.lessThan;
|
|
||||||
|
|
||||||
public class LdapSessionFactoryTests extends LdapTestCase {
|
public class LdapSessionFactoryTests extends LdapTestCase {
|
||||||
private Settings globalSettings;
|
private Settings globalSettings;
|
||||||
|
|
|
@ -44,7 +44,7 @@ import java.util.Objects;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.core.security.authc.ldap.support.SessionFactorySettings.HOSTNAME_VERIFICATION_SETTING;
|
import static org.elasticsearch.xpack.core.security.authc.ldap.support.SessionFactorySettings.HOSTNAME_VERIFICATION_SETTING;
|
||||||
import static org.elasticsearch.xpack.core.security.authc.ldap.support.SessionFactorySettings.URLS_SETTING;
|
import static org.elasticsearch.xpack.core.security.authc.ldap.support.SessionFactorySettings.URLS_SETTING;
|
||||||
//
|
|
||||||
public abstract class LdapTestCase extends ESTestCase {
|
public abstract class LdapTestCase extends ESTestCase {
|
||||||
|
|
||||||
private static final String USER_DN_TEMPLATES_SETTING_KEY = LdapSessionFactorySettings.USER_DN_TEMPLATES_SETTING.getKey();
|
private static final String USER_DN_TEMPLATES_SETTING_KEY = LdapSessionFactorySettings.USER_DN_TEMPLATES_SETTING.getKey();
|
||||||
|
@ -120,8 +120,7 @@ public abstract class LdapTestCase extends ESTestCase {
|
||||||
.put(SessionFactorySettings.TIMEOUT_TCP_CONNECTION_SETTING, TimeValue.timeValueSeconds(1L))
|
.put(SessionFactorySettings.TIMEOUT_TCP_CONNECTION_SETTING, TimeValue.timeValueSeconds(1L))
|
||||||
.put(SessionFactorySettings.IGNORE_REFERRAL_ERRORS_SETTING.getKey(), ignoreReferralErrors)
|
.put(SessionFactorySettings.IGNORE_REFERRAL_ERRORS_SETTING.getKey(), ignoreReferralErrors)
|
||||||
.put("group_search.base_dn", groupSearchBase)
|
.put("group_search.base_dn", groupSearchBase)
|
||||||
.put("group_search.scope", scope)
|
.put("group_search.scope", scope);
|
||||||
.put("ssl.verification_mode", VerificationMode.CERTIFICATE);
|
|
||||||
if (serverSetType != null) {
|
if (serverSetType != null) {
|
||||||
builder.put(LdapLoadBalancingSettings.LOAD_BALANCE_SETTINGS + "." +
|
builder.put(LdapLoadBalancingSettings.LOAD_BALANCE_SETTINGS + "." +
|
||||||
LdapLoadBalancingSettings.LOAD_BALANCE_TYPE_SETTING, serverSetType.toString());
|
LdapLoadBalancingSettings.LOAD_BALANCE_TYPE_SETTING, serverSetType.toString());
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -21,7 +21,7 @@ import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class SearchGroupsResolverTests extends GroupsResolverTestCase {
|
public class SearchGroupsResolverTests extends GroupsResolverTestCase {
|
||||||
|
|
||||||
private static final String BRUCE_BANNER_DN = "uid=hulk,ou=people,dc=oldap,dc=test,dc=elasticsearch,dc=com";
|
private static final String BRUCE_BANNER_DN = "uid=hulk,ou=people,dc=oldap,dc=test,dc=elasticsearch,dc=com";
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
Project smbFixtureProject = xpackProject("test:smb-fixture")
|
||||||
|
evaluationDependsOn(smbFixtureProject.path)
|
||||||
|
|
||||||
|
apply plugin: 'elasticsearch.vagrantsupport'
|
||||||
apply plugin: 'elasticsearch.standalone-test'
|
apply plugin: 'elasticsearch.standalone-test'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -5,10 +9,11 @@ dependencies {
|
||||||
testCompile project(path: xpackModule('security'), configuration: 'testArtifacts')
|
testCompile project(path: xpackModule('security'), configuration: 'testArtifacts')
|
||||||
}
|
}
|
||||||
|
|
||||||
// add test resources from security, so certificate tool tests can use example certs
|
// add test resources from security, so tests can use example certs
|
||||||
sourceSets.test.resources.srcDirs(project(xpackModule('security')).sourceSets.test.resources.srcDirs)
|
sourceSets.test.resources.srcDirs(project(xpackModule('security')).sourceSets.test.resources.srcDirs)
|
||||||
|
compileTestJava.options.compilerArgs << "-Xlint:-deprecation,-rawtypes,-serial,-try,-unchecked"
|
||||||
|
|
||||||
// we have to repeate these patterns because the security test resources are effectively in the src of this project
|
// we have to repeat these patterns because the security test resources are effectively in the src of this project
|
||||||
forbiddenPatterns {
|
forbiddenPatterns {
|
||||||
exclude '**/*.key'
|
exclude '**/*.key'
|
||||||
exclude '**/*.p12'
|
exclude '**/*.p12'
|
||||||
|
@ -21,7 +26,22 @@ test {
|
||||||
* other if we allow them to set the number of available processors as it's set-once in Netty.
|
* other if we allow them to set the number of available processors as it's set-once in Netty.
|
||||||
*/
|
*/
|
||||||
systemProperty 'es.set.netty.runtime.available.processors', 'false'
|
systemProperty 'es.set.netty.runtime.available.processors', 'false'
|
||||||
|
include '**/*IT.class'
|
||||||
|
include '**/*Tests.class'
|
||||||
}
|
}
|
||||||
|
|
||||||
// these are just tests, no need to audit
|
// these are just tests, no need to audit
|
||||||
thirdPartyAudit.enabled = false
|
thirdPartyAudit.enabled = false
|
||||||
|
|
||||||
|
task smbFixture {
|
||||||
|
dependsOn "vagrantCheckVersion", "virtualboxCheckVersion", smbFixtureProject.up
|
||||||
|
}
|
||||||
|
|
||||||
|
if (project.rootProject.vagrantSupported) {
|
||||||
|
if (project.hasProperty('useExternalAD') == false) {
|
||||||
|
test.dependsOn smbFixture
|
||||||
|
test.finalizedBy smbFixtureProject.halt
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
test.enabled = false
|
||||||
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.security.authc.ldap;
|
package org.elasticsearch.xpack.security.authc.ldap;
|
||||||
|
|
||||||
import com.unboundid.ldap.sdk.LDAPException;
|
import org.elasticsearch.action.support.PlainActionFuture;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.settings.MockSecureSettings;
|
import org.elasticsearch.common.settings.MockSecureSettings;
|
||||||
import org.elasticsearch.common.settings.SecureString;
|
import org.elasticsearch.common.settings.SecureString;
|
||||||
|
@ -13,7 +13,6 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.env.Environment;
|
import org.elasticsearch.env.Environment;
|
||||||
import org.elasticsearch.env.TestEnvironment;
|
import org.elasticsearch.env.TestEnvironment;
|
||||||
import org.elasticsearch.test.junit.annotations.Network;
|
|
||||||
import org.elasticsearch.threadpool.TestThreadPool;
|
import org.elasticsearch.threadpool.TestThreadPool;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
|
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
|
||||||
|
@ -21,17 +20,19 @@ import org.elasticsearch.xpack.core.security.authc.ldap.support.LdapSearchScope;
|
||||||
import org.elasticsearch.xpack.core.ssl.SSLService;
|
import org.elasticsearch.xpack.core.ssl.SSLService;
|
||||||
import org.elasticsearch.xpack.security.authc.ldap.support.LdapSession;
|
import org.elasticsearch.xpack.security.authc.ldap.support.LdapSession;
|
||||||
import org.elasticsearch.xpack.security.authc.ldap.support.LdapTestCase;
|
import org.elasticsearch.xpack.security.authc.ldap.support.LdapTestCase;
|
||||||
|
import org.elasticsearch.xpack.security.authc.ldap.support.SessionFactory;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static org.elasticsearch.xpack.security.authc.ldap.LdapUserSearchSessionFactoryTests.getLdapUserSearchSessionFactory;
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.hasItems;
|
|
||||||
|
|
||||||
public class ActiveDirectoryUserSearchSessionFactoryTests extends LdapTestCase {
|
public class ADLdapUserSearchSessionFactoryTests extends AbstractActiveDirectoryTestCase {
|
||||||
|
|
||||||
private SSLService sslService;
|
private SSLService sslService;
|
||||||
private Settings globalSettings;
|
private Settings globalSettings;
|
||||||
|
@ -53,7 +54,7 @@ public class ActiveDirectoryUserSearchSessionFactoryTests extends LdapTestCase {
|
||||||
.setSecureSettings(newSecureSettings("xpack.ssl.truststore.secure_password", "changeit"))
|
.setSecureSettings(newSecureSettings("xpack.ssl.truststore.secure_password", "changeit"))
|
||||||
.build();
|
.build();
|
||||||
sslService = new SSLService(globalSettings, env);
|
sslService = new SSLService(globalSettings, env);
|
||||||
threadPool = new TestThreadPool("LdapUserSearchSessionFactoryTests");
|
threadPool = new TestThreadPool("ADLdapUserSearchSessionFactoryTests");
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
|
@ -61,8 +62,12 @@ public class ActiveDirectoryUserSearchSessionFactoryTests extends LdapTestCase {
|
||||||
terminate(threadPool);
|
terminate(threadPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Network
|
private MockSecureSettings newSecureSettings(String key, String value) {
|
||||||
@SuppressWarnings("unchecked")
|
MockSecureSettings secureSettings = new MockSecureSettings();
|
||||||
|
secureSettings.setString(key, value);
|
||||||
|
return secureSettings;
|
||||||
|
}
|
||||||
|
|
||||||
public void testUserSearchWithActiveDirectory() throws Exception {
|
public void testUserSearchWithActiveDirectory() throws Exception {
|
||||||
String groupSearchBase = "DC=ad,DC=test,DC=elasticsearch,DC=com";
|
String groupSearchBase = "DC=ad,DC=test,DC=elasticsearch,DC=com";
|
||||||
String userSearchBase = "CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com";
|
String userSearchBase = "CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com";
|
||||||
|
@ -76,6 +81,7 @@ public class ActiveDirectoryUserSearchSessionFactoryTests extends LdapTestCase {
|
||||||
.put("bind_password", ActiveDirectorySessionFactoryTests.PASSWORD)
|
.put("bind_password", ActiveDirectorySessionFactoryTests.PASSWORD)
|
||||||
.put("user_search.filter", "(cn={0})")
|
.put("user_search.filter", "(cn={0})")
|
||||||
.put("user_search.pool.enabled", randomBoolean())
|
.put("user_search.pool.enabled", randomBoolean())
|
||||||
|
.put("follow_referrals", ActiveDirectorySessionFactoryTests.FOLLOW_REFERRALS)
|
||||||
.build();
|
.build();
|
||||||
Settings.Builder builder = Settings.builder()
|
Settings.Builder builder = Settings.builder()
|
||||||
.put(globalSettings);
|
.put(globalSettings);
|
||||||
|
@ -85,8 +91,8 @@ public class ActiveDirectoryUserSearchSessionFactoryTests extends LdapTestCase {
|
||||||
});
|
});
|
||||||
Settings fullSettings = builder.build();
|
Settings fullSettings = builder.build();
|
||||||
sslService = new SSLService(fullSettings, TestEnvironment.newEnvironment(fullSettings));
|
sslService = new SSLService(fullSettings, TestEnvironment.newEnvironment(fullSettings));
|
||||||
RealmConfig config = new RealmConfig("ad-as-ldap-test", settings, globalSettings,
|
RealmConfig config = new RealmConfig("ad-as-ldap-test", settings, globalSettings, TestEnvironment.newEnvironment(globalSettings),
|
||||||
TestEnvironment.newEnvironment(globalSettings), new ThreadContext(globalSettings));
|
new ThreadContext(globalSettings));
|
||||||
LdapUserSearchSessionFactory sessionFactory = getLdapUserSearchSessionFactory(config, sslService, threadPool);
|
LdapUserSearchSessionFactory sessionFactory = getLdapUserSearchSessionFactory(config, sslService, threadPool);
|
||||||
|
|
||||||
String user = "Bruce Banner";
|
String user = "Bruce Banner";
|
||||||
|
@ -119,20 +125,27 @@ public class ActiveDirectoryUserSearchSessionFactoryTests extends LdapTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static LdapUserSearchSessionFactory getLdapUserSearchSessionFactory(RealmConfig config, SSLService sslService, ThreadPool threadPool)
|
@Override
|
||||||
throws LDAPException {
|
protected boolean enableWarningsCheck() {
|
||||||
LdapUserSearchSessionFactory sessionFactory = new LdapUserSearchSessionFactory(config, sslService, threadPool);
|
return false;
|
||||||
if (sessionFactory.getConnectionPool() != null) {
|
|
||||||
// don't use this in production
|
|
||||||
// used here to catch bugs that might get masked by an automatic retry
|
|
||||||
sessionFactory.getConnectionPool().setRetryFailedOperationsDueToInvalidConnections(false);
|
|
||||||
}
|
|
||||||
return sessionFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private MockSecureSettings newSecureSettings(String key, String value) {
|
private LdapSession session(SessionFactory factory, String username, SecureString password) {
|
||||||
MockSecureSettings secureSettings = new MockSecureSettings();
|
PlainActionFuture<LdapSession> future = new PlainActionFuture<>();
|
||||||
secureSettings.setString(key, value);
|
factory.session(username, password, future);
|
||||||
return secureSettings;
|
return future.actionGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> groups(LdapSession ldapSession) {
|
||||||
|
Objects.requireNonNull(ldapSession);
|
||||||
|
PlainActionFuture<List<String>> future = new PlainActionFuture<>();
|
||||||
|
ldapSession.groups(future);
|
||||||
|
return future.actionGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
private LdapSession unauthenticatedSession(SessionFactory factory, String username) {
|
||||||
|
PlainActionFuture<LdapSession> future = new PlainActionFuture<>();
|
||||||
|
factory.unauthenticatedSession(username, future);
|
||||||
|
return future.actionGet();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -11,11 +11,11 @@ import com.unboundid.ldap.sdk.LDAPException;
|
||||||
import com.unboundid.ldap.sdk.LDAPInterface;
|
import com.unboundid.ldap.sdk.LDAPInterface;
|
||||||
|
|
||||||
import org.elasticsearch.ExceptionsHelper;
|
import org.elasticsearch.ExceptionsHelper;
|
||||||
|
import org.elasticsearch.common.Booleans;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.env.Environment;
|
import org.elasticsearch.env.Environment;
|
||||||
import org.elasticsearch.env.TestEnvironment;
|
import org.elasticsearch.env.TestEnvironment;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.test.junit.annotations.Network;
|
|
||||||
import org.elasticsearch.xpack.core.security.authc.ldap.ActiveDirectorySessionFactorySettings;
|
import org.elasticsearch.xpack.core.security.authc.ldap.ActiveDirectorySessionFactorySettings;
|
||||||
import org.elasticsearch.xpack.core.security.authc.ldap.support.LdapSearchScope;
|
import org.elasticsearch.xpack.core.security.authc.ldap.support.LdapSearchScope;
|
||||||
import org.elasticsearch.xpack.core.security.authc.ldap.support.SessionFactorySettings;
|
import org.elasticsearch.xpack.core.security.authc.ldap.support.SessionFactorySettings;
|
||||||
|
@ -27,11 +27,22 @@ import java.nio.file.Path;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
|
|
||||||
@Network
|
public abstract class AbstractActiveDirectoryTestCase extends ESTestCase {
|
||||||
public class AbstractActiveDirectoryIntegTests extends ESTestCase {
|
|
||||||
|
|
||||||
public static final String AD_LDAP_URL = "ldaps://54.213.145.20:636";
|
// follow referrals defaults to false here which differs from the default value of the setting
|
||||||
public static final String PASSWORD = "NickFuryHeartsES";
|
// this is needed to prevent test logs being filled by errors as the default configuration of
|
||||||
|
// the tests run against a vagrant samba4 instance configured as a domain controller with the
|
||||||
|
// ports mapped into the ephemeral port range and there is the possibility of incorrect results
|
||||||
|
// as we cannot control the URL of the referral which may contain a non-resolvable DNS name as
|
||||||
|
// this name would be served by the samba4 instance
|
||||||
|
public static final Boolean FOLLOW_REFERRALS = Booleans.parseBoolean(getFromEnv("TESTS_AD_FOLLOW_REFERRALS", "false"));
|
||||||
|
public static final String AD_LDAP_URL = getFromEnv("TESTS_AD_LDAP_URL", "ldaps://localhost:61636");
|
||||||
|
public static final String AD_LDAP_GC_URL = getFromEnv("TESTS_AD_LDAP_GC_URL", "ldaps://localhost:63269");
|
||||||
|
public static final String PASSWORD = getFromEnv("TESTS_AD_USER_PASSWORD", "Passw0rd");
|
||||||
|
public static final String AD_LDAP_PORT = getFromEnv("TESTS_AD_LDAP_PORT", "61389");
|
||||||
|
public static final String AD_LDAPS_PORT = getFromEnv("TESTS_AD_LDAPS_PORT", "61636");
|
||||||
|
public static final String AD_GC_LDAP_PORT = getFromEnv("TESTS_AD_GC_LDAP_PORT", "63268");
|
||||||
|
public static final String AD_GC_LDAPS_PORT = getFromEnv("TESTS_AD_GC_LDAPS_PORT", "63269");
|
||||||
public static final String AD_DOMAIN = "ad.test.elasticsearch.com";
|
public static final String AD_DOMAIN = "ad.test.elasticsearch.com";
|
||||||
|
|
||||||
protected SSLService sslService;
|
protected SSLService sslService;
|
||||||
|
@ -76,7 +87,12 @@ public class AbstractActiveDirectoryIntegTests extends ESTestCase {
|
||||||
.putList(SessionFactorySettings.URLS_SETTING, ldapUrl)
|
.putList(SessionFactorySettings.URLS_SETTING, ldapUrl)
|
||||||
.put(ActiveDirectorySessionFactorySettings.AD_DOMAIN_NAME_SETTING, adDomainName)
|
.put(ActiveDirectorySessionFactorySettings.AD_DOMAIN_NAME_SETTING, adDomainName)
|
||||||
.put(ActiveDirectorySessionFactorySettings.AD_USER_SEARCH_BASEDN_SETTING, userSearchDN)
|
.put(ActiveDirectorySessionFactorySettings.AD_USER_SEARCH_BASEDN_SETTING, userSearchDN)
|
||||||
.put(ActiveDirectorySessionFactorySettings.AD_USER_SEARCH_SCOPE_SETTING, scope);
|
.put(ActiveDirectorySessionFactorySettings.AD_USER_SEARCH_SCOPE_SETTING, scope)
|
||||||
|
.put(ActiveDirectorySessionFactorySettings.AD_LDAP_PORT_SETTING.getKey(), AD_LDAP_PORT)
|
||||||
|
.put(ActiveDirectorySessionFactorySettings.AD_LDAPS_PORT_SETTING.getKey(), AD_LDAPS_PORT)
|
||||||
|
.put(ActiveDirectorySessionFactorySettings.AD_GC_LDAP_PORT_SETTING.getKey(), AD_GC_LDAP_PORT)
|
||||||
|
.put(ActiveDirectorySessionFactorySettings.AD_GC_LDAPS_PORT_SETTING.getKey(), AD_GC_LDAPS_PORT)
|
||||||
|
.put("follow_referrals", FOLLOW_REFERRALS);
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
builder.put("ssl.verification_mode", hostnameVerification ? VerificationMode.FULL : VerificationMode.CERTIFICATE);
|
builder.put("ssl.verification_mode", hostnameVerification ? VerificationMode.FULL : VerificationMode.CERTIFICATE);
|
||||||
} else {
|
} else {
|
||||||
|
@ -109,4 +125,9 @@ public class AbstractActiveDirectoryIntegTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String getFromEnv(String envVar, String defaultValue) {
|
||||||
|
final String value = System.getenv(envVar);
|
||||||
|
return value == null ? defaultValue : value;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.integration.ldap;
|
package org.elasticsearch.xpack.security.authc.ldap;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchSecurityException;
|
import org.elasticsearch.ElasticsearchSecurityException;
|
||||||
import org.elasticsearch.action.ActionFuture;
|
import org.elasticsearch.action.ActionFuture;
|
||||||
|
@ -25,6 +25,7 @@ import org.elasticsearch.test.SecuritySettingsSource;
|
||||||
import org.elasticsearch.xpack.core.security.SecurityLifecycleServiceField;
|
import org.elasticsearch.xpack.core.security.SecurityLifecycleServiceField;
|
||||||
import org.elasticsearch.xpack.core.security.action.rolemapping.PutRoleMappingRequestBuilder;
|
import org.elasticsearch.xpack.core.security.action.rolemapping.PutRoleMappingRequestBuilder;
|
||||||
import org.elasticsearch.xpack.core.security.action.rolemapping.PutRoleMappingResponse;
|
import org.elasticsearch.xpack.core.security.action.rolemapping.PutRoleMappingResponse;
|
||||||
|
import org.elasticsearch.xpack.core.security.authc.ldap.ActiveDirectorySessionFactorySettings;
|
||||||
import org.elasticsearch.xpack.core.security.authc.ldap.LdapRealmSettings;
|
import org.elasticsearch.xpack.core.security.authc.ldap.LdapRealmSettings;
|
||||||
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
|
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
|
||||||
import org.elasticsearch.xpack.core.security.client.SecurityClient;
|
import org.elasticsearch.xpack.core.security.client.SecurityClient;
|
||||||
|
@ -53,6 +54,10 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
|
||||||
import static org.elasticsearch.xpack.core.security.authc.ldap.support.LdapSearchScope.ONE_LEVEL;
|
import static org.elasticsearch.xpack.core.security.authc.ldap.support.LdapSearchScope.ONE_LEVEL;
|
||||||
import static org.elasticsearch.xpack.core.security.authc.ldap.support.LdapSearchScope.SUB_TREE;
|
import static org.elasticsearch.xpack.core.security.authc.ldap.support.LdapSearchScope.SUB_TREE;
|
||||||
import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.BASIC_AUTH_HEADER;
|
import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.BASIC_AUTH_HEADER;
|
||||||
|
import static org.elasticsearch.xpack.security.authc.ldap.AbstractActiveDirectoryTestCase.AD_GC_LDAPS_PORT;
|
||||||
|
import static org.elasticsearch.xpack.security.authc.ldap.AbstractActiveDirectoryTestCase.AD_GC_LDAP_PORT;
|
||||||
|
import static org.elasticsearch.xpack.security.authc.ldap.AbstractActiveDirectoryTestCase.AD_LDAPS_PORT;
|
||||||
|
import static org.elasticsearch.xpack.security.authc.ldap.AbstractActiveDirectoryTestCase.AD_LDAP_PORT;
|
||||||
import static org.elasticsearch.xpack.security.test.SecurityTestUtils.writeFile;
|
import static org.elasticsearch.xpack.security.test.SecurityTestUtils.writeFile;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
@ -63,7 +68,7 @@ import static org.hamcrest.Matchers.equalTo;
|
||||||
public abstract class AbstractAdLdapRealmTestCase extends SecurityIntegTestCase {
|
public abstract class AbstractAdLdapRealmTestCase extends SecurityIntegTestCase {
|
||||||
|
|
||||||
public static final String XPACK_SECURITY_AUTHC_REALMS_EXTERNAL = "xpack.security.authc.realms.external";
|
public static final String XPACK_SECURITY_AUTHC_REALMS_EXTERNAL = "xpack.security.authc.realms.external";
|
||||||
public static final String PASSWORD = "NickFuryHeartsES";
|
public static final String PASSWORD = AbstractActiveDirectoryTestCase.PASSWORD;
|
||||||
public static final String ASGARDIAN_INDEX = "gods";
|
public static final String ASGARDIAN_INDEX = "gods";
|
||||||
public static final String PHILANTHROPISTS_INDEX = "philanthropists";
|
public static final String PHILANTHROPISTS_INDEX = "philanthropists";
|
||||||
public static final String SECURITY_INDEX = "security";
|
public static final String SECURITY_INDEX = "security";
|
||||||
|
@ -119,43 +124,39 @@ public abstract class AbstractAdLdapRealmTestCase extends SecurityIntegTestCase
|
||||||
final RealmConfig realm = AbstractAdLdapRealmTestCase.realmConfig;
|
final RealmConfig realm = AbstractAdLdapRealmTestCase.realmConfig;
|
||||||
Path store = getDataPath(TESTNODE_KEYSTORE);
|
Path store = getDataPath(TESTNODE_KEYSTORE);
|
||||||
Settings.Builder builder = Settings.builder();
|
Settings.Builder builder = Settings.builder();
|
||||||
if (useGlobalSSL) {
|
// don't use filter since it returns a prefixed secure setting instead of mock!
|
||||||
// don't use filter since it returns a prefixed secure setting instead of mock!
|
Settings settingsToAdd = super.nodeSettings(nodeOrdinal);
|
||||||
Settings settingsToAdd = super.nodeSettings(nodeOrdinal);
|
builder.put(settingsToAdd.filter(k -> k.startsWith("xpack.ssl.") == false), false);
|
||||||
builder.put(settingsToAdd.filter(k -> k.startsWith("xpack.ssl.") == false), false);
|
MockSecureSettings mockSecureSettings = (MockSecureSettings) Settings.builder().put(settingsToAdd).getSecureSettings();
|
||||||
MockSecureSettings mockSecureSettings = (MockSecureSettings) Settings.builder().put(settingsToAdd).getSecureSettings();
|
if (mockSecureSettings != null) {
|
||||||
if (mockSecureSettings != null) {
|
MockSecureSettings filteredSecureSettings = new MockSecureSettings();
|
||||||
MockSecureSettings filteredSecureSettings = new MockSecureSettings();
|
builder.setSecureSettings(filteredSecureSettings);
|
||||||
builder.setSecureSettings(filteredSecureSettings);
|
for (String secureSetting : mockSecureSettings.getSettingNames()) {
|
||||||
for (String secureSetting : mockSecureSettings.getSettingNames()) {
|
if (secureSetting.startsWith("xpack.ssl.") == false) {
|
||||||
if (secureSetting.startsWith("xpack.ssl.") == false) {
|
SecureString secureString = mockSecureSettings.getString(secureSetting);
|
||||||
SecureString secureString = mockSecureSettings.getString(secureSetting);
|
if (secureString == null) {
|
||||||
if (secureString == null) {
|
final byte[] fileBytes;
|
||||||
final byte[] fileBytes;
|
try (InputStream in = mockSecureSettings.getFile(secureSetting);
|
||||||
try (InputStream in = mockSecureSettings.getFile(secureSetting);
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
|
||||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
|
int numRead;
|
||||||
int numRead;
|
byte[] bytes = new byte[1024];
|
||||||
byte[] bytes = new byte[1024];
|
while ((numRead = in.read(bytes)) != -1) {
|
||||||
while ((numRead = in.read(bytes)) != -1) {
|
byteArrayOutputStream.write(bytes, 0, numRead);
|
||||||
byteArrayOutputStream.write(bytes, 0, numRead);
|
|
||||||
}
|
|
||||||
byteArrayOutputStream.flush();
|
|
||||||
fileBytes = byteArrayOutputStream.toByteArray();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new UncheckedIOException(e);
|
|
||||||
}
|
}
|
||||||
|
byteArrayOutputStream.flush();
|
||||||
filteredSecureSettings.setFile(secureSetting, fileBytes);
|
fileBytes = byteArrayOutputStream.toByteArray();
|
||||||
} else {
|
} catch (IOException e) {
|
||||||
filteredSecureSettings.setString(secureSetting, new String(secureString.getChars()));
|
throw new UncheckedIOException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filteredSecureSettings.setFile(secureSetting, fileBytes);
|
||||||
|
} else {
|
||||||
|
filteredSecureSettings.setString(secureSetting, new String(secureString.getChars()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addSslSettingsForStore(builder, store, "testnode");
|
|
||||||
} else {
|
|
||||||
builder.put(super.nodeSettings(nodeOrdinal));
|
|
||||||
}
|
}
|
||||||
|
addSslSettingsForStore(builder, store, "testnode");
|
||||||
builder.put(buildRealmSettings(realm, roleMappings, store));
|
builder.put(buildRealmSettings(realm, roleMappings, store));
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
@ -376,39 +377,44 @@ public abstract class AbstractAdLdapRealmTestCase extends SecurityIntegTestCase
|
||||||
AD(false, AD_ROLE_MAPPING,
|
AD(false, AD_ROLE_MAPPING,
|
||||||
Settings.builder()
|
Settings.builder()
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".type", LdapRealmSettings.AD_TYPE)
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".type", LdapRealmSettings.AD_TYPE)
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".domain_name", "ad.test.elasticsearch.com")
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".domain_name", ActiveDirectorySessionFactoryTests.AD_DOMAIN)
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL
|
||||||
+ ".group_search.base_dn", "CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com")
|
+ ".group_search.base_dn", "CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com")
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".group_search.scope", randomBoolean() ? SUB_TREE : ONE_LEVEL)
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".group_search.scope", randomBoolean() ? SUB_TREE : ONE_LEVEL)
|
||||||
.build()),
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".url", ActiveDirectorySessionFactoryTests.AD_LDAP_URL)
|
||||||
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".follow_referrals",
|
||||||
AD_SSL(false, AD_ROLE_MAPPING,
|
ActiveDirectorySessionFactoryTests.FOLLOW_REFERRALS)
|
||||||
Settings.builder()
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + "." +
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".type", LdapRealmSettings.AD_TYPE)
|
ActiveDirectorySessionFactorySettings.AD_LDAP_PORT_SETTING.getKey(), AD_LDAP_PORT)
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".domain_name", "ad.test.elasticsearch.com")
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + "." +
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL
|
ActiveDirectorySessionFactorySettings.AD_LDAPS_PORT_SETTING.getKey(), AD_LDAPS_PORT)
|
||||||
+ ".group_search.base_dn", "CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com")
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + "." +
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".group_search.scope", randomBoolean() ? SUB_TREE : ONE_LEVEL)
|
ActiveDirectorySessionFactorySettings.AD_GC_LDAP_PORT_SETTING.getKey(), AD_GC_LDAP_PORT)
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".url", "ldap://ad.test.elasticsearch.com:389")
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + "." +
|
||||||
|
ActiveDirectorySessionFactorySettings.AD_GC_LDAPS_PORT_SETTING.getKey(), AD_GC_LDAPS_PORT)
|
||||||
.build()),
|
.build()),
|
||||||
|
|
||||||
AD_LDAP_GROUPS_FROM_SEARCH(true, AD_ROLE_MAPPING,
|
AD_LDAP_GROUPS_FROM_SEARCH(true, AD_ROLE_MAPPING,
|
||||||
Settings.builder()
|
Settings.builder()
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".type", LdapRealmSettings.LDAP_TYPE)
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".type", LdapRealmSettings.LDAP_TYPE)
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".url", "ldaps://ad.test.elasticsearch.com:636")
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".url", ActiveDirectorySessionFactoryTests.AD_LDAP_URL)
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL
|
||||||
+ ".group_search.base_dn", "CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com")
|
+ ".group_search.base_dn", "CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com")
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".group_search.scope", randomBoolean() ? SUB_TREE : ONE_LEVEL)
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".group_search.scope", randomBoolean() ? SUB_TREE : ONE_LEVEL)
|
||||||
.putList(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".user_dn_templates",
|
.putList(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".user_dn_templates",
|
||||||
"cn={0},CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com")
|
"cn={0},CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com")
|
||||||
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".follow_referrals",
|
||||||
|
ActiveDirectorySessionFactoryTests.FOLLOW_REFERRALS)
|
||||||
.build()),
|
.build()),
|
||||||
|
|
||||||
AD_LDAP_GROUPS_FROM_ATTRIBUTE(true, AD_ROLE_MAPPING,
|
AD_LDAP_GROUPS_FROM_ATTRIBUTE(true, AD_ROLE_MAPPING,
|
||||||
Settings.builder()
|
Settings.builder()
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".type", LdapRealmSettings.LDAP_TYPE)
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".type", LdapRealmSettings.LDAP_TYPE)
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".url", "ldaps://ad.test.elasticsearch.com:636")
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".url", ActiveDirectorySessionFactoryTests.AD_LDAP_URL)
|
||||||
.putList(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".user_dn_templates",
|
.putList(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".user_dn_templates",
|
||||||
"cn={0},CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com")
|
"cn={0},CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com")
|
||||||
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".follow_referrals",
|
||||||
|
ActiveDirectorySessionFactoryTests.FOLLOW_REFERRALS)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
final boolean mapGroupsAsRoles;
|
final boolean mapGroupsAsRoles;
|
|
@ -9,9 +9,9 @@ import com.unboundid.ldap.sdk.Filter;
|
||||||
import org.elasticsearch.action.support.PlainActionFuture;
|
import org.elasticsearch.action.support.PlainActionFuture;
|
||||||
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.test.junit.annotations.Network;
|
|
||||||
import org.elasticsearch.xpack.core.security.authc.ldap.support.LdapSearchScope;
|
import org.elasticsearch.xpack.core.security.authc.ldap.support.LdapSearchScope;
|
||||||
import org.elasticsearch.xpack.core.security.support.NoOpLogger;
|
import org.elasticsearch.xpack.core.security.support.NoOpLogger;
|
||||||
|
import org.junit.Before;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -21,12 +21,16 @@ import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.hasItem;
|
import static org.hamcrest.Matchers.hasItem;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
@Network
|
|
||||||
public class ActiveDirectoryGroupsResolverTests extends GroupsResolverTestCase {
|
public class ActiveDirectoryGroupsResolverTests extends GroupsResolverTestCase {
|
||||||
|
|
||||||
private static final String BRUCE_BANNER_DN =
|
private static final String BRUCE_BANNER_DN =
|
||||||
"cn=Bruce Banner,CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com";
|
"cn=Bruce Banner,CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setReferralFollowing() {
|
||||||
|
ldapConnection.getConnectionOptions().setFollowReferrals(AbstractActiveDirectoryTestCase.FOLLOW_REFERRALS);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void testResolveSubTree() throws Exception {
|
public void testResolveSubTree() throws Exception {
|
||||||
Settings settings = Settings.builder()
|
Settings settings = Settings.builder()
|
||||||
|
@ -76,7 +80,6 @@ public class ActiveDirectoryGroupsResolverTests extends GroupsResolverTestCase {
|
||||||
{
|
{
|
||||||
String[] expectedSids = new String[]{
|
String[] expectedSids = new String[]{
|
||||||
"S-1-5-32-545", //Default Users group
|
"S-1-5-32-545", //Default Users group
|
||||||
"S-1-5-21-3510024162-210737641-214529065-513" //Default Domain Users group
|
|
||||||
};
|
};
|
||||||
final String dn = "CN=Jarvis, CN=Users, DC=ad, DC=test, DC=elasticsearch, DC=com";
|
final String dn = "CN=Jarvis, CN=Users, DC=ad, DC=test, DC=elasticsearch, DC=com";
|
||||||
PlainActionFuture<Filter> future = new PlainActionFuture<>();
|
PlainActionFuture<Filter> future = new PlainActionFuture<>();
|
||||||
|
@ -89,9 +92,8 @@ public class ActiveDirectoryGroupsResolverTests extends GroupsResolverTestCase {
|
||||||
//test a user of one groups
|
//test a user of one groups
|
||||||
{
|
{
|
||||||
String[] expectedSids = new String[]{
|
String[] expectedSids = new String[]{
|
||||||
"S-1-5-32-545", //Default Users group
|
"S-1-5-32-545" //Default Users group
|
||||||
"S-1-5-21-3510024162-210737641-214529065-513", //Default Domain Users group
|
};
|
||||||
"S-1-5-21-3510024162-210737641-214529065-1117"}; //Gods group
|
|
||||||
final String dn = "CN=Odin, CN=Users, DC=ad, DC=test, DC=elasticsearch, DC=com";
|
final String dn = "CN=Odin, CN=Users, DC=ad, DC=test, DC=elasticsearch, DC=com";
|
||||||
PlainActionFuture<Filter> future = new PlainActionFuture<>();
|
PlainActionFuture<Filter> future = new PlainActionFuture<>();
|
||||||
ActiveDirectoryGroupsResolver.buildGroupQuery(ldapConnection, dn,
|
ActiveDirectoryGroupsResolver.buildGroupQuery(ldapConnection, dn,
|
||||||
|
@ -99,25 +101,6 @@ public class ActiveDirectoryGroupsResolverTests extends GroupsResolverTestCase {
|
||||||
Filter query = future.actionGet();
|
Filter query = future.actionGet();
|
||||||
assertValidSidQuery(query, expectedSids);
|
assertValidSidQuery(query, expectedSids);
|
||||||
}
|
}
|
||||||
|
|
||||||
//test a user of many groups
|
|
||||||
{
|
|
||||||
String[] expectedSids = new String[]{
|
|
||||||
"S-1-5-32-545", //Default Users Group
|
|
||||||
"S-1-5-21-3510024162-210737641-214529065-513", //Default Domain Users group
|
|
||||||
"S-1-5-21-3510024162-210737641-214529065-1123", //Supers
|
|
||||||
"S-1-5-21-3510024162-210737641-214529065-1110", //Philanthropists
|
|
||||||
"S-1-5-21-3510024162-210737641-214529065-1108", //Geniuses
|
|
||||||
"S-1-5-21-3510024162-210737641-214529065-1106", //SHIELD
|
|
||||||
"S-1-5-21-3510024162-210737641-214529065-1105"};//Avengers
|
|
||||||
|
|
||||||
final String dn = BRUCE_BANNER_DN;
|
|
||||||
PlainActionFuture<Filter> future = new PlainActionFuture<>();
|
|
||||||
ActiveDirectoryGroupsResolver.buildGroupQuery(ldapConnection, dn,
|
|
||||||
TimeValue.timeValueSeconds(10), false, future);
|
|
||||||
Filter query = future.actionGet();
|
|
||||||
assertValidSidQuery(query, expectedSids);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertValidSidQuery(Filter query, String[] expectedSids) {
|
private void assertValidSidQuery(Filter query, String[] expectedSids) {
|
||||||
|
@ -125,7 +108,7 @@ public class ActiveDirectoryGroupsResolverTests extends GroupsResolverTestCase {
|
||||||
Pattern sidQueryPattern = Pattern.compile("\\(\\|(\\(objectSid=S(-\\d+)+\\))+\\)");
|
Pattern sidQueryPattern = Pattern.compile("\\(\\|(\\(objectSid=S(-\\d+)+\\))+\\)");
|
||||||
assertThat("[" + queryString + "] didn't match the search filter pattern",
|
assertThat("[" + queryString + "] didn't match the search filter pattern",
|
||||||
sidQueryPattern.matcher(queryString).matches(), is(true));
|
sidQueryPattern.matcher(queryString).matches(), is(true));
|
||||||
for(String sid: expectedSids) {
|
for (String sid: expectedSids) {
|
||||||
assertThat(queryString, containsString(sid));
|
assertThat(queryString, containsString(sid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,18 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.integration.ldap;
|
package org.elasticsearch.xpack.security.authc.ldap;
|
||||||
|
|
||||||
import org.elasticsearch.action.ActionFuture;
|
import org.elasticsearch.action.ActionFuture;
|
||||||
import org.elasticsearch.client.Client;
|
import org.elasticsearch.client.Client;
|
||||||
import org.elasticsearch.common.collect.MapBuilder;
|
import org.elasticsearch.common.collect.MapBuilder;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.test.junit.annotations.Network;
|
|
||||||
import org.elasticsearch.xpack.core.security.action.user.AuthenticateAction;
|
import org.elasticsearch.xpack.core.security.action.user.AuthenticateAction;
|
||||||
import org.elasticsearch.xpack.core.security.action.user.AuthenticateRequest;
|
import org.elasticsearch.xpack.core.security.action.user.AuthenticateRequest;
|
||||||
import org.elasticsearch.xpack.core.security.action.user.AuthenticateResponse;
|
import org.elasticsearch.xpack.core.security.action.user.AuthenticateResponse;
|
||||||
import org.elasticsearch.xpack.core.security.authc.AuthenticationServiceField;
|
import org.elasticsearch.xpack.core.security.authc.AuthenticationServiceField;
|
||||||
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
|
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
|
||||||
import org.elasticsearch.xpack.core.security.user.ElasticUser;
|
import org.elasticsearch.xpack.core.security.user.ElasticUser;
|
||||||
import org.elasticsearch.xpack.security.authc.ldap.ActiveDirectorySessionFactoryTests;
|
|
||||||
import org.hamcrest.Matchers;
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
|
@ -28,12 +26,11 @@ import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswo
|
||||||
/**
|
/**
|
||||||
* This tests that "run-as" works on LDAP/AD realms
|
* This tests that "run-as" works on LDAP/AD realms
|
||||||
*/
|
*/
|
||||||
@Network
|
|
||||||
public class ActiveDirectoryRunAsIT extends AbstractAdLdapRealmTestCase {
|
public class ActiveDirectoryRunAsIT extends AbstractAdLdapRealmTestCase {
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void selectRealmConfig() {
|
public static void selectRealmConfig() {
|
||||||
realmConfig = randomFrom(RealmConfig.AD, RealmConfig.AD_SSL);
|
realmConfig = RealmConfig.AD;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -41,7 +38,6 @@ public class ActiveDirectoryRunAsIT extends AbstractAdLdapRealmTestCase {
|
||||||
final Settings.Builder builder = Settings.builder().put(super.nodeSettings(nodeOrdinal));
|
final Settings.Builder builder = Settings.builder().put(super.nodeSettings(nodeOrdinal));
|
||||||
switch (realmConfig) {
|
switch (realmConfig) {
|
||||||
case AD:
|
case AD:
|
||||||
case AD_SSL:
|
|
||||||
builder.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".bind_dn", "ironman@ad.test.elasticsearch.com")
|
builder.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".bind_dn", "ironman@ad.test.elasticsearch.com")
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".bind_password", ActiveDirectorySessionFactoryTests.PASSWORD)
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".bind_password", ActiveDirectorySessionFactoryTests.PASSWORD)
|
||||||
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".user_search.pool.enabled", false);
|
.put(XPACK_SECURITY_AUTHC_REALMS_EXTERNAL + ".user_search.pool.enabled", false);
|
|
@ -13,7 +13,6 @@ import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||||
import org.elasticsearch.common.util.concurrent.UncategorizedExecutionException;
|
import org.elasticsearch.common.util.concurrent.UncategorizedExecutionException;
|
||||||
import org.elasticsearch.env.TestEnvironment;
|
import org.elasticsearch.env.TestEnvironment;
|
||||||
import org.elasticsearch.test.junit.annotations.Network;
|
|
||||||
import org.elasticsearch.threadpool.TestThreadPool;
|
import org.elasticsearch.threadpool.TestThreadPool;
|
||||||
import org.elasticsearch.threadpool.ThreadPool;
|
import org.elasticsearch.threadpool.ThreadPool;
|
||||||
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
|
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
|
||||||
|
@ -39,8 +38,7 @@ import static org.hamcrest.Matchers.hasItem;
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
import static org.hamcrest.Matchers.instanceOf;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
@Network
|
public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryTestCase {
|
||||||
public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryIntegTests {
|
|
||||||
|
|
||||||
private final SecureString SECURED_PASSWORD = new SecureString(PASSWORD);
|
private final SecureString SECURED_PASSWORD = new SecureString(PASSWORD);
|
||||||
private ThreadPool threadPool;
|
private ThreadPool threadPool;
|
||||||
|
@ -87,7 +85,7 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryI
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void testNetbiosAuth() throws Exception {
|
public void testNetbiosAuth() throws Exception {
|
||||||
final String adUrl = randomFrom("ldap://54.213.145.20:3268", "ldaps://54.213.145.20:3269", AD_LDAP_URL);
|
final String adUrl = randomFrom(AD_LDAP_URL, AD_LDAP_GC_URL);
|
||||||
RealmConfig config = new RealmConfig("ad-test", buildAdSettings(adUrl, AD_DOMAIN, false), globalSettings,
|
RealmConfig config = new RealmConfig("ad-test", buildAdSettings(adUrl, AD_DOMAIN, false), globalSettings,
|
||||||
TestEnvironment.newEnvironment(globalSettings), new ThreadContext(globalSettings));
|
TestEnvironment.newEnvironment(globalSettings), new ThreadContext(globalSettings));
|
||||||
try (ActiveDirectorySessionFactory sessionFactory = getActiveDirectorySessionFactory(config, sslService, threadPool)) {
|
try (ActiveDirectorySessionFactory sessionFactory = getActiveDirectorySessionFactory(config, sslService, threadPool)) {
|
||||||
|
@ -290,13 +288,16 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryI
|
||||||
public void testStandardLdapConnection() throws Exception {
|
public void testStandardLdapConnection() throws Exception {
|
||||||
String groupSearchBase = "DC=ad,DC=test,DC=elasticsearch,DC=com";
|
String groupSearchBase = "DC=ad,DC=test,DC=elasticsearch,DC=com";
|
||||||
String userTemplate = "CN={0},CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com";
|
String userTemplate = "CN={0},CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com";
|
||||||
Settings settings = LdapTestCase.buildLdapSettings(
|
Settings settings = Settings.builder()
|
||||||
new String[] { AD_LDAP_URL },
|
.put(LdapTestCase.buildLdapSettings(
|
||||||
new String[] { userTemplate },
|
new String[] { AD_LDAP_URL },
|
||||||
groupSearchBase,
|
new String[] { userTemplate },
|
||||||
LdapSearchScope.SUB_TREE,
|
groupSearchBase,
|
||||||
null,
|
LdapSearchScope.SUB_TREE,
|
||||||
true);
|
null,
|
||||||
|
true))
|
||||||
|
.put("follow_referrals", FOLLOW_REFERRALS)
|
||||||
|
.build();
|
||||||
if (useGlobalSSL == false) {
|
if (useGlobalSSL == false) {
|
||||||
settings = Settings.builder()
|
settings = Settings.builder()
|
||||||
.put(settings)
|
.put(settings)
|
||||||
|
@ -387,42 +388,6 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testAdAuthWithHostnameVerification() throws Exception {
|
|
||||||
RealmConfig config = new RealmConfig("ad-test", buildAdSettings(AD_LDAP_URL, AD_DOMAIN, true), globalSettings,
|
|
||||||
TestEnvironment.newEnvironment(globalSettings), new ThreadContext(globalSettings));
|
|
||||||
try (ActiveDirectorySessionFactory sessionFactory = new ActiveDirectorySessionFactory(config, sslService, threadPool)) {
|
|
||||||
|
|
||||||
String userName = "ironman";
|
|
||||||
UncategorizedExecutionException e = expectThrows(UncategorizedExecutionException.class,
|
|
||||||
() -> session(sessionFactory, userName, SECURED_PASSWORD));
|
|
||||||
assertThat(e.getCause(), instanceOf(ExecutionException.class));
|
|
||||||
assertThat(e.getCause().getCause(), instanceOf(LDAPException.class));
|
|
||||||
final LDAPException expected = (LDAPException) e.getCause().getCause();
|
|
||||||
assertThat(expected.getMessage(),
|
|
||||||
anyOf(containsString("Hostname verification failed"), containsString("peer not authenticated")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testStandardLdapHostnameVerification() throws Exception {
|
|
||||||
String groupSearchBase = "DC=ad,DC=test,DC=elasticsearch,DC=com";
|
|
||||||
String userTemplate = "CN={0},CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com";
|
|
||||||
Settings settings = Settings.builder()
|
|
||||||
.put(LdapTestCase.buildLdapSettings(AD_LDAP_URL, userTemplate, groupSearchBase, LdapSearchScope.SUB_TREE))
|
|
||||||
.put("ssl.verification_mode", VerificationMode.FULL)
|
|
||||||
.build();
|
|
||||||
RealmConfig config = new RealmConfig("ad-test", settings, globalSettings, TestEnvironment.newEnvironment(globalSettings),
|
|
||||||
new ThreadContext(globalSettings));
|
|
||||||
LdapSessionFactory sessionFactory = new LdapSessionFactory(config, sslService, threadPool);
|
|
||||||
|
|
||||||
String user = "Bruce Banner";
|
|
||||||
UncategorizedExecutionException e = expectThrows(UncategorizedExecutionException.class,
|
|
||||||
() -> session(sessionFactory, user, SECURED_PASSWORD));
|
|
||||||
assertThat(e.getCause(), instanceOf(ExecutionException.class));
|
|
||||||
assertThat(e.getCause().getCause(), instanceOf(LDAPException.class));
|
|
||||||
final LDAPException expected = (LDAPException) e.getCause().getCause();
|
|
||||||
assertThat(expected.getMessage(), anyOf(containsString("Hostname verification failed"), containsString("peer not authenticated")));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testADLookup() throws Exception {
|
public void testADLookup() throws Exception {
|
||||||
RealmConfig config = new RealmConfig("ad-test",
|
RealmConfig config = new RealmConfig("ad-test",
|
||||||
buildAdSettings(AD_LDAP_URL, AD_DOMAIN, false, true),
|
buildAdSettings(AD_LDAP_URL, AD_DOMAIN, false, true),
|
||||||
|
@ -450,7 +415,12 @@ public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryI
|
||||||
private Settings buildAdSettings(String ldapUrl, String adDomainName, boolean hostnameVerification, boolean useBindUser) {
|
private Settings buildAdSettings(String ldapUrl, String adDomainName, boolean hostnameVerification, boolean useBindUser) {
|
||||||
Settings.Builder builder = Settings.builder()
|
Settings.Builder builder = Settings.builder()
|
||||||
.put(SessionFactorySettings.URLS_SETTING, ldapUrl)
|
.put(SessionFactorySettings.URLS_SETTING, ldapUrl)
|
||||||
.put(ActiveDirectorySessionFactorySettings.AD_DOMAIN_NAME_SETTING, adDomainName);
|
.put(ActiveDirectorySessionFactorySettings.AD_DOMAIN_NAME_SETTING, adDomainName)
|
||||||
|
.put(ActiveDirectorySessionFactorySettings.AD_LDAP_PORT_SETTING.getKey(), AD_LDAP_PORT)
|
||||||
|
.put(ActiveDirectorySessionFactorySettings.AD_LDAPS_PORT_SETTING.getKey(), AD_LDAPS_PORT)
|
||||||
|
.put(ActiveDirectorySessionFactorySettings.AD_GC_LDAP_PORT_SETTING.getKey(), AD_GC_LDAP_PORT)
|
||||||
|
.put(ActiveDirectorySessionFactorySettings.AD_GC_LDAPS_PORT_SETTING.getKey(), AD_GC_LDAPS_PORT)
|
||||||
|
.put("follow_referrals", FOLLOW_REFERRALS);
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
builder.put("ssl.verification_mode", hostnameVerification ? VerificationMode.FULL : VerificationMode.CERTIFICATE);
|
builder.put("ssl.verification_mode", hostnameVerification ? VerificationMode.FULL : VerificationMode.CERTIFICATE);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.integration.ldap;
|
package org.elasticsearch.xpack.security.authc.ldap;
|
||||||
|
|
||||||
import org.elasticsearch.test.junit.annotations.Network;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -13,8 +11,7 @@ import java.io.IOException;
|
||||||
* This tests the group to role mappings from LDAP sources provided by the super class - available from super.realmConfig.
|
* This tests the group to role mappings from LDAP sources provided by the super class - available from super.realmConfig.
|
||||||
* The super class will provide appropriate group mappings via configGroupMappings()
|
* The super class will provide appropriate group mappings via configGroupMappings()
|
||||||
*/
|
*/
|
||||||
@Network
|
public class GroupMappingIT extends AbstractAdLdapRealmTestCase {
|
||||||
public class GroupMappingTests extends AbstractAdLdapRealmTestCase {
|
|
||||||
public void testAuthcAuthz() throws IOException {
|
public void testAuthcAuthz() throws IOException {
|
||||||
String avenger = realmConfig.loginWithCommonName ? "Natasha Romanoff" : "blackwidow";
|
String avenger = realmConfig.loginWithCommonName ? "Natasha Romanoff" : "blackwidow";
|
||||||
assertAccessAllowed(avenger, "avengers");
|
assertAccessAllowed(avenger, "avengers");
|
|
@ -3,9 +3,8 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.integration.ldap;
|
package org.elasticsearch.xpack.security.authc.ldap;
|
||||||
|
|
||||||
import org.elasticsearch.test.junit.annotations.Network;
|
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -14,8 +13,7 @@ import java.util.ArrayList;
|
||||||
/**
|
/**
|
||||||
* This tests the mapping of multiple groups to a role in a file based role-mapping
|
* This tests the mapping of multiple groups to a role in a file based role-mapping
|
||||||
*/
|
*/
|
||||||
@Network
|
public class MultiGroupMappingIT extends AbstractAdLdapRealmTestCase {
|
||||||
public class MultiGroupMappingTests extends AbstractAdLdapRealmTestCase {
|
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setRoleMappingType() {
|
public static void setRoleMappingType() {
|
|
@ -3,11 +3,10 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.integration.ldap;
|
package org.elasticsearch.xpack.security.authc.ldap;
|
||||||
|
|
||||||
import org.elasticsearch.common.logging.ESLoggerFactory;
|
import org.elasticsearch.common.logging.ESLoggerFactory;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.test.junit.annotations.Network;
|
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -21,8 +20,7 @@ import java.util.stream.Collectors;
|
||||||
* The required behaviour is that users from both realms (directory servers) can be authenticated using
|
* The required behaviour is that users from both realms (directory servers) can be authenticated using
|
||||||
* just their userid (the AuthenticationService tries them in order)
|
* just their userid (the AuthenticationService tries them in order)
|
||||||
*/
|
*/
|
||||||
@Network
|
public class MultipleAdRealmIT extends AbstractAdLdapRealmTestCase {
|
||||||
public class MultipleAdRealmTests extends AbstractAdLdapRealmTestCase {
|
|
||||||
|
|
||||||
private static RealmConfig secondaryRealmConfig;
|
private static RealmConfig secondaryRealmConfig;
|
||||||
|
|
|
@ -10,7 +10,6 @@ import com.unboundid.ldap.sdk.SearchRequest;
|
||||||
import com.unboundid.ldap.sdk.SearchScope;
|
import com.unboundid.ldap.sdk.SearchScope;
|
||||||
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.test.junit.annotations.Network;
|
|
||||||
import org.elasticsearch.xpack.core.security.support.NoOpLogger;
|
import org.elasticsearch.xpack.core.security.support.NoOpLogger;
|
||||||
import org.elasticsearch.xpack.security.authc.ldap.support.LdapUtils;
|
import org.elasticsearch.xpack.security.authc.ldap.support.LdapUtils;
|
||||||
|
|
||||||
|
@ -22,7 +21,6 @@ import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
import static org.hamcrest.Matchers.hasItems;
|
import static org.hamcrest.Matchers.hasItems;
|
||||||
|
|
||||||
@Network
|
|
||||||
public class UserAttributeGroupsResolverTests extends GroupsResolverTestCase {
|
public class UserAttributeGroupsResolverTests extends GroupsResolverTestCase {
|
||||||
|
|
||||||
public static final String BRUCE_BANNER_DN = "cn=Bruce Banner,CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com";
|
public static final String BRUCE_BANNER_DN = "cn=Bruce Banner,CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com";
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
Vagrant.configure("2") do |config|
|
||||||
|
|
||||||
|
config.vm.define "test.ad.elastic.local" do |config|
|
||||||
|
config.vm.box = "elastic/ubuntu-16.04-x86_64"
|
||||||
|
end
|
||||||
|
|
||||||
|
config.vm.hostname = "ad.test.elastic.local"
|
||||||
|
|
||||||
|
if Vagrant.has_plugin?("vagrant-cachier")
|
||||||
|
config.cache.scope = :box
|
||||||
|
end
|
||||||
|
|
||||||
|
config.vm.network "forwarded_port", guest: 389, host: 61389, protocol: "tcp"
|
||||||
|
config.vm.network "forwarded_port", guest: 636, host: 61636, protocol: "tcp"
|
||||||
|
config.vm.network "forwarded_port", guest: 3268, host: 63268, protocol: "tcp"
|
||||||
|
config.vm.network "forwarded_port", guest: 3269, host: 63269, protocol: "tcp"
|
||||||
|
|
||||||
|
config.vm.provision "shell", path: "src/main/resources/provision/installsmb.sh"
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,43 @@
|
||||||
|
apply plugin: 'elasticsearch.build'
|
||||||
|
|
||||||
|
Map<String, String> vagrantEnvVars = [
|
||||||
|
'VAGRANT_CWD' : "${project.projectDir.absolutePath}",
|
||||||
|
'VAGRANT_VAGRANTFILE' : 'Vagrantfile',
|
||||||
|
'VAGRANT_PROJECT_DIR' : "${project.projectDir.absolutePath}"
|
||||||
|
]
|
||||||
|
|
||||||
|
String box = "test.ad.elastic.local"
|
||||||
|
|
||||||
|
task update(type: org.elasticsearch.gradle.vagrant.VagrantCommandTask) {
|
||||||
|
command 'box'
|
||||||
|
subcommand 'update'
|
||||||
|
boxName box
|
||||||
|
environmentVars vagrantEnvVars
|
||||||
|
}
|
||||||
|
|
||||||
|
task up(type: org.elasticsearch.gradle.vagrant.VagrantCommandTask) {
|
||||||
|
command 'up'
|
||||||
|
args '--provision', '--provider', 'virtualbox'
|
||||||
|
boxName box
|
||||||
|
environmentVars vagrantEnvVars
|
||||||
|
dependsOn update
|
||||||
|
}
|
||||||
|
|
||||||
|
task halt(type: org.elasticsearch.gradle.vagrant.VagrantCommandTask) {
|
||||||
|
command 'halt'
|
||||||
|
boxName box
|
||||||
|
environmentVars vagrantEnvVars
|
||||||
|
}
|
||||||
|
|
||||||
|
task destroy(type: org.elasticsearch.gradle.vagrant.VagrantCommandTask) {
|
||||||
|
command 'destroy'
|
||||||
|
args '-f'
|
||||||
|
boxName box
|
||||||
|
environmentVars vagrantEnvVars
|
||||||
|
dependsOn halt
|
||||||
|
}
|
||||||
|
|
||||||
|
thirdPartyAudit.enabled = false
|
||||||
|
licenseHeaders.enabled = false
|
||||||
|
test.enabled = false
|
||||||
|
jarHell.enabled = false
|
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEogIBAAKCAQEApAA/+F2xZ27cKT9m16iyK3KeZclMKeR5wFhIu2OBiH2s8MWm
|
||||||
|
mP0p2xnv7k/0W/Eu/+3hjDzVgjbhOseTQKcysP9AFpcOI8Z5P1vpP+BZZWbXNCPb
|
||||||
|
/nruAfZRoiQh9/LurT0Ej0gJdIoMFFdEwuBVHX2KImTBZvdvlNW9pAjgzywSYkgd
|
||||||
|
d6Lb9x8QpVHmEGmu3N4qS+Dqj0NfH6cO/ZkRRnuK3mkQ3kCMPm3RLfKa2VRTmWqe
|
||||||
|
vx6vr9Byu5rYRfETUfI8SSk38LCXu0XUgIx2C5++CG3mqXX8+TjdWYEy6Uj/rPl7
|
||||||
|
7sZnX7Hv1gDXuBpu0Yn6icHTMnGAMGPS22jsfwIDAQABAoIBAAYdrEUK2W7OB4/S
|
||||||
|
OXeZZuuP3rBVDW4SgyfVIwE5+L6qUSS5ejkCV+k/0l7ExIwZNnN834hnTF8KxON4
|
||||||
|
RdmHYrCPFEjDYVecMzFVsCEdsLfDWgsruyyGURHpqamuR0YD3TrAp8bgHNonu8OW
|
||||||
|
bY4G56Wt5NTbhQrd919JiUTwv9F59+6TnP9cubdt2GHDD2M6TkUNpgQS0hnM578X
|
||||||
|
zrkiQlakAi+rlC2ZQkH94wxKlm53okBliiAykUmbCOGkLUT/GaQLMoN+MZ7Wv6Ib
|
||||||
|
nsH8lC0KDcH4T9VGmxjlScIJtxGUMO+dNWx6Kg7E/MSwEasUAJOCqIofRtpDUTr4
|
||||||
|
QJNo4eECgYEA32l+vZLm7OMFxhbqGnueiZXbnc/v0kveeFTDt4OWcUozMBez5H3W
|
||||||
|
AFFILTRADNbvgEAwuK5oC1hEOH5zoRfnaGXcmWayurD8ibK/t23gE5Xf6rL/vCBN
|
||||||
|
LMS6WoKXXgCKOwQ0Ke5AoaPmca0Iq8bHFmb4pBF9C/0Z1mc1fc+RWxUCgYEAu+xD
|
||||||
|
w0zhh5Ktob8Q8eNiqVMrSa9jq0MUS1ljx6qCeIGxbuvQARkJxqms3SXwR4JjEwf3
|
||||||
|
BAzetYCTFvkqrne9jhoVyZGGS0gLXSG9v3iOaP6GIa51GZwtYhBrzDuGao+UL/Cc
|
||||||
|
ke4hXpC9S7TSoprW8WWevXVa4dy1kaoFUbrTPkMCgYAxRrx8pcUnZJ9mZLF36+I4
|
||||||
|
6IPLGA0GblOAaPnOJUjubfZCWkgEUrj70vG/frHN4y5qND5KzbUHI43QhBuO4Y3Z
|
||||||
|
2fXBJASx5s2ctX9RvvtYdosv4hFD9j/vaujLg9hNFINopvG2eeVpgZQXaJnsAWjy
|
||||||
|
CP44ed8B4O5s+tCykjC2TQKBgCMxJqt/TUjnRg7hShoSXBqbkaK17rNW14kYz1/H
|
||||||
|
5bENkJ3WGVjrSHJkuhOcFDhACa+5sR+YDWjuEB2gQcb0c5IV/niGASE996rUM8WU
|
||||||
|
nQ66g4HxOsq1/aW8r4NKrmxsQPMNWzTU5HjiICD6VuvOlWwVfLm8LW3YuEP0FBTv
|
||||||
|
KLojAoGAW2EKM7SnstY4khKnC+029aZNuSy/VE6LDcn+E5vwEUgpBN5UTqOWweTv
|
||||||
|
krlEbD1uAI6aI0Ybc4jM6uyo5LSBzw1TZRS5u3prLZxyyG10JvRD0/f/QTOI21TS
|
||||||
|
LubgfTc+LXbvUpv6F29lIxHZcIe9lX7cUzHK3Wwo24QOCsXYeqU=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,22 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDmzCCAoOgAwIBAgIUdwsnIxjgSneHNVKT6JNCCsrQ3T0wDQYJKoZIhvcNAQEL
|
||||||
|
BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l
|
||||||
|
cmF0ZWQgQ0EwHhcNMTgwMjE1MTc0ODQ2WhcNMjEwMjE0MTc0ODQ2WjA0MTIwMAYD
|
||||||
|
VQQDEylFbGFzdGljIENlcnRpZmljYXRlIFRvb2wgQXV0b2dlbmVyYXRlZCBDQTCC
|
||||||
|
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKQAP/hdsWdu3Ck/Zteosity
|
||||||
|
nmXJTCnkecBYSLtjgYh9rPDFppj9KdsZ7+5P9FvxLv/t4Yw81YI24TrHk0CnMrD/
|
||||||
|
QBaXDiPGeT9b6T/gWWVm1zQj2/567gH2UaIkIffy7q09BI9ICXSKDBRXRMLgVR19
|
||||||
|
iiJkwWb3b5TVvaQI4M8sEmJIHXei2/cfEKVR5hBprtzeKkvg6o9DXx+nDv2ZEUZ7
|
||||||
|
it5pEN5AjD5t0S3ymtlUU5lqnr8er6/Qcrua2EXxE1HyPEkpN/Cwl7tF1ICMdguf
|
||||||
|
vght5ql1/Pk43VmBMulI/6z5e+7GZ1+x79YA17gabtGJ+onB0zJxgDBj0tto7H8C
|
||||||
|
AwEAAaOBpDCBoTAdBgNVHQ4EFgQUZo2Y3maL2NoxbbkwRZiC37k6QMEwbwYDVR0j
|
||||||
|
BGgwZoAUZo2Y3maL2NoxbbkwRZiC37k6QMGhOKQ2MDQxMjAwBgNVBAMTKUVsYXN0
|
||||||
|
aWMgQ2VydGlmaWNhdGUgVG9vbCBBdXRvZ2VuZXJhdGVkIENBghR3CycjGOBKd4c1
|
||||||
|
UpPok0IKytDdPTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBf
|
||||||
|
mkc4bvUR5+We/2rRqCmP4LFnl/LxfbZ9/pUPRdcxuowuK7YfxN8i44VXGpJvLtec
|
||||||
|
izhA8gvlj6GbYB/GNlHMogqEORbrMlu2o5Cev4HE/pcWpoqtVaDJqI5Hq4763EmJ
|
||||||
|
p2dXGMmU04H4LtkcCEt3xQfLQ+QIP4Dl2yEsNd248BKSsscCGm9V3vgzFzbdgndo
|
||||||
|
zUWv9hQCaEsKNtqvnkTqDy2uFjnf+xNoXFr/bI94gvD9HlZHnIC+g0TL5jjtSfCH
|
||||||
|
gjeXhC2bBKFtlSt4ClIdZTXWievYs6YDRREfaOi4F0757A/gf+hT0fjZ+9WWnUeM
|
||||||
|
UuvUnl71CNRnJ5JlNKBA
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -0,0 +1,22 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDoDCCAoigAwIBAgIUMVGoHuyNTjTFaoRmqFELz75jzDEwDQYJKoZIhvcNAQEL
|
||||||
|
BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l
|
||||||
|
cmF0ZWQgQ0EwHhcNMTgwMjE1MTc0OTExWhcNMjEwMjE0MTc0OTExWjARMQ8wDQYD
|
||||||
|
VQQDEwZzYW1iYTQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtGBwa
|
||||||
|
n+7JN2vweSUsYh4zPmh8RPIE+nEVjK1lx/rADUBY7UVjfTYC+MVKKiezZe7gYCNT
|
||||||
|
7JNKazPpgVI9e3ZFKw/UxomLqRuuvn5bTh+1tMs3afY5+GGzi7oPmEbBO3ceg0Hi
|
||||||
|
rNSTDa1rfroZnRYK8uIeSZacQnAW90plITI7rBBt9jq+W9albFbDybfDgNv+yS/C
|
||||||
|
rzIsofm4rbFC3SMRYfrT6HvwDhjOmmYKZci5x7tsn0T+3tSiR44Bw5/DgiN5kX3m
|
||||||
|
/kl9qg1eoYWbCUy1dKmQlb4Nb4uNcxrIugLB3zjBkfhMZ0OHoveKh/lJASTWik9k
|
||||||
|
xQ9rEYbpsRbuXpsHAgMBAAGjgcwwgckwHQYDVR0OBBYEFJOLa7UXKtLPibgKeFh7
|
||||||
|
Kq1+rS0/MG8GA1UdIwRoMGaAFGaNmN5mi9jaMW25MEWYgt+5OkDBoTikNjA0MTIw
|
||||||
|
MAYDVQQDEylFbGFzdGljIENlcnRpZmljYXRlIFRvb2wgQXV0b2dlbmVyYXRlZCBD
|
||||||
|
QYIUdwsnIxjgSneHNVKT6JNCCsrQ3T0wLAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/
|
||||||
|
AAABhxAAAAAAAAAAAAAAAAAAAAABMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQAD
|
||||||
|
ggEBAEHqT1WHkcF8DuOgyIBx7wKcUVQ5H1qYYlJ1xgMGrKFFZLUzouLcON7oadEu
|
||||||
|
HLIJ4Z3AKD3bqWpcls5XJ9MTECGR48tou67x9cXqTV7jR3Rh0H/VGwzwhR85vbpu
|
||||||
|
o8ielOPL8XAQOfnAFESJii5sfCU4ZwLg+3evmGZdKfhU6rqQtLimgG/Gm96vOJne
|
||||||
|
y0a/TZTWrfAarithkOHHXSSAhEI5SdW5SlZAytF4AmYqFvafwxe1+NyFwfCRy0Xl
|
||||||
|
H40WgVsq+z84psU+WyORb3THX5rgB4au9nuMXOqFKAtrJSI/uApncYraaqU28rqB
|
||||||
|
gYd8XrtjhKOLw+6viqAKu8l7/cs=
|
||||||
|
-----END CERTIFICATE-----
|
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEogIBAAKCAQEArRgcGp/uyTdr8HklLGIeMz5ofETyBPpxFYytZcf6wA1AWO1F
|
||||||
|
Y302AvjFSions2Xu4GAjU+yTSmsz6YFSPXt2RSsP1MaJi6kbrr5+W04ftbTLN2n2
|
||||||
|
Ofhhs4u6D5hGwTt3HoNB4qzUkw2ta366GZ0WCvLiHkmWnEJwFvdKZSEyO6wQbfY6
|
||||||
|
vlvWpWxWw8m3w4Db/skvwq8yLKH5uK2xQt0jEWH60+h78A4YzppmCmXIuce7bJ9E
|
||||||
|
/t7UokeOAcOfw4IjeZF95v5JfaoNXqGFmwlMtXSpkJW+DW+LjXMayLoCwd84wZH4
|
||||||
|
TGdDh6L3iof5SQEk1opPZMUPaxGG6bEW7l6bBwIDAQABAoIBAFkjr2Vus3PgHLAs
|
||||||
|
Ux52MQNGwlwszU4PAymL1sgxokpBCMBDAJbppmUFY+R7rRJQDiJyn/7aOEf8yTEZ
|
||||||
|
LhcHe7LHKFH1JGRN5DmrVDsFEoNq5bRV1z2nUfk6ncjmLJnaW8/U3Js1Ugug4YwY
|
||||||
|
KRKDuRROXHAoiW1TMZJCK4fE/q+HZeG/lz110C+GJfhtCH6PzowC4eVPeh1/FExl
|
||||||
|
TFGRFh2qnN/d5IfGWaZwazTR16OGOoZf/WYydBilcugxQFNx5osR+4nAFdMW0xD2
|
||||||
|
x2diukMf+WBjIWlO3vt9GMs8PBQsU2Ix3/+MUxC5MCUafL1GBqUSphB4YWTrNWQ0
|
||||||
|
izFEYZECgYEA1Ue8S0xL6Qxy8F1cZj+tvoGlblCTxHL65JeMl6LwMHzuNHX27s8Q
|
||||||
|
Ax9j8Z2MTWH7IBATmA56CYlA09FWRiIr38k7cNUC8KdjvjPeqHKJeTIhluiBWGLl
|
||||||
|
AE2XbEkOdjBXXg7ipF0tcBWb+/WrobzJ2T9dpMzZZOnWEB+7wsN2fy0CgYEAz8PG
|
||||||
|
TJ0u/+2q+RfeAxo0zdC/dwx8T5rJfZD0AiJpEu69oqMZdiX2M1JDabh/CFdYWyAm
|
||||||
|
AWQdSw0ugeUHeiZ0i2gujtbxDLAhpCsQ1jleJpJm7VWvgCKY7FotmXhVxA8Acmm0
|
||||||
|
slv280ezNJMJFKIONuuOtDATdX1b+MXoh5D2A4MCgYAuadwKLuJeJv1kXYzcG4N9
|
||||||
|
78zGgvaFS9hZorlPzn+ira1Q8VL5iUocw9oGHJkJxgbWZWk+L/hS1vGqpuW1gX42
|
||||||
|
xx4OYeyv3l2QaM1Nrw9Htqckphhv2aWoOTp4sDVbdw2sRGUCC9z1hV5aqI3fNqxe
|
||||||
|
gLGqSYINue2BuMYtjkfdSQKBgC0uefU3SX1GhiPdWN572HfZqYmOIYp+Mssntqiw
|
||||||
|
KwF/AaZYqbTT1JKclSRshtOdiw1mFF3BE826dB6zW8joi/e1FErj20/TDb3Rz7uG
|
||||||
|
hj8FH3UFaUEIRRFBGyGA1cXpLUO0USNodG+7a/FG+HaQN18iIsp0mga22EVlZIf2
|
||||||
|
sklZAoGAOJTQtMJfVk5KvqaZWnFou1De5BLnTq7LEvuNHlddIlXG0QQe9QcyB82G
|
||||||
|
UFqbpBR8QBTFsHdIQEA4LNQE7L1WrKR2Qj087QXHaUnlo7x2WPoSyziPet0nUn3E
|
||||||
|
gE5dgnkzX/MENKjG90wJFWNiJqz3JXIbVZKZLzkbM+u+X2+oRvs=
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,95 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
# or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
# you may not use this file except in compliance with the Elastic License.
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
|
||||||
|
MARKER_FILE=/etc/marker
|
||||||
|
|
||||||
|
if [ -f $MARKER_FILE ]; then
|
||||||
|
echo "Already provisioned..."
|
||||||
|
exit 0;
|
||||||
|
fi
|
||||||
|
|
||||||
|
VDIR=/vagrant
|
||||||
|
RESOURCES=$VDIR/src/main/resources
|
||||||
|
CERTS_DIR=$RESOURCES/certs
|
||||||
|
SSL_DIR=/var/lib/samba/private/tls
|
||||||
|
|
||||||
|
# Update package manager
|
||||||
|
apt-get update -qqy
|
||||||
|
|
||||||
|
# Install krb5 packages
|
||||||
|
apt-get install -qqy samba ldap-utils
|
||||||
|
|
||||||
|
# install ssl certs
|
||||||
|
mkdir -p $SSL_DIR
|
||||||
|
cp $CERTS_DIR/*.pem $SSL_DIR
|
||||||
|
chmod 600 $SSL_DIR/key.pem
|
||||||
|
|
||||||
|
cat $SSL_DIR/ca.pem >> /etc/ssl/certs/ca-certificates.crt
|
||||||
|
|
||||||
|
mv /etc/samba/smb.conf /etc/samba/smb.conf.orig
|
||||||
|
|
||||||
|
samba-tool domain provision --server-role=dc --use-rfc2307 --dns-backend=SAMBA_INTERNAL --realm=AD.TEST.ELASTICSEARCH.COM --domain=ADES --adminpass=Passw0rd
|
||||||
|
|
||||||
|
cp /var/lib/samba/private/krb5.conf /etc/krb5.conf
|
||||||
|
|
||||||
|
service samba-ad-dc restart
|
||||||
|
|
||||||
|
# Add users
|
||||||
|
samba-tool user add ironman Passw0rd --surname=Stark --given-name=Tony --job-title=CEO
|
||||||
|
samba-tool user add hulk Passw0rd --surname=Banner --given-name=Bruce
|
||||||
|
samba-tool user add phil Passw0rd --surname=Coulson --given-name=Phil
|
||||||
|
samba-tool user add cap Passw0rd --surname=Rogers --given-name=Steve
|
||||||
|
samba-tool user add blackwidow Passw0rd --surname=Romanoff --given-name=Natasha
|
||||||
|
samba-tool user add hawkeye Passw0rd --surname=Barton --given-name=Clint
|
||||||
|
samba-tool user add Thor Passw0rd
|
||||||
|
samba-tool user add selvig Passw0rd --surname=Selvig --given-name=Erik
|
||||||
|
samba-tool user add Odin Passw0rd
|
||||||
|
samba-tool user add Jarvis Passw0rd
|
||||||
|
samba-tool user add kraken Passw0rd --surname=Kraken --given-name=Commander
|
||||||
|
samba-tool user add fury Passw0rd --surname=Fury --given-name=Nick
|
||||||
|
|
||||||
|
# Add groups
|
||||||
|
samba-tool group add SHIELD
|
||||||
|
samba-tool group add Avengers
|
||||||
|
samba-tool group add Supers
|
||||||
|
samba-tool group add Geniuses
|
||||||
|
samba-tool group add Playboys
|
||||||
|
samba-tool group add Philanthropists
|
||||||
|
samba-tool group add Gods
|
||||||
|
samba-tool group add Billionaires
|
||||||
|
samba-tool group add "World Security Council"
|
||||||
|
samba-tool group add Hydra
|
||||||
|
|
||||||
|
# Group membership
|
||||||
|
samba-tool group addmembers "SHIELD" Thor,hawkeye,blackwidow,cap,phil,hulk,ironman
|
||||||
|
samba-tool group addmembers "Avengers" Thor,hawkeye,blackwidow,cap,hulk,ironman
|
||||||
|
samba-tool group addmembers "Supers" Avengers
|
||||||
|
samba-tool group addmembers "Geniuses" selvig,hulk,ironman
|
||||||
|
samba-tool group addmembers "Playboys" ironman
|
||||||
|
samba-tool group addmembers "Philanthropists" Thor,hulk,ironman
|
||||||
|
samba-tool group addmembers "Gods" Thor,Odin
|
||||||
|
samba-tool group addmembers "Billionaires" ironman
|
||||||
|
samba-tool group addmembers "World Security Council" fury
|
||||||
|
samba-tool group addmembers "Hydra" kraken
|
||||||
|
|
||||||
|
# update UPN
|
||||||
|
cat > /tmp/entrymods << EOL
|
||||||
|
dn: CN=Erik Selvig,CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com
|
||||||
|
changetype: modify
|
||||||
|
replace: userPrincipalName
|
||||||
|
userPrincipalName: erik.selvig@ad.test.elasticsearch.com
|
||||||
|
|
||||||
|
dn: CN=Bruce Banner,CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com
|
||||||
|
changetype: modify
|
||||||
|
add: seeAlso
|
||||||
|
seeAlso: CN=Avengers,CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com
|
||||||
|
EOL
|
||||||
|
|
||||||
|
ldapmodify -D Administrator@ad.test.elasticsearch.com -w Passw0rd -H ldaps://127.0.0.1:636 -f /tmp/entrymods -v
|
||||||
|
|
||||||
|
touch $MARKER_FILE
|
Loading…
Reference in New Issue