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

coulbeck
18.13.2006 365b9111189ba7fda737e717e16ef795d184a4eb
Fix for  [Issue 846] DN embedded in a monitor instance name.  Reviewed by gbellato.

The fix is to avoid constructing an RDN using string concatenation of the attribute type and value, when the value could contain characters that need to be quoted inside of a DN. I looked through the rest of the code at uses of DN.decode() and RDN.decode() and did not find any other places where the same mistake has been made.

The changes include updated unit tests to catch this issue.
1 files added
3 files modified
166 ■■■■■ changed files
opends/src/server/org/opends/server/backends/MonitorBackend.java 5 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/DirectoryServer.java 34 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/monitors/InternalSearchMonitorTestCase.java 53 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/monitors/TestMonitorProvider.java 74 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/backends/MonitorBackend.java
@@ -73,7 +73,6 @@
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.Debug.*;
import static org.opends.server.loggers.Error.*;
import static org.opends.server.messages.BackendMessages.*;
import static org.opends.server.messages.MessageHandler.*;
import static org.opends.server.util.ServerConstants.*;
@@ -890,9 +889,7 @@
      for (MonitorProvider monitorProvider :
           DirectoryServer.getMonitorProviders().values())
      {
        DN providerDN = DN.decode(ATTR_COMMON_NAME + "=" +
                                  monitorProvider.getMonitorInstanceName() +
                                  "," + DN_MONITOR_ROOT);
        DN providerDN = DirectoryServer.getMonitorProviderDN(monitorProvider);
        Entry monitorEntry = getMonitorEntry(providerDN, monitorProvider);
        if (filter.matchesEntry(monitorEntry))
        {
opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -4608,9 +4608,7 @@
    // Try to register this monitor provider with an appropriate JMX MBean.
    try
    {
      DN monitorDN =
           DN.decode("cn=" + monitorProvider.getMonitorInstanceName() +
                     ",cn=monitor");
      DN monitorDN = getMonitorProviderDN(monitorProvider);
      JMXMBean mBean = directoryServer.mBeans.get(monitorDN);
      if (mBean == null)
      {
@@ -4652,9 +4650,7 @@
    {
      try
      {
        DN monitorDN =
             DN.decode("cn=" + provider.getMonitorInstanceName() +
                       ",cn=monitor");
        DN monitorDN = getMonitorProviderDN(provider);
        JMXMBean mBean = directoryServer.mBeans.get(monitorDN);
        if (mBean != null)
        {
@@ -7631,5 +7627,31 @@
      System.exit(1);
    }
  }
  /**
   * Construct the DN of a monitor provider entry.
   * @param provider The monitor provider for which a DN is desired.
   * @return The DN of the monitor provider entry.
   */
  public static DN getMonitorProviderDN(MonitorProvider provider)
  {
    String monitorName = provider.getMonitorInstanceName();
    AttributeType cnType = getAttributeType(ATTR_COMMON_NAME);
    DN monitorRootDN;
    try
    {
      monitorRootDN = DN.decode(DN_MONITOR_ROOT);
    }
    catch (DirectoryException e)
    {
      // Cannot reach this point.
      throw new RuntimeException();
    }
    RDN[] baseRDNs = monitorRootDN.getRDNComponents();
    RDN[] rdns = new RDN[baseRDNs.length+1];
    rdns[0] = new RDN(cnType, new AttributeValue(cnType, monitorName));
    System.arraycopy(baseRDNs, 0, rdns, 1, baseRDNs.length);
    return new DN(rdns);
  }
}
opends/tests/unit-tests-testng/src/server/org/opends/server/monitors/InternalSearchMonitorTestCase.java
@@ -33,8 +33,11 @@
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.annotations.AfterClass;
import org.opends.server.TestCaseUtils;
import org.opends.server.api.MonitorProvider;
import static org.opends.server.util.ServerConstants.ATTR_COMMON_NAME;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
@@ -42,6 +45,10 @@
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchScope;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.AttributeType;
import org.opends.server.types.RDN;
import org.opends.server.types.AttributeValue;
import org.opends.server.types.SearchResultEntry;
import static org.testng.Assert.*;
@@ -54,6 +61,8 @@
public class InternalSearchMonitorTestCase
       extends MonitorTestCase
{
  static MonitorProvider testMonitorProvider = new TestMonitorProvider();
  /**
   * Ensures that the Directory Server is started.
   *
@@ -64,10 +73,18 @@
         throws Exception
  {
    TestCaseUtils.startServer();
    DirectoryServer.registerMonitorProvider(testMonitorProvider);
  }
  @AfterClass()
  public void deregisterTestMonitor()
  {
    DirectoryServer.deregisterMonitorProvider(
         testMonitorProvider.getMonitorInstanceName());
  }
  /**
   * Uses an internal subtree search to retrieve the monitor entries.
   *
@@ -122,13 +139,47 @@
  public void testWithBaseObjectMonitorSearch(String monitorName)
         throws Exception
  {
    AttributeType cnType = DirectoryServer.getAttributeType(ATTR_COMMON_NAME);
    RDN[] components = new RDN[2];
    components[0] = new RDN(cnType, new AttributeValue(cnType, monitorName));
    components[1] = new RDN(cnType, new AttributeValue(cnType, "monitor"));
    DN monitorDN = new DN(components);
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    InternalSearchOperation searchOperation =
         conn.processSearch(DN.decode("cn=" + monitorName + ",cn=monitor"),
         conn.processSearch(monitorDN,
              SearchScope.BASE_OBJECT,
              SearchFilter.createFilterFromString("(objectClass=*)"));
    assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
  }
  /**
   * Uses an internal subtree search to retrieve the monitor entries, then
   * verifies that the resulting entry DNs can be used to get the same
   * entries with a base object search.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  public void testWithSubtreeAndBaseMonitorSearch()
         throws Exception
  {
    InternalClientConnection conn =
         InternalClientConnection.getRootConnection();
    InternalSearchOperation searchOperation =
         conn.processSearch(DN.decode("cn=monitor"), SearchScope.WHOLE_SUBTREE,
              SearchFilter.createFilterFromString("(objectClass=*)"));
    assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
    for (SearchResultEntry sre : searchOperation.getSearchEntries())
    {
      SearchFilter filter =
           SearchFilter.createFilterFromString("(objectClass=*)");
      searchOperation =
           conn.processSearch(sre.getDN(), SearchScope.BASE_OBJECT, filter);
      assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
    }
  }
}
opends/tests/unit-tests-testng/src/server/org/opends/server/monitors/TestMonitorProvider.java
New file
@@ -0,0 +1,74 @@
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying * information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006 Sun Microsystems, Inc.
 */
package org.opends.server.monitors;
import org.opends.server.api.MonitorProvider;
import org.opends.server.config.ConfigEntry;
import org.opends.server.config.ConfigException;
import org.opends.server.types.InitializationException;
import org.opends.server.types.Attribute;
import java.util.List;
import java.util.Collections;
/**
 * This test monitor provider has a DN embedded in its instance name.
 */
class TestMonitorProvider extends MonitorProvider
{
  public TestMonitorProvider()
  {
    super("Test Monitor Thread");
  }
  public void initializeMonitorProvider(ConfigEntry configEntry)
       throws ConfigException, InitializationException
  {
    // No implementation required.
  }
  public String getMonitorInstanceName()
  {
    return "Test monitor for dc=example,dc=com";
  }
  public long getUpdateInterval()
  {
    return 0;
  }
  public void updateMonitorData()
  {
    // No implementation required.
  }
  public List<Attribute> getMonitorData()
  {
    return Collections.emptyList();
  }
}