diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/security/Security.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/security/Security.java index 5de2fde245d..52ce20a19e0 100644 --- a/elasticsearch/src/main/java/org/elasticsearch/xpack/security/Security.java +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/security/Security.java @@ -445,7 +445,14 @@ public class Security implements ActionPlugin, IngestPlugin, NetworkPlugin { assert licenseState != null; if (XPackSettings.DLS_FLS_ENABLED.get(settings)) { module.setSearcherWrapper(indexService -> - new SecurityIndexSearcherWrapper(indexService.getIndexSettings(), indexService.newQueryShardContext(), + new SecurityIndexSearcherWrapper(indexService.getIndexSettings(), + shardId -> indexService.newQueryShardContext(shardId.id(), + // we pass a null index reader, which is legal and will disable rewrite optimizations + // based on index statistics, which is probably safer... + null, + () -> { + throw new IllegalArgumentException("permission filters are not allowed to use the current timestamp"); + }), indexService.mapperService(), indexService.cache().bitsetFilterCache(), indexService.getThreadPool().getThreadContext(), licenseState, indexService.getScriptService())); diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapper.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapper.java index 2cbafbfb4da..716403eebf7 100644 --- a/elasticsearch/src/main/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapper.java +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapper.java @@ -82,6 +82,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.function.Function; import static org.apache.lucene.search.BooleanClause.Occur.SHOULD; @@ -100,21 +101,21 @@ public class SecurityIndexSearcherWrapper extends IndexSearcherWrapper { private final MapperService mapperService; private final Set allowedMetaFields; - private final QueryShardContext queryShardContext; + private final Function queryShardContextProvider; private final BitsetFilterCache bitsetFilterCache; private final XPackLicenseState licenseState; private final ThreadContext threadContext; private final Logger logger; private final ScriptService scriptService; - public SecurityIndexSearcherWrapper(IndexSettings indexSettings, QueryShardContext queryShardContext, + public SecurityIndexSearcherWrapper(IndexSettings indexSettings, Function queryShardContextProvider, MapperService mapperService, BitsetFilterCache bitsetFilterCache, ThreadContext threadContext, XPackLicenseState licenseState, ScriptService scriptService) { this.scriptService = scriptService; this.logger = Loggers.getLogger(getClass(), indexSettings.getSettings()); this.mapperService = mapperService; - this.queryShardContext = queryShardContext; + this.queryShardContextProvider = queryShardContextProvider; this.bitsetFilterCache = bitsetFilterCache; this.threadContext = threadContext; this.licenseState = licenseState; @@ -153,7 +154,7 @@ public class SecurityIndexSearcherWrapper extends IndexSearcherWrapper { if (permissions.getQueries() != null) { BooleanQuery.Builder filter = new BooleanQuery.Builder(); for (BytesReference bytesReference : permissions.getQueries()) { - QueryShardContext queryShardContext = copyQueryShardContext(this.queryShardContext); + QueryShardContext queryShardContext = queryShardContextProvider.apply(shardId); bytesReference = evaluateTemplate(bytesReference); try (XContentParser parser = XContentFactory.xContent(bytesReference).createParser(bytesReference)) { Optional queryBuilder = queryShardContext.newParseContext(parser).parseInnerQueryBuilder(); @@ -263,11 +264,6 @@ public class SecurityIndexSearcherWrapper extends IndexSearcherWrapper { return allowedMetaFields; } - // for testing: - protected QueryShardContext copyQueryShardContext(QueryShardContext context) { - return new QueryShardContext(context); - } - private void resolveParentChildJoinFields(Set allowedFields) { for (DocumentMapper mapper : mapperService.docMappers(false)) { ParentFieldMapper parentFieldMapper = mapper.parentFieldMapper(); diff --git a/elasticsearch/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperIntegrationTests.java b/elasticsearch/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperIntegrationTests.java index a919b32d723..341a2e31e63 100644 --- a/elasticsearch/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperIntegrationTests.java +++ b/elasticsearch/src/test/java/org/elasticsearch/xpack/security/authz/accesscontrol/SecurityIndexSearcherWrapperIntegrationTests.java @@ -92,14 +92,9 @@ public class SecurityIndexSearcherWrapperIntegrationTests extends ESTestCase { }); XPackLicenseState licenseState = mock(XPackLicenseState.class); when(licenseState.isDocumentAndFieldLevelSecurityAllowed()).thenReturn(true); - SecurityIndexSearcherWrapper wrapper = new SecurityIndexSearcherWrapper(indexSettings, queryShardContext, mapperService, + SecurityIndexSearcherWrapper wrapper = new SecurityIndexSearcherWrapper(indexSettings, s -> queryShardContext, mapperService, bitsetFilterCache, threadContext, licenseState, scriptService) { - @Override - protected QueryShardContext copyQueryShardContext(QueryShardContext context) { - return queryShardContext; - } - @Override protected IndicesAccessControl getIndicesAccessControl() { return new IndicesAccessControl(true, singletonMap("_index", indexAccessControl));