From 73ac738f0728f80cdeb96f16201f99d7a3bd27eb Mon Sep 17 00:00:00 2001 From: Andrey Pleskach Date: Tue, 4 Apr 2023 15:32:33 +0200 Subject: [PATCH] Fix lost privileges during auto initializing of the index (#2641) * Lost privileges fix During default initialization of the plugin configuration (plugins.security.allow_default_init_securityindex is set to true) it is possible that plugin could lose its privileges due to the thread context switching for the cluster with more than 3 nodes. * Wait for cluster managed node Added a new check that waits while cluster is in the global lock state and do not initialize index util cluster will finish leader election. Signed-off-by: Andrey Pleskach --- .../ConfigurationRepository.java | 7 ++- .../security/support/ConfigHelper.java | 46 ++++++++++--------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/opensearch/security/configuration/ConfigurationRepository.java b/src/main/java/org/opensearch/security/configuration/ConfigurationRepository.java index ac2ec48758..458097cbd8 100644 --- a/src/main/java/org/opensearch/security/configuration/ConfigurationRepository.java +++ b/src/main/java/org/opensearch/security/configuration/ConfigurationRepository.java @@ -46,6 +46,7 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import org.opensearch.rest.RestStatus; import org.opensearch.security.auditlog.config.AuditConfig; import org.opensearch.security.support.SecurityUtils; import com.google.common.collect.ImmutableMap; @@ -118,8 +119,10 @@ private ConfigurationRepository(Settings settings, final Path configPath, Thread public void run() { try { LOGGER.info("Background init thread started. Install default config?: "+installDefaultConfig.get()); - - + while (clusterService.state().blocks().hasGlobalBlockWithStatus(RestStatus.SERVICE_UNAVAILABLE)) { + LOGGER.info("Wait for cluster to be available ..."); + TimeUnit.SECONDS.sleep(1); + } if(installDefaultConfig.get()) { try { diff --git a/src/main/java/org/opensearch/security/support/ConfigHelper.java b/src/main/java/org/opensearch/security/support/ConfigHelper.java index de3e772d8b..9b70d7a7e4 100644 --- a/src/main/java/org/opensearch/security/support/ConfigHelper.java +++ b/src/main/java/org/opensearch/security/support/ConfigHelper.java @@ -38,6 +38,8 @@ import java.io.Reader; import java.io.StringReader; import java.nio.charset.StandardCharsets; +import java.security.AccessController; +import java.security.PrivilegedExceptionAction; import org.opensearch.security.securityconf.impl.Meta; import org.apache.logging.log4j.Logger; @@ -71,29 +73,31 @@ public static void uploadFile(Client tc, String filepath, String index, CType cT public static void uploadFile(Client tc, String filepath, String index, CType cType, int configVersion, boolean populateEmptyIfFileMissing) throws Exception { final String configType = cType.toLCString(); LOGGER.info("Will update '" + configType + "' with " + filepath + " and populate it with empty doc if file missing and populateEmptyIfFileMissing=" + populateEmptyIfFileMissing); + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + if (!populateEmptyIfFileMissing) { + ConfigHelper.fromYamlFile(filepath, cType, configVersion, 0, 0); + } - if (!populateEmptyIfFileMissing) { - ConfigHelper.fromYamlFile(filepath, cType, configVersion, 0, 0); - } - - try (Reader reader = createFileOrStringReader(cType, configVersion, filepath, populateEmptyIfFileMissing)) { - - final IndexRequest indexRequest = new IndexRequest(index) - .type(configVersion == 1 ? "security" : "_doc") - .id(configType) - .opType(OpType.CREATE) - .setRefreshPolicy(RefreshPolicy.IMMEDIATE) - .source(configType, readXContent(reader, XContentType.YAML)); - final String res = tc.index(indexRequest).actionGet().getId(); - - if (!configType.equals(res)) { - throw new Exception(" FAIL: Configuration for '" + configType - + "' failed for unknown reasons. Pls. consult logfile of opensearch"); + try (Reader reader = createFileOrStringReader(cType, configVersion, filepath, populateEmptyIfFileMissing)) { + + final IndexRequest indexRequest = new IndexRequest(index) + .type(configVersion == 1 ? "security" : "_doc") + .id(configType) + .opType(OpType.CREATE) + .setRefreshPolicy(RefreshPolicy.IMMEDIATE) + .source(configType, readXContent(reader, XContentType.YAML)); + final String res = tc.index(indexRequest).actionGet().getId(); + + if (!configType.equals(res)) { + throw new Exception(" FAIL: Configuration for '" + configType + + "' failed for unknown reasons. Pls. consult logfile of opensearch"); + } + LOGGER.info("Doc with id '{}' and version {} is updated in {} index.", configType, configVersion, index); + } catch (VersionConflictEngineException versionConflictEngineException) { + LOGGER.info("Index {} already contains doc with id {}, skipping update.", index, configType); } - LOGGER.info("Doc with id '{}' and version {} is updated in {} index.", configType, configVersion, index); - } catch (VersionConflictEngineException versionConflictEngineException) { - LOGGER.info("Index {} already contains doc with id {}, skipping update.", index, configType); - } + return null; + }); } public static Reader createFileOrStringReader(CType cType, int configVersion, String filepath, boolean populateEmptyIfFileMissing) throws Exception {