mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

lutoff
18.08.2007 9b97b90c77daa7c02491be3894b3ccdd51c974cd
Issue 1483 fix (use new admin framework for Access control configuration)
2 files added
7 files modified
448 ■■■■■ changed files
opends/src/admin/defn/org/opends/server/admin/std/AccessControlHandlerConfiguration.xml 55 ●●●●● patch | view | raw | blame | history
opends/src/admin/defn/org/opends/server/admin/std/DseeCompatAccessControlHandlerConfiguration.xml 45 ●●●●● patch | view | raw | blame | history
opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml 8 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/api/AccessControlProvider.java 17 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/authorization/BasicAccessControlProvider.java 8 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java 41 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/authorization/dseecompat/AciProvider.java 26 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/AccessControlConfigManager.java 243 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/DefaultAccessControlProvider.java 5 ●●●●● patch | view | raw | blame | history
opends/src/admin/defn/org/opends/server/admin/std/AccessControlHandlerConfiguration.xml
New file
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<adm:managed-object name="access-control-handler"
  plural-name="access-control-handlers"
  package="org.opends.server.admin.std"
  xmlns:adm="http://www.opends.org/admin"
  xmlns:ldap="http://www.opends.org/admin-ldap">
  <adm:synopsis>
    <adm:user-friendly-plural-name />
     manage the application-wide access-control.
  </adm:synopsis>
  <adm:profile name="ldap">
    <ldap:object-class>
      <ldap:oid>1.3.6.1.4.1.26027.1.2.1</ldap:oid>
      <ldap:name>ds-cfg-access-control-handler</ldap:name>
      <ldap:superior>top</ldap:superior>
    </ldap:object-class>
  </adm:profile>
  <adm:property name="enabled" mandatory="true">
    <adm:synopsis>
      Indicate whether the
      <adm:user-friendly-name />
      is enabled for use.
    </adm:synopsis>
    <adm:syntax>
      <adm:boolean />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:oid>1.3.6.1.4.1.26027.1.1.2</ldap:oid>
        <ldap:name>ds-cfg-acl-handler-enabled</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="acl-handler-class" mandatory="true">
    <adm:synopsis>
      The fully-qualified name of the Java class that provides the
      <adm:user-friendly-name />
      implementation.
    </adm:synopsis>
    <adm:syntax>
      <adm:java-class>
        <adm:instance-of>
          org.opends.server.authorization.dseecompat.AciProvider
        </adm:instance-of>
      </adm:java-class>
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:oid>1.3.6.1.4.1.26027.1.1.1</ldap:oid>
        <ldap:name>ds-cfg-acl-handler-class</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
</adm:managed-object>
opends/src/admin/defn/org/opends/server/admin/std/DseeCompatAccessControlHandlerConfiguration.xml
New file
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<adm:managed-object name="dsee-compat-access-control-handler"
  plural-name="dseecompat-access-control-handlers"
  package="org.opends.server.admin.std" extends="access-control-handler"
  xmlns:adm="http://www.opends.org/admin"
  xmlns:ldap="http://www.opends.org/admin-ldap">
  <adm:synopsis>
    The
    <adm:user-friendly-name />
    is the provider class for the dseecompt ACI.
  </adm:synopsis>
  <adm:profile name="ldap">
    <ldap:object-class>
      <ldap:oid>1.3.6.1.4.1.26027.1.2.87</ldap:oid>
      <ldap:name>ds-cfg-dseecompat-access-control-handler</ldap:name>
      <ldap:superior>ds-cfg-access-control-handler</ldap:superior>
    </ldap:object-class>
  </adm:profile>
  <adm:property name="global-aci" mandatory="false"
    multi-valued="true">
    <adm:synopsis>
    </adm:synopsis>
    <adm:description>
    </adm:description>
       <adm:default-behavior>
      <adm:alias>
        <adm:synopsis>
        </adm:synopsis>
      </adm:alias>
    </adm:default-behavior>
    <adm:syntax>
      <adm:string />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:oid>1.3.6.1.4.1.26027.1.1.320</ldap:oid>
        <ldap:name>ds-cfg-global-aci</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
</adm:managed-object>
opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml
@@ -21,6 +21,14 @@
      </ldap:rdn-sequence>
    </adm:profile>
  </adm:relation>
    <adm:relation name="access-control-handler">
    <adm:one-to-one />
    <adm:profile name="ldap">
      <ldap:rdn-sequence>
        cn=Access Control Handler,cn=config
      </ldap:rdn-sequence>
    </adm:profile>
  </adm:relation>
  <adm:relation name="identity-mapper">
    <adm:one-to-many />
    <adm:profile name="ldap">
opends/src/server/org/opends/server/api/AccessControlProvider.java
@@ -26,7 +26,7 @@
 */
package org.opends.server.api;
import org.opends.server.config.ConfigEntry;
import org.opends.server.admin.std.server.AccessControlHandlerCfg;
import org.opends.server.config.ConfigException;
import org.opends.server.types.InitializationException;
@@ -34,16 +34,21 @@
 * This class defines an interface for managing the life-cycle of an
 * access control handler. The access control handler configuration
 * should specify the name of a class implementing this interface.
 *
 * @param <T>
 *          The type of connection handler configuration handled by
 *          this connection handler implementation.
 */
public interface AccessControlProvider {
public interface AccessControlProvider
  <T extends AccessControlHandlerCfg> {
  /**
   * Initializes the access control handler implementation based on
   * the information in the provided configuration entry.
   *
   * @param configEntry
   *          The configuration entry that contains the information to
   *          use to initialize this access control handler.
   * @param configuration
   *          The configuration object that contains the information
   *          to use to initialize this access control handler.
   * @throws ConfigException
   *           If an unrecoverable problem arises in the process of
   *           performing the initialization.
@@ -51,7 +56,7 @@
   *           If a problem occurs during initialization that is not
   *           related to the server configuration.
   */
  void initializeAccessControlHandler(ConfigEntry configEntry)
  void initializeAccessControlHandler(T configuration)
      throws ConfigException, InitializationException;
  /**
opends/src/server/org/opends/server/authorization/BasicAccessControlProvider.java
@@ -26,9 +26,9 @@
 */
package org.opends.server.authorization;
import org.opends.server.admin.std.server.AccessControlHandlerCfg;
import org.opends.server.api.AccessControlHandler;
import org.opends.server.api.AccessControlProvider;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.types.InitializationException;
@@ -59,8 +59,10 @@
  /**
   * {@inheritDoc}
   */
  public void initializeAccessControlHandler(ConfigEntry configEntry)
      throws ConfigException, InitializationException {
  public void initializeAccessControlHandler(
      AccessControlHandlerCfg configuration) throws ConfigException,
      InitializationException
  {
    // Avoid potential race conditions constructing the handler instance
    // and create it here.
opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
@@ -27,6 +27,7 @@
package org.opends.server.authorization.dseecompat;
import org.opends.server.admin.std.server.DseeCompatAccessControlHandlerCfg;
import org.opends.server.api.AccessControlHandler;
import static org.opends.server.messages.AciMessages.*;
import static org.opends.server.authorization.dseecompat.Aci.*;
@@ -36,9 +37,6 @@
import org.opends.server.types.*;
import static org.opends.server.util.StaticUtils.toLowerCase;
import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
import org.opends.server.config.StringConfigAttribute;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import static org.opends.server.loggers.debug.DebugLogger.debugCaught;
@@ -98,12 +96,13 @@
     *  - Processes all "aci" attributes found in the "cn=config" naming
     *    context and adds them to the ACI list cache.
     *
     * @param configEntry The configuration entry passed in from the provider.
     * @param configuration The configuration entry passed in from the provider.
     * @throws InitializationException if there is a problem processing the
     * config entry or config naming context.
    */
    public AciHandler(ConfigEntry configEntry) throws InitializationException  {
        aciList = new AciList(configEntry.getDN());
    public AciHandler(DseeCompatAccessControlHandlerCfg configuration)
    throws InitializationException  {
        aciList = new AciList(configuration.dn());
        AciListenerManager aciListenerMgr =
            new AciListenerManager(aciList);
        DirectoryServer.registerChangeNotificationListener(aciListenerMgr);
@@ -114,7 +113,7 @@
               DirectoryServer.getAttributeType(ATTR_AUTHZ_GLOBAL_ACI)) == null)
            globalAciType =
                 DirectoryServer.getDefaultAttributeType(ATTR_AUTHZ_GLOBAL_ACI);
        processGlobalAcis(configEntry);
        processGlobalAcis(configuration);
        processConfigAcis();
    }
@@ -127,21 +126,23 @@
     * @throws InitializationException If there is an error reading
     * the global ACIs from the configuration entry.
     */
    private void processGlobalAcis(ConfigEntry configEntry)
    private void processGlobalAcis(
        DseeCompatAccessControlHandlerCfg configuration)
    throws InitializationException {
        int msgID = MSGID_ACI_DESCRIPTION_GLOBAL_ACI;
        StringConfigAttribute aciGlobalStub =
                new StringConfigAttribute(ATTR_AUTHZ_GLOBAL_ACI,
                        getMessage(msgID), false, true, false);
        int msgID;
        SortedSet<String> globalAci = configuration.getGlobalACI();
        try {
            StringConfigAttribute aciGlobalAttr =
                    (StringConfigAttribute)
                            configEntry.getConfigAttribute(aciGlobalStub);
            if (aciGlobalAttr != null)   {
            if (globalAci != null)   {
                LinkedHashSet<AttributeValue> attVals =
                  new LinkedHashSet<AttributeValue>(globalAci.size());
                for (String aci : globalAci)
                {
                  attVals.add(new AttributeValue(globalAciType,aci));
                }
                Attribute attr = new Attribute(globalAciType,
                        globalAciType.toString(),
                        aciGlobalAttr.getActiveValues());
                Entry e = new Entry(configEntry.getDN(), null, null, null);
                        attVals);
                Entry e = new Entry(configuration.dn(), null, null, null);
                e.addAttribute(attr, new ArrayList<AttributeValue>());
                int aciCount =  aciList.addAci(e, false, true);
                msgID  = MSGID_ACI_ADD_LIST_GLOBAL_ACIS;
@@ -156,12 +157,12 @@
                        ErrorLogSeverity.INFORMATIONAL, message, msgID);
            }
        }  catch (ConfigException e) {
        }  catch (Exception e) {
            if (debugEnabled())
                debugCaught(DebugLogLevel.ERROR, e);
            msgID = MSGID_ACI_HANDLER_FAIL_PROCESS_GLOBAL_ACI;
            String message =
                    getMessage(msgID, String.valueOf(configEntry.getDN()),
                    getMessage(msgID, String.valueOf(configuration.dn()),
                    stackTraceToSingleLineString(e));
            throw new InitializationException(msgID, message, e);
        }
opends/src/server/org/opends/server/authorization/dseecompat/AciProvider.java
@@ -27,16 +27,18 @@
package org.opends.server.authorization.dseecompat;
import org.opends.server.admin.std.server.DseeCompatAccessControlHandlerCfg;
import org.opends.server.api.AccessControlHandler;
import org.opends.server.api.AccessControlProvider;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.types.InitializationException;
/**
 * This class is the provider class for the dseecompt ACI.
 */
public class AciProvider  implements AccessControlProvider  {
public class AciProvider implements
    AccessControlProvider<DseeCompatAccessControlHandlerCfg>
{
    /*
     * The AciHandler does all the work in this package.
@@ -52,15 +54,21 @@
    /**
     * Creates the AciHandler class and calls its initialization method.
     * @param configEntry The entry containing the configuration Access Control
     * entry.
     * @throws ConfigException If the initialization fails.
     * @throws InitializationException If the initialization fails.
     * Creates the AciHandler class and calls its initialization
     * method.
     *
     * @param configuration
     *          The entry containing the configuration Access Control
     *          entry.
     * @throws ConfigException
     *           If the initialization fails.
     * @throws InitializationException
     *           If the initialization fails.
     */
    public void initializeAccessControlHandler(ConfigEntry configEntry)
    public void initializeAccessControlHandler(
      DseeCompatAccessControlHandlerCfg configuration)
    throws ConfigException, InitializationException {
         instance=new AciHandler(configEntry);
         instance=new AciHandler(configuration);
    }
    /**
opends/src/server/org/opends/server/core/AccessControlConfigManager.java
@@ -26,7 +26,6 @@
 */
package org.opends.server.core;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.debugCaught;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import org.opends.server.types.DebugLogLevel;
@@ -36,18 +35,22 @@
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import org.opends.server.admin.ClassPropertyDefinition;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.server.ServerManagementContext;
import org.opends.server.admin.std.meta.AccessControlHandlerCfgDefn;
import org.opends.server.admin.std.server.AccessControlHandlerCfg;
import org.opends.server.admin.std.server.RootCfg;
import org.opends.server.api.AccessControlHandler;
import org.opends.server.api.AccessControlProvider;
import org.opends.server.api.AlertGenerator;
import org.opends.server.api.ConfigChangeListener;
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.types.ConfigChangeResult;
import org.opends.server.types.DN;
import org.opends.server.types.ErrorLogCategory;
@@ -76,7 +79,7 @@
  private AtomicReference<AccessControlProvider> accessControlProvider;
  // The current configuration.
  private Configuration currentConfiguration;
  private PrivateACLConfiguration currentConfiguration;
  /**
   * Get the single application-wide access control manager instance.
@@ -132,37 +135,26 @@
  void initializeAccessControl() throws ConfigException,
      InitializationException {
    // Get the access control handler configuration entry.
    ConfigEntry configEntry;
    try {
      DN configEntryDN = DN.decode(DN_AUTHZ_HANDLER_CONFIG);
      configEntry = DirectoryServer.getConfigEntry(configEntryDN);
    } catch (Exception e) {
      if (debugEnabled())
      {
        debugCaught(DebugLogLevel.ERROR, e);
      }
    // Get the root configuration object.
    ServerManagementContext managementContext =
         ServerManagementContext.getInstance();
    RootCfg rootConfiguration =
         managementContext.getRootConfiguration();
      int msgID = MSGID_CONFIG_AUTHZ_CANNOT_GET_ENTRY;
      String message = getMessage(msgID,
          stackTraceToSingleLineString(e));
      throw new ConfigException(msgID, message, e);
    }
    // Don't register as an add and delete listener with the root configuration
    // as we can have only one object at a given time.
    // The access control handler entry must exist.
    if (configEntry == null) {
      int msgID = MSGID_CONFIG_AUTHZ_ENTRY_DOES_NOT_EXIST;
      String message = getMessage(msgID);
      throw new ConfigException(msgID, message);
    }
    // //Initialize the current Access control.
    AccessControlHandlerCfg accessControlConfiguration =
           rootConfiguration.getAccessControlHandler();
    // Parse the configuration entry.
    Configuration configuration = Configuration
        .readConfiguration(configEntry);
    PrivateACLConfiguration configuration = PrivateACLConfiguration
        .readConfiguration(accessControlConfiguration);
    // We have a valid usable entry, so register a change listener in
    // order to handle configuration changes.
    configEntry.registerChangeListener(new ChangeListener());
    accessControlConfiguration.addChangeListener(new ChangeListener());
    // The configuration looks valid, so install it.
    updateConfiguration(configuration);
@@ -191,10 +183,10 @@
   *           If the access control handler provider could not be
   *           instantiated.
   */
  private void updateConfiguration(Configuration newConfiguration)
  private void updateConfiguration(PrivateACLConfiguration newConfiguration)
      throws ConfigException, InitializationException {
    DN configEntryDN = newConfiguration.getConfigEntry().getDN();
    DN configEntryDN = newConfiguration.getConfiguration().dn();
    Class<? extends AccessControlProvider> newHandlerClass = null;
    if (currentConfiguration == null) {
@@ -227,9 +219,10 @@
    // finalize the old
    // one and instantiate the new.
    if (newHandlerClass != null) {
      AccessControlProvider newHandler;
      AccessControlProvider<? extends AccessControlHandlerCfg> newHandler ;
      try {
        newHandler = newHandlerClass.newInstance();
          newHandler = loadProvider(newHandlerClass.getName(), newConfiguration
            .getConfiguration());
      } catch (Exception e) {
        if (debugEnabled())
        {
@@ -244,9 +237,6 @@
      }
      // Switch the handlers without interfering with other threads.
      newHandler.initializeAccessControlHandler(newConfiguration
          .getConfigEntry());
      AccessControlProvider oldHandler = accessControlProvider
          .getAndSet(newHandler);
@@ -289,19 +279,22 @@
  /**
   * Internal class implementing the change listener interface.
   */
  private class ChangeListener implements ConfigChangeListener {
  private class ChangeListener implements
      ConfigurationChangeListener<AccessControlHandlerCfg>
  {
    /**
     * {@inheritDoc}
     */
    public boolean configChangeIsAcceptable(ConfigEntry configEntry,
        StringBuilder unacceptableReason) {
    public boolean isConfigurationChangeAcceptable(
        AccessControlHandlerCfg configuration,
        List<String> unacceptableReasons)
    {
      try {
        // Parse the configuration entry.
        Configuration.readConfiguration(configEntry);
        PrivateACLConfiguration.readConfiguration(configuration);
      } catch (ConfigException e) {
        unacceptableReason.append(e.getMessage());
        unacceptableReasons.add(e.getMessage());
        return false;
      }
@@ -312,15 +305,16 @@
     * {@inheritDoc}
     */
    public ConfigChangeResult applyConfigurationChange(
        ConfigEntry configEntry) {
        AccessControlHandlerCfg configuration)
    {
      ResultCode resultCode = ResultCode.SUCCESS;
      ArrayList<String> messages = new ArrayList<String>();
      try {
        // Parse the configuration entry.
        Configuration newConfiguration = Configuration
            .readConfiguration(configEntry);
        PrivateACLConfiguration newConfiguration = PrivateACLConfiguration
            .readConfiguration(configuration);
        // The configuration looks valid, so install it.
        updateConfiguration(newConfiguration);
@@ -339,7 +333,7 @@
  /**
   * Internal class used to represent the parsed configuration entry.
   */
  private static class Configuration {
  private static class PrivateACLConfiguration {
    // Flag indicating whether or not access control is enabled.
    private boolean enabled;
@@ -349,35 +343,36 @@
    private Class<? extends AccessControlProvider> providerClass;
    // The entry that this object is mapped to.
    private ConfigEntry configEntry;
    private AccessControlHandlerCfg configuration;
    /**
     * Parses a configuration entry and, if it is valid, returns an
     * object representation of it.
     *
     * @param configEntry
     * @param configuration
     *          The access control configuration entry.
     * @return An object representation of the parsed configuration.
     * @throws ConfigException
     *           If a the access control configuration is invalid.
     */
    public static Configuration readConfiguration(
        ConfigEntry configEntry) throws ConfigException {
    public static PrivateACLConfiguration readConfiguration(
        AccessControlHandlerCfg configuration) throws ConfigException {
      // The access control configuration entry must have the correct
      // object class.
      if (configEntry.hasObjectClass(OC_AUTHZ_HANDLER_CONFIG) == false) {
      if (configuration.getAclHandlerClass() == null) {
        int msgID = MSGID_CONFIG_AUTHZ_ENTRY_DOES_NOT_HAVE_OBJECT_CLASS;
        String message = getMessage(msgID, configEntry.toString());
        String message = getMessage(msgID, configuration.toString());
        throw new ConfigException(msgID, message);
      }
      // Parse the attributes.
      boolean enabled = getEnabledAttribute(configEntry);
      Class<? extends AccessControlProvider> providerClass =
        getClassAttribute(configEntry);
      boolean enabled = configuration.isEnabled() ;
      return new Configuration(configEntry, enabled, providerClass);
      Class<? extends AccessControlProvider> providerClass =
        getClassAttribute(configuration);
      return new PrivateACLConfiguration(configuration, enabled, providerClass);
    }
    /**
@@ -407,105 +402,51 @@
     *
     * @return Returns the configuration entry.
     */
    public ConfigEntry getConfigEntry() {
      return configEntry;
    public AccessControlHandlerCfg getConfiguration() {
      return configuration;
    }
    /**
     * Construct a new configuration object with the specified parsed
     * attribute values.
     *
     * @param configEntry
     * @param configuration
     *          The associated access control configuration entry.
     * @param enabled
     *          The value of the enabled attribute.
     * @param providerClass
     *          The access control provider class.
     */
    private Configuration(ConfigEntry configEntry, boolean enabled,
    private PrivateACLConfiguration(
        AccessControlHandlerCfg configuration, boolean enabled,
        Class<? extends AccessControlProvider> providerClass) {
      this.configEntry = configEntry;
      this.configuration = configuration;
      this.enabled = enabled;
      this.providerClass = providerClass;
    }
    /**
     * Read the value of the attribute which indicates whether or not
     * access control is enabled.
     *
     * @param configEntry
     *          The access control configuration entry.
     * @return The boolean value of the enabled attribute.
     * @throws ConfigException
     *           If the enabled attribute could not be read or if it
     *           contains an invalid value.
     */
    private static boolean getEnabledAttribute(ConfigEntry configEntry)
        throws ConfigException {
      // See if the entry contains an attribute that indicates whether
      // or not access control should be enabled.
      try {
        BooleanConfigAttribute enabledAttrStub = new BooleanConfigAttribute(
            ATTR_AUTHZ_HANDLER_ENABLED,
            getMessage(MSGID_CONFIG_AUTHZ_DESCRIPTION_ENABLED), false);
        BooleanConfigAttribute enabledAttr = (BooleanConfigAttribute)
          configEntry.getConfigAttribute(enabledAttrStub);
        if (enabledAttr == null) {
          int msgID = MSGID_CONFIG_AUTHZ_NO_ENABLED_ATTR;
          String message = getMessage(msgID, configEntry.getDN()
              .toString());
          throw new ConfigException(msgID, message);
        } else {
          // We have a valid attribute - return it.
          return enabledAttr.activeValue();
        }
      } catch (ConfigException e) {
        int msgID = MSGID_CONFIG_AUTHZ_UNABLE_TO_DETERMINE_ENABLED_STATE;
        String message = getMessage(msgID, configEntry.getDN()
            .toString(), stackTraceToSingleLineString(e));
        throw new ConfigException(msgID, message, e);
      }
    }
    /**
     * Read the value of the attribute which indicates which access
     * control implementation class to use. This method checks the
     * validity of the class name.
     *
     * @param configEntry
     *          The access control configuration entry.
     * @param configuration
     *          The access control configuration.
     * @return The access control provider class.
     * @throws ConfigException
     *           If the class attribute could not be read or if it
     *           contains an invalid class name.
     */
    private static Class<? extends AccessControlProvider> getClassAttribute(
        ConfigEntry configEntry) throws ConfigException {
        AccessControlHandlerCfg configuration) throws ConfigException {
      // If access control is enabled then make sure that the class
      // attribute is present.
      try {
        StringConfigAttribute classAttrStub = new StringConfigAttribute(
            ATTR_AUTHZ_HANDLER_CLASS,
            getMessage(MSGID_CONFIG_AUTHZ_DESCRIPTION_CLASS), true,
            false, false);
        StringConfigAttribute classAttr = (StringConfigAttribute) configEntry
            .getConfigAttribute(classAttrStub);
        if (classAttr == null) {
          int msgID = MSGID_CONFIG_AUTHZ_NO_CLASS_ATTR;
          String message = getMessage(msgID, configEntry.getDN()
              .toString());
          throw new ConfigException(msgID, message);
        }
        // Load the access control implementation class.
        String className = classAttr.activeValue();
        String className = configuration.getAclHandlerClass();
        try {
          return DirectoryServer.loadClass(className).asSubclass(
              AccessControlProvider.class);
@@ -517,7 +458,7 @@
          int msgID = MSGID_CONFIG_AUTHZ_UNABLE_TO_LOAD_CLASS;
          String message = getMessage(msgID, className, String
              .valueOf(configEntry.getDN().toString()),
              .valueOf(configuration.dn().toString()),
              stackTraceToSingleLineString(e));
          throw new ConfigException(msgID, message, e);
        } catch (ClassCastException e) {
@@ -528,14 +469,14 @@
          int msgID = MSGID_CONFIG_AUTHZ_BAD_CLASS;
          String message = getMessage(msgID, className, String
              .valueOf(configEntry.getDN().toString()),
              .valueOf(configuration.dn().toString()),
              AccessControlProvider.class.getName(),
              stackTraceToSingleLineString(e));
          throw new ConfigException(msgID, message, e);
        }
      } catch (ConfigException e) {
        int msgID = MSGID_CONFIG_AUTHZ_UNABLE_TO_DETERMINE_CLASS;
        String message = getMessage(msgID, configEntry.getDN()
        String message = getMessage(msgID, configuration.dn()
            .toString(), stackTraceToSingleLineString(e));
        throw new ConfigException(msgID, message, e);
      }
@@ -553,7 +494,7 @@
   */
  public DN getComponentEntryDN()
  {
    return currentConfiguration.getConfigEntry().getDN();
    return currentConfiguration.getConfiguration().dn();
  }
@@ -594,5 +535,57 @@
    return alerts;
  }
  /**
   * Loads the specified class, instantiates it as a AccessControlProvider, and
   * optionally initializes that instance.
   *
   * @param  className      The fully-qualified name of the Access Control
   *                        provider class to load, instantiate, and initialize.
   * @param  configuration  The configuration to use to initialize the
   *                        Access Control Provider, or {@code null} if the
   *                        Access Control Provider should not be initialized.
   *
   * @return  The possibly initialized Access Control Provider.
   *
   * @throws  InitializationException  If a problem occurred while attempting to
   *                                   initialize the Access Control Provider.
   */
  private AccessControlProvider<? extends AccessControlHandlerCfg>
               loadProvider(String className,
                             AccessControlHandlerCfg configuration)
          throws InitializationException
  {
    try
    {
      AccessControlHandlerCfgDefn definition =
        AccessControlHandlerCfgDefn.getInstance();
      ClassPropertyDefinition propertyDefinition =
           definition.getAclHandlerClassPropertyDefinition();
      Class<? extends AccessControlProvider> providerClass =
           propertyDefinition.loadClass(className, AccessControlProvider.class);
      AccessControlProvider<? extends AccessControlHandlerCfg> provider =
           (AccessControlProvider<? extends AccessControlHandlerCfg>)
           providerClass.newInstance();
      if (configuration != null)
      {
        Method method =
          provider.getClass().getMethod("initializeAccessControlHandler",
                  configuration.definition().getServerConfigurationClass());
        method.invoke(provider, configuration);
      }
      return provider;
    }
    catch (Exception e)
    {
      int msgID = MSGID_CONFIG_AUTHZ_UNABLE_TO_INSTANTIATE_HANDLER;
      String message = getMessage(msgID, className,
                                  String.valueOf(configuration.dn()),
                                  stackTraceToSingleLineString(e));
      throw new InitializationException(msgID, message, e);
    }
  }
}
opends/src/server/org/opends/server/core/DefaultAccessControlProvider.java
@@ -26,9 +26,9 @@
 */
package org.opends.server.core;
import org.opends.server.admin.std.server.AccessControlHandlerCfg;
import org.opends.server.api.AccessControlHandler;
import org.opends.server.api.AccessControlProvider;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.types.InitializationException;
import org.opends.server.types.SearchResultEntry;
@@ -63,7 +63,8 @@
  /**
   * {@inheritDoc}
   */
  public void initializeAccessControlHandler(ConfigEntry configEntry)
  public void initializeAccessControlHandler(
      AccessControlHandlerCfg configuration)
      throws ConfigException, InitializationException {
    // Avoid potential race conditions constructing the handler instance