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

boli
24.50.2006 bf7b61bf7e22fc0c1c0bf69255f44d0139c86937
Add a configuration option to limit the number of entries that will be checked for matches during a search operation. A value of -1 or 0 will remove the limit, like the behavior of DS 5 and 6. Changed the "unlimited" values of size and time limits to be consistent with the lookthrough limit (-1 or 0). 

- It adds a new server wide config attribute (ds-cfg-lookthrough-limit)
with default of 5000

- It adds a new operational attribute (ds-rlim-lookthrough-limit) so
that a user's entry can be checked for a custom lookthrough limit on
bind for per user configurations.

- cn=Directory Manager by default will not have a lookthrough limit

Fix for issue 52
12 files modified
394 ■■■■■ changed files
opends/resource/config/config.ldif 2 ●●●●● patch | view | raw | blame | history
opends/resource/schema/02-config.ldif 10 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/api/ClientConnection.java 38 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/backends/jeb/EntryContainer.java 27 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/config/ConfigConstants.java 24 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/BindOperation.java 88 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/CoreConfigManager.java 85 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/DirectoryServer.java 37 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/SearchOperation.java 4 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/ConfigMessages.java 39 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/CoreMessages.java 27 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/messages/JebMessages.java 13 ●●●●● patch | view | raw | blame | history
opends/resource/config/config.ldif
@@ -39,6 +39,7 @@
ds-cfg-proxied-authorization-identity-mapper-dn: cn=Exact Match,cn=Identity Mappers,cn=config
ds-cfg-size-limit: 1000
ds-cfg-time-limit: 60 seconds
ds-cfg-lookthrough-limit: 5000
ds-cfg-writability-mode: enabled
ds-cfg-bind-with-dn-requires-password: true
ds-cfg-default-password-policy: cn=Default Password Policy,cn=Password Policies,cn=config
@@ -1003,6 +1004,7 @@
ds-cfg-alternate-bind-dn: cn=Directory Manager
ds-rlim-size-limit: 0
ds-rlim-time-limit: 0
ds-rlim-lookthrough-limit: 0
dn: cn=Root DSE,cn=config
objectClass: top
opends/resource/schema/02-config.ldif
@@ -974,6 +974,13 @@
  Name 'ds-cfg-database-cleaner-num-threads'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE
  X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.285
  NAME 'ds-cfg-lookthrough-limit'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE
  X-ORIGIN 'OpenDS Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.286 NAME 'ds-rlim-lookthrough-limit'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE USAGE directoryOperation
  X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.1
  NAME 'ds-cfg-access-control-handler' SUP top STRUCTURAL
  MUST ( cn $ ds-cfg-acl-handler-class $ ds-cfg-acl-handler-enabled )
@@ -1151,7 +1158,8 @@
  ds-cfg-single-structural-objectclass-behavior $
  ds-cfg-notify-abandoned-operations $ ds-cfg-size-limit $ ds-cfg-time-limit $
  ds-cfg-proxied-authorization-identity-mapper-dn $ ds-cfg-writability-mode $
  ds-cfg-bind-with-dn-requires-password ) X-ORIGIN 'OpenDS Directory Server' )
  ds-cfg-bind-with-dn-requires-password $ ds-cfg-lookthrough-limit )
  X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.41 NAME 'ds-cfg-root-dn' SUP top
  AUXILIARY MAY ds-cfg-alternate-bind-dn X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.42 NAME 'ds-cfg-root-dse'
opends/src/server/org/opends/server/api/ClientConnection.java
@@ -80,6 +80,9 @@
  // The time limit for use with this client connection.
  private int timeLimit;
  // The lookthrough limit for use with this client connection.
  private int lookthroughLimit;
  // The opaque information used for storing intermediate state
  // information needed across multi-stage SASL binds.
  private Object saslAuthState;
@@ -103,6 +106,7 @@
    persistentSearches = new CopyOnWriteArrayList<PersistentSearch>();
    sizeLimit          = DirectoryServer.getSizeLimit();
    timeLimit          = DirectoryServer.getTimeLimit();
    lookthroughLimit   = DirectoryServer.getLookthroughLimit();
  }
@@ -776,6 +780,40 @@
  /**
   * Retrieves the default maximum number of entries that should
   * checked for matches during a search.
   *
   * @return  The default maximum number of entries that should
   *          checked for matches during a search.
   */
  public final int getLookthroughLimit()
  {
    assert debugEnter(CLASS_NAME, "getLookthroughLimit");
    return lookthroughLimit;
  }
  /**
   * Specifies the default maximum number of entries that should
   * be checked for matches during a search.
   *
   * @param  lookthroughLimit  The default maximum number of
   *                           entries that should be check for
   *                           matches during a search.
   */
  public final void setLookthroughLimit(int lookthroughLimit)
  {
    assert debugEnter(CLASS_NAME, "setLookthroughLimit",
      String.valueOf(lookthroughLimit));
    this.lookthroughLimit = lookthroughLimit;
  }
  /**
   * Retrieves the time limit that will be enforced for searches
   * performed using this client connection.
   *
opends/src/server/org/opends/server/backends/jeb/EntryContainer.java
@@ -838,6 +838,10 @@
    DatabaseEntry key = new DatabaseEntry(begin);
    List<Lock> lockList = new ArrayList<Lock>(1);
    int lookthroughCount = 0;
    int lookthroughLimit =
        searchOperation.getClientConnection().getLookthroughLimit();
    try
    {
      Cursor cursor = dn2id.openCursor(null, null);
@@ -851,6 +855,15 @@
        // Step forward until we pass the ending value.
        while (status == OperationStatus.SUCCESS)
        {
          if(lookthroughLimit > 0 && lookthroughCount > lookthroughLimit)
          {
            //Lookthrough limit exceeded
            searchOperation.setResultCode(ResultCode.ADMIN_LIMIT_EXCEEDED);
            searchOperation.appendErrorMessage(
              getMessage(MSGID_JEB_LOOKTHROUGH_LIMIT_EXCEEDED,
              lookthroughLimit));
            return;
          }
          int cmp = dn2idComparator.compare(key.getData(), end);
          if (cmp >= 0)
          {
@@ -901,6 +914,8 @@
            // Process the candidate entry.
            if (entry != null)
            {
              lookthroughCount++;
              if (manageDsaIT || entry.getReferralURLs() == null)
              {
                // Filter the entry.
@@ -1023,6 +1038,18 @@
      }
    }
    // Make sure the candidate list is smaller than the lookthrough limit
    int lookthroughLimit =
        searchOperation.getClientConnection().getLookthroughLimit();
    if(lookthroughLimit > 0 && entryIDList.size() > lookthroughLimit)
    {
      //Lookthrough limit exceeded
      searchOperation.setResultCode(ResultCode.ADMIN_LIMIT_EXCEEDED);
      searchOperation.appendErrorMessage(
          getMessage(MSGID_JEB_LOOKTHROUGH_LIMIT_EXCEEDED, lookthroughLimit));
      continueSearch = false;
    }
    // Iterate through the index candidates.
    if (continueSearch)
    {
opends/src/server/org/opends/server/config/ConfigConstants.java
@@ -1992,6 +1992,21 @@
   */
  public static final int DEFAULT_SIZE_LIMIT = 1000;
    /**
   * The name of the configuration attribute that holds the server lookthrough
   * limit.
   */
  public static final String ATTR_LOOKTHROUGH_LIMIT =
        NAME_PREFIX_CFG + "lookthrough-limit";
  /**
   * The default value that will be used for the server lookthrough limit if
   * no other value is given.
   */
  public static final int DEFAULT_LOOKTHROUGH_LIMIT = 5000;
  /**
@@ -3194,6 +3209,15 @@
  /**
   * The name of the operational attribute that may be included in user
   * entries to specify a lookthrough limit for that user.
   */
  public static final String OP_ATTR_USER_LOOKTHROUGH_LIMIT =
      NAME_PREFIX_RLIM + "lookthrough-limit";
  /**
   * The name of the attribute option used to indicate that a configuration
   * attribute has one or more pending values.
   */
opends/src/server/org/opends/server/core/BindOperation.java
@@ -931,6 +931,7 @@
    boolean returnAuthzID = false;
    int     sizeLimit     = DirectoryServer.getSizeLimit();
    int     timeLimit     = DirectoryServer.getTimeLimit();
    int     lookthroughLimit = DirectoryServer.getLookthroughLimit();
    // Set a flag to indicate that a bind operation is in progress.  This should
@@ -1473,6 +1474,50 @@
              }
              // See if the user's entry contains a custom lookthrough limit.
              attrType =
                   DirectoryServer.getAttributeType(
                       OP_ATTR_USER_LOOKTHROUGH_LIMIT, true);
              attrList = userEntry.getAttribute(attrType);
              if ((attrList != null) && (attrList.size() == 1))
              {
                Attribute a = attrList.get(0);
                LinkedHashSet<AttributeValue>  values = a.getValues();
                Iterator<AttributeValue> iterator = values.iterator();
                if (iterator.hasNext())
                {
                  AttributeValue v = iterator.next();
                  if (iterator.hasNext())
                  {
                    int msgID = MSGID_BIND_MULTIPLE_USER_LOOKTHROUGH_LIMITS;
                    String message =
                         getMessage(msgID, String.valueOf(userEntry.getDN()));
                    logError(ErrorLogCategory.CORE_SERVER,
                             ErrorLogSeverity.SEVERE_WARNING, message, msgID);
                  }
                  else
                  {
                    try
                    {
                      lookthroughLimit = Integer.parseInt(v.getStringValue());
                    }
                    catch (Exception e)
                    {
                      assert debugException(CLASS_NAME, "run", e);
                      int msgID =
                          MSGID_BIND_CANNOT_PROCESS_USER_LOOKTHROUGH_LIMIT;
                      String message =
                           getMessage(msgID, v.getStringValue(),
                                      String.valueOf(userEntry.getDN()));
                      logError(ErrorLogCategory.CORE_SERVER,
                               ErrorLogSeverity.SEVERE_WARNING, message, msgID);
                    }
                  }
                }
              }
              pwPolicyState.handleDeprecatedStorageSchemes(simplePassword);
              pwPolicyState.clearAuthFailureTimes();
@@ -1930,6 +1975,48 @@
                  }
                }
              }
              // See if the user's entry contains a custom lookthrough limit.
              attrType =
                   DirectoryServer.getAttributeType(
                       OP_ATTR_USER_LOOKTHROUGH_LIMIT, true);
              attrList = saslAuthUserEntry.getAttribute(attrType);
              if ((attrList != null) && (attrList.size() == 1))
              {
                Attribute a = attrList.get(0);
                LinkedHashSet<AttributeValue>  values = a.getValues();
                Iterator<AttributeValue> iterator = values.iterator();
                if (iterator.hasNext())
                {
                  AttributeValue v = iterator.next();
                  if (iterator.hasNext())
                  {
                    int msgID = MSGID_BIND_MULTIPLE_USER_LOOKTHROUGH_LIMITS;
                    String message = getMessage(msgID, userDNString);
                    logError(ErrorLogCategory.CORE_SERVER,
                             ErrorLogSeverity.SEVERE_WARNING, message, msgID);
                  }
                  else
                  {
                    try
                    {
                      lookthroughLimit = Integer.parseInt(v.getStringValue());
                    }
                    catch (Exception e)
                    {
                      assert debugException(CLASS_NAME, "run", e);
                      int msgID =
                          MSGID_BIND_CANNOT_PROCESS_USER_LOOKTHROUGH_LIMIT;
                      String message =
                           getMessage(msgID, v.getStringValue(), userDNString);
                      logError(ErrorLogCategory.CORE_SERVER,
                               ErrorLogSeverity.SEVERE_WARNING, message, msgID);
                    }
                  }
                }
              }
            }
          }
          else if (resultCode == ResultCode.SASL_BIND_IN_PROGRESS)
@@ -2037,6 +2124,7 @@
      clientConnection.setAuthenticationInfo(authInfo);
      clientConnection.setSizeLimit(sizeLimit);
      clientConnection.setTimeLimit(timeLimit);
      clientConnection.setLookthroughLimit(lookthroughLimit);
      clientConnection.setMustChangePassword(mustChangePassword);
      if (returnAuthzID)
opends/src/server/org/opends/server/core/CoreConfigManager.java
@@ -532,8 +532,8 @@
    // Determine the default server size limit.
    msgID = MSGID_CONFIG_CORE_DESCRIPTION_SIZE_LIMIT;
    IntegerConfigAttribute sizeLimitStub =
         new IntegerConfigAttribute(ATTR_SIZE_LIMIT, getMessage(msgID), true,
                                    false, false, true, 0, true,
         new IntegerConfigAttribute(ATTR_SIZE_LIMIT, getMessage(msgID), false,
                                    false, false, true, -1, true,
                                    Integer.MAX_VALUE);
    try
    {
@@ -567,7 +567,7 @@
    msgID = MSGID_CONFIG_CORE_DESCRIPTION_TIME_LIMIT;
    IntegerWithUnitConfigAttribute timeLimitStub =
         new IntegerWithUnitConfigAttribute(ATTR_TIME_LIMIT, getMessage(msgID),
                                            false, timeUnits, true, 0, true,
                                            false, timeUnits, true, -1, true,
                                            Integer.MAX_VALUE);
    try
    {
@@ -598,6 +598,41 @@
    }
    // Determine the default server lookthrough limit.
    msgID = MSGID_CONFIG_CORE_DESCRIPTION_LOOKTHROUGH_LIMIT;
    IntegerConfigAttribute lookthroughLimitStub =
         new IntegerConfigAttribute(ATTR_LOOKTHROUGH_LIMIT, getMessage(msgID),
                                    false, false, false, true, -1, true,
                                    Integer.MAX_VALUE);
    try
    {
      IntegerConfigAttribute lookthroughLimitAttr =
           (IntegerConfigAttribute)
           configRoot.getConfigAttribute(lookthroughLimitStub);
      if (lookthroughLimitAttr == null)
      {
        DirectoryServer.setLookthroughLimit(DEFAULT_LOOKTHROUGH_LIMIT);
      }
      else
      {
        DirectoryServer.setLookthroughLimit(
            lookthroughLimitAttr.activeIntValue());
      }
    }
    catch (Exception e)
    {
      // An error occurred, but this should not be considered fatal.  Log an
      // error message and use the default.
      assert debugException(CLASS_NAME, "initializeCoreConfig", e);
      logError(ErrorLogCategory.CONFIGURATION, ErrorLogSeverity.SEVERE_ERROR,
               MSGID_CONFIG_CORE_INVALID_LOOKTHROUGH_LIMIT, configRoot.getDN(),
               String.valueOf(e));
      DirectoryServer.setLookthroughLimit(DEFAULT_LOOKTHROUGH_LIMIT);
    }
    // Determine the writability mode for the Directory Server.  By default, it
    // will be writable.
    WritabilityMode writabilityMode = WritabilityMode.ENABLED;
@@ -2135,6 +2170,40 @@
    }
    // Get the server lookthrough limit.
    int lookthroughLimit = DEFAULT_LOOKTHROUGH_LIMIT;
    msgID = MSGID_CONFIG_CORE_DESCRIPTION_LOOKTHROUGH_LIMIT;
    IntegerConfigAttribute lookthroughLimitStub =
         new IntegerConfigAttribute(ATTR_LOOKTHROUGH_LIMIT,
             getMessage(msgID), false, false, false, true, -1, true,
             Integer.MAX_VALUE);
    try
    {
      IntegerConfigAttribute lookthroughLimitAttr =
           (IntegerConfigAttribute)
           configEntry.getConfigAttribute(lookthroughLimitStub);
      if (lookthroughLimitAttr != null)
      {
        lookthroughLimit = lookthroughLimitAttr.pendingIntValue();
      }
    }
    catch (Exception e)
    {
      assert debugException(CLASS_NAME, "applyNewConfiguration", e);
      // An error occurred, so we will not allow this configuration change to
      // take place.
      if (resultCode == ResultCode.SUCCESS)
      {
        resultCode = ResultCode.INVALID_ATTRIBUTE_SYNTAX;
      }
      msgID = MSGID_CONFIG_CORE_INVALID_LOOKTHROUGH_LIMIT;
      resultMessages.add(getMessage(msgID, configEntry.getDN().toString(),
                                    String.valueOf(e)));
    }
    // Get the server writability mode.
    HashSet<String> writabilityModes = new HashSet<String>(3);
    writabilityModes.add(WritabilityMode.ENABLED.toString());
@@ -2377,6 +2446,16 @@
      }
      DirectoryServer.setLookthroughLimit(lookthroughLimit);
      if (detailedResults)
      {
        resultMessages.add(getMessage(MSGID_CONFIG_SET_ATTRIBUTE,
                                      ATTR_LOOKTHROUGH_LIMIT,
                                      String.valueOf(lookthroughLimit),
                                      configEntryDN.toString()));
      }
      DirectoryServer.setWritabilityMode(writabilityMode);
      if (detailedResults)
      {
opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -378,6 +378,10 @@
  // unless overridden on a per-user basis.
  private int timeLimit;
  // The maxiumum number of candidates that should be check for matches during
  // a search.
  private int lookthroughLimit;
  // The key manager provider for the Directory Server.
  private KeyManagerProvider keyManagerProvider;
@@ -7133,6 +7137,39 @@
  /**
   * Retrieves the default maximum number of entries that should checked for
   * matches during a search.
   *
   * @return  The default maximum number of entries that should checked for
   *          matches during a search.
   */
  public static int getLookthroughLimit()
  {
    assert debugEnter(CLASS_NAME, "getLookthroughLimit");
    return directoryServer.lookthroughLimit;
  }
  /**
   * Specifies the default maximum number of entries that should be checked for
   * matches during a search.
   *
   * @param  lookthroughLimit  The default maximum number of entries that should
   *                           be check for matches during a search.
   */
  public static void setLookthroughLimit(int lookthroughLimit)
  {
    assert debugEnter(CLASS_NAME, "setLookthroughLimit",
      String.valueOf(lookthroughLimit));
    directoryServer.lookthroughLimit = lookthroughLimit;
  }
  /**
   * Retrieves the default maximum length of time in seconds that should be
   * allowed when processing a search.
   *
opends/src/server/org/opends/server/core/SearchOperation.java
@@ -797,7 +797,7 @@
    // See if the time limit has expired.  If so, then don't send the entry and
    // indicate that the search should end.
    if (TimeThread.getTime() >= timeLimitExpiration)
    if ((timeLimit > 0) && (TimeThread.getTime() >= timeLimitExpiration))
    {
      setResultCode(ResultCode.TIME_LIMIT_EXCEEDED);
      appendErrorMessage(getMessage(MSGID_SEARCH_TIME_LIMIT_EXCEEDED,
@@ -1242,7 +1242,7 @@
    // See if the time limit has expired.  If so, then don't send the entry and
    // indicate that the search should end.
    if (TimeThread.getTime() >= timeLimitExpiration)
    if ((timeLimit > 0) && (TimeThread.getTime() >= timeLimitExpiration))
    {
      setResultCode(ResultCode.TIME_LIMIT_EXCEEDED);
      appendErrorMessage(getMessage(MSGID_SEARCH_TIME_LIMIT_EXCEEDED,
opends/src/server/org/opends/server/messages/ConfigMessages.java
@@ -6073,6 +6073,25 @@
       CATEGORY_MASK_CONFIG | SEVERITY_MASK_SEVERE_ERROR | 560;
  /**
   * The message ID for the description of the server lookthrough limit
   * configuration attribute.  This does not take any arguments.
   */
  public static final int MSGID_CONFIG_CORE_DESCRIPTION_LOOKTHROUGH_LIMIT =
       CATEGORY_MASK_CONFIG | SEVERITY_MASK_INFORMATIONAL | 561;
  /**
   * The message ID for the message that will be used if an error occurs while
   * trying to process the server lookthrough limit.  This takes two arguments,
   * which are the DN of the configuration entry and a string representation
   * of the exception that was caught.
   */
  public static final int MSGID_CONFIG_CORE_INVALID_LOOKTHROUGH_LIMIT =
       CATEGORY_MASK_CONFIG | SEVERITY_MASK_SEVERE_ERROR | 562;
  /**
   * Associates a set of generic messages with the message IDs defined in this
@@ -6632,9 +6651,9 @@
    registerMessage(MSGID_CONFIG_CORE_INVALID_SIZE_LIMIT,
                    "Configuration entry %s has an invalid value for " +
                    "configuration attribute " + ATTR_SIZE_LIMIT +
                    " (it should be the a positive integer value specifying " +
                    "the size limit to use, or -1 to indicate that no limit " +
                    "should be enforced):  %s.");
                    " (It should be a positive integer value specifying " +
                    "the size limit to use, or a value of 0 or -1 to " +
                    "indicate that no limit should be enforced):  %s.");
    registerMessage(MSGID_CONFIG_CORE_DESCRIPTION_TIME_LIMIT,
                    "Specifies the default maximum length of time that " +
                    "should be allowed when processing a search operation.  " +
@@ -8808,6 +8827,20 @@
                    "acceptable according to its internal validation.  " +
                    "However, no specific information is available regarding " +
                    "the problem(s) with the entry.");
    registerMessage(MSGID_CONFIG_CORE_DESCRIPTION_LOOKTHROUGH_LIMIT,
                    "Specifies the default maximum number of candidate " +
                    "entries checked for matches when processing a search " +
                    "operation.  This may be overridden on a per-user basis " +
                    "by including the " + OP_ATTR_USER_LOOKTHROUGH_LIMIT +
                    " operational attribute in the user's entry.  Changes to " +
                    "this configuration attribute will take effect " +
                    "immediately.");
    registerMessage(MSGID_CONFIG_CORE_INVALID_LOOKTHROUGH_LIMIT,
                    "Configuration entry %s has an invalid value for " +
                    "configuration attribute " + ATTR_LOOKTHROUGH_LIMIT +
                    " (It should be a positive integer value specifying " +
                    "the lookthrough limit to use, or a value of 0 or -1 to " +
                    "indicate that no limit should be enforced):  %s.");
  }
}
opends/src/server/org/opends/server/messages/CoreMessages.java
@@ -5824,6 +5824,25 @@
       CATEGORY_MASK_CORE | SEVERITY_MASK_MILD_ERROR | 556;
   /**
   * The message ID for the message that will be used if a user entry contains
   * multiple values for the user-specific lookthrough limit attribute.
    * This takes a single argument, which is the DN of the user entry.
   */
  public static final int MSGID_BIND_MULTIPLE_USER_LOOKTHROUGH_LIMITS =
       CATEGORY_MASK_CORE | SEVERITY_MASK_SEVERE_WARNING | 557;
  /**
   * The message ID for the message that will be used if an error occurs while
   * trying to parse a user-specific lookthrough value as an integer. This takes
   * two arguments, which are the provided lookthrough limit value and the DN
   * of the user entry.
   */
  public static final int MSGID_BIND_CANNOT_PROCESS_USER_LOOKTHROUGH_LIMIT =
       CATEGORY_MASK_CORE | SEVERITY_MASK_SEVERE_WARNING | 558;
  /**
   * Associates a set of generic messages with the message IDs defined
@@ -7870,6 +7889,14 @@
                    "An error occured while trying to create an instance " +
                    "of class %s to use as the Directory Server work queue:  " +
                    "%s.");
    registerMessage(MSGID_BIND_MULTIPLE_USER_LOOKTHROUGH_LIMITS,
                    "There are multiple user-specific lookthrough limit " +
                    "values contained in user entry %s.  The default server " +
                    "lookthrough limit will be used.");
    registerMessage(MSGID_BIND_CANNOT_PROCESS_USER_LOOKTHROUGH_LIMIT,
                    "The user-specific lookthrough limit value %s contained " +
                    "in user entry %s could not be parsed as an integer.  " +
                    "The default server lookthrough limit will be used.");
  }
}
opends/src/server/org/opends/server/messages/JebMessages.java
@@ -1231,6 +1231,16 @@
  /**
   * The message ID for the string representation of the result code that will
   * be used for operations that failed because the operation lookthrough
   *  limit was exceeded.
   */
  public static final int MSGID_JEB_LOOKTHROUGH_LIMIT_EXCEEDED =
       CATEGORY_MASK_CORE | SEVERITY_MASK_INFORMATIONAL | 127;
  /**
   * Associates a set of generic messages with the message IDs defined in this
@@ -1721,5 +1731,8 @@
                    "Entry record with ID %s is not compatible with this " +
                    "version of the backend database. " +
                    "Entry version: %x");
    registerMessage(MSGID_JEB_LOOKTHROUGH_LIMIT_EXCEEDED,
                    "This search operation has checked the maximum of %d " +
                    "entries for matches.");
  }
}