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

dugan
06.49.2007 4e2366ebec6d1c05a9c22e7d01e010ee4dea45fc
Put server into lockdown mode if ACI parsing fails during server startup or backend initialization. Issue #1750.
5 files modified
366 ■■■■ changed files
opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java 70 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/authorization/dseecompat/AciList.java 73 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java 161 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/AciMessages.java 38 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/util/ServerConstants.java 24 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
@@ -29,21 +29,22 @@
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.*;
import static org.opends.server.config.ConfigConstants.ATTR_AUTHZ_GLOBAL_ACI;
import org.opends.server.core.*;
import static org.opends.server.loggers.ErrorLogger.logError;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import static org.opends.server.loggers.debug.DebugLogger.getTracer;
import org.opends.server.loggers.debug.DebugTracer;
import static org.opends.server.messages.AciMessages.*;
import static org.opends.server.messages.MessageHandler.getMessage;
import org.opends.server.types.*;
import static org.opends.server.util.StaticUtils.toLowerCase;
import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
import static org.opends.server.config.ConfigConstants.*;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.internal.InternalClientConnection;
import static org.opends.server.schema.SchemaConstants.*;
import org.opends.server.protocols.internal.InternalSearchOperation;
import static org.opends.server.schema.SchemaConstants.SYNTAX_DN_OID;
import org.opends.server.types.*;
import static org.opends.server.util.ServerConstants.OID_GET_EFFECTIVE_RIGHTS;
import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString;
import static org.opends.server.util.StaticUtils.toLowerCase;
import java.util.*;
import java.util.concurrent.locks.Lock;
@@ -52,19 +53,26 @@
 * The AciHandler class performs the main processing for the
 * dseecompat package.
 */
public class AciHandler extends AccessControlHandler
{
public class AciHandler extends AccessControlHandler {
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
    /*
     * The list that holds that ACIs keyed by the DN of the entry
      * holding the ACI.
     * holding the ACI.
     */
    private AciList aciList;
    /*
     * The listener that handles ACI changes caused by LDAP operations, ACI
     * decode failure alert logging and backend initialization ACI list
     * adjustment.
     */
    private AciListenerManager aciListenerMgr;
    /**
     * Attribute type corresponding to "aci" attribute.
     */
@@ -95,21 +103,15 @@
     */
     public static String ALL_ATTRS_MATCHED = "allAttrsMatched";
    /**
     * This constructor instantiates the ACI handler class that performs the
     * main processing for the dseecompat ACI package. It does the following
     * initializations:
     *
     *
     *  - Instantiates the ACI list cache.
     *
     *  - Instantiates and registers the change notification listener that is
     *    used to manage the ACI list cache after ACI modifications have been
     *    performed.
     *
     *  - Instantiates and registers the backend initialization listener that is
     *    used to manage the ACI list cache when backends are
     *    initialized/finalized.
     *  - Instantiates thr AciListenerManager.
     *
     *  - Processes all global attribute types found in the configuration entry
     *    and adds them to the ACI list cache.
@@ -124,11 +126,9 @@
    */
    public AciHandler(DseeCompatAccessControlHandlerCfg configuration)
    throws InitializationException  {
        aciList = new AciList(configuration.dn());
        AciListenerManager aciListenerMgr =
            new AciListenerManager(aciList);
        DirectoryServer.registerChangeNotificationListener(aciListenerMgr);
        DirectoryServer.registerBackendInitializationListener(aciListenerMgr);
        DN configurationDN=configuration.dn();
        aciList = new AciList(configurationDN);
        aciListenerMgr = new AciListenerManager(aciList, configurationDN);
        if((aciType = DirectoryServer.getAttributeType("aci")) == null)
            aciType = DirectoryServer.getDefaultAttributeType("aci");
        if((globalAciType =
@@ -143,7 +143,9 @@
     * Process all global ACI attribute types found in the configuration
     * entry and adds them to that ACI list cache. It also logs messages about
     * the number of ACI attribute types added to the cache. This method is
     * called once at startup.
     * called once at startup.  It also will put the server into  lockdown
     * mode if needed.
     *
     * @param configuration   The config handler containing the ACI
     *  configuration information.
     * @throws InitializationException If there is an error reading
@@ -153,6 +155,7 @@
        DseeCompatAccessControlHandlerCfg configuration)
    throws InitializationException {
        int msgID;
        LinkedList<String>failedACIMsgs=new LinkedList<String>();
        SortedSet<String> globalAci = configuration.getGlobalACI();
        try {
            if (globalAci != null)   {
@@ -167,7 +170,9 @@
                        attVals);
                Entry e = new Entry(configuration.dn(), null, null, null);
                e.addAttribute(attr, new ArrayList<AttributeValue>());
                int aciCount =  aciList.addAci(e, false, true);
                int aciCount =  aciList.addAci(e, false, true, failedACIMsgs);
                if(!failedACIMsgs.isEmpty())
                    aciListenerMgr.logMsgsSetLockDownMode(failedACIMsgs);
                msgID  = MSGID_ACI_ADD_LIST_GLOBAL_ACIS;
                String message = getMessage(msgID, Integer.toString(aciCount));
                logError(ErrorLogCategory.ACCESS_CONTROL,
@@ -194,7 +199,9 @@
    /**
     * Process all ACIs under the "cn=config" naming context and adds them to
     * the ACI list cache. It also logs messages about the number of ACIs added
     * to the cache. This method is called once at startup.
     * to the cache. This method is called once at startup.  It will put the
     * server in lockdown mode if needed.
     *
     * @throws InitializationException If there is an error searching for
     * the ACIs in the naming context.
     */
@@ -204,6 +211,7 @@
            DN configDN=DN.decode("cn=config");
            LinkedHashSet<String> attrs = new LinkedHashSet<String>(1);
            attrs.add("aci");
            LinkedList<String>failedACIMsgs=new LinkedList<String>();
            InternalClientConnection conn =
                    InternalClientConnection.getRootConnection();
            InternalSearchOperation op = conn.processSearch(configDN,
@@ -216,7 +224,10 @@
                logError(ErrorLogCategory.ACCESS_CONTROL,
                        ErrorLogSeverity.INFORMATIONAL, message, msgID);
            } else {
                int validAcis = aciList.addAci(op.getSearchEntries());
                int validAcis =
                           aciList.addAci(op.getSearchEntries(), failedACIMsgs);
                if(!failedACIMsgs.isEmpty())
                    aciListenerMgr.logMsgsSetLockDownMode(failedACIMsgs);
                int    msgID  = MSGID_ACI_ADD_LIST_ACIS;
                String message = getMessage(msgID, Integer.toString(validAcis),
                        String.valueOf(configDN));
@@ -231,6 +242,7 @@
        }
    }
    /**
     * Checks to see if a LDAP modification is allowed access.
     *
@@ -372,7 +384,7 @@
     * @return  True if access is allowed.
     */
    private boolean testApplicableLists(AciEvalContext evalCtx) {
        EnumEvalResult res=EnumEvalResult.FALSE;
        EnumEvalResult res;
        evalCtx.setEvalReason(EnumEvalReason.NO_REASON);
        LinkedList<Aci>denys=evalCtx.getDenyList();
        LinkedList<Aci>allows=evalCtx.getAllowList();
opends/src/server/org/opends/server/authorization/dseecompat/AciList.java
@@ -27,16 +27,16 @@
package org.opends.server.authorization.dseecompat;
import static org.opends.server.messages.AciMessages.*;
import org.opends.server.api.Backend;
import static org.opends.server.authorization.dseecompat.AciHandler.aciType;
import static org.opends.server.authorization.dseecompat.AciHandler.globalAciType;
import static org.opends.server.loggers.ErrorLogger.logError;
import static org.opends.server.messages.AciMessages.MSGID_ACI_ADD_LIST_FAILED_DECODE;
import static org.opends.server.messages.MessageHandler.getMessage;
import org.opends.server.types.*;
import java.util.*;
import static org.opends.server.authorization.dseecompat.AciHandler.*;
import org.opends.server.types.*;
import org.opends.server.api.Backend;
/**
 * The AciList class performs caching of the ACI attribute values
 * using the entry DN as the key.
@@ -135,9 +135,12 @@
   * to check for global ACIs since they are processe by the AciHandler at
   * startup using the addACi single entry method.
   * @param entries The set of entries containing the "aci" attribute values.
   * @param failedACIMsgs List that will hold error messages from ACI decode
   *                      exceptions.
   * @return The number of valid ACI attribute values added to the ACI list.
   */
  public synchronized int addAci(List<? extends Entry> entries)
  public synchronized int addAci(List<? extends Entry> entries,
                                 LinkedList<String> failedACIMsgs)
  {
    // Copy the ACI list.
    LinkedHashMap<DN,List<Aci>> aciCopy = copyList();
@@ -147,7 +150,8 @@
      DN dn=entry.getDN();
      List<Attribute> attributeList =
           entry.getOperationalAttribute(AciHandler.aciType);
      validAcis += addAciAttributeList(aciCopy, dn, attributeList);
      validAcis += addAciAttributeList(aciCopy, dn, configDN,
                                       attributeList, failedACIMsgs);
    }
    // Replace the ACI list with the copy.
@@ -162,10 +166,13 @@
   * @param hasAci True if the "aci" attribute type was seen in the entry.
   * @param hasGlobalAci True if the "ds-cfg-global-aci" attribute type was
   * seen in the entry.
   * @param failedACIMsgs List that will hold error messages from ACI decode
   *                      exceptions.
   * @return The number of valid ACI attribute values added to the ACI list.
   */
  public synchronized int addAci(Entry entry,  boolean hasAci,
                                               boolean hasGlobalAci) {
                                 boolean hasGlobalAci,
                                 LinkedList<String> failedACIMsgs) {
    int validAcis=0;
    // Copy the ACI list.
@@ -175,12 +182,14 @@
    //attributes are skipped.
    if(hasGlobalAci && entry.getDN().equals(configDN)) {
        List<Attribute> attributeList = entry.getAttribute(globalAciType);
        validAcis = addAciAttributeList(aciCopy, DN.nullDN(), attributeList);
        validAcis = addAciAttributeList(aciCopy, DN.nullDN(), configDN,
                                        attributeList, failedACIMsgs);
    }
    if(hasAci) {
        List<Attribute> attributeList = entry.getAttribute(aciType);
        validAcis += addAciAttributeList(aciCopy, entry.getDN(), attributeList);
        validAcis += addAciAttributeList(aciCopy, entry.getDN(), configDN,
                                         attributeList, failedACIMsgs);
    }
    // Replace the ACI list with the copy.
    aciList = aciCopy;
@@ -194,13 +203,18 @@
   * returned of the number of valid ACIs added.
   * @param aciList The ACI list to which the ACI is to be added.
   * @param dn The DN to use as the key in the ACI list.
   * @param configDN The DN of the configuration entry used to configure the
   *                 ACI handler. Used if a global ACI has an decode exception.
   * @param attributeList List of attributes containing the ACI attribute
   * values.
   * @param failedACIMsgs List that will hold error messages from ACI decode
   *                      exceptions.
   * @return The number of valid attribute values added to the ACI list.
   */
  private static int addAciAttributeList(
       LinkedHashMap<DN,List<Aci>> aciList, DN dn,
       List<Attribute> attributeList) {
  private static int addAciAttributeList(LinkedHashMap<DN,List<Aci>> aciList,
                                         DN dn, DN configDN,
                                         List<Attribute> attributeList,
                                         LinkedList<String> failedACIMsgs) {
    if (attributeList == null) {
      return 0;
@@ -215,19 +229,16 @@
          acis.add(aci);
          validAcis++;
        } catch (AciException ex) {
          /* An illegal ACI might have been loaded
           * during import and is failing at ACI handler
           * initialization time. Log a message and continue
           * processing. ACIs added via LDAP add have their
           * syntax checked before adding and should never
           * hit this code.
           */
          int    msgID  = MSGID_ACI_ADD_LIST_FAILED_DECODE;
          String message = getMessage(msgID,
                                      ex.getMessage());
          logError(ErrorLogCategory.ACCESS_CONTROL,
                   ErrorLogSeverity.INFORMATIONAL,
                   message, msgID);
          DN msgDN=dn;
          if(dn == DN.nullDN()) {
            msgDN=configDN;
          }
            String t=value.getValue().toString();
          String message = getMessage(msgID, value.getValue().toString(),
                                            String.valueOf(msgDN),
                                            ex.getMessage());
          failedACIMsgs.add(message);
        }
      }
    }
@@ -255,12 +266,14 @@
      // Copy the ACI list.
      LinkedHashMap<DN,List<Aci>> aciCopy = copyList();
      LinkedList<String>failedACIMsgs=new LinkedList<String>();
      //Process "aci" attribute types.
      if(hasAci) {
          aciCopy.remove(oldEntry.getDN());
          List<Attribute> attributeList =
                  newEntry.getOperationalAttribute(aciType);
          addAciAttributeList(aciCopy,newEntry.getDN(),attributeList);
          addAciAttributeList(aciCopy,newEntry.getDN(), configDN,
                              attributeList, failedACIMsgs);
      }
      //Process global "ds-cfg-global-aci" attribute type. The oldentry
      //DN is checked to verify it is equal to the config DN. If not those
@@ -269,7 +282,8 @@
          aciCopy.remove(DN.nullDN());
          List<Attribute> attributeList =
                  newEntry.getAttribute(globalAciType);
          addAciAttributeList(aciCopy, DN.nullDN(), attributeList);
          addAciAttributeList(aciCopy, DN.nullDN(), configDN,
                              attributeList, failedACIMsgs);
      }
      // Replace the ACI list with the copy.
      aciList = aciCopy;
@@ -376,8 +390,9 @@
            //ACI with a new DN is being made. Log a message if it does and
            //keep going.
            int    msgID  = MSGID_ACI_ADD_LIST_FAILED_DECODE;
            String message = getMessage(msgID,
                    ex.getMessage());
            String message = getMessage(msgID, aci.toString(),
                                        String.valueOf(relocateDN),
                                        ex.getMessage());
            logError(ErrorLogCategory.ACCESS_CONTROL,
                    ErrorLogSeverity.INFORMATIONAL,
                    message, msgID);
opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java
@@ -30,6 +30,7 @@
import org.opends.server.api.ChangeNotificationListener;
import org.opends.server.api.BackendInitializationListener;
import org.opends.server.api.Backend;
import org.opends.server.api.AlertGenerator;
import org.opends.server.types.operation.PostResponseAddOperation;
import org.opends.server.types.operation.PostResponseDeleteOperation;
import org.opends.server.types.operation.PostResponseModifyOperation;
@@ -42,8 +43,12 @@
import org.opends.server.types.*;
import static org.opends.server.messages.AciMessages.*;
import static org.opends.server.messages.MessageHandler.getMessage;
import org.opends.server.core.DirectoryServer;
import static org.opends.server.util.ServerConstants.*;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.LinkedList;
import java.util.LinkedHashMap;
/**
 * The AciListenerManager updates an ACI list after each
@@ -51,13 +56,31 @@
 * and finalized.
 */
public class AciListenerManager
        implements ChangeNotificationListener, BackendInitializationListener {
        implements ChangeNotificationListener, BackendInitializationListener,
                   AlertGenerator {
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
    /**
     * The fully-qualified name of this class.
     */
    private static final String CLASS_NAME =
         "org.opends.server.authorization.dseecompat.AciListenerManager";
    /*
     *  The configuration DN.
     */
    private DN configurationDN;
    /*
     *  True if the server is in lockdown mode.
     */
    private boolean inLockDownMode=false;
    /*
     * The AciList caches the ACIs.
     */
@@ -87,11 +110,23 @@
    }
    /**
     * Save the list created by the AciHandler routine.
     * Save the list created by the AciHandler routine. Registers as an
     * Alert Generator that can send alerts when the server is being put
     * in lockdown  mode. Registers as backend initialization listener that is
     * used to manage the ACI list cache when backends are
     * initialized/finalized. Registers as a change notification listener that
     * is used to manage the ACI list cache after ACI modifications have been
     * performed.
     *
     * @param aciList The list object created and loaded by the handler.
     * @param cfgDN The DN of the access control configuration entry.
     */
    public AciListenerManager(AciList aciList) {
    public AciListenerManager(AciList aciList, DN cfgDN) {
        this.aciList=aciList;
        this.configurationDN=cfgDN;
        DirectoryServer.registerChangeNotificationListener(this);
        DirectoryServer.registerBackendInitializationListener(this);
        DirectoryServer.registerAlertGenerator(this);
    }
    /**
@@ -118,10 +153,13 @@
    public void handleAddOperation(PostResponseAddOperation addOperation,
                                   Entry entry) {
        boolean hasAci, hasGlobalAci=false;
        //Ignore this list, the ACI syntax has already passed and it should be
        //empty.
        LinkedList<String>failedACIMsgs=new LinkedList<String>();
        //This entry might have both global and aci attribute types.
        if((hasAci=entry.hasOperationalAttribute(AciHandler.aciType)) ||
                (hasGlobalAci=entry.hasAttribute(AciHandler.globalAciType)))
            aciList.addAci(entry, hasAci, hasGlobalAci);
            aciList.addAci(entry, hasAci, hasGlobalAci, failedACIMsgs);
    }
    /**
@@ -176,18 +214,18 @@
    public void performBackendInitializationProcessing(Backend backend) {
      InternalClientConnection conn =
           InternalClientConnection.getRootConnection();
      LinkedList<String>failedACIMsgs=new LinkedList<String>();
      for (DN baseDN : backend.getBaseDNs()) {
        try {
          if (! backend.entryExists(baseDN))  {
            continue;
          }
        } catch (Exception e) {
          if (debugEnabled())
          {
            TRACER.debugCaught(DebugLogLevel.ERROR, e);
          }
          //TODO log message
          continue;
            if (debugEnabled())
            {
                TRACER.debugCaught(DebugLogLevel.ERROR, e);
            }
            continue;
        }
        InternalSearchOperation internalSearch =
             new InternalSearchOperation(
@@ -200,12 +238,11 @@
        try  {
          backend.search(internalSearch);
        } catch (Exception e) {
          if (debugEnabled())
          {
            TRACER.debugCaught(DebugLogLevel.ERROR, e);
          }
          //TODO log message
          continue;
            if (debugEnabled())
            {
                TRACER.debugCaught(DebugLogLevel.ERROR, e);
            }
            continue;
        }
        if(internalSearch.getSearchEntries().isEmpty()) {
          int    msgID  = MSGID_ACI_ADD_LIST_NO_ACIS;
@@ -214,7 +251,9 @@
                   ErrorLogSeverity.INFORMATIONAL, message, msgID);
        } else {
          int validAcis = aciList.addAci(
               internalSearch.getSearchEntries());
               internalSearch.getSearchEntries(), failedACIMsgs);
          if(!failedACIMsgs.isEmpty())
                    logMsgsSetLockDownMode(failedACIMsgs);
          int    msgID  = MSGID_ACI_ADD_LIST_ACIS;
          String message = getMessage(msgID, Integer.toString(validAcis),
                                      String.valueOf(baseDN));
@@ -232,4 +271,92 @@
    public void performBackendFinalizationProcessing(Backend backend) {
        aciList.removeAci(backend);
    }
    /**
     * Retrieves the fully-qualified name of the Java class for this alert
     * generator implementation.
     *
     * @return  The fully-qualified name of the Java class for this alert
     *          generator implementation.
     */
    public String getClassName()
    {
        return CLASS_NAME;
    }
    /**
     * Retrieves the DN of the configuration entry used to configure the
     * handler.
     *
     * @return  The DN of the configuration entry containing the Access Control
     *          configuration information.
     */
    public DN getComponentEntryDN()
    {
      return this.configurationDN;
    }
    /**
     * Retrieves information about the set of alerts that this generator may
     * produce.  The map returned should be between the notification type for a
     * particular notification and the human-readable description for that
     * notification.  This alert generator must not generate any alerts with
     * types that are not contained in this list.
     *
     * @return  Information about the set of alerts that this generator may
     *          produce.
     */
    public LinkedHashMap<String,String> getAlerts()
    {
        LinkedHashMap<String,String> alerts =
                new LinkedHashMap<String,String>();
        alerts.put(ALERT_TYPE_ACCESS_CONTROL_PARSE_FAILED,
                ALERT_DESCRIPTION_ACCESS_CONTROL_PARSE_FAILED);
        return alerts;
    }
    /**
     * Log the exception messages from the failed ACI decode and then put the
     * server in lockdown mode -- if needed.
     *
     * @param failedACIMsgs  List of exception messages from failed ACI decodes.
     */
    public  void logMsgsSetLockDownMode(LinkedList<String> failedACIMsgs) {
        int msgID=MSGID_ACI_SERVER_DECODE_FAILED;
        for(String msg : failedACIMsgs) {
            String message=getMessage(msgID, msg);
            logError(ErrorLogCategory.ACCESS_CONTROL,
                    ErrorLogSeverity.SEVERE_ERROR,
                    message, msgID);
        }
        if(!inLockDownMode)
            setLockDownMode();
    }
    /**
     * Send an MSGID_ACI_ENTER_LOCKDOWN_MODE alert notification and put the
     * server in lockdown mode.
     *
     */
    private void setLockDownMode() {
        if(!inLockDownMode) {
            inLockDownMode=true;
            //Send ALERT_TYPE_ACCESS_CONTROL_PARSE_FAILED alert that
            //lockdown is about to be entered.
            int lockDownID=MSGID_ACI_ENTER_LOCKDOWN_MODE;
            String lockDownMsg=getMessage(lockDownID);
            DirectoryServer.sendAlertNotification(this,
                    ALERT_TYPE_ACCESS_CONTROL_PARSE_FAILED,
                    lockDownID, lockDownMsg );
            //Enter lockdown mode.
            DirectoryServer.setLockdownMode(true);
        }
    }
}
opends/src/server/org/opends/server/messages/AciMessages.java
@@ -496,8 +496,9 @@
     * The message ID for the ACI message that will be generated when
     * an ACI decode failed because of an syntax error. This message is usually
     * generated by an invalid ACI that was added during import which
     * fails the decode at server startup. This takes one
     * argument, which is the message string thrown by the AciException.
     * fails the decode at server startup. This takes three
     * argument, which are the ACI string, the DN of the entry containing the
     * ACI, and the message string thrown by the AciException.
     */
    public static final int MSGID_ACI_ADD_LIST_FAILED_DECODE =
        CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 48;
@@ -764,6 +765,25 @@
  public static final int MSGID_ACI_SYNTAX_ROLEDN_NOT_SUPPORTED =
       CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 76;
   /**
   * The message ID for the message that will be used if there are ACI decode
   * failures at server initialization time or during a backend initialization.
   * This takes one argument, which is the error message from the ACI decode
   * exception.
   */
  public static final int MSGID_ACI_SERVER_DECODE_FAILED =
       CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 77;
   /**
   * The message ID for the message that will be used if there are ACI decode
   * failures at server initialization time or during a backend initialization
   * causing the server is being put in lockdown mode. The takes no arguments.
   */
  public static final int MSGID_ACI_ENTER_LOCKDOWN_MODE =
       CATEGORY_MASK_ACCESS_CONTROL | SEVERITY_MASK_SEVERE_WARNING | 78;
    /**
     * Associates a set of generic messages with the message IDs defined in
     * this class.
@@ -1066,8 +1086,8 @@
               "because of the following reason: %s");
        registerMessage(MSGID_ACI_ADD_LIST_FAILED_DECODE,
                "An attempt to decode an Access Control Instruction (ACI)" +
                " failed because of the following reason: %s");
                " \"%s\", located in the entry \"%s\", " +
                "because of the following reason: %s");
        registerMessage(MSGID_ACI_ADD_LIST_NO_ACIS,
                "No Access Control Instruction (ACI) attribute types were" +
@@ -1203,5 +1223,15 @@
              "value \"%s\" is invalid because it contains" +
              " the roledn keyword, which is not supported,  replace it with " +
              "the groupdn keyword");
        registerMessage(MSGID_ACI_SERVER_DECODE_FAILED,
                "Failed to decode the Access Control " +
                "Instruction (ACI)%s");
        registerMessage(MSGID_ACI_ENTER_LOCKDOWN_MODE,
                "The server is being put into lockdown mode because " +
                "invalid ACIs rules were detected either when the server " +
                "was started or during a backend initialization");
    }
}
opends/src/server/org/opends/server/util/ServerConstants.java
@@ -1557,6 +1557,30 @@
  /**
   * The description for the alert type that will be used for the alert
   * notification generated if the dseecompat access control subsystem failed
   * to parse one or more ACI rules when the server is first started or a
   * backend is being initialized.
   */
  public static final String ALERT_DESCRIPTION_ACCESS_CONTROL_PARSE_FAILED =
          "This alert type will be used to notify administrators if the  " +
             "dseecompat access control subsystem failed to correctly parse " +
             "one or more ACI rules when the server is first started.";
  /**
   * The alert type string that will be used for the alert notification
   * generated if the dseecompat access control subsystem failed to parse
   * one or more ACI rules when the server is first started or a backend
   * is being initialized.
   */
  public static final String ALERT_TYPE_ACCESS_CONTROL_PARSE_FAILED =
          "org.opends.server.authentiation.dseecompat.ACIParseFailed";
  /**
   * The name of the default password storage scheme that will be used for new
   * passwords.
   */