From 2e56b3f76709f8f82fabad8a51362c18cbba5fe4 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Mon, 22 Sep 2014 08:46:59 +0000
Subject: [PATCH] OPENDJ-1206 (CR-4368) Create a new ReplicationBackend/ChangelogBackend to support cn=changelog
---
opendj3-server-dev/src/server/org/opends/server/crypto/CryptoManagerSync.java | 283 ++++++++++++++++++++++++++------------------------------
1 files changed, 130 insertions(+), 153 deletions(-)
diff --git a/opendj3-server-dev/src/server/org/opends/server/crypto/CryptoManagerSync.java b/opendj3-server-dev/src/server/org/opends/server/crypto/CryptoManagerSync.java
index 6bc9cf7..13648db 100644
--- a/opendj3-server-dev/src/server/org/opends/server/crypto/CryptoManagerSync.java
+++ b/opendj3-server-dev/src/server/org/opends/server/crypto/CryptoManagerSync.java
@@ -26,14 +26,23 @@
*/
package org.opends.server.crypto;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+
import org.forgerock.i18n.LocalizableMessage;
import org.forgerock.i18n.slf4j.LocalizedLogger;
import org.forgerock.opendj.ldap.DereferenceAliasesPolicy;
+import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.SearchScope;
import org.opends.admin.ads.ADSContext;
import org.opends.server.api.Backend;
import org.opends.server.api.BackendInitializationListener;
-import org.opends.server.api.ChangeNotificationListener;
+import org.opends.server.api.plugin.InternalDirectoryServerPlugin;
+import org.opends.server.api.plugin.PluginResult.PostResponse;
import org.opends.server.config.ConfigConstants;
import org.opends.server.controls.EntryChangeNotificationControl;
import org.opends.server.controls.PersistentSearchChangeType;
@@ -43,71 +52,75 @@
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.ldap.LDAPControl;
-import org.opends.server.types.*;
-import org.forgerock.opendj.ldap.ResultCode;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.Control;
+import org.opends.server.types.CryptoManagerException;
+import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.Entry;
+import org.opends.server.types.InitializationException;
+import org.opends.server.types.ObjectClass;
+import org.opends.server.types.RDN;
+import org.opends.server.types.SearchFilter;
+import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.operation.PostResponseAddOperation;
import org.opends.server.types.operation.PostResponseDeleteOperation;
import org.opends.server.types.operation.PostResponseModifyOperation;
-import org.opends.server.types.operation.PostResponseModifyDNOperation;
import static org.opends.messages.CoreMessages.*;
+import static org.opends.server.api.plugin.PluginType.*;
import static org.opends.server.config.ConfigConstants.*;
+import static org.opends.server.protocols.internal.InternalClientConnection.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
-import java.util.LinkedHashSet;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.HashMap;
-
/**
* This class defines an object that synchronizes certificates from the admin
* data branch into the trust store backend, and synchronizes secret-key entries
* from the admin data branch to the crypto manager secret-key cache.
*/
-public class CryptoManagerSync
- implements BackendInitializationListener, ChangeNotificationListener
+public class CryptoManagerSync extends InternalDirectoryServerPlugin
+ implements BackendInitializationListener
{
- /**
- * The debug log tracer for this object.
- */
+ /** The debug log tracer for this object. */
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
-
-
- // The DN of the administration suffix.
+ /** The DN of the administration suffix. */
private DN adminSuffixDN;
- // The DN of the instance keys container within the admin suffix.
+ /** The DN of the instance keys container within the admin suffix. */
private DN instanceKeysDN;
- // The DN of the secret keys container within the admin suffix.
+ /** The DN of the secret keys container within the admin suffix. */
private DN secretKeysDN;
- // The DN of the trust store root.
+ /** The DN of the trust store root. */
private DN trustStoreRootDN;
- // The attribute type that is used to specify a server instance certificate.
- AttributeType attrCert;
+ /** The attribute type that is used to specify a server instance certificate. */
+ private final AttributeType attrCert;
- // The attribute type that holds a server certificate identifier.
- AttributeType attrAlias;
+ /** The attribute type that holds a server certificate identifier. */
+ private final AttributeType attrAlias;
- // The attribute type that holds the time a key was compromised.
- AttributeType attrCompromisedTime;
+ /** The attribute type that holds the time a key was compromised. */
+ private final AttributeType attrCompromisedTime;
- // A filter on object class to select key entries.
+ /** A filter on object class to select key entries. */
private SearchFilter keySearchFilter;
- // The instance key objectclass.
- private ObjectClass ocInstanceKey;
+ /** The instance key objectclass. */
+ private final ObjectClass ocInstanceKey;
- // The cipher key objectclass.
- private ObjectClass ocCipherKey;
+ /** The cipher key objectclass. */
+ private final ObjectClass ocCipherKey;
- // The mac key objectclass.
- private ObjectClass ocMacKey;
+ /** The mac key objectclass. */
+ private final ObjectClass ocMacKey;
+
+ /** Dummy configuration DN. */
+ private static final String CONFIG_DN = "cn=Crypto Manager Sync,cn=config";
/**
* Creates a new instance of this trust store synchronization thread.
@@ -116,29 +129,17 @@
* initialization, such as a failure to publish the instance-key-pair
* public-key-certificate in ADS.
*/
- public CryptoManagerSync()
- throws InitializationException
+ public CryptoManagerSync() throws InitializationException
{
- this(true);
- }
-
- /**
- * Creates a new instance of this trust store synchronization thread.
- *
- * @param publishInstanceKey whether the instance key must be published in
- * the ADS or not.
- * @throws InitializationException in case an exception occurs during
- * initialization, such as a failure to publish the instance-key-pair
- * public-key-certificate in ADS.
- */
- public CryptoManagerSync(boolean publishInstanceKey)
- throws InitializationException
- {
+ super(toDN(CONFIG_DN), EnumSet.of(
+ // No implementation required for modify_dn operations
+ // FIXME: Technically it is possible to perform a subtree modDN
+ // in this case however such subtree modDN would essentially be
+ // moving configuration branches which should not happen.
+ POST_RESPONSE_ADD, POST_RESPONSE_MODIFY, POST_RESPONSE_DELETE),
+ true);
try {
- if (publishInstanceKey)
- {
- CryptoManagerImpl.publishInstanceKeyEntryInADS();
- }
+ CryptoManagerImpl.publishInstanceKeyEntryInADS();
}
catch (CryptoManagerException ex) {
throw new InitializationException(ex.getMessageObject());
@@ -160,15 +161,11 @@
}
catch (DirectoryException e)
{
- //
}
- ocInstanceKey = DirectoryServer.getObjectClass(
- OC_CRYPTO_INSTANCE_KEY, true);
- ocCipherKey = DirectoryServer.getObjectClass(
- OC_CRYPTO_CIPHER_KEY, true);
- ocMacKey = DirectoryServer.getObjectClass(
- OC_CRYPTO_MAC_KEY, true);
+ ocInstanceKey = DirectoryServer.getObjectClass(OC_CRYPTO_INSTANCE_KEY, true);
+ ocCipherKey = DirectoryServer.getObjectClass(OC_CRYPTO_CIPHER_KEY, true);
+ ocMacKey = DirectoryServer.getObjectClass(OC_CRYPTO_MAC_KEY, true);
attrCert = DirectoryServer.getAttributeType(
ConfigConstants.ATTR_CRYPTO_PUBLIC_KEY_CERTIFICATE, true);
@@ -182,22 +179,32 @@
searchAdminSuffix();
}
- DirectoryServer.registerChangeNotificationListener(this);
+ DirectoryServer.registerInternalPlugin(this);
+ }
+
+ private static DN toDN(final String dn) throws InitializationException
+ {
+ try
+ {
+ return DN.valueOf(dn);
+ }
+ catch (DirectoryException e)
+ {
+ throw new RuntimeException(e);
+ }
}
private void searchAdminSuffix()
{
- InternalClientConnection conn =
- InternalClientConnection.getRootConnection();
LinkedHashSet<String> attributes = new LinkedHashSet<String>(0);
ArrayList<Control> controls = new ArrayList<Control>(0);
InternalSearchOperation searchOperation =
- new InternalSearchOperation(conn,
- InternalClientConnection.nextOperationID(),
- InternalClientConnection.nextMessageID(),
+ new InternalSearchOperation(getRootConnection(),
+ nextOperationID(),
+ nextMessageID(),
controls,
adminSuffixDN, SearchScope.WHOLE_SUBTREE,
DereferenceAliasesPolicy.NEVER,
@@ -231,9 +238,7 @@
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public void performBackendInitializationProcessing(Backend backend)
{
@@ -250,9 +255,7 @@
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
public void performBackendFinalizationProcessing(Backend backend)
{
@@ -306,7 +309,7 @@
{
for (Control c : controls)
{
- if (c.getOID().equals(OID_ENTRY_CHANGE_NOTIFICATION))
+ if (OID_ENTRY_CHANGE_NOTIFICATION.equals(c.getOID()))
{
if (c instanceof LDAPControl)
{
@@ -331,8 +334,7 @@
if (ecn != null &&
ecn.getChangeType() == PersistentSearchChangeType.DELETE)
{
- // The entry was deleted so we should remove it from the local trust
- // store.
+ // entry was deleted so remove it from the local trust store
if (dstEntry != null)
{
deleteEntry(dstDN);
@@ -340,24 +342,21 @@
}
else if (searchEntry.hasAttribute(attrCompromisedTime))
{
- // The key was compromised so we should remove it from the local
- // trust store.
+ // key was compromised so remove it from the local trust store
if (dstEntry != null)
{
deleteEntry(dstDN);
}
}
+ else if (dstEntry == null)
+ {
+ // The entry was added
+ addEntry(searchEntry, dstDN);
+ }
else
{
- // The entry was added or modified.
- if (dstEntry == null)
- {
- addEntry(searchEntry, dstDN);
- }
- else
- {
- modifyEntry(searchEntry, dstEntry);
- }
+ // The entry was modified
+ modifyEntry(searchEntry, dstEntry);
}
}
}
@@ -371,11 +370,8 @@
*/
private void modifyEntry(Entry srcEntry, Entry dstEntry)
{
- List<Attribute> srcList;
- srcList = srcEntry.getAttribute(attrCert);
-
- List<Attribute> dstList;
- dstList = dstEntry.getAttribute(attrCert);
+ List<Attribute> srcList = srcEntry.getAttribute(attrCert);
+ List<Attribute> dstList = dstEntry.getAttribute(attrCert);
// Check for changes to the certificate value.
boolean differ = false;
@@ -386,21 +382,12 @@
differ = true;
}
}
- else if (dstList == null)
+ else if (dstList == null
+ || srcList.size() != dstList.size()
+ || !srcList.equals(dstList))
{
differ = true;
}
- else if (srcList.size() != dstList.size())
- {
- differ = true;
- }
- else
- {
- if (!srcList.equals(dstList))
- {
- differ = true;
- }
- }
if (differ)
{
@@ -470,19 +457,22 @@
}
}
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
- public void handleAddOperation(PostResponseAddOperation addOperation,
- Entry entry)
+ public PostResponse doPostResponse(PostResponseAddOperation op)
{
- if (addOperation.getEntryDN().isDescendantOf(instanceKeysDN))
+ if (op.getResultCode() != ResultCode.SUCCESS)
+ {
+ return PostResponse.continueOperationProcessing();
+ }
+
+ final Entry entry = op.getEntryToAdd();
+ final DN entryDN = op.getEntryDN();
+ if (entryDN.isDescendantOf(instanceKeysDN))
{
handleInstanceKeyAddOperation(entry);
}
- else if (addOperation.getEntryDN().isDescendantOf(secretKeysDN))
+ else if (entryDN.isDescendantOf(secretKeysDN))
{
try
{
@@ -501,6 +491,7 @@
"Failed to import key entry: %s", e.getMessage()));
}
}
+ return PostResponse.continueOperationProcessing();
}
@@ -521,19 +512,17 @@
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
- public void handleDeleteOperation(PostResponseDeleteOperation deleteOperation,
- Entry entry)
+ public PostResponse doPostResponse(PostResponseDeleteOperation op)
{
- if (!deleteOperation.getEntryDN().isDescendantOf(instanceKeysDN))
+ if (op.getResultCode() != ResultCode.SUCCESS
+ || !op.getEntryDN().isDescendantOf(instanceKeysDN))
{
- return;
+ return PostResponse.continueOperationProcessing();
}
- RDN srcRDN = entry.getName().rdn();
+ RDN srcRDN = op.getEntryToDelete().getName().rdn();
// Only process the entry if it has the expected form of RDN.
// FIXME: Technically it is possible to perform a subtree in
@@ -542,24 +531,28 @@
if (!srcRDN.isMultiValued() &&
srcRDN.getAttributeType(0).equals(attrAlias))
{
- DN dstDN = trustStoreRootDN.child(srcRDN);
-
- deleteEntry(dstDN);
+ DN destDN = trustStoreRootDN.child(srcRDN);
+ deleteEntry(destDN);
}
+ return PostResponse.continueOperationProcessing();
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
- public void handleModifyOperation(PostResponseModifyOperation modifyOperation,
- Entry oldEntry, Entry newEntry)
+ public PostResponse doPostResponse(PostResponseModifyOperation op)
{
- if (modifyOperation.getEntryDN().isDescendantOf(instanceKeysDN))
+ if (op.getResultCode() != ResultCode.SUCCESS)
+ {
+ return PostResponse.continueOperationProcessing();
+ }
+
+ final Entry newEntry = op.getModifiedEntry();
+ final DN entryDN = op.getEntryDN();
+ if (entryDN.isDescendantOf(instanceKeysDN))
{
handleInstanceKeyModifyOperation(newEntry);
}
- else if (modifyOperation.getEntryDN().isDescendantOf(secretKeysDN))
+ else if (entryDN.isDescendantOf(secretKeysDN))
{
try
{
@@ -578,6 +571,7 @@
"Failed to import modified key entry: %s", e.getMessage()));
}
}
+ return PostResponse.continueOperationProcessing();
}
private void handleInstanceKeyModifyOperation(Entry newEntry)
@@ -610,31 +604,14 @@
deleteEntry(dstDN);
}
}
+ else if (dstEntry == null)
+ {
+ addEntry(newEntry, dstDN);
+ }
else
{
- if (dstEntry == null)
- {
- addEntry(newEntry, dstDN);
- }
- else
- {
- modifyEntry(newEntry, dstEntry);
- }
+ modifyEntry(newEntry, dstEntry);
}
}
}
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void handleModifyDNOperation(
- PostResponseModifyDNOperation modifyDNOperation, Entry oldEntry,
- Entry newEntry)
- {
- // No implementation required.
- // FIXME: Technically it is possible to perform a subtree modDN
- // in this case however such subtree modDN would essentially be
- // moving configuration branches which should not happen.
- }
}
--
Gitblit v1.10.0