From 2021fe3e69527d25fb1b2dc67e4e931e6a56260a Mon Sep 17 00:00:00 2001
From: neil_a_wilson <neil_a_wilson@localhost>
Date: Fri, 13 Apr 2007 15:59:03 +0000
Subject: [PATCH] Update the member virtual attribute implementation so that it provides a mechanism for preventing the entire member list from being returned, which can be a very expensive operation. When running with this configuration, the attribute will handle requests that determine whether a given user is a member of the group, but will not list the entire set of membership.
---
opends/resource/schema/02-config.ldif | 7 ++
opends/src/server/org/opends/server/extensions/MemberVirtualAttributeProvider.java | 47 ++++++++++++++-
opends/src/admin/defn/org/opends/server/admin/std/MemberVirtualAttributeConfiguration.xml | 42 ++++++++++++++
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/VirtualStaticGroupTestCase.java | 59 +++++++++++++++++++
opends/resource/config/config.ldif | 4 +
opends/tests/unit-tests-testng/resource/config-changes.ldif | 10 +++
6 files changed, 166 insertions(+), 3 deletions(-)
diff --git a/opends/resource/config/config.ldif b/opends/resource/config/config.ldif
index 9752405..9b6458b 100644
--- a/opends/resource/config/config.ldif
+++ b/opends/resource/config/config.ldif
@@ -1741,22 +1741,26 @@
dn: cn=Virtual Static member,cn=Virtual Attributes,cn=config
objectClass: top
objectClass: ds-cfg-virtual-attribute
+objectClass: ds-cfg-member-virtual-attribute
cn: Virtual Static member
ds-cfg-virtual-attribute-class: org.opends.server.extensions.MemberVirtualAttributeProvider
ds-cfg-virtual-attribute-enabled: true
ds-cfg-virtual-attribute-type: member
ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real
ds-cfg-virtual-attribute-filter: (&(objectClass=groupOfNames)(objectClass=ds-virtual-static-group))
+ds-cfg-allow-retrieving-membership: false
dn: cn=Virtual Static uniqueMember,cn=Virtual Attributes,cn=config
objectClass: top
objectClass: ds-cfg-virtual-attribute
+objectClass: ds-cfg-member-virtual-attribute
cn: Virtual Static uniqueMember
ds-cfg-virtual-attribute-class: org.opends.server.extensions.MemberVirtualAttributeProvider
ds-cfg-virtual-attribute-enabled: true
ds-cfg-virtual-attribute-type: uniqueMember
ds-cfg-virtual-attribute-conflict-behavior: virtual-overrides-real
ds-cfg-virtual-attribute-filter: (&(objectClass=groupOfUniqueNames)(objectClass=ds-virtual-static-group))
+ds-cfg-allow-retrieving-membership: false
dn: cn=Work Queue,cn=config
objectClass: top
diff --git a/opends/resource/schema/02-config.ldif b/opends/resource/schema/02-config.ldif
index 9138149..9dba19d 100644
--- a/opends/resource/schema/02-config.ldif
+++ b/opends/resource/schema/02-config.ldif
@@ -1156,6 +1156,9 @@
attributeTypes: ( 1.3.6.1.4.1.26027.1.1.344
NAME 'ds-cfg-virtual-attribute-value' 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.345
+ NAME 'ds-cfg-allow-retrieving-membership' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
+ SINGLE-VALUE 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 )
@@ -1615,4 +1618,8 @@
NAME 'ds-cfg-user-defined-virtual-attribute' SUP ds-cfg-virtual-attribute
STRUCTURAL MUST ds-cfg-virtual-attribute-value
X-ORIGIN 'OpenDS Directory Server' )
+objectClasses: ( 1.3.6.1.4.1.26027.1.2.101
+ NAME 'ds-cfg-member-virtual-attribute' SUP ds-cfg-virtual-attribute
+ STRUCTURAL MUST ds-cfg-allow-retrieving-membership
+ X-ORIGIN 'OpenDS Directory Server' )
diff --git a/opends/src/admin/defn/org/opends/server/admin/std/MemberVirtualAttributeConfiguration.xml b/opends/src/admin/defn/org/opends/server/admin/std/MemberVirtualAttributeConfiguration.xml
new file mode 100644
index 0000000..ea649c0
--- /dev/null
+++ b/opends/src/admin/defn/org/opends/server/admin/std/MemberVirtualAttributeConfiguration.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<adm:managed-object name="member-virtual-attribute"
+plural-name="user-defined-virtual-attributes"
+package="org.opends.server.admin.std" extends="virtual-attribute"
+xmlns:adm="http://www.opends.org/admin"
+xmlns:ldap="http://www.opends.org/admin-ldap">
+ <adm:synopsis>
+ The
+ <adm:user-friendly-name />
+ is used to generate a member or uniqueMember attribute whose values are the
+ DNs of the members of a specified group. This is used to implement virtual
+ static group functionality, in which it is possible to create an entry which
+ looks like a static group but obtains all of its membership from a dynamic
+ group (or some other type of group, including another static group).
+ </adm:synopsis>
+ <adm:profile name="ldap">
+ <ldap:object-class>
+ <ldap:oid>1.3.6.1.4.1.26027.1.2.101</ldap:oid>
+ <ldap:name>ds-cfg-member-virtual-attribute</ldap:name>
+ <ldap:superior>ds-cfg-virtual-attribute</ldap:superior>
+ </ldap:object-class>
+ </adm:profile>
+ <adm:property name="allow-retrieving-membership" mandatory="true">
+ <adm:synopsis>
+ Indicates whether to handle requests that request all values for the
+ virtual attribute. This can be a very expensive operation in some cases,
+ and is not in-line with the primary function of virtual static groups,
+ which is to make it possible to use static group idioms to determine
+ whether a given user is a member.
+ </adm:synopsis>
+ <adm:syntax>
+ <adm:boolean />
+ </adm:syntax>
+ <adm:profile name="ldap">
+ <ldap:attribute>
+ <ldap:oid>1.3.6.1.4.1.26027.1.1.345</ldap:oid>
+ <ldap:name>ds-cfg-allow-retrieving-membership</ldap:name>
+ </ldap:attribute>
+ </adm:profile>
+ </adm:property>
+</adm:managed-object>
+
diff --git a/opends/src/server/org/opends/server/extensions/MemberVirtualAttributeProvider.java b/opends/src/server/org/opends/server/extensions/MemberVirtualAttributeProvider.java
index 6bbf9c1..1432512 100644
--- a/opends/src/server/org/opends/server/extensions/MemberVirtualAttributeProvider.java
+++ b/opends/src/server/org/opends/server/extensions/MemberVirtualAttributeProvider.java
@@ -32,7 +32,8 @@
import java.util.LinkedHashSet;
import java.util.List;
-import org.opends.server.admin.std.server.VirtualAttributeCfg;
+import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.std.server.MemberVirtualAttributeCfg;
import org.opends.server.api.Group;
import org.opends.server.api.VirtualAttributeProvider;
import org.opends.server.config.ConfigException;
@@ -42,6 +43,7 @@
import org.opends.server.types.AttributeValue;
import org.opends.server.types.ByteString;
import org.opends.server.types.ConditionResult;
+import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
@@ -62,12 +64,16 @@
* uniqueMember attribute.
*/
public class MemberVirtualAttributeProvider
- extends VirtualAttributeProvider<VirtualAttributeCfg>
+ extends VirtualAttributeProvider<MemberVirtualAttributeCfg>
+ implements ConfigurationChangeListener<MemberVirtualAttributeCfg>
{
// The attribute type used to indicate which target group should be used to
// obtain the member list.
private AttributeType targetGroupType;
+ // The current configuration for this member virtual attribute.
+ private MemberVirtualAttributeCfg currentConfig;
+
/**
@@ -88,9 +94,12 @@
*/
@Override()
public void initializeVirtualAttributeProvider(
- VirtualAttributeCfg configuration)
+ MemberVirtualAttributeCfg configuration)
throws ConfigException, InitializationException
{
+ configuration.addMemberChangeListener(this);
+ currentConfig = configuration;
+
targetGroupType =
DirectoryServer.getAttributeType(ATTR_TARGET_GROUP_DN, true);
}
@@ -115,6 +124,11 @@
public LinkedHashSet<AttributeValue> getValues(Entry entry,
VirtualAttributeRule rule)
{
+ if (! currentConfig.isAllowRetrievingMembership())
+ {
+ return new LinkedHashSet<AttributeValue>(0);
+ }
+
Group g = DirectoryServer.getGroupManager().getGroupInstance(entry.getDN());
if (g == null)
{
@@ -336,5 +350,32 @@
searchOperation.setResultCode(ResultCode.UNWILLING_TO_PERFORM);
return;
}
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isConfigurationChangeAcceptable(
+ MemberVirtualAttributeCfg configuration,
+ List<String> unacceptableReasons)
+ {
+ // The new configuration should always be acceptable.
+ return true;
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConfigChangeResult applyConfigurationChange(
+ MemberVirtualAttributeCfg configuration)
+ {
+ // Just accept the new configuration as-is.
+ currentConfig = configuration;
+
+ return new ConfigChangeResult(ResultCode.SUCCESS, false);
+ }
}
diff --git a/opends/tests/unit-tests-testng/resource/config-changes.ldif b/opends/tests/unit-tests-testng/resource/config-changes.ldif
index 328fb33..1aa7cf1 100644
--- a/opends/tests/unit-tests-testng/resource/config-changes.ldif
+++ b/opends/tests/unit-tests-testng/resource/config-changes.ldif
@@ -525,3 +525,13 @@
ds-cfg-database-checkpointer-wakeup-interval: 30 seconds
ds-cfg-database-lock-num-lock-tables: 19
+dn: cn=Virtual Static member,cn=Virtual Attributes,cn=config
+changetype: modify
+replace: ds-cfg-allow-retrieving-membership
+ds-cfg-allow-retrieving-membership: true
+
+dn: cn=Virtual Static uniqueMember,cn=Virtual Attributes,cn=config
+changetype: modify
+replace: ds-cfg-allow-retrieving-membership
+ds-cfg-allow-retrieving-membership: true
+
diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/VirtualStaticGroupTestCase.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/VirtualStaticGroupTestCase.java
index fc43be7..0b5a832 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/VirtualStaticGroupTestCase.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/VirtualStaticGroupTestCase.java
@@ -837,6 +837,65 @@
/**
+ * Tests the behavior of the member virtual attribute with different settings
+ * for the "allow retrieving membership" attribute.
+ *
+ * @throws Exception If an unexpected problem occurs.
+ */
+ @Test()
+ public void testAllowRetrievingMembership()
+ throws Exception
+ {
+ TestCaseUtils.initializeTestBackend(true);
+ TestCaseUtils.addEntries(LDIF_LINES);
+
+ Entry e = DirectoryServer.getEntry(vmd1);
+ assertNotNull(e);
+ assertTrue(e.hasAttribute(memberType));
+
+ Attribute a = e.getAttribute(memberType).get(0);
+ assertEquals(a.getValues().size(), 1);
+
+ AttributeValue v = new AttributeValue(memberType, u4.toString());
+ assertTrue(a.hasValue(v));
+
+
+ InternalClientConnection conn =
+ InternalClientConnection.getRootConnection();
+
+ LinkedList<Modification> mods = new LinkedList<Modification>();
+ mods.add(new Modification(ModificationType.REPLACE,
+ new Attribute("ds-cfg-allow-retrieving-membership", "false")));
+ DN definitionDN =
+ DN.decode("cn=Virtual Static member,cn=Virtual Attributes,cn=config");
+ ModifyOperation modifyOperation = conn.processModify(definitionDN, mods);
+ assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
+
+
+ e = DirectoryServer.getEntry(vmd1);
+ assertNotNull(e);
+ assertTrue(e.hasAttribute(memberType));
+
+ a = e.getAttribute(memberType).get(0);
+ assertEquals(a.getValues().size(), 0);
+
+ v = new AttributeValue(memberType, u4.toString());
+ assertTrue(a.hasValue(v));
+
+
+ mods = new LinkedList<Modification>();
+ mods.add(new Modification(ModificationType.REPLACE,
+ new Attribute("ds-cfg-allow-retrieving-membership", "true")));
+ modifyOperation = conn.processModify(definitionDN, mods);
+ assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
+
+
+ cleanUp();
+ }
+
+
+
+ /**
* Removes all of the groups that have been added to the server.
*
* @throws Exception If an unexpected problem occurs.
--
Gitblit v1.10.0