Remove copy-pasted code (elastic/x-pack-elasticsearch#4298)
* Remove copy-pasted code An examination of the x-pack source code revealed copy-pasted code in ActiveDirectoryGroupsResolver in the binarySidToStringSid method. I have replaced this with an apache2 implementation from the apache directory studio project. Furthermore, I have added a test that leverages a real binary/string SID pair retrieved from an active directory domain controller. The apache2-based implementation is exempt for the license checker. Original commit: elastic/x-pack-elasticsearch@81a7471261
This commit is contained in:
parent
650b80a982
commit
8d6f36c507
|
@ -13,6 +13,7 @@
|
||||||
<suppress files="plugin[/\\]core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]persistent[/\\]CompletionPersistentTaskAction.java" checks="LineLength" />
|
<suppress files="plugin[/\\]core[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]persistent[/\\]CompletionPersistentTaskAction.java" checks="LineLength" />
|
||||||
<suppress files="plugin[/\\]security[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]security[/\\]Security.java" checks="LineLength" />
|
<suppress files="plugin[/\\]security[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]security[/\\]Security.java" checks="LineLength" />
|
||||||
<suppress files="plugin[/\\]security[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]security[/\\]authc[/\\]Realms.java" checks="LineLength" />
|
<suppress files="plugin[/\\]security[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]security[/\\]authc[/\\]Realms.java" checks="LineLength" />
|
||||||
|
<suppress files="plugin[/\\]security[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]security[/\\]authc[/\\]ldap[/\\]ActiveDirectorySIDUtil.java" checks="LineLength" />
|
||||||
<suppress files="plugin[/\\]ml[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]ml[/\\]integration[/\\]TooManyJobsIT.java" checks="LineLength" />
|
<suppress files="plugin[/\\]ml[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]ml[/\\]integration[/\\]TooManyJobsIT.java" checks="LineLength" />
|
||||||
<suppress files="plugin[/\\]core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]persistent[/\\]TestPersistentTasksPlugin.java" checks="LineLength" />
|
<suppress files="plugin[/\\]core[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]persistent[/\\]TestPersistentTasksPlugin.java" checks="LineLength" />
|
||||||
<suppress files="plugin[/\\]security[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]security[/\\]action[/\\]user[/\\]TransportGetUsersActionTests.java" checks="LineLength" />
|
<suppress files="plugin[/\\]security[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]xpack[/\\]security[/\\]action[/\\]user[/\\]TransportGetUsersActionTests.java" checks="LineLength" />
|
||||||
|
|
|
@ -84,6 +84,11 @@ dependencyLicenses {
|
||||||
mapping from: /http.*/, to: 'httpclient'
|
mapping from: /http.*/, to: 'httpclient'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
licenseHeaders {
|
||||||
|
// This class was sourced from apache directory studio for some microsoft-specific logic
|
||||||
|
excludes << 'org/elasticsearch/xpack/security/authc/ldap/ActiveDirectorySIDUtil.java'
|
||||||
|
}
|
||||||
|
|
||||||
forbiddenPatterns {
|
forbiddenPatterns {
|
||||||
exclude '**/*.key'
|
exclude '**/*.key'
|
||||||
exclude '**/*.p12'
|
exclude '**/*.p12'
|
||||||
|
|
|
@ -30,7 +30,7 @@ import static org.elasticsearch.xpack.security.authc.ldap.support.LdapUtils.OBJE
|
||||||
import static org.elasticsearch.xpack.security.authc.ldap.support.LdapUtils.search;
|
import static org.elasticsearch.xpack.security.authc.ldap.support.LdapUtils.search;
|
||||||
import static org.elasticsearch.xpack.security.authc.ldap.support.LdapUtils.searchForEntry;
|
import static org.elasticsearch.xpack.security.authc.ldap.support.LdapUtils.searchForEntry;
|
||||||
import static org.elasticsearch.xpack.core.security.authc.ldap.support.SessionFactorySettings.IGNORE_REFERRAL_ERRORS_SETTING;
|
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;
|
||||||
|
|
||||||
class ActiveDirectoryGroupsResolver implements GroupsResolver {
|
class ActiveDirectoryGroupsResolver implements GroupsResolver {
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ class ActiveDirectoryGroupsResolver implements GroupsResolver {
|
||||||
} else {
|
} else {
|
||||||
final byte[][] tokenGroupSIDBytes = entry.getAttributeValueByteArrays(TOKEN_GROUPS);
|
final byte[][] tokenGroupSIDBytes = entry.getAttributeValueByteArrays(TOKEN_GROUPS);
|
||||||
List<Filter> orFilters = Arrays.stream(tokenGroupSIDBytes)
|
List<Filter> orFilters = Arrays.stream(tokenGroupSIDBytes)
|
||||||
.map((sidBytes) -> Filter.createEqualityFilter("objectSid", binarySidToStringSid(sidBytes)))
|
.map((sidBytes) -> Filter.createEqualityFilter("objectSid", convertToString(sidBytes)))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
listener.onResponse(Filter.createORFilter(orFilters));
|
listener.onResponse(Filter.createORFilter(orFilters));
|
||||||
}
|
}
|
||||||
|
@ -92,46 +92,4 @@ class ActiveDirectoryGroupsResolver implements GroupsResolver {
|
||||||
TOKEN_GROUPS);
|
TOKEN_GROUPS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* To better understand what the sid is and how its string representation looks like, see
|
|
||||||
* http://blogs.msdn.com/b/alextch/archive/2007/06/18/sample-java-application-that-retrieves-group-membership-of-an-active-directory
|
|
||||||
* -user-account.aspx
|
|
||||||
*
|
|
||||||
* @param SID byte encoded security ID
|
|
||||||
*/
|
|
||||||
private static String binarySidToStringSid(byte[] SID) {
|
|
||||||
String strSID;
|
|
||||||
|
|
||||||
//convert the SID into string format
|
|
||||||
|
|
||||||
long version;
|
|
||||||
long authority;
|
|
||||||
long count;
|
|
||||||
long rid;
|
|
||||||
|
|
||||||
strSID = "S";
|
|
||||||
version = SID[0];
|
|
||||||
strSID = strSID + "-" + Long.toString(version);
|
|
||||||
authority = SID[4];
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
authority <<= 8;
|
|
||||||
authority += SID[4 + i] & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
strSID = strSID + "-" + Long.toString(authority);
|
|
||||||
count = SID[2];
|
|
||||||
count <<= 8;
|
|
||||||
count += SID[1] & 0xFF;
|
|
||||||
for (int j = 0; j < count; j++) {
|
|
||||||
rid = SID[11 + (j * 4)] & 0xFF;
|
|
||||||
for (int k = 1; k < 4; k++) {
|
|
||||||
rid <<= 8;
|
|
||||||
rid += SID[11 - k + (j * 4)] & 0xFF;
|
|
||||||
}
|
|
||||||
strSID = strSID + "-" + Long.toString(rid);
|
|
||||||
}
|
|
||||||
return strSID;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code sourced from:http://svn.apache.org/repos/asf/directory/studio/tags/2.0.0.v20170904-M13/plugins/valueeditors/src/main/java/org/apache/directory/studio/valueeditors/msad/InPlaceMsAdObjectSidValueEditor.java
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.xpack.security.authc.ldap;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
|
||||||
|
class ActiveDirectorySIDUtil {
|
||||||
|
|
||||||
|
static String convertToString( byte[] bytes )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The binary data structure, from http://msdn.microsoft.com/en-us/library/cc230371(PROT.10).aspx:
|
||||||
|
* byte[0] - Revision (1 byte): An 8-bit unsigned integer that specifies the revision level of
|
||||||
|
* the SID structure. This value MUST be set to 0x01.
|
||||||
|
* byte[1] - SubAuthorityCount (1 byte): An 8-bit unsigned integer that specifies the number of
|
||||||
|
* elements in the SubAuthority array. The maximum number of elements allowed is 15.
|
||||||
|
* byte[2-7] - IdentifierAuthority (6 bytes): A SID_IDENTIFIER_AUTHORITY structure that contains
|
||||||
|
* information, which indicates the authority under which the SID was created. It describes the
|
||||||
|
* entity that created the SID and manages the account.
|
||||||
|
* Six element arrays of 8-bit unsigned integers that specify the top-level authority
|
||||||
|
* big-endian!
|
||||||
|
* and then - SubAuthority (variable): A variable length array of unsigned 32-bit integers that
|
||||||
|
* uniquely identifies a principal relative to the IdentifierAuthority. Its length is determined
|
||||||
|
* by SubAuthorityCount. little-endian!
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ( bytes == null ) || ( bytes.length < 8 ) )
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Invalid SID");
|
||||||
|
}
|
||||||
|
|
||||||
|
char[] hex = Hex.encodeHex( bytes );
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
// start with 'S'
|
||||||
|
sb.append( 'S' );
|
||||||
|
|
||||||
|
// revision
|
||||||
|
int revision = Integer.parseInt( new String( hex, 0, 2 ), 16 );
|
||||||
|
sb.append( '-' );
|
||||||
|
sb.append( revision );
|
||||||
|
|
||||||
|
// get count
|
||||||
|
int count = Integer.parseInt( new String( hex, 2, 2 ), 16 );
|
||||||
|
|
||||||
|
// check length
|
||||||
|
if ( bytes.length != ( 8 + count * 4 ) )
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Invalid SID");
|
||||||
|
}
|
||||||
|
|
||||||
|
// get authority, big-endian
|
||||||
|
long authority = Long.parseLong( new String( hex, 4, 12 ), 16 );
|
||||||
|
sb.append( '-' );
|
||||||
|
sb.append( authority );
|
||||||
|
|
||||||
|
// sub-authorities, little-endian
|
||||||
|
for ( int i = 0; i < count; i++ )
|
||||||
|
{
|
||||||
|
StringBuffer rid = new StringBuffer();
|
||||||
|
|
||||||
|
for ( int k = 3; k >= 0; k-- )
|
||||||
|
{
|
||||||
|
rid.append( hex[16 + ( i * 8 ) + ( k * 2 )] );
|
||||||
|
rid.append( hex[16 + ( i * 8 ) + ( k * 2 ) + 1] );
|
||||||
|
}
|
||||||
|
|
||||||
|
long subAuthority = Long.parseLong( rid.toString(), 16 );
|
||||||
|
sb.append( '-' );
|
||||||
|
sb.append( subAuthority );
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.xpack.security.authc.ldap;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
|
||||||
|
public class ActiveDirectorySIDUtilTests extends ESTestCase {
|
||||||
|
|
||||||
|
private static final String USER_SID_HEX ="01050000000000051500000050bd51b583ef8ebc4c75521ae9030000";
|
||||||
|
private static final String USER_STRING_SID = "S-1-5-21-3042032976-3163484035-441611596-1001";
|
||||||
|
|
||||||
|
public void testSidConversion() throws Exception {
|
||||||
|
assertThat(USER_STRING_SID, equalTo(ActiveDirectorySIDUtil.convertToString(Hex.decodeHex(USER_SID_HEX.toCharArray()))));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue