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,14 +2687,21 @@ 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); 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,6 +230,8 @@ ArrayList<Message> messages = new ArrayList<Message>(); ClientConnection connection = bindOperation.getClientConnection(); boolean fullCheck = false; if (connection.mustEvaluateNetworkGroup(bindOperation)) { DN dn; try { dn = DN.decode(bindOperation.getRawBindDN()); @@ -239,15 +241,15 @@ } AuthenticationType authType = bindOperation.getAuthenticationType(); NetworkGroup ng = NetworkGroup.findBindMatchingNetworkGroup(connection, dn, authType, connection.isSecure()); 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> "); }