From 7369ecc8296a0329e424596ff71c60629add3ce2 Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Wed, 21 Feb 2007 19:44:18 +0000
Subject: [PATCH] Redesign the server to support multiple key manager providers, trust manager providers, and certificate mappers, and update the components which need access to those elements so that they can specify which one they want to use. Among other things, this will provide the ability to use different certificates for different listeners, and provide template configuration entries that make it easier for users to enable SSL and/or StartTLS.
---
opends/src/server/org/opends/server/core/CertificateMapperConfigManager.java | 1226 +++++++++++++++++++++++++--------------------------------
1 files changed, 534 insertions(+), 692 deletions(-)
diff --git a/opends/src/server/org/opends/server/core/CertificateMapperConfigManager.java b/opends/src/server/org/opends/server/core/CertificateMapperConfigManager.java
index 30957dd..51b25e5 100644
--- a/opends/src/server/org/opends/server/core/CertificateMapperConfigManager.java
+++ b/opends/src/server/org/opends/server/core/CertificateMapperConfigManager.java
@@ -22,24 +22,29 @@
* CDDL HEADER END
*
*
- * Portions Copyright 2006 Sun Microsystems, Inc.
+ * Portions Copyright 2006-2007 Sun Microsystems, Inc.
*/
package org.opends.server.core;
import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
import org.opends.server.api.CertificateMapper;
import org.opends.server.api.ConfigAddListener;
import org.opends.server.api.ConfigChangeListener;
import org.opends.server.api.ConfigDeleteListener;
+import org.opends.server.api.ConfigHandler;
+import org.opends.server.api.ConfigurableComponent;
import org.opends.server.config.BooleanConfigAttribute;
import org.opends.server.config.ConfigEntry;
+import org.opends.server.config.ConfigException;
import org.opends.server.config.StringConfigAttribute;
-import org.opends.server.extensions.SubjectEqualsDNCertificateMapper;
import org.opends.server.types.ConfigChangeResult;
-import org.opends.server.types.DirectoryException;
import org.opends.server.types.DN;
import org.opends.server.types.ErrorLogCategory;
import org.opends.server.types.ErrorLogSeverity;
@@ -51,16 +56,17 @@
import static org.opends.server.loggers.Error.*;
import static org.opends.server.messages.ConfigMessages.*;
import static org.opends.server.messages.MessageHandler.*;
+import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
- * This class defines a utility that will be used to manage the configuration
- * for the Directory Server certificate mapper. Only a single certificate
- * mapper may be defined, but if it is absent or disabled, then a default
- * provider will be used that will assume that the certificate subject is equal
- * to the user entry's DN.
+ * This class defines a utility that will be used to manage the set of
+ * certificate mappers defined in the Directory Server. It will initialize the
+ * certificate mappers when the server starts, and then will manage any
+ * additions, removals, or modifications of any certificate mappers while the
+ * server is running.
*/
public class CertificateMapperConfigManager
implements ConfigChangeListener, ConfigAddListener, ConfigDeleteListener
@@ -73,251 +79,139 @@
+ // A mapping between the DNs of the config entries and the associated
+ // certificate mappers.
+ private ConcurrentHashMap<DN,CertificateMapper> mappers;
+
+ // The configuration handler for the Directory Server.
+ private ConfigHandler configHandler;
+
+
+
/**
- * Creates a new instance of this certificate mapper provider config manager.
+ * Creates a new instance of this certificate mapper config manager.
*/
public CertificateMapperConfigManager()
{
assert debugConstructor(CLASS_NAME);
- // No implementation is required.
+ configHandler = DirectoryServer.getConfigHandler();
+ mappers = new ConcurrentHashMap<DN,CertificateMapper>();
}
/**
- * Initializes the configuration associated with the Directory Server
- * certificate mapper. This should only be called at Directory Server
- * startup. If an error occurs, then a message will be logged and the default
- * certificate mapper will be installed.
+ * Initializes all certificate mappers currently defined in the Directory
+ * Server configuration. This should only be called at Directory Server
+ * startup.
*
- * @throws InitializationException If a problem occurs while trying to
- * install the default certificate mapper.
+ * @throws ConfigException If a configuration problem causes the certificate
+ * mapper initialization process to fail.
+ *
+ * @throws InitializationException If a problem occurs while initializing
+ * the certificate mappers that is not
+ * related to the server configuration.
*/
- public void initializeCertificateMapper()
- throws InitializationException
+ public void initializeCertificateMappers()
+ throws ConfigException, InitializationException
{
- assert debugEnter(CLASS_NAME, "initializeCertificateMapper");
+ assert debugEnter(CLASS_NAME, "initializeCertificateMappers");
- // First, install the default certificate mapper so that there will be one
- // even if we encounter a problem later.
+ // First, get the configuration base entry.
+ ConfigEntry baseEntry;
try
{
- SubjectEqualsDNCertificateMapper defaultMapper =
- new SubjectEqualsDNCertificateMapper();
- defaultMapper.initializeCertificateMapper(null);
- DirectoryServer.setCertificateMapper(defaultMapper);
+ DN certMapperBase = DN.decode(DN_CERTMAPPER_CONFIG_BASE);
+ baseEntry = configHandler.getConfigEntry(certMapperBase);
}
catch (Exception e)
{
- assert debugException(CLASS_NAME, "initializeCertificateMapper", e);
+ assert debugException(CLASS_NAME, "initializeCertificateMappers",
+ e);
- int msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_INSTALL_DEFAULT_MAPPER;
- String message = getMessage(msgID, stackTraceToSingleLineString(e));
- throw new InitializationException(msgID, message, e);
+ int msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_GET_BASE;
+ String message = getMessage(msgID, String.valueOf(e));
+ throw new ConfigException(msgID, message, e);
+ }
+
+ if (baseEntry == null)
+ {
+ // The certificate mapper base entry does not exist. This is not
+ // acceptable, so throw an exception.
+ int msgID = MSGID_CONFIG_CERTMAPPER_BASE_DOES_NOT_EXIST;
+ String message = getMessage(msgID);
+ throw new ConfigException(msgID, message);
}
- // Get the certificate mapper configuration entry. If it is not present,
- // then register an add listener and just go with the default mapper.
- DN configEntryDN;
- ConfigEntry configEntry;
- try
- {
- configEntryDN = DN.decode(DN_CERTMAPPER_CONFIG);
- configEntry = DirectoryServer.getConfigEntry(configEntryDN);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "initializeCertificateMapper", e);
+ // Register add and delete listeners with the certificate mapper base entry.
+ // We don't care about modifications to it.
+ baseEntry.registerAddListener(this);
+ baseEntry.registerDeleteListener(this);
- logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
- MSGID_CONFIG_CERTMAPPER_CANNOT_GET_CONFIG_ENTRY,
- stackTraceToSingleLineString(e));
+
+ // See if the base entry has any children. If not, then we don't need to do
+ // anything else.
+ if (! baseEntry.hasChildren())
+ {
return;
}
- if (configEntry == null)
+
+ // Iterate through the child entries and process them as certificate mapper
+ // configuration entries.
+ for (ConfigEntry childEntry : baseEntry.getChildren().values())
{
- logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_WARNING,
- MSGID_CONFIG_CERTMAPPER_NO_CONFIG_ENTRY);
+ childEntry.registerChangeListener(this);
+
+ StringBuilder unacceptableReason = new StringBuilder();
+ if (! configAddIsAcceptable(childEntry, unacceptableReason))
+ {
+ logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
+ MSGID_CONFIG_CERTMAPPER_ENTRY_UNACCEPTABLE,
+ childEntry.getDN().toString(), unacceptableReason.toString());
+ continue;
+ }
try
{
- ConfigEntry parentEntry =
- DirectoryServer
- .getConfigEntry(configEntryDN.getParentDNInSuffix());
- if (parentEntry != null)
+ ConfigChangeResult result = applyConfigurationAdd(childEntry);
+ if (result.getResultCode() != ResultCode.SUCCESS)
{
- parentEntry.registerAddListener(this);
+ StringBuilder buffer = new StringBuilder();
+
+ List<String> resultMessages = result.getMessages();
+ if ((resultMessages == null) || (resultMessages.isEmpty()))
+ {
+ buffer.append(getMessage(MSGID_CONFIG_UNKNOWN_UNACCEPTABLE_REASON));
+ }
+ else
+ {
+ Iterator<String> iterator = resultMessages.iterator();
+
+ buffer.append(iterator.next());
+ while (iterator.hasNext())
+ {
+ buffer.append(EOL);
+ buffer.append(iterator.next());
+ }
+ }
+
+ logError(ErrorLogCategory.CONFIGURATION,
+ ErrorLogSeverity.SEVERE_ERROR,
+ MSGID_CONFIG_CERTMAPPER_CANNOT_CREATE_MAPPER,
+ childEntry.getDN().toString(), buffer.toString());
}
}
catch (Exception e)
{
- assert debugException(CLASS_NAME, "initializeCertificateMapper", e);
-
logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
- MSGID_CONFIG_CERTMAPPER_CANNOT_REGISTER_ADD_LISTENER,
- stackTraceToSingleLineString(e));
- }
-
- return;
- }
-
-
- // At this point, we have a configuration entry. Register a change listener
- // with it so we can be notified of changes to it over time. We will also
- // want to register a delete listener with its parent to allow us to
- // determine if the entry is deleted.
- configEntry.registerChangeListener(this);
- try
- {
- DN parentDN = configEntryDN.getParentDNInSuffix();
- ConfigEntry parentEntry = DirectoryServer.getConfigEntry(parentDN);
- if (parentEntry != null)
- {
- parentEntry.registerDeleteListener(this);
+ MSGID_CONFIG_CERTMAPPER_CANNOT_CREATE_MAPPER,
+ childEntry.getDN().toString(), String.valueOf(e));
}
}
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "initializeCertificateMapper", e);
-
- logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_WARNING,
- MSGID_CONFIG_CERTMAPPER_CANNOT_REGISTER_DELETE_LISTENER,
- stackTraceToSingleLineString(e));
- }
-
-
- // See if the entry indicates whether the certificate mapper should be
- // enabled.
- int msgID = MSGID_CONFIG_CERTMAPPER_DESCRIPTION_ENABLED;
- BooleanConfigAttribute enabledStub =
- new BooleanConfigAttribute(ATTR_CERTMAPPER_ENABLED, getMessage(msgID),
- false);
- try
- {
- BooleanConfigAttribute enabledAttr =
- (BooleanConfigAttribute)
- configEntry.getConfigAttribute(enabledStub);
- if (enabledAttr == null)
- {
- // The attribute is not present, so the certificate mapper will be
- // disabled. Log a warning message and return.
- logError(ErrorLogCategory.CONFIGURATION,
- ErrorLogSeverity.SEVERE_WARNING,
- MSGID_CONFIG_CERTMAPPER_NO_ENABLED_ATTR);
- return;
- }
- else if (! enabledAttr.activeValue())
- {
- // The certificate mapper is explicitly disabled. Log a mild warning
- // and return.
- logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.MILD_WARNING,
- MSGID_CONFIG_CERTMAPPER_DISABLED);
- return;
- }
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "initializeCertificateMapper", e);
-
- logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
- MSGID_CONFIG_CERTMAPPER_UNABLE_TO_DETERMINE_ENABLED_STATE,
- stackTraceToSingleLineString(e));
- return;
- }
-
-
- // See if it specifies the class name for the certificate mapper
- // implementation.
- String className;
- msgID = MSGID_CONFIG_CERTMAPPER_DESCRIPTION_CLASS;
- StringConfigAttribute classStub =
- new StringConfigAttribute(ATTR_CERTMAPPER_CLASS, getMessage(msgID),
- true, false, false);
- try
- {
- StringConfigAttribute classAttr =
- (StringConfigAttribute) configEntry.getConfigAttribute(classStub);
- if (classAttr == null)
- {
- logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
- MSGID_CONFIG_CERTMAPPER_NO_CLASS_ATTR);
- return;
- }
- else
- {
- className = classAttr.activeValue();
- }
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "initializeCertificateMapper", e);
-
- logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
- MSGID_CONFIG_CERTMAPPER_CANNOT_DETERMINE_CLASS,
- stackTraceToSingleLineString(e));
- return;
- }
-
-
- // Try to load the class and instantiate it as a certificate mapper.
- Class certificateMapperClass;
- try
- {
- // FIXME -- Should we use a custom class loader for this?
- certificateMapperClass = Class.forName(className);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "initializeCertificateMapper", e);
-
- logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
- MSGID_CONFIG_CERTMAPPER_CANNOT_LOAD_CLASS,
- String.valueOf(className), stackTraceToSingleLineString(e));
- return;
- }
-
- CertificateMapper certificateMapper;
- try
- {
- certificateMapper =
- (CertificateMapper) certificateMapperClass.newInstance();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "initializeCertificateMapper", e);
-
- logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
- MSGID_CONFIG_CERTMAPPER_CANNOT_INSTANTIATE_CLASS,
- String.valueOf(className), stackTraceToSingleLineString(e));
- return;
- }
-
-
- // Try to initialize the certificate mapper with the contents of the
- // configuration entry.
- try
- {
- certificateMapper.initializeCertificateMapper(configEntry);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "initializeCertificateMapper", e);
-
- logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
- MSGID_CONFIG_CERTMAPPER_CANNOT_INITIALIZE,
- String.valueOf(className), stackTraceToSingleLineString(e));
- return;
- }
-
-
- // Install the new certificate mapper in the server. We don't need to do
- // anything to get rid of the previous null provider since it doesn't
- // consume any resources.
- DirectoryServer.setCertificateMapper(certificateMapper);
}
@@ -342,21 +236,97 @@
String.valueOf(configEntry), "java.lang.StringBuilder");
- // See if the entry indicates whether the certificate mapper should be
- // enabled.
- int msgID = MSGID_CONFIG_CERTMAPPER_DESCRIPTION_ENABLED;
- BooleanConfigAttribute enabledStub =
- new BooleanConfigAttribute(ATTR_CERTMAPPER_ENABLED, getMessage(msgID),
- false);
+ // Make sure that the entry has an appropriate objectclass for a certificate
+ // mapper.
+ if (! configEntry.hasObjectClass(OC_CERTIFICATE_MAPPER))
+ {
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_OBJECTCLASS;
+ String message = getMessage(msgID, configEntry.getDN().toString());
+ unacceptableReason.append(message);
+ return false;
+ }
+
+
+ // Make sure that the entry specifies the mapper class name.
+ StringConfigAttribute classNameAttr;
try
{
- BooleanConfigAttribute enabledAttr =
- (BooleanConfigAttribute)
- configEntry.getConfigAttribute(enabledStub);
+ StringConfigAttribute classStub =
+ new StringConfigAttribute(ATTR_CERTMAPPER_CLASS,
+ getMessage(MSGID_CONFIG_CERTMAPPER_DESCRIPTION_CLASS),
+ true, false, true);
+ classNameAttr = (StringConfigAttribute)
+ configEntry.getConfigAttribute(classStub);
+
+ if (classNameAttr == null)
+ {
+ int msgID = MSGID_CONFIG_CERTMAPPER_NO_CLASS_NAME;
+ String message = getMessage(msgID, configEntry.getDN().toString());
+ unacceptableReason.append(message);
+ return false;
+ }
+ }
+ catch (Exception e)
+ {
+ assert debugException(CLASS_NAME, "configChangeIsAcceptable", e);
+
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_CLASS_NAME;
+ String message = getMessage(msgID, configEntry.getDN().toString(),
+ String.valueOf(e));
+ unacceptableReason.append(message);
+ return false;
+ }
+
+ Class mapperClass;
+ try
+ {
+ // FIXME -- Should this be done with a custom class loader?
+ mapperClass = Class.forName(classNameAttr.pendingValue());
+ }
+ catch (Exception e)
+ {
+ assert debugException(CLASS_NAME, "configChangeIsAcceptable", e);
+
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_CLASS_NAME;
+ String message = getMessage(msgID, configEntry.getDN().toString(),
+ String.valueOf(e));
+ unacceptableReason.append(message);
+ return false;
+ }
+
+ try
+ {
+ CertificateMapper mapper = (CertificateMapper) mapperClass.newInstance();
+ }
+ catch(Exception e)
+ {
+ assert debugException(CLASS_NAME, "configChangeIsAcceptable", e);
+
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_CLASS;
+ String message = getMessage(msgID, mapperClass.getName(),
+ String.valueOf(configEntry.getDN()),
+ String.valueOf(e));
+ unacceptableReason.append(message);
+ return false;
+ }
+
+
+ // See if this certificate mapper should be enabled.
+ BooleanConfigAttribute enabledAttr;
+ try
+ {
+ BooleanConfigAttribute enabledStub =
+ new BooleanConfigAttribute(ATTR_CERTMAPPER_ENABLED,
+ getMessage(MSGID_CONFIG_CERTMAPPER_DESCRIPTION_ENABLED),
+ false);
+ enabledAttr = (BooleanConfigAttribute)
+ configEntry.getConfigAttribute(enabledStub);
+
if (enabledAttr == null)
{
- msgID = MSGID_CONFIG_CERTMAPPER_NO_ENABLED_ATTR;
- unacceptableReason.append(getMessage(msgID));
+ int msgID = MSGID_CONFIG_CERTMAPPER_NO_ENABLED_ATTR;
+ String message = getMessage(msgID, configEntry.getDN().toString());
+ unacceptableReason.append(message);
return false;
}
}
@@ -364,82 +334,16 @@
{
assert debugException(CLASS_NAME, "configChangeIsAcceptable", e);
- msgID = MSGID_CONFIG_CERTMAPPER_UNABLE_TO_DETERMINE_ENABLED_STATE;
- unacceptableReason.append(getMessage(msgID,
- stackTraceToSingleLineString(e)));
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_ENABLED_VALUE;
+ String message = getMessage(msgID, configEntry.getDN().toString(),
+ String.valueOf(e));
+ unacceptableReason.append(message);
return false;
}
- // See if it specifies the class name for the certificate mapper
- // implementation.
- String className;
- msgID = MSGID_CONFIG_CERTMAPPER_DESCRIPTION_CLASS;
- StringConfigAttribute classStub =
- new StringConfigAttribute(ATTR_CERTMAPPER_CLASS, getMessage(msgID),
- true, false, false);
- try
- {
- StringConfigAttribute classAttr =
- (StringConfigAttribute) configEntry.getConfigAttribute(classStub);
- if (classAttr == null)
- {
- msgID = MSGID_CONFIG_CERTMAPPER_NO_CLASS_ATTR;
- unacceptableReason.append(getMessage(msgID));
- return false;
- }
- else
- {
- className = classAttr.activeValue();
- }
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "configChangeIsAcceptable", e);
-
- msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_DETERMINE_CLASS;
- unacceptableReason.append(getMessage(msgID,
- stackTraceToSingleLineString(e)));
- return false;
- }
-
-
- // Try to load the class and instantiate it as a certificate mapper.
- Class certificateMapperClass;
- try
- {
- // FIXME -- Should we use a custom class loader for this?
- certificateMapperClass = Class.forName(className);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "configChangeIsAcceptable", e);
-
- msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_LOAD_CLASS;
- unacceptableReason.append(getMessage(msgID, String.valueOf(className),
- stackTraceToSingleLineString(e)));
- return false;
- }
-
- try
- {
- CertificateMapper certificateMapper =
- (CertificateMapper) certificateMapperClass.newInstance();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "configChangeIsAcceptable", e);
-
- msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_INSTANTIATE_CLASS;
- unacceptableReason.append(getMessage(msgID, String.valueOf(className),
- stackTraceToSingleLineString(e)));
- return false;
- }
-
-
- // If we've gotten to this point, then it is acceptable as far as we are
- // concerned. If it is unacceptable according to the configuration, then
- // the certificate mapper itself will make that determination.
+ // If we've gotten here then the certificate mapper entry appears to be
+ // acceptable.
return true;
}
@@ -460,72 +364,78 @@
assert debugEnter(CLASS_NAME, "applyConfigurationChange",
String.valueOf(configEntry));
+
+ DN configEntryDN = configEntry.getDN();
ResultCode resultCode = ResultCode.SUCCESS;
boolean adminActionRequired = false;
ArrayList<String> messages = new ArrayList<String>();
- // See if the entry indicates whether the certificate mapper should be
- // enabled. If not, then make sure that the certificate mapper is disabled
- // and return since we don't need to do anything else.
- boolean needsEnabled = false;
- String existingProviderClass = null;
- int msgID = MSGID_CONFIG_CERTMAPPER_DESCRIPTION_ENABLED;
- BooleanConfigAttribute enabledStub =
- new BooleanConfigAttribute(ATTR_CERTMAPPER_ENABLED, getMessage(msgID),
- false);
+ // Make sure that the entry has an appropriate objectclass for a certificate
+ // mapper.
+ if (! configEntry.hasObjectClass(OC_CERTIFICATE_MAPPER))
+ {
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_CLASS;
+ messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
+ resultCode = ResultCode.UNWILLING_TO_PERFORM;
+ return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+ }
+
+
+ // Get the corresponding certificate mapper if it is active.
+ CertificateMapper mapper = mappers.get(configEntryDN);
+
+
+ // See if this mapper should be enabled or disabled.
+ boolean needsEnabled = false;
+ BooleanConfigAttribute enabledAttr;
try
{
- BooleanConfigAttribute enabledAttr =
- (BooleanConfigAttribute)
- configEntry.getConfigAttribute(enabledStub);
+ BooleanConfigAttribute enabledStub =
+ new BooleanConfigAttribute(ATTR_CERTMAPPER_ENABLED,
+ getMessage(MSGID_CONFIG_CERTMAPPER_DESCRIPTION_ENABLED),
+ false);
+ enabledAttr = (BooleanConfigAttribute)
+ configEntry.getConfigAttribute(enabledStub);
+
if (enabledAttr == null)
{
- msgID = MSGID_CONFIG_CERTMAPPER_NO_ENABLED_ATTR;
- messages.add(getMessage(msgID));
- resultCode = ResultCode.OBJECTCLASS_VIOLATION;
+ int msgID = MSGID_CONFIG_CERTMAPPER_NO_ENABLED_ATTR;
+ messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
+ resultCode = ResultCode.UNWILLING_TO_PERFORM;
return new ConfigChangeResult(resultCode, adminActionRequired,
messages);
}
- else if (! enabledAttr.pendingValue())
- {
- DirectoryServer.getCertificateMapper().finalizeCertificateMapper();
- // The provider should be disabled, so install the default certificate
- // mapper and return.
- try
- {
- SubjectEqualsDNCertificateMapper defaultMapper =
- new SubjectEqualsDNCertificateMapper();
- defaultMapper.initializeCertificateMapper(null);
- DirectoryServer.setCertificateMapper(defaultMapper);
- return new ConfigChangeResult(resultCode, adminActionRequired,
- messages);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "applyConfigurationChange", e);
-
- msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_INSTALL_DEFAULT_MAPPER;
- messages.add(getMessage(msgID, stackTraceToSingleLineString(e)));
- resultCode = DirectoryServer.getServerErrorResultCode();
- return new ConfigChangeResult(resultCode, adminActionRequired,
- messages);
- }
- }
- else
+ if (enabledAttr.activeValue())
{
- // The provider should be enabled. If it isn't, then set a flag to
- // indicate that we need to create it when we have more information.
- if (DirectoryServer.getCertificateMapper() instanceof
- SubjectEqualsDNCertificateMapper)
+ if (mapper == null)
{
needsEnabled = true;
}
else
{
- existingProviderClass =
- DirectoryServer.getCertificateMapper().getClass().getName();
+ // The mapper is already active, so no action is required.
+ }
+ }
+ else
+ {
+ if (mapper == null)
+ {
+ // The mapper is already disabled, so no action is required and we
+ // can short-circuit out of this processing.
+ return new ConfigChangeResult(resultCode, adminActionRequired,
+ messages);
+ }
+ else
+ {
+ // The mapper is active, so it needs to be disabled. Do this and
+ // return that we were successful.
+ mappers.remove(configEntryDN);
+ DirectoryServer.deregisterCertificateMapper(configEntryDN);
+ mapper.finalizeCertificateMapper();
+ return new ConfigChangeResult(resultCode, adminActionRequired,
+ messages);
}
}
}
@@ -533,133 +443,118 @@
{
assert debugException(CLASS_NAME, "applyConfigurationChange", e);
- msgID = MSGID_CONFIG_CERTMAPPER_UNABLE_TO_DETERMINE_ENABLED_STATE;
- messages.add(getMessage(msgID, stackTraceToSingleLineString(e)));
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_ENABLED_VALUE;
+ messages.add(getMessage(msgID, String.valueOf(configEntryDN),
+ String.valueOf(e)));
resultCode = DirectoryServer.getServerErrorResultCode();
return new ConfigChangeResult(resultCode, adminActionRequired, messages);
}
- // Get the class name from the configuration entry.
+ // Make sure that the entry specifies the mapper class name. If it has
+ // changed, then we will not try to dynamically apply it.
String className;
- msgID = MSGID_CONFIG_CERTMAPPER_DESCRIPTION_CLASS;
- StringConfigAttribute classStub =
- new StringConfigAttribute(ATTR_CERTMAPPER_CLASS, getMessage(msgID),
- true, false, false);
try
{
- StringConfigAttribute classAttr =
+ StringConfigAttribute classStub =
+ new StringConfigAttribute(ATTR_CERTMAPPER_CLASS,
+ getMessage(MSGID_CONFIG_CERTMAPPER_DESCRIPTION_CLASS),
+ true, false, true);
+ StringConfigAttribute classNameAttr =
(StringConfigAttribute) configEntry.getConfigAttribute(classStub);
- if (classAttr == null)
+
+ if (classNameAttr == null)
{
- msgID = MSGID_CONFIG_CERTMAPPER_NO_CLASS_ATTR;
- messages.add(getMessage(msgID));
+ int msgID = MSGID_CONFIG_CERTMAPPER_NO_CLASS_NAME;
+ messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
resultCode = ResultCode.OBJECTCLASS_VIOLATION;
return new ConfigChangeResult(resultCode, adminActionRequired,
messages);
}
- else
- {
- className = classAttr.activeValue();
- }
+
+ className = classNameAttr.pendingValue();
}
catch (Exception e)
{
assert debugException(CLASS_NAME, "applyConfigurationChange", e);
- msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_DETERMINE_CLASS;
- messages.add(getMessage(msgID, stackTraceToSingleLineString(e)));
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_CLASS_NAME;
+ messages.add(getMessage(msgID, String.valueOf(configEntryDN),
+ String.valueOf(e)));
resultCode = DirectoryServer.getServerErrorResultCode();
return new ConfigChangeResult(resultCode, adminActionRequired, messages);
}
- // If the certificate mapper is already enabled and the specified class is
- // different from the class that is currently in use, then we won't try to
- // do anything. The certificate mapper must be disabled and re-enabled
- // before the configuration change will be accepted.
- if (! needsEnabled)
+ boolean classChanged = false;
+ String oldClassName = null;
+ if (mapper != null)
{
- if (! className.equals(existingProviderClass))
+ oldClassName = mapper.getClass().getName();
+ classChanged = (! className.equals(oldClassName));
+ }
+
+
+ if (classChanged)
+ {
+ // This will not be applied dynamically. Add a message to the response
+ // and indicate that admin action is required.
+ adminActionRequired = true;
+ messages.add(getMessage(MSGID_CONFIG_CERTMAPPER_CLASS_ACTION_REQUIRED,
+ String.valueOf(oldClassName),
+ String.valueOf(className),
+ String.valueOf(configEntryDN)));
+ return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+ }
+
+
+ if (needsEnabled)
+ {
+ try
{
- msgID = MSGID_CONFIG_CERTMAPPER_NOT_SWITCHING_CLASSES;
- messages.add(getMessage(msgID, String.valueOf(existingProviderClass),
- String.valueOf(className)));
- resultCode = ResultCode.UNWILLING_TO_PERFORM;
- adminActionRequired = true;
+ // FIXME -- Should this be done with a dynamic class loader?
+ Class mapperClass = Class.forName(className);
+ mapper = (CertificateMapper) mapperClass.newInstance();
+ }
+ catch (Exception e)
+ {
+ assert debugException(CLASS_NAME, "applyConfigurationChange", e);
+
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_CLASS;
+ messages.add(getMessage(msgID, className,
+ String.valueOf(configEntryDN),
+ String.valueOf(e)));
+ resultCode = DirectoryServer.getServerErrorResultCode();
return new ConfigChangeResult(resultCode, adminActionRequired,
messages);
}
- else
+
+ try
{
- // We don't need to do anything because it's already enabled and has the
- // right class.
+ mapper.initializeCertificateMapper(configEntry);
+ }
+ catch (Exception e)
+ {
+ assert debugException(CLASS_NAME, "applyConfigurationChange", e);
+
+ int msgID = MSGID_CONFIG_CERTMAPPER_INITIALIZATION_FAILED;
+ messages.add(getMessage(msgID, className,
+ String.valueOf(configEntryDN),
+ String.valueOf(e)));
+ resultCode = DirectoryServer.getServerErrorResultCode();
return new ConfigChangeResult(resultCode, adminActionRequired,
messages);
}
- }
- // Try to load the class and instantiate it as a certificate mapper.
- Class certificateMapperClass;
- try
- {
- // FIXME -- Should we use a custom class loader for this?
- certificateMapperClass = Class.forName(className);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "applyConfigurationChange", e);
-
- msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_LOAD_CLASS;
- messages.add(getMessage(msgID, String.valueOf(className),
- stackTraceToSingleLineString(e)));
- resultCode = DirectoryServer.getServerErrorResultCode();
- return new ConfigChangeResult(resultCode, adminActionRequired, messages);
- }
-
- CertificateMapper certificateMapper;
- try
- {
- certificateMapper =
- (CertificateMapper) certificateMapperClass.newInstance();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "applyConfigurationChange", e);
-
- msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_INSTANTIATE_CLASS;
- messages.add(getMessage(msgID, String.valueOf(className),
- stackTraceToSingleLineString(e)));
- resultCode = DirectoryServer.getServerErrorResultCode();
+ mappers.put(configEntryDN, mapper);
+ DirectoryServer.registerCertificateMapper(configEntryDN, mapper);
return new ConfigChangeResult(resultCode, adminActionRequired, messages);
}
- // Try to initialize the certificate mapper with the contents of the
- // configuration entry.
- try
- {
- certificateMapper.initializeCertificateMapper(configEntry);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "applyConfigurationChange", e);
-
- msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_INITIALIZE;
- messages.add(getMessage(msgID, String.valueOf(className),
- stackTraceToSingleLineString(e)));
- resultCode = DirectoryServer.getServerErrorResultCode();
- return new ConfigChangeResult(resultCode, adminActionRequired, messages);
- }
-
-
- // Install the new certificate mapper in the server. We don't need to do
- // anything to get rid of the previous default mapper since it doesn't
- // consume any resources.
- DirectoryServer.setCertificateMapper(certificateMapper);
-
-
+ // If we've gotten here, then there haven't been any changes to anything
+ // that we care about.
return new ConfigChangeResult(resultCode, adminActionRequired, messages);
}
@@ -685,127 +580,161 @@
String.valueOf(configEntry), "java.lang.StringBuilder");
- // Get the DN of the provided entry and see if it is the DN that we expect
- // for the certificate mapper configuration. If it is not, then it's not an
- // entry that we care about so return true.
- DN providedEntryDN = configEntry.getDN();
- DN expectedEntryDN;
- try
+ // Make sure that no entry already exists with the specified DN.
+ DN configEntryDN = configEntry.getDN();
+ if (mappers.containsKey(configEntryDN))
{
- expectedEntryDN = DN.decode(DN_CERTMAPPER_CONFIG);
- }
- catch (DirectoryException de)
- {
- assert debugException(CLASS_NAME, "configAddIsAcceptable", de);
-
- unacceptableReason.append(de.getErrorMessage());
+ int msgID = MSGID_CONFIG_CERTMAPPER_EXISTS;
+ String message = getMessage(msgID, String.valueOf(configEntryDN));
+ unacceptableReason.append(message);
return false;
}
- if (! providedEntryDN.equals(expectedEntryDN))
+
+ // Make sure that the entry has an appropriate objectclass for a certificate
+ // mapper.
+ if (! configEntry.hasObjectClass(OC_CERTIFICATE_MAPPER))
{
- return true;
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_OBJECTCLASS;
+ String message = getMessage(msgID, configEntry.getDN().toString());
+ unacceptableReason.append(message);
+ return false;
}
- // See if the entry indicates whether the certificate mapper should be
- // enabled.
- int msgID = MSGID_CONFIG_CERTMAPPER_DESCRIPTION_ENABLED;
- BooleanConfigAttribute enabledStub =
- new BooleanConfigAttribute(ATTR_CERTMAPPER_ENABLED, getMessage(msgID),
- false);
+ // Make sure that the entry specifies the certificate mapper class.
+ StringConfigAttribute classNameAttr;
try
{
- BooleanConfigAttribute enabledAttr =
- (BooleanConfigAttribute)
- configEntry.getConfigAttribute(enabledStub);
+ StringConfigAttribute classStub =
+ new StringConfigAttribute(ATTR_CERTMAPPER_CLASS,
+ getMessage(MSGID_CONFIG_CERTMAPPER_DESCRIPTION_CLASS),
+ true, false, true);
+ classNameAttr = (StringConfigAttribute)
+ configEntry.getConfigAttribute(classStub);
+
+ if (classNameAttr == null)
+ {
+ int msgID = MSGID_CONFIG_CERTMAPPER_NO_CLASS_NAME;
+ String message = getMessage(msgID, configEntry.getDN().toString());
+ unacceptableReason.append(message);
+ return false;
+ }
+ }
+ catch (Exception e)
+ {
+ assert debugException(CLASS_NAME, "configAddIsAcceptable", e);
+
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_CLASS_NAME;
+ String message = getMessage(msgID, configEntry.getDN().toString(),
+ String.valueOf(e));
+ unacceptableReason.append(message);
+ return false;
+ }
+
+ Class mapperClass;
+ try
+ {
+ // FIXME -- Should this be done with a custom class loader?
+ mapperClass = Class.forName(classNameAttr.pendingValue());
+ }
+ catch (Exception e)
+ {
+ assert debugException(CLASS_NAME, "configAddIsAcceptable", e);
+
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_CLASS_NAME;
+ String message = getMessage(msgID, configEntry.getDN().toString(),
+ String.valueOf(e));
+ unacceptableReason.append(message);
+ return false;
+ }
+
+ CertificateMapper mapper;
+ try
+ {
+ mapper = (CertificateMapper) mapperClass.newInstance();
+ }
+ catch (Exception e)
+ {
+ assert debugException(CLASS_NAME, "configAddIsAcceptable", e);
+
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_CLASS;
+ String message = getMessage(msgID, mapperClass.getName(),
+ String.valueOf(configEntryDN),
+ String.valueOf(e));
+ unacceptableReason.append(message);
+ return false;
+ }
+
+
+ // See if this mapper should be enabled.
+ BooleanConfigAttribute enabledAttr;
+ try
+ {
+ BooleanConfigAttribute enabledStub =
+ new BooleanConfigAttribute(ATTR_CERTMAPPER_ENABLED,
+ getMessage(MSGID_CONFIG_CERTMAPPER_DESCRIPTION_ENABLED),
+ false);
+ enabledAttr = (BooleanConfigAttribute)
+ configEntry.getConfigAttribute(enabledStub);
+
if (enabledAttr == null)
{
- msgID = MSGID_CONFIG_CERTMAPPER_NO_ENABLED_ATTR;
- unacceptableReason.append(getMessage(msgID));
+ int msgID = MSGID_CONFIG_CERTMAPPER_NO_ENABLED_ATTR;
+ String message = getMessage(msgID, configEntry.getDN().toString());
+ unacceptableReason.append(message);
+ return false;
+ }
+ else if (! enabledAttr.pendingValue())
+ {
+ // The certificate mapper is not enabled so we don't need to do any
+ // further validation.
+ return true;
+ }
+ }
+ catch (Exception e)
+ {
+ assert debugException(CLASS_NAME, "configAddIsAcceptable", e);
+
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_ENABLED_VALUE;
+ String message = getMessage(msgID, configEntry.getDN().toString(),
+ String.valueOf(e));
+ unacceptableReason.append(message);
+ return false;
+ }
+
+
+ // If the mapper is a configurable component, then make sure that its
+ // configuration is valid.
+ if (mapper instanceof ConfigurableComponent)
+ {
+ ConfigurableComponent cc = (ConfigurableComponent) mapper;
+ LinkedList<String> errorMessages = new LinkedList<String>();
+ if (! cc.hasAcceptableConfiguration(configEntry, errorMessages))
+ {
+ if (errorMessages.isEmpty())
+ {
+ int msgID = MSGID_CONFIG_CERTMAPPER_UNACCEPTABLE_CONFIG;
+ unacceptableReason.append(getMessage(msgID,
+ String.valueOf(configEntryDN)));
+ }
+ else
+ {
+ Iterator<String> iterator = errorMessages.iterator();
+ unacceptableReason.append(iterator.next());
+ while (iterator.hasNext())
+ {
+ unacceptableReason.append(" ");
+ unacceptableReason.append(iterator.next());
+ }
+ }
+
return false;
}
}
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "configAddIsAcceptable", e);
-
- msgID = MSGID_CONFIG_CERTMAPPER_UNABLE_TO_DETERMINE_ENABLED_STATE;
- unacceptableReason.append(getMessage(msgID,
- stackTraceToSingleLineString(e)));
- return false;
- }
- // See if it specifies the class name for the certificate mapper
- // implementation.
- String className;
- msgID = MSGID_CONFIG_CERTMAPPER_DESCRIPTION_CLASS;
- StringConfigAttribute classStub =
- new StringConfigAttribute(ATTR_CERTMAPPER_CLASS, getMessage(msgID),
- true, false, false);
- try
- {
- StringConfigAttribute classAttr =
- (StringConfigAttribute) configEntry.getConfigAttribute(classStub);
- if (classAttr == null)
- {
- msgID = MSGID_CONFIG_CERTMAPPER_NO_CLASS_ATTR;
- unacceptableReason.append(getMessage(msgID));
- return false;
- }
- else
- {
- className = classAttr.activeValue();
- }
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "configAddIsAcceptable", e);
-
- msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_DETERMINE_CLASS;
- unacceptableReason.append(getMessage(msgID,
- stackTraceToSingleLineString(e)));
- return false;
- }
-
-
- // Try to load the class and instantiate it as a certificate mapper.
- Class certificateMapperClass;
- try
- {
- // FIXME -- Should we use a custom class loader for this?
- certificateMapperClass = Class.forName(className);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "configAddIsAcceptable", e);
-
- msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_LOAD_CLASS;
- unacceptableReason.append(getMessage(msgID, String.valueOf(className),
- stackTraceToSingleLineString(e)));
- return false;
- }
-
- try
- {
- CertificateMapper certificateMapper =
- (CertificateMapper) certificateMapperClass.newInstance();
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "configAddIsAcceptable", e);
-
- msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_INSTANTIATE_CLASS;
- unacceptableReason.append(getMessage(msgID, String.valueOf(className),
- stackTraceToSingleLineString(e)));
- return false;
- }
-
-
- // If we've gotten to this point, then it is acceptable as far as we are
- // concerned. If it is unacceptable according to the configuration, then
- // the certificate mapper itself will make that determination.
+ // If we've gotten here then the mapper entry appears to be acceptable.
return true;
}
@@ -825,84 +754,48 @@
assert debugEnter(CLASS_NAME, "applyConfigurationAdd",
String.valueOf(configEntry));
+
+ DN configEntryDN = configEntry.getDN();
ResultCode resultCode = ResultCode.SUCCESS;
boolean adminActionRequired = false;
ArrayList<String> messages = new ArrayList<String>();
- // Get the DN of the provided entry and see if it is the DN that we expect
- // for the certificate mapper configuration. If it is not, then it's not an
- // entry that we care about so return without doing anything.
- DN providedEntryDN = configEntry.getDN();
- DN expectedEntryDN;
- try
+ // Make sure that the entry has an appropriate objectclass for a certificate
+ // mapper.
+ if (! configEntry.hasObjectClass(OC_CERTIFICATE_MAPPER))
{
- expectedEntryDN = DN.decode(DN_CERTMAPPER_CONFIG);
- }
- catch (DirectoryException de)
- {
- assert debugException(CLASS_NAME, "applyConfigurationAdd", de);
-
- messages.add(de.getErrorMessage());
- resultCode = de.getResultCode();
- return new ConfigChangeResult(resultCode, adminActionRequired, messages);
- }
-
- if (! providedEntryDN.equals(expectedEntryDN))
- {
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_OBJECTCLASS;
+ messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
+ resultCode = ResultCode.UNWILLING_TO_PERFORM;
return new ConfigChangeResult(resultCode, adminActionRequired, messages);
}
- // Register as a change listener of the provided entry so that we will be
- // notified of changes to it. We will also want to register a delete
- // listener with its parent to allow us to determine if the entry is
- // deleted.
- configEntry.registerChangeListener(this);
+ // See if this mapper should be enabled or disabled.
+ BooleanConfigAttribute enabledAttr;
try
{
- DN parentDN = configEntry.getDN().getParentDNInSuffix();
- ConfigEntry parentEntry = DirectoryServer.getConfigEntry(parentDN);
- if (parentEntry != null)
- {
- parentEntry.registerDeleteListener(this);
- }
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "applyConfigurationAdd", e);
+ BooleanConfigAttribute enabledStub =
+ new BooleanConfigAttribute(ATTR_CERTMAPPER_ENABLED,
+ getMessage(MSGID_CONFIG_CERTMAPPER_DESCRIPTION_ENABLED),
+ false);
+ enabledAttr = (BooleanConfigAttribute)
+ configEntry.getConfigAttribute(enabledStub);
- logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_WARNING,
- MSGID_CONFIG_CERTMAPPER_CANNOT_REGISTER_DELETE_LISTENER,
- stackTraceToSingleLineString(e));
- }
-
-
- // See if the entry indicates whether the certificate mapper should be
- // enabled.
- int msgID = MSGID_CONFIG_CERTMAPPER_DESCRIPTION_ENABLED;
- BooleanConfigAttribute enabledStub =
- new BooleanConfigAttribute(ATTR_CERTMAPPER_ENABLED, getMessage(msgID),
- false);
- try
- {
- BooleanConfigAttribute enabledAttr =
- (BooleanConfigAttribute)
- configEntry.getConfigAttribute(enabledStub);
if (enabledAttr == null)
{
- // The attribute is not present, so the certificate mapper will be
- // disabled. Log a warning message and return.
- messages.add(getMessage(MSGID_CONFIG_CERTMAPPER_NO_ENABLED_ATTR));
- resultCode = ResultCode.OBJECTCLASS_VIOLATION;
+ // The attribute doesn't exist, so it will be disabled by default.
+ int msgID = MSGID_CONFIG_CERTMAPPER_NO_ENABLED_ATTR;
+ messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
+ resultCode = ResultCode.SUCCESS;
return new ConfigChangeResult(resultCode, adminActionRequired,
messages);
}
else if (! enabledAttr.activeValue())
{
- // The certificate mapper is explicitly disabled. Log a mild warning
- // and return.
- messages.add(getMessage(MSGID_CONFIG_CERTMAPPER_DISABLED));
+ // It is explicitly configured as disabled, so we don't need to do
+ // anything.
return new ConfigChangeResult(resultCode, adminActionRequired,
messages);
}
@@ -911,107 +804,86 @@
{
assert debugException(CLASS_NAME, "applyConfigurationAdd", e);
- msgID = MSGID_CONFIG_CERTMAPPER_UNABLE_TO_DETERMINE_ENABLED_STATE;
- messages.add(getMessage(msgID, stackTraceToSingleLineString(e)));
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_ENABLED_VALUE;
+ messages.add(getMessage(msgID, String.valueOf(configEntryDN),
+ String.valueOf(e)));
resultCode = DirectoryServer.getServerErrorResultCode();
return new ConfigChangeResult(resultCode, adminActionRequired, messages);
}
- // See if it specifies the class name for the certificate mapper
- // implementation.
+ // Make sure that the entry specifies the mapper class name.
String className;
- msgID = MSGID_CONFIG_CERTMAPPER_DESCRIPTION_CLASS;
- StringConfigAttribute classStub =
- new StringConfigAttribute(ATTR_CERTMAPPER_CLASS, getMessage(msgID),
- true, false, false);
try
{
- StringConfigAttribute classAttr =
+ StringConfigAttribute classStub =
+ new StringConfigAttribute(ATTR_CERTMAPPER_CLASS,
+ getMessage(MSGID_CONFIG_CERTMAPPER_DESCRIPTION_CLASS),
+ true, false, true);
+ StringConfigAttribute classNameAttr =
(StringConfigAttribute) configEntry.getConfigAttribute(classStub);
- if (classAttr == null)
+
+ if (classNameAttr == null)
{
- messages.add(getMessage(MSGID_CONFIG_CERTMAPPER_NO_CLASS_ATTR));
+ int msgID = MSGID_CONFIG_CERTMAPPER_NO_CLASS_NAME;
+ messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
resultCode = ResultCode.OBJECTCLASS_VIOLATION;
return new ConfigChangeResult(resultCode, adminActionRequired,
messages);
}
- else
- {
- className = classAttr.activeValue();
- }
+
+ className = classNameAttr.pendingValue();
}
catch (Exception e)
{
assert debugException(CLASS_NAME, "applyConfigurationAdd", e);
- msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_DETERMINE_CLASS;
- messages.add(getMessage(msgID, stackTraceToSingleLineString(e)));
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_CLASS_NAME;
+ messages.add(getMessage(msgID, String.valueOf(configEntryDN),
+ String.valueOf(e)));
resultCode = DirectoryServer.getServerErrorResultCode();
return new ConfigChangeResult(resultCode, adminActionRequired, messages);
}
- // Try to load the class and instantiate it as a certificate mapper.
- Class certificateMapperClass;
+ // Load and initialize the mapper class, and register it with the Directory
+ // Server.
+ CertificateMapper mapper;
try
{
- // FIXME -- Should we use a custom class loader for this?
- certificateMapperClass = Class.forName(className);
+ // FIXME -- Should this be done with a dynamic class loader?
+ Class mapperClass = Class.forName(className);
+ mapper = (CertificateMapper) mapperClass.newInstance();
}
catch (Exception e)
{
assert debugException(CLASS_NAME, "applyConfigurationAdd", e);
- msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_LOAD_CLASS;
- messages.add(getMessage(msgID, String.valueOf(className),
- stackTraceToSingleLineString(e)));
+ int msgID = MSGID_CONFIG_CERTMAPPER_INVALID_CLASS;
+ messages.add(getMessage(msgID, className, String.valueOf(configEntryDN),
+ String.valueOf(e)));
resultCode = DirectoryServer.getServerErrorResultCode();
return new ConfigChangeResult(resultCode, adminActionRequired, messages);
}
- CertificateMapper certificateMapper;
try
{
- certificateMapper =
- (CertificateMapper) certificateMapperClass.newInstance();
+ mapper.initializeCertificateMapper(configEntry);
}
catch (Exception e)
{
assert debugException(CLASS_NAME, "applyConfigurationAdd", e);
- msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_INSTANTIATE_CLASS;
- messages.add(getMessage(msgID, String.valueOf(className),
- stackTraceToSingleLineString(e)));
+ int msgID = MSGID_CONFIG_CERTMAPPER_INITIALIZATION_FAILED;
+ messages.add(getMessage(msgID, className, String.valueOf(configEntryDN),
+ String.valueOf(e)));
resultCode = DirectoryServer.getServerErrorResultCode();
return new ConfigChangeResult(resultCode, adminActionRequired, messages);
}
- // Try to initialize the certificate mapper with the contents of the
- // configuration entry.
- try
- {
- certificateMapper.initializeCertificateMapper(configEntry);
- }
- catch (Exception e)
- {
- assert debugException(CLASS_NAME, "applyConfigurationAdd", e);
-
- msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_INITIALIZE;
- messages.add(getMessage(msgID, String.valueOf(className),
- stackTraceToSingleLineString(e)));
- resultCode = DirectoryServer.getServerErrorResultCode();
- return new ConfigChangeResult(resultCode, adminActionRequired, messages);
- }
-
-
- // Install the new certificate mapper in the server. We don't need to do
- // anything to get rid of the previous default mapper since it doesn't
- // consume any resources.
- DirectoryServer.setCertificateMapper(certificateMapper);
-
-
+ mappers.put(configEntryDN, mapper);
+ DirectoryServer.registerCertificateMapper(configEntryDN, mapper);
return new ConfigChangeResult(resultCode, adminActionRequired, messages);
}
@@ -1037,46 +909,7 @@
String.valueOf(configEntry), "java.lang.StringBuilder");
- // Get the DN of the provided entry and see if it is the DN that we expect
- // for the certificate mapper configuration. If it is not, then it's not an
- // entry that we care about so return true.
- DN providedEntryDN = configEntry.getDN();
- DN expectedEntryDN;
- try
- {
- expectedEntryDN = DN.decode(DN_CERTMAPPER_CONFIG);
- }
- catch (DirectoryException de)
- {
- assert debugException(CLASS_NAME, "configAddIsAcceptable", de);
-
- unacceptableReason.append(de.getErrorMessage());
- return false;
- }
-
- if (! providedEntryDN.equals(expectedEntryDN))
- {
- return true;
- }
-
-
- // Determine whether there is a valid certificate mapper installed (i.e.,
- // not the default mapper). If a valid mapper is installed, then we will
- // not allow the entry to be removed.
- CertificateMapper installedMapper =
- DirectoryServer.getCertificateMapper();
- if (! (installedMapper instanceof SubjectEqualsDNCertificateMapper))
- {
- int msgID = MSGID_CONFIG_CERTMAPPER_CANNOT_REMOVE_ACTIVE_PROVIDER;
- unacceptableReason.append(getMessage(msgID,
- installedMapper.getClass().getName()));
- return false;
- }
-
-
- // If we've gotten to this point, then it is acceptable as far as we are
- // concerned. If it is unacceptable according to the configuration, then
- // the certificate mapper itself will make that determination.
+ // A delete should always be acceptable, so just return true.
return true;
}
@@ -1095,14 +928,23 @@
assert debugEnter(CLASS_NAME, "applyConfigurationDelete",
String.valueOf(configEntry));
- ResultCode resultCode = ResultCode.SUCCESS;
- boolean adminActionRequired = false;
- ArrayList<String> messages = new ArrayList<String>();
+
+ DN configEntryDN = configEntry.getDN();
+ ResultCode resultCode = ResultCode.SUCCESS;
+ boolean adminActionRequired = false;
- // Since we can never delete an active configuration, there is nothing that
- // we need to do if a delete does go through.
- return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+ // See if the entry is registered as a certificate mapper. If so,
+ // deregister it and stop the mapper.
+ CertificateMapper mapper = mappers.remove(configEntryDN);
+ if (mapper != null)
+ {
+ DirectoryServer.deregisterCertificateMapper(configEntryDN);
+ mapper.finalizeCertificateMapper();
+ }
+
+
+ return new ConfigChangeResult(resultCode, adminActionRequired);
}
}
--
Gitblit v1.10.0