Skip to content

Commit

Permalink
Returning tokenGroups attribute as SID string instead of byte array (e…
Browse files Browse the repository at this point in the history
…lastic#63509) (elastic#63683)

* Returning tokenGroups attribute as SID string instead of byte array (elastic#63509)

* Returning tokenGroups attribute as SID string instead of byte array (AD metadata)

Resolves: elastic#61173

* Returning tokenGroups attribute as SID string instead of byte array (AD metadata)

Resolves: elastic#61173

* Adding test

* Adding test

* Adding test

* Fixing test

* Fixing test

* Addressing PR comments

* Nit fix

* Nit fixes

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

* Fixing resolve

* Fixing conflict resolution

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
BigPandaToo and elasticmachine authored Oct 14, 2020
1 parent a73ce5b commit 92c2a5a
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@

import static org.elasticsearch.xpack.core.security.authc.ldap.support.SessionFactorySettings.IGNORE_REFERRAL_ERRORS_SETTING;
import static org.elasticsearch.xpack.security.authc.ldap.ActiveDirectorySIDUtil.convertToString;
import static org.elasticsearch.xpack.security.authc.ldap.ActiveDirectorySIDUtil.TOKEN_GROUPS;
import static org.elasticsearch.xpack.security.authc.ldap.ActiveDirectorySessionFactory.buildDnFromDomain;
import static org.elasticsearch.xpack.security.authc.ldap.support.LdapUtils.OBJECT_CLASS_PRESENCE_FILTER;
import static org.elasticsearch.xpack.security.authc.ldap.support.LdapUtils.search;
import static org.elasticsearch.xpack.security.authc.ldap.support.LdapUtils.searchForEntry;

class ActiveDirectoryGroupsResolver implements GroupsResolver {

private static final String TOKEN_GROUPS = "tokenGroups";
private final String baseDn;
private final LdapSearchScope scope;
private final boolean ignoreReferralErrors;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@

import org.apache.commons.codec.binary.Hex;

class ActiveDirectorySIDUtil {

static String convertToString( byte[] bytes )
public class ActiveDirectorySIDUtil {
public static final String TOKEN_GROUPS = "tokenGroups";
public static String convertToString(byte[] bytes)
{
/*
* The binary data structure, from http://msdn.microsoft.com/en-us/library/cc230371(PROT.10).aspx:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import java.util.function.Function;
import java.util.stream.Collectors;

import static org.elasticsearch.xpack.security.authc.ldap.ActiveDirectorySIDUtil.convertToString;
import static org.elasticsearch.xpack.security.authc.ldap.ActiveDirectorySIDUtil.TOKEN_GROUPS;
import static org.elasticsearch.xpack.security.authc.ldap.support.LdapUtils.OBJECT_CLASS_PRESENCE_FILTER;
import static org.elasticsearch.xpack.security.authc.ldap.support.LdapUtils.searchForEntry;

Expand Down Expand Up @@ -77,10 +79,15 @@ private Map<String, Object> toMap(Function<String, Attribute> attributes) {
attr -> attr.getName(),
attr -> {
final String[] values = attr.getValues();
if(attr.getName().equals(TOKEN_GROUPS)) {
return values.length == 1 ? convertToString(attr.getValueByteArrays()[0]) :
Arrays.stream(attr.getValueByteArrays())
.map((sidBytes) -> convertToString(sidBytes))
.collect(Collectors.toList());
}
return values.length == 1 ? values[0] : Arrays.asList(values);
})
})
)
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.List;
import java.util.regex.Pattern;


import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.hasItem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.elasticsearch.action.support.PlainActionFuture;
import org.elasticsearch.common.settings.SecureString;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.common.util.concurrent.UncategorizedExecutionException;
import org.elasticsearch.env.Environment;
Expand All @@ -20,11 +21,13 @@
import org.elasticsearch.xpack.core.security.authc.RealmSettings;
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.support.LdapMetadataResolverSettings;
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.ssl.SSLConfigurationSettings;
import org.elasticsearch.xpack.core.ssl.SSLService;
import org.elasticsearch.xpack.core.ssl.VerificationMode;
import org.elasticsearch.xpack.security.authc.ldap.support.LdapMetadataResolver;
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.SessionFactory;
Expand All @@ -33,21 +36,26 @@

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import static org.elasticsearch.xpack.core.security.authc.RealmSettings.getFullSettingKey;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.everyItem;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.matchesPattern;

public class ActiveDirectorySessionFactoryTests extends AbstractActiveDirectoryTestCase {

private static final String REALM_NAME = "ad-test";
private static final RealmConfig.RealmIdentifier REALM_ID = new RealmConfig.RealmIdentifier("active_directory", REALM_NAME);
private final SecureString SECURED_PASSWORD = new SecureString(PASSWORD);
private ThreadPool threadPool;
private static final String BRUCE_BANNER_DN = "cn=Bruce Banner,CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com";

@Before
public void init() throws Exception {
Expand Down Expand Up @@ -366,6 +374,35 @@ public void testADLookup() throws Exception {
}
}

@SuppressWarnings("unchecked")
public void testResolveTokenGroupsSID() throws Exception {
Settings settings = Settings.builder()
.put("path.home", createTempDir())
.put(RealmSettings.getFullSettingKey(REALM_ID, RealmSettings.ORDER_SETTING), 0)
.put(buildAdSettings(REALM_ID, AD_LDAP_URL, AD_DOMAIN, "CN=Users,DC=ad,DC=test,DC=elasticsearch,DC=com",
LdapSearchScope.SUB_TREE, false))
.put(ActiveDirectorySessionFactorySettings.AD_GROUP_SEARCH_BASEDN_SETTING, "DC=ad,DC=test,DC=elasticsearch,DC=com")
.put(ActiveDirectorySessionFactorySettings.AD_GROUP_SEARCH_SCOPE_SETTING, LdapSearchScope.SUB_TREE)
.put(getFullSettingKey(REALM_ID, LdapMetadataResolverSettings.ADDITIONAL_METADATA_SETTING), "tokenGroups")
.build();
RealmConfig config = configureRealm("ad-test", LdapRealmSettings.AD_TYPE, settings);
final PlainActionFuture<Map<String, Object>> future = new PlainActionFuture<>();
LdapMetadataResolver resolver = new LdapMetadataResolver(config, true);
try (ActiveDirectorySessionFactory sessionFactory = getActiveDirectorySessionFactory(config, sslService, threadPool)) {
String userName = "hulk";
try (LdapSession ldap = session(sessionFactory, userName, SECURED_PASSWORD)) {
assertConnectionCanReconnect(ldap.getConnection());
resolver.resolve(ldap.getConnection(), BRUCE_BANNER_DN, TimeValue.timeValueSeconds(1), logger, null, future);
Map<String, Object> metadataGroupSIDs = future.get();
assertThat(metadataGroupSIDs.size(), equalTo(1));
assertNotNull(metadataGroupSIDs.get("tokenGroups"));
List<String> SIDs = ((List<String>) metadataGroupSIDs.get("tokenGroups"));
assertThat(SIDs.size(), equalTo(7));
assertThat(SIDs, everyItem(matchesPattern("S-1-5-(?:21|32)-\\d+(?:-\\d+\\-\\d+\\-\\d+)?")));
}
}
}

private Settings buildAdSettings(String ldapUrl, String adDomainName, boolean hostnameVerification) {
return buildAdSettings(ldapUrl, adDomainName, hostnameVerification, randomBoolean());
}
Expand Down

0 comments on commit 92c2a5a

Please sign in to comment.