diff --git a/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UserRoleMapper.java b/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UserRoleMapper.java index 8c5e27ec2a9..ffdab15e3b5 100644 --- a/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UserRoleMapper.java +++ b/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/UserRoleMapper.java @@ -7,9 +7,13 @@ package org.elasticsearch.xpack.security.authc.support; import com.unboundid.ldap.sdk.DN; import com.unboundid.ldap.sdk.LDAPException; +import com.unboundid.util.LDAPSDKUsageException; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.message.ParameterizedMessage; import org.apache.lucene.util.automaton.CharacterRunAutomaton; import org.elasticsearch.action.ActionListener; import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.xpack.core.security.authc.RealmConfig; import org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl.ExpressionModel; import org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl.FieldExpression; @@ -78,7 +82,7 @@ public interface UserRoleMapper { model.defineField("dn", dn, new DistinguishedNamePredicate(dn)); model.defineField("groups", groups, groups.stream() .>map(DistinguishedNamePredicate::new) - .reduce((a, b) -> a.or(b)) + .reduce(Predicate::or) .orElse(fieldValue -> false) ); metadata.keySet().forEach(k -> model.defineField("metadata." + k, metadata.get(k))); @@ -155,6 +159,8 @@ public interface UserRoleMapper { * */ class DistinguishedNamePredicate implements Predicate { + private static final Logger LOGGER = Loggers.getLogger(DistinguishedNamePredicate.class); + private final String string; private final DN dn; @@ -164,10 +170,17 @@ public interface UserRoleMapper { } private static DN parseDn(String string) { - try { - return new DN(string); - } catch (LDAPException e) { + if (string == null) { return null; + } else { + try { + return new DN(string); + } catch (LDAPException | LDAPSDKUsageException e) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace(new ParameterizedMessage("failed to parse [{}] as a DN", string), e); + } + return null; + } } } @@ -227,7 +240,7 @@ public interface UserRoleMapper { } return testString.equalsIgnoreCase(dn.toNormalizedString()); } - return false; + return string == null && fieldValue.getValue() == null; } } } diff --git a/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/DistinguishedNamePredicateTests.java b/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/DistinguishedNamePredicateTests.java index b771ab21ae8..d04f0ad7f93 100644 --- a/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/DistinguishedNamePredicateTests.java +++ b/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/support/DistinguishedNamePredicateTests.java @@ -48,6 +48,30 @@ public class DistinguishedNamePredicateTests extends ESTestCase { assertPredicate(predicate, null, false); } + public void testParsingMalformedInput() { + Predicate predicate = new UserRoleMapper.DistinguishedNamePredicate(null); + assertPredicate(predicate, null, true); + assertPredicate(predicate, "", false); + assertPredicate(predicate, randomAlphaOfLengthBetween(1, 8), false); + + predicate = new UserRoleMapper.DistinguishedNamePredicate(""); + assertPredicate(predicate, null, false); + assertPredicate(predicate, "", true); + assertPredicate(predicate, randomAlphaOfLengthBetween(1, 8), false); + + predicate = new UserRoleMapper.DistinguishedNamePredicate("foo="); + assertPredicate(predicate, null, false); + assertPredicate(predicate, "foo", false); + assertPredicate(predicate, "foo=", true); + assertPredicate(predicate, randomAlphaOfLengthBetween(5, 12), false); + + predicate = new UserRoleMapper.DistinguishedNamePredicate("=bar"); + assertPredicate(predicate, null, false); + assertPredicate(predicate, "bar", false); + assertPredicate(predicate, "=bar", true); + assertPredicate(predicate, randomAlphaOfLengthBetween(5, 12), false); + } + private void assertPredicate(Predicate predicate, Object value, boolean expected) { assertThat("Predicate [" + predicate + "] match [" + value + "]", predicate.test(new FieldValue(value)), equalTo(expected)); }