/**
   * 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. 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.
   */
  private void processConfigAcis() throws InitializationException {
    LinkedHashSet<String> requestAttrs = new LinkedHashSet<String>(1);
    requestAttrs.add("aci");
    LinkedList<Message> failedACIMsgs = new LinkedList<Message>();
    InternalClientConnection conn = InternalClientConnection.getRootConnection();

    ConfigHandler configBackend = DirectoryServer.getConfigHandler();
    for (DN baseDN : configBackend.getBaseDNs()) {
      try {
        if (!configBackend.entryExists(baseDN)) {
          continue;
        }
      } catch (Exception e) {
        if (debugEnabled()) {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }

        // FIXME -- Is there anything that we need to do here?
        continue;
      }

      try {
        InternalSearchOperation internalSearch =
            new InternalSearchOperation(
                conn,
                InternalClientConnection.nextOperationID(),
                InternalClientConnection.nextMessageID(),
                null,
                baseDN,
                SearchScope.WHOLE_SUBTREE,
                DereferencePolicy.NEVER_DEREF_ALIASES,
                0,
                0,
                false,
                SearchFilter.createFilterFromString("aci=*"),
                requestAttrs,
                null);
        LocalBackendSearchOperation localSearch = new LocalBackendSearchOperation(internalSearch);

        configBackend.search(localSearch);

        if (!internalSearch.getSearchEntries().isEmpty()) {
          int validAcis = aciList.addAci(internalSearch.getSearchEntries(), failedACIMsgs);
          if (!failedACIMsgs.isEmpty()) {
            aciListenerMgr.logMsgsSetLockDownMode(failedACIMsgs);
          }
          Message message =
              INFO_ACI_ADD_LIST_ACIS.get(Integer.toString(validAcis), String.valueOf(baseDN));
          logError(message);
        }
      } catch (Exception e) {
        Message message = INFO_ACI_HANDLER_FAIL_PROCESS_ACI.get();
        throw new InitializationException(message, e);
      }
    }
  }
 /**
  * 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. 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 the global ACIs from the
  *     configuration entry.
  */
 private void processGlobalAcis(DseeCompatAccessControlHandlerCfg configuration)
     throws InitializationException {
   SortedSet<Aci> globalAcis = configuration.getGlobalACI();
   try {
     if (globalAcis != null) {
       aciList.addAci(DN.nullDN(), globalAcis);
       Message message = INFO_ACI_ADD_LIST_GLOBAL_ACIS.get(Integer.toString(globalAcis.size()));
       logError(message);
     }
   } catch (Exception e) {
     if (debugEnabled()) {
       TRACER.debugCaught(DebugLogLevel.ERROR, e);
     }
     Message message =
         INFO_ACI_HANDLER_FAIL_PROCESS_GLOBAL_ACI.get(String.valueOf(configuration.dn()));
     throw new InitializationException(message, e);
   }
 }
  /**
   * Check access using the specified container. This container will have all of the information to
   * gather applicable ACIs and perform evaluation on them.
   *
   * @param container An ACI operation container which has all of the information needed to check
   *     access.
   * @return True if access is allowed.
   */
  boolean accessAllowed(AciContainer container) {
    DN dn = container.getResourceEntry().getDN();
    // For ACI_WRITE_ADD and ACI_WRITE_DELETE set the ACI_WRITE
    // right.
    if (container.hasRights(ACI_WRITE_ADD) || container.hasRights(ACI_WRITE_DELETE)) {
      container.setRights(container.getRights() | ACI_WRITE);
    }
    // Check if the ACI_SELF right needs to be set (selfwrite right).
    // Only done if the right is ACI_WRITE, an attribute value is set
    // and that attribute value is a DN.
    if ((container.getCurrentAttributeValue() != null)
        && (container.hasRights(ACI_WRITE))
        && (isAttributeDN(container.getCurrentAttributeType()))) {
      String DNString = null;
      try {
        DNString = container.getCurrentAttributeValue().getValue().toString();
        DN tmpDN = DN.decode(DNString);
        // Have a valid DN, compare to clientDN to see if the ACI_SELF
        // right should be set.
        if (tmpDN.equals(container.getClientDN())) {
          container.setRights(container.getRights() | ACI_SELF);
        }
      } catch (DirectoryException ex) {
        // Log a message and keep going.
        Message message = WARN_ACI_NOT_VALID_DN.get(DNString);
        logError(message);
      }
    }

    // Check proxy authorization only if the entry has not already been
    // processed (working on a new entry). If working on a new entry,
    // then only do a proxy check if the right is not set to ACI_PROXY
    // and the proxied authorization control has been decoded.
    if (!container.hasSeenEntry()) {
      if (container.isProxiedAuthorization()
          && !container.hasRights(ACI_PROXY)
          && !container.hasRights(ACI_SKIP_PROXY_CHECK)) {
        int currentRights = container.getRights();
        // Save the current rights so they can be put back if on
        // success.
        container.setRights(ACI_PROXY);
        // Switch to the original authorization entry, not the proxied
        // one.
        container.useOrigAuthorizationEntry(true);
        if (!accessAllowed(container)) {
          return false;
        }
        // Access is ok, put the original rights back.
        container.setRights(currentRights);
        // Put the proxied authorization entry back to the current
        // authorization entry.
        container.useOrigAuthorizationEntry(false);
      }
      // Set the seen flag so proxy processing is not performed for this
      // entry again.
      container.setSeenEntry(true);
    }

    /*
     * First get all allowed candidate ACIs.
     */
    LinkedList<Aci> candidates = aciList.getCandidateAcis(dn);
    /*
     * Create an applicable list of ACIs by target matching each
     * candidate ACI against the container's target match view.
     */
    createApplicableList(candidates, container);
    /*
     * Evaluate the applicable list.
     */
    boolean ret = testApplicableLists(container);
    // Build summary string if doing geteffectiverights eval.
    if (container.isGetEffectiveRightsEval()) {
      AciEffectiveRights.createSummary(container, ret, "main");
    }
    return ret;
  }