From fe19ac2d6f1b978356b29e81901b91ae7a09daf9 Mon Sep 17 00:00:00 2001
From: Chris Ridd <chris.ridd@forgerock.com>
Date: Fri, 02 Oct 2015 12:39:01 +0000
Subject: [PATCH] OPENDJ-2312 Check rightsMask for all operations in setEval{User,Op}Attributes
---
opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java | 84 ++++++++++++++++++++++++++++
opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/AciTestCase.java | 73 +++++++++++++++++++++--
opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciContainer.java | 4
3 files changed, 151 insertions(+), 10 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciContainer.java b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciContainer.java
index 69a2ee9..4477aeb 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciContainer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/authorization/dseecompat/AciContainer.java
@@ -805,7 +805,7 @@
/** {@inheritDoc} */
@Override
public void setEvalUserAttributes(int v) {
- if(operation instanceof SearchOperation && rightsMask == ACI_READ) {
+ if(rightsMask == ACI_READ) {
if(v == ACI_FOUND_USER_ATTR_RULE) {
evalAllAttributes |= ACI_FOUND_USER_ATTR_RULE;
evalAllAttributes &= ~ACI_USER_ATTR_STAR_MATCHED;
@@ -820,7 +820,7 @@
/** {@inheritDoc} */
@Override
public void setEvalOpAttributes(int v) {
- if(operation instanceof SearchOperation && rightsMask == ACI_READ) {
+ if(rightsMask == ACI_READ) {
if(v == ACI_FOUND_OP_ATTR_RULE) {
evalAllAttributes |= ACI_FOUND_OP_ATTR_RULE;
evalAllAttributes &= ~ACI_OP_ATTR_PLUS_MATCHED;
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/AciTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/AciTestCase.java
index a7adc51..675d984 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/AciTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/AciTestCase.java
@@ -199,6 +199,47 @@
return oStream.toString();
}
+ /**
+ * Perform a modify operation, and request attributes via a preRead control.
+ *
+ * @param bindDn The user to authenticate as.
+ * @param bindPassword The user's credentials.
+ * @param ldif The modification to make.
+ * @param attributes A space-separated list of attributes to return.
+ *
+ * @return The output of the command.
+ *
+ * @throws Exception If an unexpected problem occurred.
+ */
+ protected String preReadModify(String bindDn, String bindPassword,
+ String ldif, String attributes) throws Exception
+ {
+ File tempFile = getTemporaryLdifFile();
+ TestCaseUtils.writeFile(tempFile, ldif);
+
+ ArrayList<String> argList=new ArrayList<>(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);
+ if (attributes != null) {
+ argList.add("--preReadAttributes");
+ argList.add(attributes);
+ }
+ argList.add("-f");
+ argList.add(tempFile.getAbsolutePath());
+ String[] args = new String[argList.size()];
+
+ oStream.reset();
+ int retVal =LDAPModify.mainModify(argList.toArray(args), false, oStream, oStream);
+ Assert.assertEquals(retVal, 0, "Returned error: " + oStream);
+ return oStream.toString();
+ }
+
protected String LDAPSearchCtrl(String bindDn, String bindPassword,
String proxyDN, String controlStr,
String base, String filter, String attr) {
@@ -719,26 +760,42 @@
protected Map<String, String> getAttrMap(String resultString)
{
- StringReader r=new StringReader(resultString);
- BufferedReader br=new BufferedReader(r);
+ return getAttrMap(resultString, false);
+ }
+
+ /**
+ * Parse a tool output for an LDIF record, returning the attributes in a Map.
+ *
+ * @param resultString The entire output from the operation
+ * @param stripHeader Set to {@code true} if data before the LDIF needs to be ignored
+ * @return A map of attribute-values
+ */
+ protected Map<String, String> getAttrMap(String resultString, boolean stripHeader)
+ {
+ StringReader r = new StringReader(resultString);
+ BufferedReader br = new BufferedReader(r);
+ boolean stripping = stripHeader;
Map<String, String> attrMap = new HashMap<>();
try {
- while(true) {
+ while (true) {
String s = br.readLine();
- if(s == null)
+ if (s == null)
{
break;
}
- if(s.startsWith("dn:"))
- {
+ if (stripping) {
+ if (s.startsWith("dn:"))
+ {
+ stripping = false;
+ }
continue;
}
String[] a=s.split(": ");
- if(a.length != 2)
+ if (a.length != 2)
{
break;
}
- attrMap.put(a[0].toLowerCase(),a[1]);
+ attrMap.put(a[0].toLowerCase(), a[1]);
}
} catch (IOException e) {
Assert.fail(e.getMessage());
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java
index 27d6ddf..0be9464 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java
@@ -122,9 +122,42 @@
"allow (search, read) " +
"userattr=\"l#Austin\";)";
+ private static final
+ String controlAci = "(targetcontrol=\"1.3.6.1.1.13.1\")" +
+ "(version 3.0;acl \"use pre-read control\";" +
+ "allow (read) " +
+ "userdn=\"ldap:///anyone\";)";
+
+ private static final String user3ForbiddenUserAttr = "sn";
+ private static final String user3ForbiddenOperationalAttr = "createTimestamp";
+ private static final String user3AllowedUserAttr = "uid";
+ private static final String user3AllowedOperationalAttr = "ds-privilege-name";
+ private static final String user3WritableAttr = "description";
+
+ private static final
+ String selfWriteAci = "(targetattr=\"" + user3WritableAttr + "\")" +
+ "(version 3.0;acl \"self write description\";" +
+ "allow (write) " +
+ "userdn=\"ldap:///self\";)";
+
+ private static final
+ String selfDenyAttrReadAci = "(targetattr=\"" + user3ForbiddenUserAttr + "||" +
+ user3ForbiddenOperationalAttr + "\")" +
+ "(version 3.0;acl \"self deny attribute reads\";" +
+ "deny (read,search) " +
+ "userdn=\"ldap:///self\";)";
+
+ private static final
+ String selfReadAllAttrsAci = "(targetattr=\"*||+\")" +
+ "(version 3.0; acl \"self read/search all attributes\";" +
+ "allow (read,search) " +
+ "userdn=\"ldap:///self\";)";
+
@BeforeClass
public void setupClass() throws Exception {
deleteAttrFromAdminEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
+ String aciLdif3 = makeAddLDIF(ATTR_AUTHZ_GLOBAL_ACI, ACCESS_HANDLER_DN, controlAci, selfWriteAci);
+ LDIFModify(aciLdif3, DIR_MGR_DN, PWD);
addEntries("o=test");
}
@@ -217,6 +250,57 @@
}
/**
+ * Test targetattr behaviour with modify and pre-read controls
+ *
+ * @throws Exception If a test result is unexpected.
+ */
+ @Test
+ public void testTargetAttrPreRead() throws Exception {
+ String aciLdif=makeAddLDIF("aci", user3,
+ controlAci, selfWriteAci, selfDenyAttrReadAci, selfReadAllAttrsAci);
+ LDIFModify(aciLdif, DIR_MGR_DN, PWD);
+
+ // sanity check that search does not return the forbidden attributes
+ String searchResults =
+ LDAPSearchParams(user3, PWD, null, null, null, user3, filter, "+ *");
+ assertNotEquals(searchResults, "");
+ Map<String, String> attrMap = getAttrMap(searchResults);
+ assertFalse(attrMap.containsKey(user3ForbiddenUserAttr));
+ assertFalse(attrMap.containsKey(user3ForbiddenOperationalAttr));
+ assertTrue(attrMap.containsKey(user3AllowedUserAttr));
+
+ // check we can't pre-read the forbidden user attribute
+ String modifyLdif1 = makeAddLDIF(user3WritableAttr, user3, "don't care 1");
+ String modifyResults1 = preReadModify(user3, PWD, modifyLdif1, user3ForbiddenUserAttr);
+ assertNotEquals(modifyResults1, "");
+ Map<String, String> modifyMap1 = getAttrMap(modifyResults1, true);
+ assertFalse(modifyMap1.containsKey(user3ForbiddenUserAttr));
+
+ // check we can't pre-read the forbidden operational attribute
+ String modifyLdif2 = makeAddLDIF(user3WritableAttr, user3, "don't care 2");
+ String modifyResults2 = preReadModify(user3, PWD, modifyLdif2, user3ForbiddenOperationalAttr);
+ assertNotEquals(modifyResults2, "");
+ Map<String, String> modifyMap2 = getAttrMap(modifyResults2, true);
+ assertFalse(modifyMap2.containsKey(user3ForbiddenOperationalAttr));
+
+ // check we can pre-read the allowed user attribute
+ String modifyLdif3 = makeAddLDIF(user3WritableAttr, user3, "don't care 3");
+ String modifyResults3 = preReadModify(user3, PWD, modifyLdif3, user3AllowedUserAttr);
+ assertNotEquals(modifyResults3, "");
+ Map<String, String> modifyMap3 = getAttrMap(modifyResults3, true);
+ assertTrue(modifyMap3.containsKey(user3AllowedUserAttr));
+
+ // check we can pre-read the allowed operational attribute
+ String modifyLdif4 = makeAddLDIF(user3WritableAttr, user3, "don't care 4");
+ String modifyResults4 = preReadModify(user3, PWD, modifyLdif4, user3AllowedOperationalAttr);
+ assertNotEquals(modifyResults4, "");
+ Map<String, String> modifyMap4 = getAttrMap(modifyResults4, true);
+ assertTrue(modifyMap4.containsKey(user3AllowedOperationalAttr));
+
+ deleteAttrFromEntry(user3, "aci");
+ }
+
+ /**
* Test targetattr shorthand behavior, all attrs both user and operational.
* See comments.
*
--
Gitblit v1.10.0