From fe10ac8a380a9a349bbe26794263501611918e69 Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Mon, 30 Jul 2007 00:42:18 +0000
Subject: [PATCH] Provide a mechanism to disable privileges in the server if necessary. If a privilege is disabled, then the server will behave as if all users have that privilege. This can help improve compatibility with environments that expect a feature to always be available, or to only be governed by access control.
---
opends/resource/schema/02-config.ldif | 4
opends/src/server/org/opends/server/core/DirectoryServer.java | 44 +++++++
opends/src/server/org/opends/server/api/ClientConnection.java | 12 +
opends/tests/unit-tests-testng/src/server/org/opends/server/types/PrivilegeTestCase.java | 61 ++++++++++
opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml | 141 +++++++++++++++++++++++
opends/src/server/org/opends/server/core/CoreConfigManager.java | 81 +++++++++++++
6 files changed, 337 insertions(+), 6 deletions(-)
diff --git a/opends/resource/schema/02-config.ldif b/opends/resource/schema/02-config.ldif
index a8d3197..7e8d6fd 100644
--- a/opends/resource/schema/02-config.ldif
+++ b/opends/resource/schema/02-config.ldif
@@ -1532,6 +1532,8 @@
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' )
+attributeTypes: ( 1.3.6.1.4.1.26027.1.1.457 NAME 'ds-cfg-disabled-privilege'
+ 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 )
@@ -1746,7 +1748,7 @@
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 $ ds-cfg-allowed-task )
+ ds-cfg-smtp-server $ ds-cfg-allowed-task $ ds-cfg-disabled-privilege )
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' )
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
index e57546f..8682e77 100644
--- a/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
+++ b/opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
@@ -526,5 +526,146 @@
</adm:profile>
</adm:property>
+ <adm:property name="disabled-privilege" mandatory="false" multi-valued="true">
+ <adm:synopsis>
+ Specifies the name of a privilege that should not be evaluated by the
+ server. If a privilege is disabled, then it will be assumed that all
+ clients (including unauthenticated clients) will have that privilege.
+ </adm:synopsis>
+ <adm:default-behavior>
+ <adm:alias>
+ <adm:synopsis>
+ If no values are defined, then the server will enforce all privileges.
+ </adm:synopsis>
+ </adm:alias>
+ </adm:default-behavior>
+ <adm:syntax>
+ <adm:enumeration>
+ <adm:value name="bypass-acl">
+ <adm:synopsis>
+ Allows the associated user to bypass access control checks performed
+ by the server.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="modify-acl">
+ <adm:synopsis>
+ Allows the associated user to modify the server's access control
+ configuration.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="config-read">
+ <adm:synopsis>
+ Allows the associated user to read the server configuration.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="config-write">
+ <adm:synopsis>
+ Allows the associated user to update the server configuration. The
+ config-read privilege is also required.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="jmx-read">
+ <adm:synopsis>
+ Allows the associated user to perform JMX read operations.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="jmx-write">
+ <adm:synopsis>
+ Allows the associated user to perform JMX write operations.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="jmx-notify">
+ <adm:synopsis>
+ Allows the associated user to subscribe to receive JMX
+ notifications.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="ldif-import">
+ <adm:synopsis>
+ Allows the user to request that the server process LDIF import
+ tasks.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="ldif-export">
+ <adm:synopsis>
+ Allows the user to request that the server process LDIF export
+ tasks.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="backend-backup">
+ <adm:synopsis>
+ Allows the user to request that the server process backup tasks.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="backend-restore">
+ <adm:synopsis>
+ Allows the user to request that the server process restore tasks.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="server-shutdown">
+ <adm:synopsis>
+ Allows the user to request that the server shut down.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="server-restart">
+ <adm:synopsis>
+ Allows the user to request that the server perform an in-core
+ restart.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="proxied-auth">
+ <adm:synopsis>
+ Allows the user to use the proxied authorization control, or to
+ perform a bind that specifies an alternate authorization identity.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="disconnect-client">
+ <adm:synopsis>
+ Allows the user to terminate other client connections.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="cancel-request">
+ <adm:synopsis>
+ Allows the user to cancel operations in progress on other client
+ connections.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="password-reset">
+ <adm:synopsis>
+ Allows the user to reset user passwords.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="data-sync">
+ <adm:synopsis>
+ Allows the user to participate in data synchronization.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="update-schema">
+ <adm:synopsis>
+ Allows the user to make changes to the server schema.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="privilege-change">
+ <adm:synopsis>
+ Allows the user to make changes to the set of defined root
+ privileges, as well as to grant and revoke privileges for users.
+ </adm:synopsis>
+ </adm:value>
+ <adm:value name="unindexed-search">
+ <adm:synopsis>
+ Allows the user to request that the server process a search that
+ cannot be optimized using server indexes.
+ </adm:synopsis>
+ </adm:value>
+ </adm:enumeration>
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:oid>1.3.6.1.4.1.26027.1.1.455</ldap:oid>
+ <ldap:name>ds-cfg-disabled-privilege</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+
</adm:managed-object>
diff --git a/opends/src/server/org/opends/server/api/ClientConnection.java b/opends/src/server/org/opends/server/api/ClientConnection.java
index cacc625..1c268df 100644
--- a/opends/src/server/org/opends/server/api/ClientConnection.java
+++ b/opends/src/server/org/opends/server/api/ClientConnection.java
@@ -960,8 +960,6 @@
public boolean hasPrivilege(Privilege privilege,
Operation operation)
{
- boolean result;
-
if (privilege == Privilege.PROXIED_AUTH)
{
// This determination should always be made against the
@@ -970,9 +968,11 @@
Entry authEntry = authenticationInfo.getAuthenticationEntry();
boolean isRoot = authenticationInfo.isRoot();
return getPrivileges(authEntry,
- isRoot).contains(Privilege.PROXIED_AUTH);
+ isRoot).contains(Privilege.PROXIED_AUTH) ||
+ DirectoryServer.isDisabled(Privilege.PROXIED_AUTH);
}
+ boolean result;
if (operation == null)
{
result = privileges.contains(privilege);
@@ -992,7 +992,8 @@
if (operation.getAuthorizationDN().equals(
authenticationInfo.getAuthorizationDN()))
{
- result = privileges.contains(privilege);
+ result = privileges.contains(privilege) ||
+ DirectoryServer.isDisabled(privilege);
if (debugEnabled())
{
DN authDN = authenticationInfo.getAuthenticationDN();
@@ -1017,7 +1018,8 @@
boolean isRoot =
DirectoryServer.isRootDN(authorizationEntry.getDN());
result = getPrivileges(authorizationEntry,
- isRoot).contains(privilege);
+ isRoot).contains(privilege) ||
+ DirectoryServer.isDisabled(privilege);
}
}
}
diff --git a/opends/src/server/org/opends/server/core/CoreConfigManager.java b/opends/src/server/org/opends/server/core/CoreConfigManager.java
index e712717..ce9865c 100644
--- a/opends/src/server/org/opends/server/core/CoreConfigManager.java
+++ b/opends/src/server/org/opends/server/core/CoreConfigManager.java
@@ -29,11 +29,13 @@
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.std.meta.GlobalCfgDefn;
import org.opends.server.admin.std.server.GlobalCfg;
import org.opends.server.admin.std.server.RootCfg;
import org.opends.server.admin.server.ServerManagementContext;
@@ -43,6 +45,7 @@
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DN;
import org.opends.server.types.InitializationException;
+import org.opends.server.types.Privilege;
import org.opends.server.types.ResultCode;
import org.opends.server.types.WritabilityMode;
@@ -253,6 +256,84 @@
DirectoryServer.setMailServerPropertySets(mailServerProperties);
DirectoryServer.setAllowedTasks(globalConfig.getAllowedTask());
+
+
+ HashSet<Privilege> disabledPrivileges = new HashSet<Privilege>();
+ Set<GlobalCfgDefn.DisabledPrivilege> configuredDisabledPrivs =
+ globalConfig.getDisabledPrivilege();
+ if (configuredDisabledPrivs != null)
+ {
+ for (GlobalCfgDefn.DisabledPrivilege p : configuredDisabledPrivs)
+ {
+ switch (p)
+ {
+ case BACKEND_BACKUP:
+ disabledPrivileges.add(Privilege.BACKEND_BACKUP);
+ break;
+ case BACKEND_RESTORE:
+ disabledPrivileges.add(Privilege.BACKEND_RESTORE);
+ break;
+ case BYPASS_ACL:
+ disabledPrivileges.add(Privilege.BYPASS_ACL);
+ break;
+ case CANCEL_REQUEST:
+ disabledPrivileges.add(Privilege.CANCEL_REQUEST);
+ break;
+ case CONFIG_READ:
+ disabledPrivileges.add(Privilege.CONFIG_READ);
+ break;
+ case CONFIG_WRITE:
+ disabledPrivileges.add(Privilege.CONFIG_WRITE);
+ break;
+ case DATA_SYNC:
+ disabledPrivileges.add(Privilege.DATA_SYNC);
+ break;
+ case DISCONNECT_CLIENT:
+ disabledPrivileges.add(Privilege.DISCONNECT_CLIENT);
+ break;
+ case JMX_NOTIFY:
+ disabledPrivileges.add(Privilege.JMX_NOTIFY);
+ break;
+ case JMX_READ:
+ disabledPrivileges.add(Privilege.JMX_READ);
+ break;
+ case JMX_WRITE:
+ disabledPrivileges.add(Privilege.JMX_WRITE);
+ break;
+ case LDIF_EXPORT:
+ disabledPrivileges.add(Privilege.LDIF_EXPORT);
+ break;
+ case LDIF_IMPORT:
+ disabledPrivileges.add(Privilege.LDIF_IMPORT);
+ break;
+ case MODIFY_ACL:
+ disabledPrivileges.add(Privilege.MODIFY_ACL);
+ break;
+ case PASSWORD_RESET:
+ disabledPrivileges.add(Privilege.PASSWORD_RESET);
+ break;
+ case PRIVILEGE_CHANGE:
+ disabledPrivileges.add(Privilege.PRIVILEGE_CHANGE);
+ break;
+ case PROXIED_AUTH:
+ disabledPrivileges.add(Privilege.PROXIED_AUTH);
+ break;
+ case SERVER_RESTART:
+ disabledPrivileges.add(Privilege.SERVER_RESTART);
+ break;
+ case SERVER_SHUTDOWN:
+ disabledPrivileges.add(Privilege.SERVER_SHUTDOWN);
+ break;
+ case UNINDEXED_SEARCH:
+ disabledPrivileges.add(Privilege.UNINDEXED_SEARCH);
+ break;
+ case UPDATE_SCHEMA:
+ disabledPrivileges.add(Privilege.UPDATE_SCHEMA);
+ break;
+ }
+ }
+ }
+ DirectoryServer.setDisabledPrivileges(disabledPrivileges);
}
diff --git a/opends/src/server/org/opends/server/core/DirectoryServer.java b/opends/src/server/org/opends/server/core/DirectoryServer.java
index 865a256..3388200 100644
--- a/opends/src/server/org/opends/server/core/DirectoryServer.java
+++ b/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 disabled privileges.
+ private Set<Privilege> disabledPrivileges;
+
// The set of allowed task classes.
private Set<String> allowedTasks;
@@ -722,6 +725,7 @@
directoryServer.importTaskListeners =
new CopyOnWriteArrayList<ImportTaskListener>();
directoryServer.allowedTasks = new LinkedHashSet<String>(0);
+ directoryServer.disabledPrivileges = new LinkedHashSet<Privilege>(0);
}
@@ -7423,6 +7427,46 @@
/**
+ * Retrieves the set of privileges that have been disabled.
+ *
+ * @return The set of privileges that have been disabled.
+ */
+ public static Set<Privilege> getDisabledPrivileges()
+ {
+ return directoryServer.disabledPrivileges;
+ }
+
+
+
+ /**
+ * Indicates whether the specified privilege is disabled.
+ *
+ * @param privilege The privilege for which to make the determination.
+ *
+ * @return {@code true} if the specified privilege is disabled, or
+ * {@code false} if not.
+ */
+ public static boolean isDisabled(Privilege privilege)
+ {
+ return directoryServer.disabledPrivileges.contains(privilege);
+ }
+
+
+
+ /**
+ * Specifies the set of privileges that should be disabled in the server.
+ *
+ * @param disabledPrivileges The set of privileges that should be disabled
+ * in the server.
+ */
+ public static void setDisabledPrivileges(Set<Privilege> disabledPrivileges)
+ {
+ directoryServer.disabledPrivileges = disabledPrivileges;
+ }
+
+
+
+ /**
* Registers the provided backup task listener with the Directory Server.
*
* @param listener The backup task listener to register with the Directory
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/types/PrivilegeTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/types/PrivilegeTestCase.java
index 934cba1..c9b7072 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/types/PrivilegeTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/types/PrivilegeTestCase.java
@@ -63,6 +63,7 @@
import org.opends.server.tools.LDAPModify;
import org.opends.server.tools.LDAPPasswordModify;
import org.opends.server.tools.LDAPSearch;
+import org.opends.server.tools.dsconfig.DSConfig;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
@@ -2300,6 +2301,66 @@
/**
+ * Tests the ability to disable a privilege so that an operation which will
+ * fail for a user without an appropriate privilege will succeed if that
+ * privilege is disabled.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testDisablePrivilege()
+ throws Exception
+ {
+ // Make sure that the operation fails when the privilege is not disabled.
+ String[] searchArgs =
+ {
+ "-h", "127.0.0.1",
+ "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+ "-o", "mech=PLAIN",
+ "-o", "authid=dn:cn=Directory Manager",
+ "-o", "authzid=u:privileged.user",
+ "-w", "password",
+ "-b", "o=test",
+ "-s", "base",
+ "(objectClass=*)"
+ };
+
+ assertFalse(LDAPSearch.mainSearch(searchArgs, false, null, null) == 0);
+
+
+ // Disable the PROXIED_AUTH privilege and verify that the operation now
+ // succeeds.
+ String[] configArgs =
+ {
+ "-h", "127.0.0.1",
+ "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+ "-D", "cn=Directory Manager",
+ "-w", "password",
+ "set-global-configuration-prop",
+ "--add", "disabled-privilege:proxied-auth"
+ };
+ assertEquals(DSConfig.main(configArgs, false, System.out, System.err), 0);
+ assertEquals(LDAPSearch.mainSearch(searchArgs, false, null, null), 0);
+
+
+ // Re-enable the PROXIED_AUTH privilege and verify that the operation
+ // fails again.
+ configArgs = new String[]
+ {
+ "-h", "127.0.0.1",
+ "-p", String.valueOf(TestCaseUtils.getServerLdapPort()),
+ "-D", "cn=Directory Manager",
+ "-w", "password",
+ "set-global-configuration-prop",
+ "--remove", "disabled-privilege:proxied-auth"
+ };
+ assertEquals(DSConfig.main(configArgs, false, System.out, System.err), 0);
+ assertFalse(LDAPSearch.mainSearch(searchArgs, false, null, null) == 0);
+ }
+
+
+
+ /**
* Tests the ability to update the set of privileges for a user on the fly
* and have them take effect immediately.
*
--
Gitblit v1.10.0