From 571884cec31d00f0c1b9de186fb1bbac17d289d5 Mon Sep 17 00:00:00 2001
From: dugan <dugan@localhost>
Date: Wed, 01 Aug 2007 01:15:44 +0000
Subject: [PATCH] Add ACI support to control whether a "smart referral" (named subordinate references -- RFC 3296) may be returned to a client. Smart referral entries contain the referral objectclass and have one or more "ref" attributes containing LDAP URLS. The ref attribute type has usage distributedOperation, so the operational shorthand '+' character can be used to match it:
---
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java | 2
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/GetEffectiveRightsTestCase.java | 2
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java | 12 +
opendj-sdk/opends/src/server/org/opends/server/core/DefaultAccessControlHandler.java | 2
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AlternateRootDN.java | 2
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java | 49 +++++-
opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java | 4
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/ReferencesTestCase.java | 214 ++++++++++++++++++++++++++++++
opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationWrapper.java | 4
opendj-sdk/opends/src/server/org/opends/server/types/operation/PreOperationSearchOperation.java | 5
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/ExtOpTestCase.java | 2
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetControlTestCase.java | 2
opendj-sdk/opends/src/server/org/opends/server/types/operation/PreParseSearchOperation.java | 14 -
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java | 57 +++++--
opendj-sdk/opends/src/server/org/opends/server/api/AccessControlHandler.java | 10 +
opendj-sdk/opends/src/server/org/opends/server/backends/jeb/DN2URI.java | 2
opendj-sdk/opends/src/server/org/opends/server/core/SearchOperation.java | 4
17 files changed, 329 insertions(+), 58 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/api/AccessControlHandler.java b/opendj-sdk/opends/src/server/org/opends/server/api/AccessControlHandler.java
index 12200ab..a15238b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/api/AccessControlHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/api/AccessControlHandler.java
@@ -308,7 +308,10 @@
/**
* Indicates whether the provided search result reference may be
- * sent to the client.
+ * sent to the client based on the access control configuration.
+ *
+ * @param dn A DN that can be used in the access
+ * determination.
*
* @param searchOperation The search operation with which the
* provided reference is associated.
@@ -319,8 +322,9 @@
* the reference to be returned to the client, or
* {@code false} if not.
*/
- public abstract boolean maySend(SearchOperation searchOperation,
- SearchResultReference searchReference);
+ public abstract boolean maySend(DN dn,
+ SearchOperation searchOperation,
+ SearchResultReference searchReference);
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
index 77c3ba1..fa824cd 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
@@ -97,6 +97,12 @@
*/
static AttributeType debugSearchIndex;
+ /**
+ * Attribute type corresponding to the "ref" attribute type. Used in the
+ * search reference access check.
+ */
+ static AttributeType refAttrType;
+
/*
* DN corresponding to "debugsearchindex" attribute type.
*/
@@ -149,6 +155,14 @@
DirectoryServer.
getDefaultAttributeType(EntryContainer.ATTR_DEBUG_SEARCH_INDEX);
}
+
+ if((refAttrType =
+ DirectoryServer.
+ getAttributeType(ATTR_REFERRAL_URL)) == null) {
+ refAttrType =
+ DirectoryServer.
+ getDefaultAttributeType(ATTR_REFERRAL_URL);
+ }
try {
debugSearchIndexDN=DN.decode("cn=debugsearch");
} catch (DirectoryException ex) {
@@ -1232,26 +1246,39 @@
new AciLDAPOperationContainer(operation, e, (ACI_READ | ACI_EXT_OP));
ret=accessAllowed(operationContainer);
}
- if(operation.getRequestOID().equals(OID_PROXIED_AUTH_V2) ||
- operation.getRequestOID().equals(OID_PROXIED_AUTH_V1))
- operation.
- setAttachment(ORIG_AUTH_ENTRY, operation.getAuthorizationEntry());
return ret;
}
- //Not planned to be implemented methods.
-
- /**
+ /**
* {@inheritDoc}
*/
@Override
- public boolean maySend(SearchOperation operation,
- SearchResultReference reference) {
- //TODO: Deferred.
- return true;
+ public boolean maySend(DN dn, SearchOperation operation,
+ SearchResultReference reference) {
+ boolean ret;
+ if(!(ret=skipAccessCheck(operation))) {
+ Entry e = new Entry(dn, null, null, null);
+ LinkedHashSet<AttributeValue> vals = new LinkedHashSet<AttributeValue>();
+ List<String> URLStrings=reference.getReferralURLs();
+ //Load the values, a bind rule might want to evaluate them.
+ for(String URLString : URLStrings) {
+ vals.add(new AttributeValue(refAttrType, URLString));
+ }
+ Attribute attr =
+ new Attribute(refAttrType, ATTR_REFERRAL_URL, vals);
+ e.addAttribute(attr,null);
+ SearchResultEntry se=new SearchResultEntry(e);
+ AciLDAPOperationContainer operationContainer =
+ new AciLDAPOperationContainer(operation,
+ (ACI_READ), se);
+ operationContainer.setCurrentAttributeType(refAttrType);
+ ret=accessAllowed(operationContainer);
+ }
+ return ret;
}
+
/**
* {@inheritDoc}
*/
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java
index 5cc1340..fc0b121 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java
@@ -46,10 +46,8 @@
import static org.opends.server.messages.MessageHandler.getMessage;
import org.opends.server.core.DirectoryServer;
import static org.opends.server.util.ServerConstants.*;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.LinkedList;
-import java.util.LinkedHashMap;
+
+import java.util.*;
/**
* The AciListenerManager updates an ACI list after each
@@ -216,6 +214,10 @@
InternalClientConnection conn =
InternalClientConnection.getRootConnection();
LinkedList<String>failedACIMsgs=new LinkedList<String>();
+ //Add manageDsaIT control so any ACIs in referral entries will be
+ //picked up.
+ ArrayList<Control> controls = new ArrayList<Control>(1);
+ controls.add(new Control(OID_MANAGE_DSAIT_CONTROL, true));
for (DN baseDN : backend.getBaseDNs()) {
try {
if (! backend.entryExists(baseDN)) {
@@ -233,7 +235,7 @@
conn,
InternalClientConnection.nextOperationID(),
InternalClientConnection.nextMessageID(),
- null, baseDN, SearchScope.WHOLE_SUBTREE,
+ controls, baseDN, SearchScope.WHOLE_SUBTREE,
DereferencePolicy.NEVER_DEREF_ALIASES,
0, 0, false, aciFilter, attrs, null);
LocalBackendSearchOperation localInternalSearch =
diff --git a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/DN2URI.java b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/DN2URI.java
index d432af7..cb2a7ca 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/DN2URI.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/backends/jeb/DN2URI.java
@@ -667,7 +667,7 @@
} while (status == OperationStatus.SUCCESS);
SearchResultReference reference = new SearchResultReference(URIList);
- if (!searchOp.returnReference(reference))
+ if (!searchOp.returnReference(dn, reference))
{
return false;
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/DefaultAccessControlHandler.java b/opendj-sdk/opends/src/server/org/opends/server/core/DefaultAccessControlHandler.java
index 1980fd6..40eadf2 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/DefaultAccessControlHandler.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/DefaultAccessControlHandler.java
@@ -216,7 +216,7 @@
* {@inheritDoc}
*/
@Override
- public boolean maySend(SearchOperation searchOperation,
+ public boolean maySend(DN dn, SearchOperation searchOperation,
SearchResultReference searchReference)
{
return true;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperation.java b/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperation.java
index 80fb4fa..6769aa2 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperation.java
@@ -258,13 +258,15 @@
* should be performed to potentially send it back to the client.
*
* @param reference The search reference to send to the client.
+ * @param dn The DN related to the specified search reference.
*
* @return <CODE>true</CODE> if the caller should continue processing the
* search request and sending additional entries and references , or
* <CODE>false</CODE> if not for some reason (e.g., the size limit
* has been reached or the search has been abandoned).
*/
- public abstract boolean returnReference(SearchResultReference reference);
+ public abstract boolean returnReference(DN dn,
+ SearchResultReference reference);
/**
* Sends the search result done message to the client. Note that this method
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java b/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java
index d95e942..69f0534 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java
@@ -1040,7 +1040,7 @@
/**
* {@inheritDoc}
*/
- public final boolean returnReference(SearchResultReference reference)
+ public final boolean returnReference(DN dn, SearchResultReference reference)
{
// See if the operation has been abandoned. If so, then don't send the
// reference and indicate that the search should end.
@@ -1073,7 +1073,7 @@
// See if the client has permission to read this reference.
if (AccessControlConfigManager.getInstance()
- .getAccessControlHandler().maySend(this, reference) == false) {
+ .getAccessControlHandler().maySend(dn, this, reference) == false) {
return true;
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationWrapper.java b/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationWrapper.java
index 0673335..6246a26 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationWrapper.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationWrapper.java
@@ -76,9 +76,9 @@
/**
* {@inheritDoc}
*/
- public boolean returnReference(SearchResultReference reference)
+ public boolean returnReference(DN dn, SearchResultReference reference)
{
- return search.returnReference(reference);
+ return search.returnReference(dn, reference);
}
/**
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/operation/PreOperationSearchOperation.java b/opendj-sdk/opends/src/server/org/opends/server/types/operation/PreOperationSearchOperation.java
index db145f8..16d1044 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/operation/PreOperationSearchOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/operation/PreOperationSearchOperation.java
@@ -175,6 +175,8 @@
/**
* Returns the provided search result reference to the client.
*
+ * @param dn A DN related to the specified search
+ * reference.
* @param reference The search reference that should be returned.
*
* @return {@code true} if the caller should continue processing
@@ -183,6 +185,7 @@
* (e.g., the size limit has been reached or the search has
* been abandoned).
*/
- public boolean returnReference(SearchResultReference reference);
+ public boolean
+ returnReference(DN dn ,SearchResultReference reference);
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/types/operation/PreParseSearchOperation.java b/opendj-sdk/opends/src/server/org/opends/server/types/operation/PreParseSearchOperation.java
index c25f1a5..5284d17 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/types/operation/PreParseSearchOperation.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/types/operation/PreParseSearchOperation.java
@@ -31,14 +31,7 @@
import java.util.LinkedHashSet;
import java.util.List;
-import org.opends.server.types.ByteString;
-import org.opends.server.types.Control;
-import org.opends.server.types.DereferencePolicy;
-import org.opends.server.types.Entry;
-import org.opends.server.types.RawFilter;
-import org.opends.server.types.SearchResultReference;
-import org.opends.server.types.SearchScope;
-
+import org.opends.server.types.*;
/**
@@ -234,6 +227,8 @@
* Returns the provided search result reference to the client.
*
* @param reference The search reference that should be returned.
+ * @param dn A DN related to the specified search
+ * reference.
*
* @return {@code true} if the caller should continue processing
* the search request and sending additional entries and
@@ -241,6 +236,7 @@
* (e.g., the size limit has been reached or the search has
* been abandoned).
*/
- public boolean returnReference(SearchResultReference reference);
+ public boolean
+ returnReference(DN dn, SearchResultReference reference);
}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java
index 1244306..3240d8b 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java
@@ -49,7 +49,8 @@
public static final String filter = "(objectclass=*)";
public static final String ACCESS_HANDLER_DN =
"cn=Access Control Handler,cn=config";
-
+ public static final String refURL=
+ "ldap://kansashost/OU=People,O=Kansas,C=US";
//GLOBAL ACIs
protected final static String G_READ_ACI =
@@ -227,9 +228,11 @@
argList.add("-s");
argList.add("sub");
argList.add(filter);
- String[] attrs=attr.split("\\s+");
- for(String a : attrs)
- argList.add(a);
+ if(attr != null) {
+ String[] attrs=attr.split("\\s+");
+ for(String a : attrs)
+ argList.add(a);
+ }
String[] args = new String[argList.size()];
oStream.reset();
int retVal =
@@ -253,6 +256,12 @@
_LDIFModify(ldif, bindDn, bindPassword, null, false, -1);
}
+ protected void LDIFModify(String ldif, String bindDn, String bindPassword,
+ String ctrlString)
+ throws Exception {
+ _LDIFModify(ldif, bindDn, bindPassword, ctrlString, false, -1);
+ }
+
protected void LDIFDelete(String dn, String bindDn, String bindPassword,
String controlStr, int rc) {
_LDIFDelete(dn, bindDn, bindPassword, controlStr, rc);
@@ -413,26 +422,26 @@
}
- protected void addEntries() throws Exception {
+ protected void addEntries(String suffix) throws Exception {
TestCaseUtils.initializeTestBackend(true);
TestCaseUtils.addEntries(
- "dn: ou=People,o=test",
+ "dn: ou=People," + suffix,
"objectClass: top",
"objectClass: organizationalUnit",
"ou: People",
"",
- "dn: ou=admins,o=test",
+ "dn: ou=admins," + suffix ,
"objectClass: top",
"objectClass: organizationalUnit",
"ou: admins",
"",
- "dn: cn=group,ou=People,o=test",
+ "dn: cn=group,ou=People," + suffix,
"objectclass: top",
"objectclass: groupOfNames",
"cn: group",
- "member: uid=user.3,ou=People,o=test",
+ "member: uid=user.3,ou=People," + suffix,
"",
- "dn: uid=superuser,ou=admins,o=test",
+ "dn: uid=superuser,ou=admins," + suffix,
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
@@ -444,7 +453,7 @@
"userPassword: password",
"ds-privilege-name: proxied-auth",
"",
- "dn: uid=proxyuser,ou=admins,o=test",
+ "dn: uid=proxyuser,ou=admins," + suffix,
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
@@ -455,7 +464,21 @@
"cn: User 1",
"userPassword: password",
"",
- "dn: uid=user.1,ou=People,o=test",
+ "dn: uid=smart referral admin,uid=proxyuser,ou=admins," + suffix,
+ "objectClass: top",
+ "objectClass: extensibleobject",
+ "objectClass: referral",
+ "ref:" + refURL,
+ "ref: ldap://texashost/OU=People,O=Texas,C=US",
+ "",
+ "dn: uid=smart referral people,ou=people," + suffix,
+ "objectClass: top",
+ "objectClass: extensibleobject",
+ "objectClass: referral",
+ "ref:" + refURL,
+ "ref: ldap://texashost/OU=People,O=Texas,C=US",
+ "",
+ "dn: uid=user.1,ou=People," + suffix,
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
@@ -465,10 +488,10 @@
"sn: 1",
"cn: User1",
"l: Austin",
- "manager: cn=group,ou=People,o=test",
+ "manager: cn=group,ou=People," + suffix,
"userPassword: password",
"",
- "dn: uid=user.2,ou=People,o=test",
+ "dn: uid=user.2,ou=People," + suffix,
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
@@ -480,7 +503,7 @@
"l: dallas",
"userPassword: password",
"",
- "dn: uid=user.3,ou=People,o=test",
+ "dn: uid=user.3,ou=People," + suffix,
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
@@ -493,7 +516,7 @@
"userPassword: password",
"ds-privilege-name: proxied-auth",
"",
- "dn: uid=user.4,ou=People,o=test",
+ "dn: uid=user.4,ou=People," + suffix,
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
@@ -505,7 +528,7 @@
"l: ft worth",
"userPassword: password",
"",
- "dn: uid=user.5,ou=People,o=test",
+ "dn: uid=user.5,ou=People," + suffix,
"objectClass: top",
"objectClass: person",
"objectClass: organizationalPerson",
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AlternateRootDN.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AlternateRootDN.java
index dbf633d..1485019 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AlternateRootDN.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AlternateRootDN.java
@@ -72,7 +72,7 @@
public void setupClass() throws Exception {
TestCaseUtils.startServer();
deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
- addEntries();
+ addEntries("o=test");
addRootEntry();
}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/ExtOpTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/ExtOpTestCase.java
index 3843231..05473db 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/ExtOpTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/ExtOpTestCase.java
@@ -120,7 +120,7 @@
public void setupClass() throws Exception {
TestCaseUtils.startServer();
deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
- addEntries();
+ addEntries("o=test");
}
@AfterClass
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/GetEffectiveRightsTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/GetEffectiveRightsTestCase.java
index c7fa970..101c274 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/GetEffectiveRightsTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/GetEffectiveRightsTestCase.java
@@ -165,7 +165,7 @@
public void setupClass() throws Exception {
TestCaseUtils.startServer();
deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
- addEntries();
+ addEntries("o=test");
}
@AfterClass
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/ReferencesTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/ReferencesTestCase.java
new file mode 100644
index 0000000..1b6975c
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/ReferencesTestCase.java
@@ -0,0 +1,214 @@
+/*
+ * 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.authorization.dseecompat;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.opends.server.TestCaseUtils;
+import static org.opends.server.util.ServerConstants.OID_MANAGE_DSAIT_CONTROL;
+import static org.opends.server.config.ConfigConstants.ATTR_AUTHZ_GLOBAL_ACI;
+
+import java.util.HashMap;
+import java.io.StringReader;
+import java.io.BufferedReader;
+import java.io.IOException;
+
+
+/**
+ * Unit test to test ACI behavior and Named Subordinate References (RFC 3296).
+ * This test needs a jeb backend, the memory backend cannot be used.
+ */
+
+public class ReferencesTestCase extends AciTestCase{
+ private static String suffix="dc=example,dc=com";
+ private static final String level5User="uid=user.5,ou=People," + suffix;
+ private static final String adminBase="ou=Admins," + suffix;
+ private static final String peopleBase="ou=people," + suffix;
+ private static final String smartReferralAdmin=
+ "uid=smart referral admin,uid=proxyuser,ou=admins," + suffix;
+ private static final String ctrlString = OID_MANAGE_DSAIT_CONTROL + ":false";
+
+ //Allow based on plus operator.
+ private static final
+ String ALLOW_OC_PLUS = "(targetattr=\"objectclass || +\")" +
+ "(version 3.0;acl \"plus\";" +
+ "allow (search, read) " +
+ "userdn=\"ldap:///" + level5User + "\";)";
+
+ //Allow based on ref name.
+ private static final
+ String ALLOW_OC = "(targetattr=\"objectclass || ref\")" +
+ "(version 3.0;acl \"ref name\";" +
+ "allow (search, read) " +
+ "userdn=\"ldap:///" + level5User + "\";)";
+
+ //Allow based on target keyword.
+ private static final
+ String ALLOW_PEOPLE =
+ "(target=\"ldap:///" + peopleBase + "\")" +
+ "(targetattr=\"objectclass || ref\")" +
+ "(version 3.0;acl \"target\";" +
+ "allow (search, read) " +
+ "userdn=\"ldap:///" + level5User + "\";)";
+
+ @BeforeClass
+ public void setupClass() throws Exception {
+ TestCaseUtils.startServer();
+ deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
+ TestCaseUtils.clearJEBackend(true,"userRoot", suffix);
+ addEntries(suffix);
+ }
+
+ @AfterClass
+ public void tearDown() throws Exception {
+ String aciLdif=makeAddLDIF(ATTR_AUTHZ_GLOBAL_ACI, ACCESS_HANDLER_DN,
+ G_READ_ACI, G_SELF_MOD, G_SCHEMA, G_DSE, G_USER_OPS, G_CONTROL,
+ E_EXTEND_OP);
+ LDIFModify(aciLdif, DIR_MGR_DN, PWD);
+ TestCaseUtils.clearJEBackend(false,"userRoot", suffix);
+ }
+
+ @BeforeMethod
+ public void clearBackend() throws Exception {
+ deleteAttrFromEntry(adminBase, "aci");
+ deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
+ }
+
+ /**
+ * Test using ACI added to admin base containing "ref" attribute type name
+ * specified in targetattr keword.
+ *
+ * @throws Exception If results are unexpected.
+ */
+ @Test()
+ public void testRef() throws Exception {
+ String pwdLdifs =
+ makeAddLDIF("aci", adminBase, ALLOW_OC);
+
+ LDIFModify(pwdLdifs, DIR_MGR_DN, PWD);
+ String userResults =
+ LDAPSearchParams(level5User, PWD, null,null, null,
+ adminBase, filter, null);
+ Assert.assertTrue(isRefMap(userResults));
+ }
+
+ /**
+ * Test using ACI added to actual referral entry (added using ldifmodify
+ * passing manageDsaIT control).
+ *
+ * @throws Exception If results are unexpected.
+ */
+ @Test()
+ public void testRefAci() throws Exception {
+ String pwdLdifs =
+ makeAddLDIF("aci", smartReferralAdmin, ALLOW_OC);
+ //Add the ACI passing the manageDsaIT control.
+ LDIFModify(pwdLdifs, DIR_MGR_DN, PWD, ctrlString);
+ String userResults =
+ LDAPSearchParams(level5User, PWD, null,null, null,
+ adminBase, filter, null);
+ Assert.assertTrue(isRefMap(userResults));
+ }
+
+
+
+ /**
+ * Test global ACI allowing the "ref" attribute type to be returned only if
+ * if the search is under the people base. A search under the admin base
+ * should not return a reference.
+ *
+ * @throws Exception If an unexpected result is returned.
+ */
+ @Test()
+ public void testGlobalTargetAci() throws Exception {
+ String pwdLdifs =
+ makeAddLDIF(ATTR_AUTHZ_GLOBAL_ACI, ACCESS_HANDLER_DN, ALLOW_PEOPLE);
+ LDIFModify(pwdLdifs, DIR_MGR_DN, PWD);
+ //Fail, ACI only allows people references
+ String userResults =
+ LDAPSearchParams(level5User, PWD, null,null, null,
+ adminBase, filter, null);
+ Assert.assertFalse(isRefMap(userResults));
+ //Pass, ACI allows people references
+ String userResults1 =
+ LDAPSearchParams(level5User, PWD, null,null, null,
+ peopleBase, filter, null);
+ Assert.assertTrue(isRefMap(userResults1));
+ }
+
+
+
+ /**
+ * Test global ACI allowing the "ref" attribute type specifed by the
+ * plus operator.
+ *
+ * @throws Exception If an unexpected result us returned.
+ */
+ @Test()
+ public void testGlobalAci() throws Exception {
+ String pwdLdifs =
+ makeAddLDIF(ATTR_AUTHZ_GLOBAL_ACI, ACCESS_HANDLER_DN, ALLOW_OC_PLUS);
+ LDIFModify(pwdLdifs, DIR_MGR_DN, PWD);
+ String userResults =
+ LDAPSearchParams(level5User, PWD, null,null, null,
+ adminBase, filter, null);
+ Assert.assertTrue(isRefMap(userResults));
+ }
+
+
+ /**
+ * Simple function that searches for the "SearchReference" string and returns
+ * true if it is seen.
+ *
+ * @param resultString The string containing the results from the search.
+ * @return True if the "SearchReference" string is seen in the results.
+ */
+ protected boolean
+ isRefMap(String resultString) {
+ boolean ret=false;
+ StringReader r=new StringReader(resultString);
+ BufferedReader br=new BufferedReader(r);
+ try {
+ while(true) {
+ String s = br.readLine();
+ if(s == null)
+ break;
+ if(s.startsWith("SearchReference")) {
+ ret=true;
+ break;
+ }
+ }
+ } catch (IOException e) {
+ Assert.assertEquals(0, 1, e.getMessage());
+ }
+ return ret;
+ }
+}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java
index 73c6a75..aa4a0fa 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java
@@ -124,7 +124,7 @@
public void setupClass() throws Exception {
TestCaseUtils.startServer();
deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
- addEntries();
+ addEntries("o=test");
}
@AfterClass
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetControlTestCase.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetControlTestCase.java
index 2ff7888..e2b13a4 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetControlTestCase.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetControlTestCase.java
@@ -63,7 +63,7 @@
public void setupClass() throws Exception {
TestCaseUtils.startServer();
deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
- addEntries();
+ addEntries("o=test");
}
@AfterClass
--
Gitblit v1.10.0