| opends/resource/config/config.ldif | ●●●●● patch | view | raw | blame | history | |
| opends/resource/schema/02-config.ldif | ●●●●● patch | view | raw | blame | history | |
| opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml | ●●●●● patch | view | raw | blame | history | |
| opends/src/server/org/opends/server/backends/task/TaskScheduler.java | ●●●●● patch | view | raw | blame | history | |
| opends/src/server/org/opends/server/core/CoreConfigManager.java | ●●●●● patch | view | raw | blame | history | |
| opends/src/server/org/opends/server/core/DirectoryServer.java | ●●●●● patch | view | raw | blame | history | |
| opends/src/server/org/opends/server/messages/BackendMessages.java | ●●●●● patch | view | raw | blame | history | |
| opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/AllowedTaskTestCase.java | ●●●●● patch | view | raw | blame | history | |
| opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/DummyTask.java | ●●●●● patch | view | raw | blame | history |
opends/resource/config/config.ldif
@@ -46,6 +46,18 @@ ds-cfg-bind-with-dn-requires-password: true ds-cfg-reject-unauthenticated-requests: false ds-cfg-default-password-policy: cn=Default Password Policy,cn=Password Policies,cn=config ds-cfg-allowed-task: org.opends.server.tasks.AddSchemaFileTask ds-cfg-allowed-task: org.opends.server.tasks.BackupTask ds-cfg-allowed-task: org.opends.server.tasks.DisconnectClientTask ds-cfg-allowed-task: org.opends.server.tasks.EnterLockdownModeTask ds-cfg-allowed-task: org.opends.server.tasks.ExportTask ds-cfg-allowed-task: org.opends.server.tasks.ImportTask ds-cfg-allowed-task: org.opends.server.tasks.InitializeTargetTask ds-cfg-allowed-task: org.opends.server.tasks.InitializeTask ds-cfg-allowed-task: org.opends.server.tasks.LeaveLockdownModeTask ds-cfg-allowed-task: org.opends.server.tasks.RebuildTask ds-cfg-allowed-task: org.opends.server.tasks.RestoreTask ds-cfg-allowed-task: org.opends.server.tasks.ShutdownTask dn: cn=Access Control Handler,cn=config objectClass: top opends/resource/schema/02-config.ldif
@@ -1530,6 +1530,8 @@ attributeTypes: ( 1.3.6.1.4.1.26027.1.1.455 NAME 'ds-task-disconnect-notify-client' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'OpenDS Directory Server' ) attributeTypes: ( 1.3.6.1.4.1.26027.1.1.456 NAME 'ds-cfg-allowed-task' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 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 ) @@ -1744,7 +1746,8 @@ ds-cfg-proxied-authorization-identity-mapper-dn $ ds-cfg-writability-mode $ ds-cfg-reject-unauthenticated-requests $ ds-cfg-bind-with-dn-requires-password $ ds-cfg-lookthrough-limit $ ds-cfg-smtp-server ) X-ORIGIN 'OpenDS Directory Server' ) ds-cfg-smtp-server $ ds-cfg-allowed-task ) 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/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
@@ -501,5 +501,30 @@ </adm:profile> </adm:property> <adm:property name="allowed-task" mandatory="false" multi-valued="true"> <adm:synopsis> Specifies the fully-qualified name of a Java class that may be invoked in the server. Any attempt to invoke a task not included in the list of allowed tasks will be rejected. </adm:synopsis> <adm:default-behavior> <adm:alias> <adm:synopsis> If no values are defined, then the server will not allow any tasks to be invoked. </adm:synopsis> </adm:alias> </adm:default-behavior> <adm:syntax> <adm:string /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.454</ldap:oid> <ldap:name>ds-cfg-allowed-task</ldap:name> </ldap:attribute> </adm:profile> </adm:property> </adm:managed-object> opends/src/server/org/opends/server/backends/task/TaskScheduler.java
@@ -1829,6 +1829,13 @@ } String taskClassName = value.getStringValue(); if (! DirectoryServer.getAllowedTasks().contains(taskClassName)) { int msgID = MSGID_TASKSCHED_NOT_ALLOWED_TASK; String message = getMessage(msgID, taskClassName); throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message, msgID); } // Try to load the specified class. opends/src/server/org/opends/server/core/CoreConfigManager.java
@@ -251,6 +251,8 @@ } } DirectoryServer.setMailServerPropertySets(mailServerProperties); DirectoryServer.setAllowedTasks(globalConfig.getAllowedTask()); } opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -522,6 +522,9 @@ // The error logger that will be used during the Directory Server startup. private TextErrorLogPublisher startupErrorLogPublisher; // The set of allowed task classes. private Set<String> allowedTasks; // The fully-qualified name of the configuration handler class. private String configClass; @@ -718,6 +721,7 @@ new CopyOnWriteArrayList<ExportTaskListener>(); directoryServer.importTaskListeners = new CopyOnWriteArrayList<ImportTaskListener>(); directoryServer.allowedTasks = new LinkedHashSet<String>(0); } @@ -7392,6 +7396,33 @@ /** * Retrieves a set containing the names of the allowed tasks that may be * invoked in the server. * * @return A set containing the names of the allowed tasks that may be * invoked in the server. */ public static Set<String> getAllowedTasks() { return directoryServer.allowedTasks; } /** * Specifies the set of allowed tasks that may be invoked in the server. * * @param allowedTasks A set containing the names of the allowed tasks that * may be invoked in the server. */ public static void setAllowedTasks(Set<String> allowedTasks) { directoryServer.allowedTasks = allowedTasks; } /** * Registers the provided backup task listener with the Directory Server. * * @param listener The backup task listener to register with the Directory opends/src/server/org/opends/server/messages/BackendMessages.java
@@ -3227,6 +3227,16 @@ /** * The message ID for the message that will be used if an attempt is made to * schedule a task that is not included in the set of allowed tasks. This * takes a single argument, which is the name of the target class. */ public static final int MSGID_TASKSCHED_NOT_ALLOWED_TASK = CATEGORY_MASK_BACKEND | SEVERITY_MASK_SEVERE_ERROR | 298; /** * Associates a set of generic messages with the message IDs defined in this * class. */ @@ -4238,6 +4248,9 @@ "The provided task entry contains multiple values for " + "the %s attribute, which is used to specify the task " + "class name, but only a single value is allowed"); registerMessage(MSGID_TASKSCHED_NOT_ALLOWED_TASK, "The Directory Server is not configured to allow task " + "%s to be invoked"); registerMessage(MSGID_TASKSCHED_CANNOT_LOAD_CLASS, "An error occurred while attempting to load class %s " + "specified in attribute %s of the provided task entry: " + opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/AllowedTaskTestCase.java
New file @@ -0,0 +1,233 @@ /* * 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 2007 Sun Microsystems, Inc. */ package org.opends.server.tasks; import org.testng.annotations.Test; import org.testng.annotations.BeforeClass; import org.opends.server.TestCaseUtils; import org.opends.server.backends.task.Task; import org.opends.server.backends.task.TaskBackend; import org.opends.server.backends.task.TaskState; import org.opends.server.core.DirectoryServer; import org.opends.server.extensions.GetConnectionIDExtendedOperation; import org.opends.server.protocols.ldap.LDAPResultCode; import org.opends.server.tools.LDAPModify; import org.opends.server.tools.dsconfig.DSConfig; import org.opends.server.types.DN; import static org.testng.Assert.*; import static org.opends.server.util.ServerConstants.*; /** * Tests the ability of the server to control the set of tasks that are allowed * to be executed. */ public class AllowedTaskTestCase extends TasksTestCase { /** * Make sure that the Directory Server is running. * * @throws Exception If an unexpected problem occurs. */ @BeforeClass() public void startServer() throws Exception { TestCaseUtils.startServer(); } /** * Tests the function of the ds-cfg-allowed-task configuration attribute * using a dummy task. * * @throws Exception If an unexpected problem occurs. */ @Test() public void testAllowedTask() throws Exception { // Try to add the dummy task and expect it to fail because it's not allowed. String path = TestCaseUtils.createTempFile( "dn: ds-task-id=testAllowedTask 1,cn=Scheduled Tasks,cn=Tasks", "changetype: add", "objectClass: top", "objectClass: ds-task", "ds-task-id: testAllowedTask 1", "ds-task-class-name: org.opends.server.tasks.DummyTask"); String[] args = { "-h", "127.0.0.1", "-p", String.valueOf(TestCaseUtils.getServerLdapPort()), "-D", "cn=Directory Manager", "-w", "password", "-f", path }; assertEquals(LDAPModify.mainModify(args, false, System.out, System.err), LDAPResultCode.UNWILLING_TO_PERFORM); // Update the set of allowed tasks to include the dummy task. args = new String[] { "-h", "127.0.0.1", "-p", String.valueOf(TestCaseUtils.getServerLdapPort()), "-D", "cn=Directory Manager", "-w", "password", "set-global-configuration-prop", "--add", "allowed-task:org.opends.server.tasks.DummyTask" }; assertEquals(DSConfig.main(args, false, System.out, System.err), 0); // Now verify that we can add the task and have it complete successfully. path = TestCaseUtils.createTempFile( "dn: ds-task-id=testAllowedTask 2,cn=Scheduled Tasks,cn=Tasks", "changetype: add", "objectClass: top", "objectClass: ds-task", "ds-task-id: testAllowedTask 2", "ds-task-class-name: org.opends.server.tasks.DummyTask"); args = new String[] { "-h", "127.0.0.1", "-p", String.valueOf(TestCaseUtils.getServerLdapPort()), "-D", "cn=Directory Manager", "-w", "password", "-f", path }; assertEquals(LDAPModify.mainModify(args, false, System.out, System.err), LDAPResultCode.SUCCESS); Task task = getCompletedTask(DN.decode( "ds-task-id=testAllowedTask 2,cn=Scheduled Tasks,cn=Tasks")); assertNotNull(task); assertEquals(task.getTaskState(), TaskState.COMPLETED_SUCCESSFULLY); // Remove the task class from the set of allowed tasks and verify that we // can no longer schedule the task. args = new String[] { "-h", "127.0.0.1", "-p", String.valueOf(TestCaseUtils.getServerLdapPort()), "-D", "cn=Directory Manager", "-w", "password", "set-global-configuration-prop", "--remove", "allowed-task:org.opends.server.tasks.DummyTask" }; assertEquals(DSConfig.main(args, false, System.out, System.err), 0); // Now verify that we can add the task and have it complete successfully. path = TestCaseUtils.createTempFile( "dn: ds-task-id=testAllowedTask 3,cn=Scheduled Tasks,cn=Tasks", "changetype: add", "objectClass: top", "objectClass: ds-task", "ds-task-id: testAllowedTask 3", "ds-task-class-name: org.opends.server.tasks.DummyTask"); args = new String[] { "-h", "127.0.0.1", "-p", String.valueOf(TestCaseUtils.getServerLdapPort()), "-D", "cn=Directory Manager", "-w", "password", "-f", path }; assertEquals(LDAPModify.mainModify(args, false, System.out, System.err), LDAPResultCode.UNWILLING_TO_PERFORM); } /** * Retrieves the specified task from the server, waiting for it to finish all * the running its going to do before returning. * * @param taskEntryDN The DN of the entry for the task to retrieve. * * @return The requested task entry. * * @throws Exception If an unexpected problem occurs. */ private Task getCompletedTask(DN taskEntryDN) throws Exception { TaskBackend taskBackend = (TaskBackend) DirectoryServer.getBackend(DN.decode("cn=tasks")); Task task = taskBackend.getScheduledTask(taskEntryDN); if (task == null) { long stopWaitingTime = System.currentTimeMillis() + 10000L; while ((task == null) && (System.currentTimeMillis() < stopWaitingTime)) { Thread.sleep(10); task = taskBackend.getScheduledTask(taskEntryDN); } } if (task == null) { throw new AssertionError("There is no such task " + taskEntryDN.toString()); } if (! TaskState.isDone(task.getTaskState())) { long stopWaitingTime = System.currentTimeMillis() + 20000L; while ((! TaskState.isDone(task.getTaskState())) && (System.currentTimeMillis() < stopWaitingTime)) { Thread.sleep(10); } } if (! TaskState.isDone(task.getTaskState())) { throw new AssertionError("Task " + taskEntryDN.toString() + " did not complete in a timely manner."); } return task; } } opends/tests/unit-tests-testng/src/server/org/opends/server/tasks/DummyTask.java
New file @@ -0,0 +1,64 @@ /* * 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 2007 Sun Microsystems, Inc. */ package org.opends.server.tasks; import org.opends.server.backends.task.Task; import org.opends.server.backends.task.TaskState; import org.opends.server.types.DirectoryException; /** * This class provides an implementation of a Directory Server task always * completes successfully. It is intended only for testing purposes. */ public class DummyTask extends Task { /** * {@inheritDoc} */ @Override public void initializeTask() throws DirectoryException { // No implementation is required. } /** * {@inheritDoc} */ protected TaskState runTask() { return TaskState.COMPLETED_SUCCESSFULLY; } }