From 5c703f3851c86aacbcbcfd5cb216d84da4a204c3 Mon Sep 17 00:00:00 2001
From: dugan <dugan@localhost>
Date: Thu, 17 May 2007 11:33:06 +0000
Subject: [PATCH] ACI fixes and unit tests for issues related to targetattr keyword and returning operational attributes.
---
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java | 166 ++++++++++
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargets.java | 20 +
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargetMatchContext.java | 33 ++
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/GetEffectiveRightsTestCase.java | 269 ----------------
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java | 5
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/Aci.java | 21 +
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java | 43 ++
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java | 50 ++-
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java | 300 ++++++++++++++++++
9 files changed, 614 insertions(+), 293 deletions(-)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/Aci.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/Aci.java
index b56d87b..bb665b4 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/Aci.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/Aci.java
@@ -250,6 +250,27 @@
public static final int TARGATTRFILTERS_DELETE = 0x2000;
/**
+ * ACI_ATTR_STAR_MATCHED is the flag set when the evaluation reason of a
+ * AciHandler.maysend ACI_READ access evaluation was the result of an
+ * ACI targetattr all attributes expression (targetattr="*") target match.
+ * For this flag to be set, there must be only one ACI matching.
+ *
+ * This flag and ACI_FOUND_ATTR_RULE are used in the
+ * AciHandler.filterEntry.accessAllowedAttrs method to skip access
+ * evaluation if the flag is ACI_ATTR_STAR_MATCHED (all attributes match)
+ * and the attribute type is not operational.
+ */
+ public static final int ACI_ATTR_STAR_MATCHED = 0x0008;
+
+ /**
+ * ACI_FOUND_ATTR_RULE is the flag set when the evaluation reason of a
+ * AciHandler.maysend ACI_READ access evaluation was the result of an
+ * ACI targetattr specific attribute expression
+ * (targetattr="some attribute type") target match.
+ */
+ public static final int ACI_FOUND_ATTR_RULE = 0x0010;
+
+ /**
* ACI_NULL is used to set the container rights to all zeros. Used
* by LDAP modify.
*/
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java
index 495212b..71e208a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java
@@ -101,6 +101,12 @@
* The entry being evaluated (resource entry).
*/
private Entry resourceEntry;
+
+ /*
+ * Saves the resource entry. Used in geteffectiverights evaluation to
+ * restore the current resource entry state after a read right was
+ * evaluated.
+ */
private Entry saveResourceEntry;
/*
@@ -225,6 +231,11 @@
*/
private String summaryString=null;
+ /*
+ * Flag used to determine if ACI all attributes target matched.
+ */
+ private int evalAllAttributes=0;
+
/**
* This constructor is used by all currently supported LDAP operations.
*
@@ -265,6 +276,9 @@
this.specificAttrs=getEffectiveRightsControl.getAttributes();
fullEntry=(Entry)operation.getAttachment(ALL_ATTRS_RESOURCE_ENTRY);
}
+ String allAttrs=(String)operation.getAttachment(ALL_ATTRS_MATCHED);
+ if(allAttrs != null)
+ evalAllAttributes = ACI_ATTR_STAR_MATCHED;
}
//Reference the current authorization entry, so it can be put back
//if an access proxy check was performed.
@@ -791,4 +805,33 @@
return "selfwrite";
return null;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setACIEvalAttributesRule(int v) {
+ if(operation instanceof SearchOperation && (rights == ACI_READ)) {
+ if(v == ACI_FOUND_ATTR_RULE) {
+ evalAllAttributes |= ACI_FOUND_ATTR_RULE;
+ evalAllAttributes &= ~ACI_ATTR_STAR_MATCHED;
+ } else
+ evalAllAttributes |= Aci.ACI_ATTR_STAR_MATCHED;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasACIEvalAttributes() {
+ return (evalAllAttributes == 0) ||
+ (evalAllAttributes & ACI_FOUND_ATTR_RULE) == ACI_FOUND_ATTR_RULE;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void clearACIEvalAttributesRule(int v) {
+ evalAllAttributes &= ~v;
+ }
}
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 fc4d426..7521308 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
@@ -85,6 +85,13 @@
public static String ALL_ATTRS_RESOURCE_ENTRY = "allAttrsResourceEntry";
/**
+ * String used to indicate that the evaluating ACI had a all attributes
+ * targetattr match (targetattr="*").
+ */
+ public static String ALL_ATTRS_MATCHED = "allAttrsMatched";
+
+
+ /**
* This constructor instantiates the ACI handler class that performs the
* main processing for the dseecompat ACI package. It does the following
* initializations:
@@ -556,16 +563,16 @@
return ret;
}
- /**
- * Check if the specified attribute type is a DN by checking if its syntax
- * OID is equal to the DN syntax OID.
- * @param attribute The attribute type to check.
- * @return True if the attribute type syntax OID is equal to a DN syntax OID.
- */
- private boolean isAttributeDN(AttributeType attribute) {
- return (attribute.getSyntaxOID().equals(SYNTAX_DN_OID));
- }
-
+ /**
+ * Check if the specified attribute type is a DN by checking if its syntax
+ * OID is equal to the DN syntax OID.
+ * @param attribute The attribute type to check.
+ * @return True if the attribute type syntax OID is equal to a DN syntax
+ * OID.
+ */
+ private boolean isAttributeDN(AttributeType attribute) {
+ return (attribute.getSyntaxOID().equals(SYNTAX_DN_OID));
+ }
/**
* Performs an access check against all of the attributes of an entry.
@@ -579,15 +586,17 @@
*/
private SearchResultEntry
accessAllowedAttrs(AciLDAPOperationContainer container) {
- Entry e=container.getResourceEntry();
- List<AttributeType> typeList=getAllAttrs(e);
- for(AttributeType attrType : typeList) {
- container.setCurrentAttributeType(attrType);
- if(!accessAllowed(container)) {
- e.removeAttribute(attrType);
- }
+ Entry e=container.getResourceEntry();
+ List<AttributeType> typeList=getAllAttrs(e);
+ for(AttributeType attrType : typeList) {
+ if(!container.hasACIEvalAttributes() && !attrType.isOperational())
+ continue;
+ container.setCurrentAttributeType(attrType);
+ if(!accessAllowed(container)) {
+ e.removeAttribute(attrType);
}
- return container.getSearchResultEntry();
+ }
+ return container.getSearchResultEntry();
}
/**
@@ -600,6 +609,8 @@
*/
private List<AttributeType> getAllAttrs(Entry e) {
Map<AttributeType,List<Attribute>> attrMap = e.getUserAttributes();
+ Map<AttributeType,List<Attribute>> opAttrMap =
+ e.getOperationalAttributes();
List<AttributeType> typeList=new LinkedList<AttributeType>();
Attribute attr=e.getObjectClassAttribute();
/*
@@ -611,6 +622,7 @@
typeList.add(ocType);
}
typeList.addAll(attrMap.keySet());
+ typeList.addAll(opAttrMap.keySet());
return typeList;
}
@@ -877,6 +889,8 @@
if (ret) {
operationContainer.setRights(ACI_READ);
ret=accessAllowedEntry(operationContainer);
+ if(ret && !operationContainer.hasACIEvalAttributes())
+ operation.setAttachment(ALL_ATTRS_MATCHED, ALL_ATTRS_MATCHED);
}
}
if(ret && operation.getAttachment(OID_GET_EFFECTIVE_RIGHTS) != null)
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargetMatchContext.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargetMatchContext.java
index 3ccb74b..f70e3bb 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargetMatchContext.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargetMatchContext.java
@@ -165,6 +165,39 @@
* @return True if a match context is evaluating geteffectiverights.
*/
boolean isGetEffectiveRightsEval();
+
+ /**
+ * This method toggles a mask that indicates that access checking of
+ * individual non-operational attributes may or may not be skipped depending
+ * on if there is a single ACI containing a targetattr all attributes rule
+ * (targetattr="*").
+ *
+ * The only case where individual non-operational attribute access checking
+ * can be skipped, is when a single ACI matched using a targetattr
+ * all attributes rule.
+ *
+ * @param v The flag to set the mask to.
+ */
+ void setACIEvalAttributesRule(int v);
+
+ /**
+ * Return true if the evaluating ACI either contained an explicitly defined
+ * attribute type in a targeattr target rule or both a targetattr all
+ * attributes rule matched and a explictly defined targetattr target rule
+ * matched.
+ *
+ * @return True if the above condition was seen.
+ */
+ boolean hasACIEvalAttributes();
+
+
+ /**
+ * Used to clear the mask used to detect if access checking needs to be
+ * performed on individual non-operational attributes types.
+ *
+ * @param v The flag to clear (always ACI_ATTR_STAR_MATCHED)
+ */
+ public void clearACIEvalAttributesRule(int v);
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargets.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargets.java
index 8fd9d7b..d7d212d 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargets.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargets.java
@@ -411,9 +411,23 @@
AttributeType a=targetMatchCtx.getCurrentAttributeType();
int rights=targetMatchCtx.getRights();
boolean isFirstAttr=targetMatchCtx.isFirstAttribute();
- if((a != null) && (targets.getTargetAttr() != null))
- ret=TargetAttr.isApplicable(a, targets.getTargetAttr());
- else if((a != null) || (targets.getTargetAttr() != null)) {
+ if((a != null) && (targets.getTargetAttr() != null)) {
+ ret=TargetAttr.isApplicable(a,targets.getTargetAttr());
+ targetMatchCtx.clearACIEvalAttributesRule(ACI_ATTR_STAR_MATCHED);
+ /*
+ If a explicitly defined targetattr's match rule has not
+ been seen (~ACI_FOUND_ATTR_RULE) and the current attribute type
+ is applicable because of a targetattr all attributes rule match,
+ set a flag to indicate this situation (ACI_ATTR_STAR_MATCHED).
+ Else the attributes is applicable because it is operational or
+ not a targetattr's all attribute match.
+ */
+ if(ret && targets.getTargetAttr().isAllAttributes() &&
+ !targetMatchCtx.hasACIEvalAttributes())
+ targetMatchCtx.setACIEvalAttributesRule(ACI_ATTR_STAR_MATCHED);
+ else
+ targetMatchCtx.setACIEvalAttributesRule(ACI_FOUND_ATTR_RULE);
+ } else if((a != null) || (targets.getTargetAttr() != null)) {
if((aci.hasRights(skipRights)) &&
(skipRightsHasRights(rights)))
ret=true;
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java
index ea6b303..632f9c9 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java
@@ -178,7 +178,6 @@
*/
public EnumEvalResult evaluate(AciEvalContext evalCtx) {
EnumEvalResult matched;
- boolean undefined=false;
switch(userAttrType) {
case ROLEDN:
@@ -194,9 +193,7 @@
default:
matched=evalVAL(evalCtx);
}
- if(matched == EnumEvalResult.ERR)
- undefined=true;
- return matched.getRet(type, undefined);
+ return matched;
}
/** Evaluate a VALUE userattr type. Look in client entry for an
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
new file mode 100644
index 0000000..5d6d9c7
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java
@@ -0,0 +1,300 @@
+/*
+ * 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.opends.server.DirectoryServerTestCase;
+import org.opends.server.TestCaseUtils;
+import org.opends.server.tools.LDAPModify;
+import org.opends.server.tools.LDAPSearch;
+import static org.opends.server.util.ServerConstants.EOL;
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+import java.io.*;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
+
+@Test(groups = { "precommit", "dseecompat" })
+public abstract class AciTestCase extends DirectoryServerTestCase {
+ public static final String DIR_MGR_DN = "cn=Directory Manager";
+ public static final String PWD = "password";
+ public static final String filter = "(objectclass=*)";
+ public static final String ACCESS_HANDLER_DN =
+ "cn=Access Control Handler,cn=config";
+
+ private static ByteArrayOutputStream oStream = new ByteArrayOutputStream();
+ private static ThreadLocal<Map<String,File>> tempLdifFile =
+ new ThreadLocal<Map<String,File>>();
+
+ protected String LDAPSearchCtrl(String bindDn, String bindPassword,
+ String proxyDN, String controlStr,
+ String base, String filter, String attr)
+ throws Exception {
+ ArrayList<String> argList=new ArrayList<String>(20);
+ argList.add("-h");
+ argList.add("127.0.0.1");
+ argList.add("-p");
+ argList.add(String.valueOf(TestCaseUtils.getServerLdapPort()));
+ argList.add("-D");
+ argList.add(bindDn);
+ argList.add("-w");
+ argList.add(bindPassword);
+ argList.add("-T");
+ if(proxyDN != null) {
+ argList.add("-Y");
+ argList.add("dn:" + proxyDN);
+ }
+ if(controlStr != null) {
+ argList.add("-J");
+ argList.add(controlStr);
+ }
+ argList.add("-b");
+ argList.add(base);
+ argList.add("-s");
+ argList.add("sub");
+ argList.add(filter);
+ String[] attrs=attr.split("\\s+");
+ for(String a : attrs)
+ argList.add(a);
+ String[] args = new String[argList.size()];
+ oStream.reset();
+ int retVal =
+ LDAPSearch.mainSearch(argList.toArray(args), false, oStream, oStream);
+ Assert.assertEquals(0, retVal, "Returned error: " + oStream.toString());
+ return oStream.toString();
+ }
+
+ protected String LDAPSearchParams(String bindDn, String bindPassword,
+ String proxyDN, String authzid, String[] attrList,
+ String base, String filter ,String attr)
+ throws Exception {
+ ArrayList<String> argList=new ArrayList<String>(20);
+ argList.add("-h");
+ argList.add("127.0.0.1");
+ argList.add("-p");
+ argList.add(String.valueOf(TestCaseUtils.getServerLdapPort()));
+ argList.add("-D");
+ argList.add(bindDn);
+ argList.add("-w");
+ argList.add(bindPassword);
+ argList.add("-T");
+ if(proxyDN != null) {
+ argList.add("-Y");
+ argList.add("dn:" + proxyDN);
+ }
+ if(authzid != null) {
+ argList.add("-g");
+ argList.add(authzid);
+ }
+ if(attrList != null) {
+ for(String a : attrList) {
+ argList.add("-e");
+ argList.add(a);
+ }
+ }
+ argList.add("-b");
+ argList.add(base);
+ argList.add("-s");
+ argList.add("sub");
+ argList.add(filter);
+ String[] attrs=attr.split("\\s+");
+ for(String a : attrs)
+ argList.add(a);
+ String[] args = new String[argList.size()];
+ oStream.reset();
+ int retVal =
+ LDAPSearch.mainSearch(argList.toArray(args), false, oStream, oStream);
+ Assert.assertEquals(0, retVal, "Returned error: " + oStream.toString());
+ return oStream.toString();
+ }
+
+ protected void modEntries(String ldif, String bindDn, String bindPassword)
+ throws Exception {
+ File tempFile = getTemporaryLdifFile();
+ TestCaseUtils.writeFile(tempFile, ldif);
+ ArrayList<String> argList=new ArrayList<String>(20);
+ argList.add("-h");
+ argList.add("127.0.0.1");
+ argList.add("-p");
+ argList.add(String.valueOf(TestCaseUtils.getServerLdapPort()));
+ argList.add("-D");
+ argList.add(bindDn);
+ argList.add("-w");
+ argList.add(bindPassword);
+ argList.add("-f");
+ argList.add(tempFile.getAbsolutePath());
+ String[] args = new String[argList.size()];
+ ldapModify(argList.toArray(args));
+ }
+
+ protected void ldapModify(String[] args) {
+ oStream.reset();
+ LDAPModify.mainModify(args, false, oStream, oStream);
+ }
+
+ protected void deleteAttrFromEntry(String dn, String attr)
+ throws Exception {
+ StringBuilder ldif = new StringBuilder();
+ ldif.append(TestCaseUtils.makeLdif(
+ "dn: " + dn,
+ "changetype: modify",
+ "delete: " + attr));
+ modEntries(ldif.toString(), DIR_MGR_DN, PWD);
+ }
+
+ protected static String makeAddAciLdif(String attr, String dn, String... acis) {
+ StringBuilder ldif = new StringBuilder();
+ ldif.append("dn: ").append(dn).append(EOL);
+ ldif.append("changetype: modify").append(EOL);
+ ldif.append("add: ").append(attr).append(EOL);
+ for(String aci : acis)
+ ldif.append(attr).append(":").append(aci).append(EOL);
+ ldif.append(EOL);
+ return ldif.toString();
+ }
+
+ protected File getTemporaryLdifFile() throws IOException {
+ Map<String,File> tempFilesForThisThread = tempLdifFile.get();
+ if (tempFilesForThisThread == null) {
+ tempFilesForThisThread = new HashMap<String,File>();
+ tempLdifFile.set(tempFilesForThisThread);
+ }
+ File tempFile = tempFilesForThisThread.get("effectiverights-tests");
+ if (tempFile == null) {
+ tempFile = File.createTempFile("effectiverights-tests", ".ldif");
+ tempFile.deleteOnExit();
+ tempFilesForThisThread.put("effectiverights-tests", tempFile);
+ }
+ return tempFile;
+ }
+
+ protected void addEntries() throws Exception {
+ TestCaseUtils.initializeTestBackend(true);
+ TestCaseUtils.addEntries(
+ "dn: ou=People,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: People",
+ "",
+ "dn: ou=admins,o=test",
+ "objectClass: top",
+ "objectClass: organizationalUnit",
+ "ou: admins",
+ "",
+ "dn: cn=group,ou=People,o=test",
+ "objectclass: top",
+ "objectclass: groupOfNames",
+ "cn: group",
+ "member: uid=user.1,ou=People,o=test",
+ "",
+ "dn: uid=superuser,ou=admins,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: superuser",
+ "givenName: superuser",
+ "sn: 1",
+ "cn: User 1",
+ "userPassword: password",
+ "ds-privilege-name: proxied-auth",
+ "",
+ "dn: uid=proxyuser,ou=admins,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: proxyuser",
+ "givenName: proxyuser",
+ "sn: 1",
+ "cn: User 1",
+ "userPassword: password",
+ "",
+ "dn: uid=user.1,ou=People,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: user.1",
+ "givenName: User 1",
+ "sn: 1",
+ "cn: User1",
+ "l: Austin",
+ "userPassword: password",
+ "",
+ "dn: uid=user.2,ou=People,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: user.2",
+ "givenName: User 2",
+ "sn: 2",
+ "cn: User 2",
+ "l: dallas",
+ "userPassword: password",
+ "",
+ "dn: uid=user.3,ou=People,o=test",
+ "objectClass: top",
+ "objectClass: person",
+ "objectClass: organizationalPerson",
+ "objectClass: inetOrgPerson",
+ "uid: user.3",
+ "givenName: User 3",
+ "sn: 3",
+ "mail: user.3@test",
+ "description: user.3 description",
+ "cn: User 3",
+ "l: Austin",
+ "userPassword: password");
+ }
+
+ protected HashMap<String, String>
+ getAttrMap(String resultString) throws Exception {
+ StringReader r=new StringReader(resultString);
+ BufferedReader br=new BufferedReader(r);
+ HashMap<String, String> attrMap = new HashMap<String,String>();
+ try {
+ while(true) {
+ String s = br.readLine();
+ if(s == null)
+ break;
+ if(s.startsWith("dn:"))
+ continue;
+ String[] a=s.split(": ");
+ if(a.length != 2)
+ break;
+ attrMap.put(a[0],a[1]);
+ }
+ } catch (IOException e) {
+ Assert.assertEquals(0, 1, e.getMessage());
+ }
+ return attrMap;
+ }
+}
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 4ae744c..80f36c2 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
@@ -32,26 +32,11 @@
import org.testng.annotations.BeforeMethod;
import static org.opends.server.config.ConfigConstants.*;
import org.testng.Assert;
-import static org.testng.Assert.assertEquals;
import org.opends.server.TestCaseUtils;
-import org.opends.server.types.AttributeType;
-import org.opends.server.types.Attribute;
-import org.opends.server.tools.LDAPSearch;
-import org.opends.server.tools.LDAPModify;
import static org.opends.server.util.ServerConstants.OID_GET_EFFECTIVE_RIGHTS;
-import static org.opends.server.util.ServerConstants.EOL;
-
-import java.io.*;
-import java.util.ArrayList;
-import java.util.Map;
import java.util.HashMap;
-import java.util.List;
-public class GetEffectiveRightsTestCase {
- private static ByteArrayOutputStream oStream = new ByteArrayOutputStream();
- private static final String DIR_MGR_DN = "cn=Directory Manager";
- private static final String PWD = "password";
- private static final String filter = "(objectclass=*)";
+public class GetEffectiveRightsTestCase extends AciTestCase {
private static final String base="uid=user.3,ou=People,o=test";
private static final String user1="uid=user.1,ou=People,o=test";
private static final String superUser="uid=superuser,ou=admins,o=test";
@@ -79,9 +64,6 @@
private static final
String allRights = "add:1,delete:1,read:1,write:1,proxy:1";
- private static final
- String ACCESS_HANDLER_DN = "cn=Access Control Handler,cn=config";
-
//Results for attributeLevel searches
private static final String srwMailAttrRights =
"search:1,read:1,compare:0,write:1," +
@@ -415,253 +397,4 @@
String retRightsStr=attrMap.get(entryLevel);
Assert.assertTrue(retRightsStr.equals(reqRightsStr));
}
-
- private HashMap<String, String>
- getAttrMap(String resultString) throws Exception {
- StringReader r=new StringReader(resultString);
- BufferedReader br=new BufferedReader(r);
- HashMap<String, String> attrMap = new HashMap<String,String>();
- try {
- while(true) {
- String s = br.readLine();
- if(s == null)
- break;
- if(s.startsWith("dn:"))
- continue;
- String[] a=s.split(": ");
- if(a.length != 2)
- break;
- attrMap.put(a[0],a[1]);
- }
- } catch (IOException e) {
- Assert.assertEquals(0, 1, e.getMessage());
- }
- return attrMap;
- }
-
-
- private void addEntries() throws Exception {
- TestCaseUtils.initializeTestBackend(true);
- TestCaseUtils.addEntries(
- "dn: ou=People,o=test",
- "objectClass: top",
- "objectClass: organizationalUnit",
- "ou: People",
- "",
- "dn: ou=admins,o=test",
- "objectClass: top",
- "objectClass: organizationalUnit",
- "ou: admins",
- "",
- "dn: cn=group,ou=People,o=test",
- "objectclass: top",
- "objectclass: groupOfNames",
- "cn: group",
- "member: uid=user.1,ou=People,o=test",
- "",
- "dn: uid=superuser,ou=admins,o=test",
- "objectClass: top",
- "objectClass: person",
- "objectClass: organizationalPerson",
- "objectClass: inetOrgPerson",
- "uid: superuser",
- "givenName: superuser",
- "sn: 1",
- "cn: User 1",
- "userPassword: password",
- "ds-privilege-name: proxied-auth",
- "",
- "dn: uid=proxyuser,ou=admins,o=test",
- "objectClass: top",
- "objectClass: person",
- "objectClass: organizationalPerson",
- "objectClass: inetOrgPerson",
- "uid: proxyuser",
- "givenName: proxyuser",
- "sn: 1",
- "cn: User 1",
- "userPassword: password",
- "",
- "dn: uid=user.1,ou=People,o=test",
- "objectClass: top",
- "objectClass: person",
- "objectClass: organizationalPerson",
- "objectClass: inetOrgPerson",
- "uid: user.1",
- "givenName: User",
- "sn: 1",
- "cn: User 1",
- "userPassword: password",
- "",
- "dn: uid=user.2,ou=People,o=test",
- "objectClass: top",
- "objectClass: person",
- "objectClass: organizationalPerson",
- "objectClass: inetOrgPerson",
- "uid: user.2",
- "givenName: User",
- "sn: 2",
- "cn: User 2",
- "userPassword: password",
- "",
- "dn: uid=user.3,ou=People,o=test",
- "objectClass: top",
- "objectClass: person",
- "objectClass: organizationalPerson",
- "objectClass: inetOrgPerson",
- "uid: user.3",
- "givenName: User",
- "sn: 3",
- "mail: user.3@test",
- "description: user.3 description",
- "cn: User 3",
- "userPassword: password");
- }
-
- private String LDAPSearchCtrl(String bindDn, String bindPassword,
- String proxyDN, String controlStr,
- String base, String filter, String attr)
- throws Exception {
- ArrayList<String> argList=new ArrayList<String>(20);
- argList.add("-h");
- argList.add("127.0.0.1");
- argList.add("-p");
- argList.add(String.valueOf(TestCaseUtils.getServerLdapPort()));
- argList.add("-D");
- argList.add(bindDn);
- argList.add("-w");
- argList.add(bindPassword);
- argList.add("-T");
- if(proxyDN != null) {
- argList.add("-Y");
- argList.add("dn:" + proxyDN);
- }
- if(controlStr != null) {
- argList.add("-J");
- argList.add(controlStr);
- }
- argList.add("-b");
- argList.add(base);
- argList.add("-s");
- argList.add("sub");
- argList.add(filter);
- String[] attrs=attr.split("\\s+");
- for(String a : attrs)
- argList.add(a);
- String[] args = new String[argList.size()];
- oStream.reset();
- int retVal =
- LDAPSearch.mainSearch(argList.toArray(args), false, oStream, oStream);
- Assert.assertEquals(0, retVal, "Returned error: " + oStream.toString());
- return oStream.toString();
- }
-
- private String LDAPSearchParams(String bindDn, String bindPassword,
- String proxyDN, String authzid, String[] attrList,
- String base, String filter ,String attr)
- throws Exception {
- ArrayList<String> argList=new ArrayList<String>(20);
- argList.add("-h");
- argList.add("127.0.0.1");
- argList.add("-p");
- argList.add(String.valueOf(TestCaseUtils.getServerLdapPort()));
- argList.add("-D");
- argList.add(bindDn);
- argList.add("-w");
- argList.add(bindPassword);
- argList.add("-T");
- if(proxyDN != null) {
- argList.add("-Y");
- argList.add("dn:" + proxyDN);
- }
- if(authzid != null) {
- argList.add("-g");
- argList.add(authzid);
- }
- if(attrList != null) {
- for(String a : attrList) {
- argList.add("-e");
- argList.add(a);
- }
- }
- argList.add("-b");
- argList.add(base);
- argList.add("-s");
- argList.add("sub");
- argList.add(filter);
- String[] attrs=attr.split("\\s+");
- for(String a : attrs)
- argList.add(a);
- String[] args = new String[argList.size()];
- oStream.reset();
- int retVal =
- LDAPSearch.mainSearch(argList.toArray(args), false, oStream, oStream);
- Assert.assertEquals(0, retVal, "Returned error: " + oStream.toString());
- return oStream.toString();
- }
-
-
- private void modEntries(String ldif, String bindDn, String bindPassword)
- throws Exception {
- File tempFile = getTemporaryLdifFile();
- TestCaseUtils.writeFile(tempFile, ldif);
- ArrayList<String> argList=new ArrayList<String>(20);
- argList.add("-h");
- argList.add("127.0.0.1");
- argList.add("-p");
- argList.add(String.valueOf(TestCaseUtils.getServerLdapPort()));
- argList.add("-D");
- argList.add(bindDn);
- argList.add("-w");
- argList.add(bindPassword);
- argList.add("-f");
- argList.add(tempFile.getAbsolutePath());
- String[] args = new String[argList.size()];
- ldapModify(argList.toArray(args));
- }
-
-
- private void ldapModify(String[] args) {
- oStream.reset();
- LDAPModify.mainModify(args, false, oStream, oStream);
- }
-
- private void deleteAttrFromEntry(String dn, String attr)
- throws Exception {
- StringBuilder ldif = new StringBuilder();
- ldif.append(TestCaseUtils.makeLdif(
- "dn: " + dn,
- "changetype: modify",
- "delete: " + attr));
- modEntries(ldif.toString(), DIR_MGR_DN, PWD);
- }
-
- private static ThreadLocal<Map<String,File>> tempLdifFile =
- new ThreadLocal<Map<String,File>>();
-
- private File getTemporaryLdifFile() throws IOException {
- Map<String,File> tempFilesForThisThread = tempLdifFile.get();
- if (tempFilesForThisThread == null) {
- tempFilesForThisThread = new HashMap<String,File>();
- tempLdifFile.set(tempFilesForThisThread);
- }
- File tempFile = tempFilesForThisThread.get("effectiverights-tests");
- if (tempFile == null) {
- tempFile = File.createTempFile("effectiverights-tests", ".ldif");
- tempFile.deleteOnExit();
- tempFilesForThisThread.put("effectiverights-tests", tempFile);
- }
- return tempFile;
- }
-
- private static String makeAddAciLdif(String attr, String dn, String... acis) {
- StringBuilder ldif = new StringBuilder();
- ldif.append("dn: ").append(dn).append(EOL);
- ldif.append("changetype: modify").append(EOL);
- ldif.append("add: ").append(attr).append(EOL);
- for(String aci : acis)
- ldif.append(attr).append(":").append(aci).append(EOL);
- ldif.append(EOL);
- return ldif.toString();
- }
}
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
new file mode 100644
index 0000000..da90cbd
--- /dev/null
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java
@@ -0,0 +1,166 @@
+/*
+ * 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.Test;
+import org.testng.Assert;
+import org.opends.server.TestCaseUtils;
+import static org.opends.server.config.ConfigConstants.*;
+
+import java.util.HashMap;
+
+public class TargetAttrTestCase extends AciTestCase {
+
+ private static String attrList="sn uid l";
+ private static String opAttrList="sn uid aci";
+ private static final String user1="uid=user.1,ou=People,o=test";
+ private static final String user3="uid=user.3,ou=People,o=test";
+ public static final String aciFilter = "(aci=*)";
+
+ private static final
+ String userAttrAci = "(targetattr=\"*\")" +
+ "(version 3.0;acl \"read/search userattr\";" +
+ "allow (search, read) " +
+ "userattr=\"l#Austin\";)";
+
+ private static final
+ String userAttrAci1 = "(targetattr=\"*\")" +
+ "(version 3.0;acl \"read/search userattr\";" +
+ "allow (search, read) " +
+ "userattr!=\"l#New York\";)";
+
+ private static final
+ String nonOpAttrAci = "(targetattr=\"*\")" +
+ "(version 3.0;acl \"read/search non-operational attr\";" +
+ "allow (search, read) " +
+ "userdn=\"ldap:///uid=user.3,ou=People,o=test\";)";
+
+ private static final
+ String opAttrAci = "(targetattr=\"aci\")" +
+ "(version 3.0;acl \"read/search operational attr\";" +
+ "allow (search, read) " +
+ "userdn=\"ldap:///uid=user.3,ou=People,o=test\";)";
+
+ @BeforeClass
+ public void setupClass() throws Exception {
+ TestCaseUtils.startServer();
+ deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
+ addEntries();
+ }
+
+ /**
+ * Test targetattr behavior using userattr bind rule.
+ *
+ * @throws Exception If a test result is unexpected.
+ */
+ @Test()
+ public void testTargetAttrUserAttr() throws Exception {
+ String aciLdif=makeAddAciLdif("aci", user1, userAttrAci);
+ modEntries(aciLdif, DIR_MGR_DN, PWD);
+ String userResults =
+ LDAPSearchParams(user3, PWD, null, null, null,
+ user1, filter, attrList);
+ Assert.assertFalse(userResults.equals(""));
+ HashMap<String, String> attrMap=getAttrMap(userResults);
+ checkAttributeVal(attrMap, "l", "Austin");
+ checkAttributeVal(attrMap, "sn", "1");
+ checkAttributeVal(attrMap, "uid", "user.1");
+ deleteAttrFromEntry(user1, "aci");
+ String aciLdif1=makeAddAciLdif("aci", user1, userAttrAci1);
+ modEntries(aciLdif1, DIR_MGR_DN, PWD);
+ String userResults1 =
+ LDAPSearchParams(user3, PWD, null, null, null,
+ user1, filter, attrList);
+ Assert.assertFalse(userResults1.equals(""));
+ HashMap<String, String> attrMap1=getAttrMap(userResults1);
+ checkAttributeVal(attrMap1, "l", "Austin");
+ checkAttributeVal(attrMap1, "sn", "1");
+ checkAttributeVal(attrMap1, "uid", "user.1");
+ deleteAttrFromEntry(user1, "aci");
+ }
+
+ /**
+ * Test targetattr and operational attribute behavior. See comments.
+ *
+ * @throws Exception If a test result is unexpected.
+ */
+ @Test()
+ public void testTargetAttrOpAttr() throws Exception {
+ //Add aci that only allows non-operational attributes search/read.
+ String aciLdif=makeAddAciLdif("aci", user1, nonOpAttrAci);
+ modEntries(aciLdif, DIR_MGR_DN, PWD);
+ String userResults =
+ LDAPSearchParams(user3, PWD, null, null, null,
+ user1, filter, opAttrList);
+ Assert.assertFalse(userResults.equals(""));
+ HashMap<String, String> attrMap=getAttrMap(userResults);
+ //The aci attribute type is operational, it should not be there.
+ //The other two should be there.
+ Assert.assertFalse(attrMap.containsKey("aci"));
+ Assert.assertTrue(attrMap.containsKey("sn"));
+ Assert.assertTrue(attrMap.containsKey("uid"));
+ deleteAttrFromEntry(user1, "aci");
+ //Add aci that allows both non-operational attributes and the operational
+ //attribute "aci" search/read.
+ String aciLdif1=makeAddAciLdif("aci", user1, nonOpAttrAci, opAttrAci);
+ modEntries(aciLdif1, DIR_MGR_DN, PWD);
+ String userResults1 =
+ LDAPSearchParams(user3, PWD, null, null, null,
+ user1, filter, opAttrList);
+ Assert.assertFalse(userResults1.equals(""));
+ HashMap<String, String> attrMap1=getAttrMap(userResults1);
+ //All three attributes should be there.
+ Assert.assertTrue(attrMap1.containsKey("aci"));
+ Assert.assertTrue(attrMap1.containsKey("sn"));
+ Assert.assertTrue(attrMap1.containsKey("uid"));
+ deleteAttrFromEntry(user1, "aci");
+ //Add ACI that only allows only aci operational attribute search/read.
+ String aciLdif2=makeAddAciLdif("aci", user1, opAttrAci);
+ modEntries(aciLdif2, DIR_MGR_DN, PWD);
+ String userResults2 =
+ LDAPSearchParams(user3, PWD, null, null, null,
+ user1, aciFilter, opAttrList);
+ Assert.assertFalse(userResults2.equals(""));
+ HashMap<String, String> attrMap2=getAttrMap(userResults2);
+ //Only operational attribute aci should be there, the other two should
+ //not.
+ Assert.assertTrue(attrMap2.containsKey("aci"));
+ Assert.assertFalse(attrMap2.containsKey("sn"));
+ Assert.assertFalse(attrMap2.containsKey("uid"));
+ deleteAttrFromEntry(user1, "aci");
+ }
+
+ private void
+ checkAttributeVal(HashMap<String, String> attrMap, String attr,
+ String val) throws Exception {
+ String mapVal=attrMap.get(attr);
+ Assert.assertTrue(mapVal.equals(val));
+ }
+
+}
--
Gitblit v1.10.0