Skip to content

Commit

Permalink
SOLR-16777: Schema Designer now correctly manages trust of the Config…
Browse files Browse the repository at this point in the history
…Sets it is managing

Co-authored-by: Houston Putman <[email protected]>
  • Loading branch information
2 people authored and Ishan Chattopadhyaya committed Nov 4, 2023
1 parent 3b395d9 commit 6e9ed20
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 21 deletions.
2 changes: 2 additions & 0 deletions solr/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ Bug Fixes

* SOLR-16452: Do not update PRS states if local version is newer (Hitesh Khamesra via noble)

* SOLR-16777: Schema Designer now correctly manages trust of the ConfigSets it is managing. (Ishan Chattopadhyaya, Skay, Houston Putman)

Optimizations
---------------------
* SOLR-16555: SolrIndexSearcher - FilterCache intersections/andNot should not clone bitsets repeatedly (Kevin Risden, David Smiley)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package org.apache.solr.handler.admin;

import java.io.IOException;
import java.io.InputStream;
import java.lang.invoke.MethodHandles;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -311,7 +312,7 @@ private void ensureOverwritingUntrustedConfigSet(SolrZkClient zkClient, String c
}
}

private static boolean isCurrentlyTrusted(SolrZkClient zkClient, String configSetZkPath) {
public static boolean isCurrentlyTrusted(SolrZkClient zkClient, String configSetZkPath) {
byte[] configSetNodeContent;
try {
configSetNodeContent = zkClient.getData(configSetZkPath, null, null, true);
Expand All @@ -329,7 +330,33 @@ private static boolean isCurrentlyTrusted(SolrZkClient zkClient, String configSe
return (boolean) contentMap.getOrDefault("trusted", true);
}

static boolean isTrusted(SolrQueryRequest req, AuthenticationPlugin authPlugin) {
public void setConfigMetadata(String configName, Map<String, Object> data) throws IOException {
try {
coreContainer.getZkController().getZkClient().makePath(
ZkConfigManager.CONFIGS_ZKNODE + "/" + configName,
Utils.toJSON(data),
CreateMode.PERSISTENT,
null,
false,
true);
} catch (KeeperException | InterruptedException e) {
throw new IOException("Error setting config metadata", SolrZkClient.checkInterrupted(e));
}
}

public void removeConfigSetTrust(String configSetName) {
try {
Map<String, Object> metadata = Collections.singletonMap("trusted", false);
setConfigMetadata(configSetName, metadata);
} catch (IOException e) {
throw new SolrException(
SolrException.ErrorCode.SERVER_ERROR,
"Could not remove trusted flag for configSet " + configSetName + ": " + e.getMessage(),
e);
}
}

public static boolean isTrusted(SolrQueryRequest req, AuthenticationPlugin authPlugin) {
if (authPlugin != null && req.getUserPrincipal() != null) {
log.debug("Trusted configset request");
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.SolrConfig;
import org.apache.solr.core.SolrResourceLoader;
import org.apache.solr.handler.admin.ConfigSetsHandler;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.RawResponseWriter;
import org.apache.solr.response.SolrQueryResponse;
Expand Down Expand Up @@ -112,8 +113,8 @@ public SchemaDesignerAPI(CoreContainer coreContainer) {
this.coreContainer = coreContainer;
this.schemaSuggester = schemaSuggester;
this.sampleDocLoader = sampleDocLoader;
this.settingsDAO = new SchemaDesignerSettingsDAO(coreContainer);
this.configSetHelper = new SchemaDesignerConfigSetHelper(this.coreContainer, this.schemaSuggester);
this.settingsDAO = new SchemaDesignerSettingsDAO(coreContainer, configSetHelper);
}

public static SchemaSuggester newSchemaSuggester(CoreContainer coreContainer) {
Expand Down Expand Up @@ -233,11 +234,12 @@ public void updateFileContents(SolrQueryRequest req, SolrQueryResponse rsp) thro

byte[] data = DefaultSampleDocumentsLoader.streamAsBytes(extractSingleContentStream(req, true).getStream());
Exception updateFileError = null;
boolean requestIsTrusted = ConfigSetsHandler.isTrusted(req, coreContainer.getAuthenticationPlugin());
if (SOLR_CONFIG_XML.equals(file)) {
// verify the updated solrconfig.xml is valid before saving to ZK (to avoid things blowing up later)
try {
InMemoryResourceLoader loader = new InMemoryResourceLoader(coreContainer, mutableId, SOLR_CONFIG_XML, data);
SolrConfig.readFromResourceLoader(loader, SOLR_CONFIG_XML, true, null);
SolrConfig.readFromResourceLoader(loader, SOLR_CONFIG_XML, requestIsTrusted, null);
} catch (Exception exc) {
updateFileError = exc;
}
Expand All @@ -260,6 +262,11 @@ public void updateFileContents(SolrQueryRequest req, SolrQueryResponse rsp) thro
} catch (KeeperException | InterruptedException e) {
throw new IOException("Failed to save data in ZK at path: " + zkPath, SolrZkClient.checkInterrupted(e));
}
// If the request is untrusted, and the configSet is trusted, remove the trusted flag on the
// configSet.
if (ConfigSetsHandler.isCurrentlyTrusted(zkClient, ZkConfigManager.CONFIGS_ZKNODE + "/" + mutableId) && !requestIsTrusted) {
coreContainer.getConfigSetsHandler().removeConfigSetTrust(mutableId);
}

configSetHelper.reloadTempCollection(mutableId, false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -610,10 +610,9 @@ ManagedIndexSchema deleteNestedDocsFieldsIfNeeded(ManagedIndexSchema schema, boo
}

SolrConfig loadSolrConfig(String configSet) {
SolrResourceLoader resourceLoader = cc.getResourceLoader();
ZkSolrResourceLoader zkLoader =
new ZkSolrResourceLoader(resourceLoader.getInstancePath(), configSet, resourceLoader.getClassLoader(), new Properties(), cc.getZkController());
return SolrConfig.readFromResourceLoader(zkLoader, SOLR_CONFIG_XML, false, null);
ZkSolrResourceLoader zkLoader = zkLoaderForConfigSet(configSet);
boolean trusted = isConfigSetTrusted(configSet);
return SolrConfig.readFromResourceLoader(zkLoader, SOLR_CONFIG_XML, trusted, null);
}

ManagedIndexSchema loadLatestSchema(String configSet) {
Expand Down Expand Up @@ -1075,4 +1074,34 @@ void deleteConfig(String configSet) throws IOException {
void copyConfig(String from, String to) throws IOException {
configManager.copyConfigDir(from, to);
}

public boolean isConfigSetTrusted(String configSetName) {
try {
return cc.getConfigSetsHandler().isCurrentlyTrusted(cc.getZkController().getZkClient(), ZkConfigManager.CONFIGS_ZKNODE + "/" + configSetName);
} catch (Exception e) {
throw new SolrException(
SolrException.ErrorCode.SERVER_ERROR,
"Could not load conf " + configSetName + ": " + e.getMessage(),
e);
}
}

public void removeConfigSetTrust(String configSetName) {
try {
Map<String, Object> metadata = Collections.singletonMap("trusted", false);
cc.getConfigSetsHandler().setConfigMetadata(configSetName, metadata);
} catch (IOException e) {
throw new SolrException(
SolrException.ErrorCode.SERVER_ERROR,
"Could not remove trusted flag for configSet " + configSetName + ": " + e.getMessage(),
e);
}
}

protected ZkSolrResourceLoader zkLoaderForConfigSet(final String configSet) {
SolrResourceLoader resourceLoader = cc.getResourceLoader();
ZkSolrResourceLoader zkLoader =
new ZkSolrResourceLoader(resourceLoader.getInstancePath(), configSet, resourceLoader.getClassLoader(), new Properties(), cc.getZkController());
return zkLoader;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.solr.cloud.ZkController;
import org.apache.solr.cloud.ZkSolrResourceLoader;
Expand All @@ -33,7 +32,6 @@
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.PluginInfo;
import org.apache.solr.core.SolrConfig;
import org.apache.solr.core.SolrResourceLoader;
import org.apache.solr.update.processor.UpdateRequestProcessorChain;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.data.Stat;
Expand All @@ -49,14 +47,15 @@ class SchemaDesignerSettingsDAO implements SchemaDesignerConstants {
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

private final CoreContainer cc;
private final SchemaDesignerConfigSetHelper configSetHelper;

SchemaDesignerSettingsDAO(CoreContainer cc) {
SchemaDesignerSettingsDAO(CoreContainer cc, SchemaDesignerConfigSetHelper configSetHelper) {
this.cc = cc;
this.configSetHelper = configSetHelper;
}

SchemaDesignerSettings getSettings(String configSet) {
SolrConfig solrConfig =
SolrConfig.readFromResourceLoader(zkLoaderForConfigSet(configSet), SOLR_CONFIG_XML, true, null);
SolrConfig solrConfig = configSetHelper.loadSolrConfig(configSet);
return getSettings(solrConfig);
}

Expand Down Expand Up @@ -97,8 +96,14 @@ boolean persistIfChanged(String configSet, SchemaDesignerSettings settings) thro
}

if (changed) {
ZkController.persistConfigResourceToZooKeeper(zkLoaderForConfigSet(configSet), overlay.getZnodeVersion(),
ConfigOverlay.RESOURCE_NAME, overlay.toByteArray(), true);
try (ZkSolrResourceLoader resourceLoader = configSetHelper.zkLoaderForConfigSet(configSet)) {
ZkController.persistConfigResourceToZooKeeper(
resourceLoader,
overlay.getZnodeVersion(),
ConfigOverlay.RESOURCE_NAME,
overlay.toByteArray(),
true);
}
}

return changed;
Expand Down Expand Up @@ -160,9 +165,4 @@ private boolean hasFieldGuessingURPChain(final SolrConfig solrConfig) {
}
return hasPlugin;
}

private ZkSolrResourceLoader zkLoaderForConfigSet(final String configSet) {
SolrResourceLoader loader = cc.getResourceLoader();
return new ZkSolrResourceLoader(loader.getInstancePath(), configSet, loader.getClassLoader(), new Properties(), cc.getZkController());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ public void testDAO() throws Exception {
CollectionAdminRequest.createCollection(collection, configSet, 1, 1).process(cluster.getSolrClient());
CollectionsHandler.waitForActiveCollection(collection, cc, rsp);

SchemaDesignerSettingsDAO dao = new SchemaDesignerSettingsDAO(cc);
SchemaDesignerConfigSetHelper csh = new SchemaDesignerConfigSetHelper(cc, null);
SchemaDesignerSettingsDAO dao = new SchemaDesignerSettingsDAO(cc, csh);
SchemaDesignerSettings settings = dao.getSettings(configSet);
assertNotNull(settings);

Expand Down

0 comments on commit 6e9ed20

Please sign in to comment.