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

floblanc
29.40.2008 2964e0f4cbf0dcee17b1d333a0ac3312e9a5370d
Implement a network group dedicated to the admin connector:
- this network group is not configurable, and unbreakable
- all connections handled by the admin connector are managed by this network group
- all JMX connections are managed by this network group
- this network group provides access to all private and public suffixes

Modify the behavior of the default network group in MANUAL mode:
- in manual mode, the default network group is empty
- in auto mode (=standard OpenDS mode), the default network group still provides access to all private and public suffixes

14 files modified
338 ■■■■ changed files
opends/src/server/org/opends/server/admin/AdministrationConnector.java 1 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/api/ClientConnection.java 24 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/api/ConnectionHandler.java 22 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/DirectoryServer.java 116 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/WorkflowConfigManager.java 7 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/networkgroups/NetworkGroup.java 49 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/networkgroups/ResourceLimits.java 1 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/plugins/NetworkGroupPlugin.java 38 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java 5 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java 2 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java 4 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java 4 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/core/WorkflowConfigurationTest.java 16 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java 49 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/admin/AdministrationConnector.java
@@ -157,6 +157,7 @@
      new LDAPConnectionHandler(new SynchronousStrategy(), FRIENDLY_NAME);
    adminConnectionHandler.
      initializeConnectionHandler(ldapConnectionHandlerCfg);
    adminConnectionHandler.setAdminConnectionHandler();
    // Register this as a change listener.
    config.addChangeListener(this);
opends/src/server/org/opends/server/api/ClientConnection.java
@@ -59,9 +59,11 @@
import org.opends.server.types.Entry;
import org.opends.server.types.IntermediateResponse;
import org.opends.server.types.Operation;
import org.opends.server.types.OperationType;
import org.opends.server.types.Privilege;
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SearchResultReference;
import org.opends.server.types.operation.PreParseOperation;
import org.opends.server.util.TimeThread;
import static org.opends.messages.CoreMessages.*;
@@ -541,9 +543,29 @@
  /**
   * Indicates whether the network group must be evaluated for
   * the next connection.
   * @param operation The operation going to be performed. Bind
   *                  operations imply a network group evaluation.
   * @return boolean indicating if the network group must be evaluated
   */
  public boolean mustEvaluateNetworkGroup() {
  public boolean mustEvaluateNetworkGroup(
          PreParseOperation operation) {
    //  Connections inside the internal network group MUST NOT
    // change network group
    if (this.networkGroup == NetworkGroup.getInternalNetworkGroup()) {
      return false;
    }
    // Connections inside the admin network group MUST NOT
    // change network group
    if (this.networkGroup == NetworkGroup.getAdminNetworkGroup()) {
      return false;
    }
    // If the operation is a BIND, the network group MUST be evaluated
    if (operation != null
        && operation.getOperationType() == OperationType.BIND) {
      return true;
    }
    return mustEvaluateNetworkGroup;
  }
opends/src/server/org/opends/server/api/ConnectionHandler.java
@@ -60,6 +60,9 @@
  // The monitor associated with this connection handler.
  private ConnectionHandlerMonitor monitor;
  // Is this handler the admin connection handler
  private boolean isAdminConnectionHandler = false;
  /**
@@ -239,6 +242,25 @@
  /**
   * Sets this connection handler as the admin connection handler.
   */
  public void setAdminConnectionHandler() {
    isAdminConnectionHandler = true;
  }
  /**
   * Returns whether this connection handler is the admin
   * connection handler.
   * @return boolean True if this connection handler is the admin
   *                 connection handler, false otherwise
   */
  public boolean isAdminConnectionHandler() {
    return isAdminConnectionHandler;
  }
  /**
   * Retrieves a string representation of this connection handler.
   *
   * @return A string representation of this connection handler.
opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -74,6 +74,7 @@
import org.opends.server.api.plugin.PluginType;
import org.opends.server.api.plugin.PluginResult;
import org.opends.server.backends.RootDSEBackend;
import static org.opends.server.config.ConfigConstants.DN_CONFIG_ROOT;
import static org.opends.server.config.ConfigConstants.DN_MONITOR_ROOT;
import static org.opends.server.config.ConfigConstants.ENV_VAR_INSTALL_ROOT;
import org.opends.server.config.ConfigEntry;
@@ -2613,8 +2614,7 @@
  /**
   * Deregisters a workflow with the default network group and
   * deregisters the workflow with the server. This method is
   * Deregisters a workflow with the default network group. This method is
   * intended to be called when workflow configuration mode is
   * auto.
   *
@@ -2628,17 +2628,54 @@
    // being configured for the backend (there is one worklfow per
    // backend base DN).
    NetworkGroup defaultNetworkGroup = NetworkGroup.getDefaultNetworkGroup();
    Workflow workflow = defaultNetworkGroup.deregisterWorkflow(baseDN);
    WorkflowImpl workflowImpl = (WorkflowImpl) workflow;
    workflowImpl.deregister();
    defaultNetworkGroup.deregisterWorkflow(baseDN);
  }
  /**
   * Deregisters a workflow with the admin network group. This method is
   * intended to be called when workflow configuration mode is
   * auto.
   *
   * @param baseDN  the DN of the workflow to deregister
   */
  private static void deregisterWorkflowWithAdminNetworkGroup(
      DN baseDN
      )
  {
    // Get the admin network group and deregister all the workflows
    // being configured for the backend (there is one worklfow per
    // backend base DN).
    NetworkGroup adminNetworkGroup = NetworkGroup.getAdminNetworkGroup();
    adminNetworkGroup.deregisterWorkflow(baseDN);
  }
  /**
   * Deregisters a workflow with the internal network group and
   * deregisters the workflow with the server. This method is
   * intended to be called when workflow configuration mode is
   * auto.
   *
   * @param baseDN  the DN of the workflow to deregister
   */
  private static void deregisterWorkflowWithInternalNetworkGroup(
      DN baseDN
      )
  {
    // Get the internal network group and deregister all the workflows
    // being configured for the backend (there is one workflow per
    // backend base DN).
    NetworkGroup internalNetworkGroup = NetworkGroup.getInternalNetworkGroup();
    Workflow workflow = internalNetworkGroup.deregisterWorkflow(baseDN);
    WorkflowImpl workflowImpl = (WorkflowImpl) workflow;
    workflowImpl.deregister();
  }
  /**
   * Creates a set of workflows for a given backend and registers the
   * workflows with the default network group. There are as many workflows
   * as base DNs defined in the backend. This method is intended
   * to be called when workflow configuration mode is auto.
   * workflows with the default network group, the internal network group
   * and he admin network group. There are as many workflows
   * as base DNs defined in the backend.
   *
   * @param backend  the backend handled by the workflow
   *
@@ -2650,12 +2687,19 @@
      Backend backend
      ) throws DirectoryException
  {
    // Create a worklfow for each backend base DN and register the workflow
    // with the default network group.
    // Create a workflow for each backend base DN and register the workflow
    // with the default/internal/admin network group.
    for (DN curBaseDN: backend.getBaseDNs())
    {
      WorkflowImpl workflowImpl = createWorkflow(curBaseDN, backend);
      registerWorkflowWithDefaultNetworkGroup(workflowImpl);
      registerWorkflowWithAdminNetworkGroup(workflowImpl);
      registerWorkflowWithInternalNetworkGroup(workflowImpl);
      // Special case for cn=config
      // it must not be added to the default ng except in auto mode
      if (!curBaseDN.equals(DN.decode(DN_CONFIG_ROOT))
          || workflowConfigurationModeIsAuto()) {
        registerWorkflowWithDefaultNetworkGroup(workflowImpl);
      }
    }
  }
@@ -2721,6 +2765,44 @@
  /**
   * Registers a workflow with the admin network group. This method
   * is intended to be called when workflow configuration mode is auto.
   *
   * @param workflowImpl  The workflow to register with the
   *                      admin network group
   *
   * @throws  DirectoryException  If the workflow is already registered with
   *                              the admin network group
   */
  private static void registerWorkflowWithAdminNetworkGroup(
      WorkflowImpl workflowImpl
      ) throws DirectoryException
  {
    NetworkGroup adminNetworkGroup = NetworkGroup.getAdminNetworkGroup();
    adminNetworkGroup.registerWorkflow(workflowImpl);
  }
  /**
   * Registers a workflow with the internal network group. This method
   * is intended to be called when workflow configuration mode is auto.
   *
   * @param workflowImpl  The workflow to register with the
   *                      internal network group
   *
   * @throws  DirectoryException  If the workflow is already registered with
   *                              the internal network group
   */
  private static void registerWorkflowWithInternalNetworkGroup(
      WorkflowImpl workflowImpl
      ) throws DirectoryException
  {
    NetworkGroup internalNetworkGroup = NetworkGroup.getInternalNetworkGroup();
    internalNetworkGroup.registerWorkflow(workflowImpl);
  }
  /**
   * Creates the missing workflows, one for the config backend and one for
   * the rootDSE backend.
   *
@@ -2765,14 +2847,15 @@
      // move to manual mode
      try
      {
        directoryServer.configureWorkflowsManual();
        setWorkflowConfigurationMode(newMode);
        directoryServer.configureWorkflowsManual();
      }
      catch (Exception e)
      {
        // rollback to auto mode
        try
        {
           setWorkflowConfigurationMode(oldMode);
           directoryServer.configureWorkflowsAuto();
        }
        catch (Exception ee)
@@ -2791,14 +2874,15 @@
      // move to auto mode
      try
      {
        directoryServer.configureWorkflowsAuto();
        setWorkflowConfigurationMode(newMode);
        directoryServer.configureWorkflowsAuto();
      }
      catch (Exception e)
      {
        // rollback to manual mode
        try
        {
           setWorkflowConfigurationMode(oldMode);
           directoryServer.configureWorkflowsManual();
        }
        catch (Exception ee)
@@ -2875,6 +2959,8 @@
        try
        {
          workflowImpl = createWorkflow(baseDN, backend);
          registerWorkflowWithInternalNetworkGroup(workflowImpl);
          registerWorkflowWithAdminNetworkGroup(workflowImpl);
          registerWorkflowWithDefaultNetworkGroup(workflowImpl);
        }
        catch (DirectoryException e)
@@ -6642,6 +6728,8 @@
        if (! baseDN.equals(DN.decode("cn=config")))
        {
          WorkflowImpl workflowImpl = createWorkflow(baseDN, backend);
          registerWorkflowWithInternalNetworkGroup(workflowImpl);
          registerWorkflowWithAdminNetworkGroup(workflowImpl);
          registerWorkflowWithDefaultNetworkGroup(workflowImpl);
        }
      }
@@ -6683,7 +6771,9 @@
      // by the workflow config manager.
      if (workflowConfigurationModeIsAuto())
      {
        deregisterWorkflowWithAdminNetworkGroup(baseDN);
        deregisterWorkflowWithDefaultNetworkGroup(baseDN);
        deregisterWorkflowWithInternalNetworkGroup(baseDN);
      }
    }
  }
opends/src/server/org/opends/server/core/WorkflowConfigManager.java
@@ -306,8 +306,11 @@
    workflows.put(workflowCfg.dn(), workflowImpl);
    workflowImpl.register();
    // Register the workflow with the default network group
    NetworkGroup.getDefaultNetworkGroup().registerWorkflow(workflowImpl);
    // Register the workflow with the internal network group
    NetworkGroup.getInternalNetworkGroup().registerWorkflow(workflowImpl);
    // Register the workflow with the admin network group
    NetworkGroup.getAdminNetworkGroup().registerWorkflow(workflowImpl);
  }
}
opends/src/server/org/opends/server/core/networkgroups/NetworkGroup.java
@@ -84,6 +84,20 @@
      new NetworkGroup ("default");
  // The admin network group (singleton).
  // The admin network group has no criterion, no policy, and gives
  // access to all the workflows.
  private static NetworkGroup adminNetworkGroup =
      new NetworkGroup ("admin");
  // The internal network group (singleton).
  // The internal network group has no criterion, no policy, and gives
  // access to all the workflows. The purpose of the internal network
  // group is to allow internal connections to perform operations.
  private static NetworkGroup internalNetworkGroup =
      new NetworkGroup("internal");
  // The list of all network groups that are registered with the server.
  // The defaultNetworkGroup is not in the list of registered network groups.
  private static TreeMap<String, NetworkGroup> registeredNetworkGroups =
@@ -411,13 +425,6 @@
      // Rebuild the list of naming context handled by the network group
      rebuildNamingContextList();
    }
    // If the workflow has been deregistered then deregister it with
    // the default network group as well
    if (deregistered && (this != defaultNetworkGroup))
    {
      defaultNetworkGroup.deregisterWorkflow(workflow);
    }
  }
@@ -771,6 +778,26 @@
  /**
   * Returns the admin network group.
   * @return the admin network group
   */
  public static NetworkGroup getAdminNetworkGroup()
  {
    return adminNetworkGroup;
  }
  /**
   * Returns the internal network group.
   * @return the internal network group
   */
  public static NetworkGroup getInternalNetworkGroup()
  {
    return internalNetworkGroup;
  }
  /**
   * Rebuilds the list of naming contexts handled by the network group.
   * This operation should be performed whenever a workflow topology
   * has been updated (workflow registration or de-registration).
@@ -853,9 +880,14 @@
        networkGroup.invalidate();
      }
      defaultNetworkGroup.invalidate();
      adminNetworkGroup.invalidate();
      internalNetworkGroup.invalidate();
      registeredNetworkGroups = new TreeMap<String,NetworkGroup>();
      orderedNetworkGroups = new ArrayList<NetworkGroup>();
      defaultNetworkGroup = new NetworkGroup ("default");
      adminNetworkGroup = new NetworkGroup ("admin");
      internalNetworkGroup = new NetworkGroup("internal");
    }
  }
@@ -915,11 +947,14 @@
  {
    // Reset the default network group
    defaultNetworkGroup.reset();
    adminNetworkGroup.reset();
    internalNetworkGroup.reset();
    // Reset all the registered network group
    synchronized (registeredNetworkGroupsLock)
    {
      registeredNetworkGroups = new TreeMap<String, NetworkGroup>();
      orderedNetworkGroups = new ArrayList<NetworkGroup>();
    }
  }
opends/src/server/org/opends/server/core/networkgroups/ResourceLimits.java
@@ -129,6 +129,7 @@
      searchSizeLimit = resourcesCfg.getSearchSizeLimit();
      searchTimeLimit = (int) resourcesCfg.getSearchTimeLimit();
      minSearchSubstringLength = resourcesCfg.getMinSubstringLength();
      connectionsPerIpMap = new HashMap<String, Integer>();
      resourcesCfg.addChangeListener(this);
      isConfigured = true;
opends/src/server/org/opends/server/plugins/NetworkGroupPlugin.java
@@ -177,7 +177,7 @@
          ArrayList<Message> messages)
  {
    boolean fullCheck = false;
    if (connection.mustEvaluateNetworkGroup()) {
    if (connection.mustEvaluateNetworkGroup(operation)) {
        NetworkGroup ng = NetworkGroup.findMatchingNetworkGroup(connection);
        if (ng != connection.getNetworkGroup()) {
          connection.setNetworkGroup(ng);
@@ -230,24 +230,26 @@
    ArrayList<Message> messages = new ArrayList<Message>();
    ClientConnection connection = bindOperation.getClientConnection();
    boolean fullCheck = false;
    DN dn;
    try {
      dn = DN.decode(bindOperation.getRawBindDN());
    } catch (DirectoryException ex) {
      return PluginResult.PreParse.stopProcessing(ResultCode.OPERATIONS_ERROR,
              ex.getMessageObject());
    if (connection.mustEvaluateNetworkGroup(bindOperation)) {
      DN dn;
      try {
        dn = DN.decode(bindOperation.getRawBindDN());
      } catch (DirectoryException ex) {
        return PluginResult.PreParse.stopProcessing(ResultCode.OPERATIONS_ERROR,
                ex.getMessageObject());
      }
      AuthenticationType authType = bindOperation.getAuthenticationType();
      NetworkGroup ng = NetworkGroup.findBindMatchingNetworkGroup(connection,
            dn, authType, connection.isSecure());
      if (ng != connection.getNetworkGroup()) {
        connection.setNetworkGroup(ng);
        fullCheck = true;
      }
      connection.mustEvaluateNetworkGroup(false);
    }
    AuthenticationType authType = bindOperation.getAuthenticationType();
    NetworkGroup ng = NetworkGroup.findBindMatchingNetworkGroup(connection, dn,
            authType, connection.isSecure());
    if (ng != connection.getNetworkGroup()) {
      connection.setNetworkGroup(ng);
      fullCheck = true;
    }
    connection.mustEvaluateNetworkGroup(false);
    if (!checkNetworkGroup(connection, bindOperation, fullCheck, messages)) {
      return PluginResult.PreParse.stopProcessing(
              ResultCode.ADMIN_LIMIT_EXCEEDED, messages.get(0));
opends/src/server/org/opends/server/protocols/internal/InternalClientConnection.java
@@ -45,6 +45,7 @@
import org.opends.server.api.ConnectionHandler;
import org.opends.server.api.ConnectionSecurityProvider;
import org.opends.server.core.*;
import org.opends.server.core.networkgroups.NetworkGroup;
import org.opends.server.extensions.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.asn1.ASN1OctetString;
@@ -166,6 +167,8 @@
    super();
    this.setNetworkGroup(NetworkGroup.getInternalNetworkGroup());
    // This connection will be authenticated as a root user so that no
    // access control will be enforced.
    String commonName    = "Internal Client";
@@ -285,6 +288,8 @@
    super();
    this.setNetworkGroup(NetworkGroup.getInternalNetworkGroup());
    this.authenticationInfo = authInfo;
    super.setAuthenticationInfo(authInfo);
    super.setSizeLimit(0);
opends/src/server/org/opends/server/protocols/jmx/JmxClientConnection.java
@@ -74,6 +74,7 @@
import static org.opends.messages.ProtocolMessages.*;
import org.opends.messages.MessageBuilder;
import org.opends.server.core.networkgroups.NetworkGroup;
/**
@@ -134,6 +135,7 @@
  {
    super();
    this.setNetworkGroup(NetworkGroup.getAdminNetworkGroup());
    nextMessageID    = new AtomicInteger(1);
    nextOperationID  = new AtomicLong(0);
opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
@@ -59,6 +59,7 @@
import org.opends.server.core.SearchOperation;
import org.opends.server.core.SearchOperationBasis;
import org.opends.server.core.UnbindOperationBasis;
import org.opends.server.core.networkgroups.NetworkGroup;
import org.opends.server.extensions.NullConnectionSecurityProvider;
import org.opends.server.extensions.TLSCapableConnection;
import org.opends.server.extensions.TLSConnectionSecurityProvider;
@@ -236,6 +237,9 @@
    this.connectionHandler     = connectionHandler;
    if (connectionHandler.isAdminConnectionHandler()) {
      setNetworkGroup(NetworkGroup.getAdminNetworkGroup());
    }
    this.clientChannel         = clientChannel;
    this.securityProvider      = null;
    this.clearSecurityProvider = null;
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendWorkflowElement.java
@@ -237,6 +237,10 @@
        super.initialize(
          configuration.getWorkflowElementId(), BACKEND_WORKFLOW_ELEMENT);
        backend = newBackend;
        if (backend != null)
        {
          setPrivate(backend.isPrivateBackend());
        }
      }
    }
opends/tests/unit-tests-testng/src/server/org/opends/server/core/WorkflowConfigurationTest.java
@@ -284,7 +284,7 @@
  
  /**
   * Creates a workflow to handle a local backend. The default network
   * Creates a workflow to handle a local backend. The internal network
   * group is used.
   *
   * @param baseDN     the base DN of the workflow
@@ -310,8 +310,8 @@
        workflowID, DN.decode(baseDN), workflowElement);
    workflowImpl.register();
    
    // Register the workflow with the default network group
    NetworkGroup.getDefaultNetworkGroup().registerWorkflow(workflowImpl);
    // Register the workflow with the internal network group
    NetworkGroup.getInternalNetworkGroup().registerWorkflow(workflowImpl);
    
    return workflowImpl;
  }
@@ -329,8 +329,8 @@
    // Elaborate the workflow ID
    String workflowID = baseDN + "#" + backendID;
    // Deregister the workflow with the default network group
    NetworkGroup.getDefaultNetworkGroup().deregisterWorkflow(workflowID);
    // Deregister the workflow with the internal network group
    NetworkGroup.getInternalNetworkGroup().deregisterWorkflow(workflowID);
    // Deregister the workflow with the server
    Workflow workflow = WorkflowImpl.getWorkflow(workflowID);
@@ -666,7 +666,7 @@
    // Move to the manual mode
    setModeManual();
    
    // Create a route for o=test suffix in the default network group.
    // Create a route for o=test suffix in the internal network group.
    // Search on o=test should succeed.
    WorkflowImpl workflowImpl = createWorkflow(baseDN, backendID);
    InternalSearchOperation searchOperation =
@@ -688,9 +688,9 @@
    searchOperation.run();
    assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
    
    // Put back the default network group in the client conenction
    // Put back the internal network group in the client conenction
    // and check that searches are still working.
    clientConnection.setNetworkGroup(NetworkGroup.getDefaultNetworkGroup());
    clientConnection.setNetworkGroup(NetworkGroup.getInternalNetworkGroup());
    searchOperation.run();
    assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
    
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java
@@ -145,6 +145,11 @@
   * - one baseDN
   * - one subordinateDN
   * - a boolean telling whether we expect to find a workflow for the baseDN
   *   in the default network group
   * - a boolean telling whether we expect to find a workflow for the baseDN
   *   in the admin network group
   * - a boolean telling whether we expect to find a workflow for the baseDN
   *   in the internal network group
   *
   * @return set of DNs
   * @throws Exception  when DN.decode fails
@@ -192,13 +197,13 @@
    // Sets of DNs
    Object[][] myData =
    {
        { dnRootDSE,  null,                 true  },
        { dnConfig,   dnSubordinateConfig,  true  },
        { dnMonitor,  dnSubordinateMonitor, true  },
        { dnTasks,    dnSubordinateTasks,   true  },
        { dnSchema,   null,                 true  },
        { dnBackups,  null,                 true  },
        { dnDummy,    null,                 false },
        { dnRootDSE,  null,                 true,  true,  true },
        { dnConfig,   dnSubordinateConfig,  true,  true,  true },
        { dnMonitor,  dnSubordinateMonitor, true,  true,  true },
        { dnTasks,    dnSubordinateTasks,   true,  true,  true },
        { dnSchema,   null,                 true,  true,  true },
        { dnBackups,  null,                 true,  true,  true },
        { dnDummy,    null,                 false, false, false },
    };
    return myData;
@@ -521,7 +526,9 @@
  public void checkDefaultNetworkGroup(
      DN      dnToSearch,
      DN      dnSubordinate,
      boolean exists
      boolean existsInDefault,
      boolean existsInAdmin,
      boolean existsInInternal
      )
  {
    // let's get the default network group -- it should always exist
@@ -529,10 +536,34 @@
    assertNotNull(defaultNG);
    // let's check the routing through the network group
    doCheckNetworkGroup(defaultNG, dnToSearch, dnSubordinate, null, exists);
    doCheckNetworkGroup(defaultNG, dnToSearch, dnSubordinate, null,
            existsInDefault);
    // Dump the default network group
    dump(defaultNG, "defaultNetworkGroup> ");
    // let's get the admin network group -- it should always exist
    NetworkGroup adminNG = NetworkGroup.getAdminNetworkGroup();
    assertNotNull(adminNG);
    // let's check the routing through the network group
    doCheckNetworkGroup(adminNG, dnToSearch, dnSubordinate, null,
            existsInAdmin);
    // Dump the default network group
    dump(adminNG, "adminNetworkGroup> ");
    // let's get the internal network group -- it should always exist
    NetworkGroup internalNG = NetworkGroup.getInternalNetworkGroup();
    assertNotNull(internalNG);
    // let's check the routing through the network group
    doCheckNetworkGroup(internalNG, dnToSearch, dnSubordinate, null,
            existsInInternal);
    // Dump the default network group
    dump(internalNG, "internalNetworkGroup> ");
  }