From aa0e4d425f783910b890c68b4105b6a7610d97b9 Mon Sep 17 00:00:00 2001 From: Jay Modi Date: Mon, 17 Oct 2016 11:00:04 -0400 Subject: [PATCH] security: system user needs put mapping permissions to shrink indices The system user gets used to put mappings for an index during recovery from local shards, which is how the shrink index process works. The system user previously had this privilege in 2.x as we did not have the ThreadContext and dynamic mapping updates would be done by the system user; with the ThreadContext, these mapping updates are done by the actual user so this privilege was removed from the SystemUser. Closes elastic/elasticsearch#3766 Original commit: elastic/x-pack-elasticsearch@cd5d7bea538390a76ede2bc92ae5e1430e277c22 --- .../authz/privilege/SystemPrivilege.java | 3 +- .../ShrinkIndexWithSecurityIT.java | 59 +++++++++++++++++++ .../authz/privilege/PrivilegeTests.java | 2 +- 3 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 elasticsearch/src/test/java/org/elasticsearch/integration/ShrinkIndexWithSecurityIT.java diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/security/authz/privilege/SystemPrivilege.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/security/authz/privilege/SystemPrivilege.java index d3c32ec15a2..2b4e2d93b1c 100644 --- a/elasticsearch/src/main/java/org/elasticsearch/xpack/security/authz/privilege/SystemPrivilege.java +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/security/authz/privilege/SystemPrivilege.java @@ -19,7 +19,8 @@ public class SystemPrivilege extends Privilege { "internal:*", "indices:monitor/*", // added for monitoring "cluster:monitor/*", // added for monitoring - "cluster:admin/reroute" // added for DiskThresholdDecider.DiskListener + "cluster:admin/reroute", // added for DiskThresholdDecider.DiskListener + "indices:admin/mapping/put" // needed for recovery and shrink api )); SystemPrivilege() { diff --git a/elasticsearch/src/test/java/org/elasticsearch/integration/ShrinkIndexWithSecurityIT.java b/elasticsearch/src/test/java/org/elasticsearch/integration/ShrinkIndexWithSecurityIT.java new file mode 100644 index 00000000000..c4a62a8563f --- /dev/null +++ b/elasticsearch/src/test/java/org/elasticsearch/integration/ShrinkIndexWithSecurityIT.java @@ -0,0 +1,59 @@ +/* + * 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.integration; + +import org.elasticsearch.cluster.node.DiscoveryNode; +import org.elasticsearch.common.collect.ImmutableOpenMap; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.index.query.TermsQueryBuilder; +import org.elasticsearch.test.ESIntegTestCase.ClusterScope; +import org.elasticsearch.test.SecurityIntegTestCase; + +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; + +/** + * Integration test that uses multiple data nodes to test that the shrink index api works with security. + */ +@ClusterScope(minNumDataNodes = 2) +public class ShrinkIndexWithSecurityIT extends SecurityIntegTestCase { + + @Override + protected final boolean ignoreExternalCluster() { + return true; + } + + public void testShrinkIndex() throws Exception { + final int randomNumberOfDocs = scaledRandomIntBetween(2, 12); + for (int i = 0; i < randomNumberOfDocs; i++) { + client().prepareIndex("bigindex", "type").setSource("foo", "bar").get(); + } + + ImmutableOpenMap dataNodes = client().admin().cluster().prepareState().get().getState().nodes() + .getDataNodes(); + DiscoveryNode[] discoveryNodes = dataNodes.values().toArray(DiscoveryNode.class); + final String mergeNode = discoveryNodes[0].getName(); + ensureGreen(); + // relocate all shards to one node such that we can merge it. + client().admin().indices().prepareUpdateSettings("bigindex") + .setSettings(Settings.builder() + .put("index.routing.allocation.require._name", mergeNode) + .put("index.blocks.write", true)).get(); + + // wait for green and then shrink + ensureGreen(); + assertAcked(client().admin().indices().prepareShrinkIndex("bigindex", "shrunk_bigindex") + .setSettings(Settings.builder() + .put("index.number_of_replicas", 0) + .put("index.number_of_shards", 1) + .build())); + + // verify all docs + ensureGreen(); + assertHitCount(client().prepareSearch("shrunk_bigindex").setSize(100).setQuery(new TermsQueryBuilder("foo", "bar")).get(), + randomNumberOfDocs); + } +} diff --git a/elasticsearch/src/test/java/org/elasticsearch/xpack/security/authz/privilege/PrivilegeTests.java b/elasticsearch/src/test/java/org/elasticsearch/xpack/security/authz/privilege/PrivilegeTests.java index ca7de7c931d..a8e48882f3b 100644 --- a/elasticsearch/src/test/java/org/elasticsearch/xpack/security/authz/privilege/PrivilegeTests.java +++ b/elasticsearch/src/test/java/org/elasticsearch/xpack/security/authz/privilege/PrivilegeTests.java @@ -241,7 +241,7 @@ public class PrivilegeTests extends ESTestCase { assertThat(predicate.test("whatever"), is(false)); assertThat(predicate.test("cluster:admin/reroute"), is(true)); assertThat(predicate.test("cluster:admin/whatever"), is(false)); - assertThat(predicate.test("indices:admin/mapping/put"), is(false)); + assertThat(predicate.test("indices:admin/mapping/put"), is(true)); assertThat(predicate.test("indices:admin/mapping/whatever"), is(false)); } }