From 1a2cdfb5cf5f89348e8fee7ceeaa699d4aa54cea Mon Sep 17 00:00:00 2001
From: Fabio Pistolesi <fabio.pistolesi@forgerock.com>
Date: Thu, 21 Apr 2016 15:17:15 +0000
Subject: [PATCH] OPENDJ-2616 Support protection of pluggable backend data at rest
---
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java | 85 ++++++++++++++++++++++++++++--------------
1 files changed, 57 insertions(+), 28 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
index 05f2f3a..8e71e8a 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
@@ -88,10 +88,12 @@
import org.opends.server.core.ModifyDNOperation;
import org.opends.server.core.ModifyOperation;
import org.opends.server.core.SearchOperation;
+import org.opends.server.core.ServerContext;
import org.opends.server.types.Attribute;
import org.opends.server.types.Attributes;
import org.opends.server.types.CanceledOperationException;
import org.opends.server.types.Control;
+import org.opends.server.crypto.CryptoSuite;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.Modification;
@@ -161,6 +163,10 @@
*/
private final String treePrefix;
+ private final ServerContext serverContext;
+
+ private CryptoSuite cryptoSuite;
+
/**
* This class is responsible for managing the configuration for attribute
* indexes used within this entry container.
@@ -174,7 +180,7 @@
{
try
{
- new AttributeIndex(cfg, state, EntryContainer.this);
+ newAttributeIndex(cfg);
return true;
}
catch(Exception e)
@@ -190,7 +196,7 @@
final ConfigChangeResult ccr = new ConfigChangeResult();
try
{
- final AttributeIndex index = new AttributeIndex(cfg, state, EntryContainer.this);
+ final AttributeIndex index = newAttributeIndex(cfg);
storage.write(new WriteOperation()
{
@Override
@@ -338,26 +344,15 @@
final Lock sharedLock = lock.readLock();
final Lock exclusiveLock = lock.writeLock();
- /**
- * Create a new entry container object.
- *
- * @param baseDN The baseDN this entry container will be responsible for
- * storing on disk.
- * @param backendID ID of the backend that is creating this entry container.
- * It is needed by the Directory Server entry cache methods.
- * @param config The configuration of the backend.
- * @param storage The storage for this entryContainer.
- * @param rootContainer The root container this entry container is in.
- * @throws ConfigException if a configuration related error occurs.
- */
- EntryContainer(DN baseDN, String backendID, PluggableBackendCfg config, Storage storage,
- RootContainer rootContainer) throws ConfigException
+ EntryContainer(DN baseDN, String backendID, PluggableBackendCfg config, Storage storage, RootContainer rootContainer,
+ ServerContext serverContext) throws ConfigException
{
this.backendID = backendID;
this.baseDN = baseDN;
this.config = config;
this.storage = storage;
this.rootContainer = rootContainer;
+ this.serverContext = serverContext;
this.treePrefix = baseDN.toNormalizedUrlSafeString();
this.id2childrenCount = new ID2ChildrenCount(getIndexName(ID2CHILDREN_COUNT_TREE_NAME));
this.dn2id = new DN2ID(getIndexName(DN2ID_TREE_NAME), baseDN);
@@ -375,6 +370,22 @@
config.addBackendVLVIndexDeleteListener(vlvIndexCfgManager);
}
+ private AttributeIndex newAttributeIndex(BackendIndexCfg cfg) throws ConfigException
+ {
+ return new AttributeIndex(cfg, state, this, cryptoSuite);
+ }
+
+ private DataConfig newDataConfig(PluggableBackendCfg config)
+ {
+ return new DataConfig.Builder()
+ .compress(config.isEntriesCompressed())
+ .encode(config.isCompactEncoding())
+ .encrypt(config.isConfidentialityEnabled())
+ .cryptoSuite(cryptoSuite)
+ .schema(rootContainer.getCompressedSchema())
+ .build();
+ }
+
private TreeName getIndexName(String indexId)
{
return new TreeName(treePrefix, indexId);
@@ -393,10 +404,9 @@
boolean shouldCreate = accessMode.isWriteable();
try
{
- DataConfig entryDataConfig = new DataConfig(
- config.isEntriesCompressed(), config.isCompactEncoding(), rootContainer.getCompressedSchema());
-
- id2entry = new ID2Entry(getIndexName(ID2ENTRY_TREE_NAME), entryDataConfig);
+ cryptoSuite = serverContext.getCryptoManager().newCryptoSuite(config.getCipherTransformation(),
+ config.getCipherKeyLength());
+ id2entry = new ID2Entry(getIndexName(ID2ENTRY_TREE_NAME), newDataConfig(config));
id2entry.open(txn, shouldCreate);
id2childrenCount.open(txn, shouldCreate);
dn2id.open(txn, shouldCreate);
@@ -407,7 +417,7 @@
{
BackendIndexCfg indexCfg = config.getBackendIndex(idx);
- final AttributeIndex index = new AttributeIndex(indexCfg, state, this);
+ final AttributeIndex index = newAttributeIndex(indexCfg);
index.open(txn, shouldCreate);
if(!index.isTrusted())
{
@@ -2341,11 +2351,25 @@
}
@Override
- public boolean isConfigurationChangeAcceptable(
- PluggableBackendCfg cfg, List<LocalizableMessage> unacceptableReasons)
+ public boolean isConfigurationChangeAcceptable(PluggableBackendCfg cfg, List<LocalizableMessage> unacceptableReasons)
{
- // This is always true because only all config attributes used
- // by the entry container should be validated by the admin framework.
+ StringBuilder builder = new StringBuilder();
+ for (AttributeIndex attributeIndex : attrIndexMap.values())
+ {
+ if (attributeIndex.isConfidentialityEnabled() && !cfg.isConfidentialityEnabled())
+ {
+ if (builder.length() > 0)
+ {
+ builder.append(", ");
+ }
+ builder.append(attributeIndex.getAttributeType().getNameOrOID());
+ }
+ }
+ if (builder.length() > 0)
+ {
+ unacceptableReasons.add(ERR_BACKEND_CANNOT_CHANGE_CONFIDENTIALITY.get(getBaseDN(), builder.toString()));
+ return false;
+ }
return true;
}
@@ -2362,9 +2386,9 @@
@Override
public void run(WriteableTransaction txn) throws Exception
{
- DataConfig entryDataConfig = new DataConfig(cfg.isEntriesCompressed(),
- cfg.isCompactEncoding(), rootContainer.getCompressedSchema());
- id2entry.setDataConfig(entryDataConfig);
+ cryptoSuite.setCipherTransformation(cfg.getCipherTransformation());
+ cryptoSuite.setCipherKeyLength(cfg.getCipherKeyLength());
+ id2entry.setDataConfig(newDataConfig(cfg));
EntryContainer.this.config = cfg;
}
@@ -2476,6 +2500,11 @@
return false;
}
+ boolean isConfidentialityEnabled()
+ {
+ return config.isConfidentialityEnabled();
+ }
+
/**
* Fetch the base Entry of the EntryContainer.
* @param searchBaseDN the DN for the base entry
--
Gitblit v1.10.0