From df0a434d42e18e7cef08c9fa804bb0927a3b6a79 Mon Sep 17 00:00:00 2001
From: dugan <dugan@localhost>
Date: Mon, 21 May 2007 22:47:07 +0000
Subject: [PATCH] Correct problem QA found with fix for issue 1606, where the attribute(s) still were not being returned when they should be. Also, corrected problem where userattr bind rule was using filtered resource entry for userattr bind rule evaluation, causing the bind rule to sometimes not be evaluated correctly if the attribute isn't present during a userattr attribute value expression.
---
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java | 22 +++++++---
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargetMatchContext.java | 8 ++-
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java | 8 +++
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java | 41 ++++++++++++++++----
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java | 13 ++++--
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciEvalContext.java | 16 ++++++++
6 files changed, 85 insertions(+), 23 deletions(-)
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 71e208a..52537f4 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
@@ -260,10 +260,15 @@
if(origAuthorizationEntry != null)
this.proxiedAuthorization=true;
this.authorizationEntry=operation.getAuthorizationEntry();
- //Only need to process the geteffectiverights control once, -- for a
- //SearchOperation with read right. It is saved in the operation
- //attachment after that.
+ //The ACI_READ right at constructor time can only be the result of the
+ //AciHandler.filterEntry method. This method processes the
+ //geteffectiverights control, so it needs to check for it. There are
+ //two other checks done, because the resource entry passed to that method
+ //is filtered (it may not contain enough attribute information
+ //to evaluate correctly). See the the comments below.
if(operation instanceof SearchOperation && (rights == ACI_READ)) {
+ //Checks if a geteffectiverights control was sent and
+ //sets up the structures needed.
GetEffectiveRights getEffectiveRightsControl =
(GetEffectiveRights)
operation.getAttachment(OID_GET_EFFECTIVE_RIGHTS);
@@ -274,12 +279,18 @@
else
this.authzid=getEffectiveRightsControl.getAuthzDN();
this.specificAttrs=getEffectiveRightsControl.getAttributes();
- fullEntry=(Entry)operation.getAttachment(ALL_ATTRS_RESOURCE_ENTRY);
}
+ //If the ACI evaluated because of an Targetattr="*", then the
+ //AciHandler.maySend method signaled this via adding this attachment
+ //string.
String allAttrs=(String)operation.getAttachment(ALL_ATTRS_MATCHED);
if(allAttrs != null)
evalAllAttributes = ACI_ATTR_STAR_MATCHED;
- }
+ //The AciHandler.maySend method also adds the full attribute version of
+ //the resource entry in this attachment.
+ fullEntry=(Entry)operation.getAttachment(ALL_ATTRS_RESOURCE_ENTRY);
+ } else
+ fullEntry=this.resourceEntry;
//Reference the current authorization entry, so it can be put back
//if an access proxy check was performed.
this.saveAuthorizationEntry=this.authorizationEntry;
@@ -823,15 +834,29 @@
* {@inheritDoc}
*/
public boolean hasACIEvalAttributes() {
- return (evalAllAttributes == 0) ||
- (evalAllAttributes & ACI_FOUND_ATTR_RULE) == ACI_FOUND_ATTR_RULE;
+ return (evalAllAttributes & ACI_FOUND_ATTR_RULE) == ACI_FOUND_ATTR_RULE;
}
/**
+ * Return true if the evaluating ACI either contained a targetattr all
+ * attributes rule matched only.
+ *
+ * @return True if the above condition was seen.
+ **/
+ public boolean hasACIAllAttributes() {
+ return (evalAllAttributes & ACI_ATTR_STAR_MATCHED) == ACI_ATTR_STAR_MATCHED;
+ }
+
+ /**
* {@inheritDoc}
*/
public void clearACIEvalAttributesRule(int v) {
- evalAllAttributes &= ~v;
+ if(v == 0)
+ evalAllAttributes=0;
+ else
+ evalAllAttributes &= ~v;
}
+
+
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciEvalContext.java b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciEvalContext.java
index 401e79e..2baf36b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciEvalContext.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciEvalContext.java
@@ -304,4 +304,20 @@
* @return The name of the ACI that last matched a targattrfilters rule.
*/
public String getTargAttrFiltersAciName();
+
+ /**
+ * The full entry with all of the attributes was saved
+ * in the operation's attachment mechanism when the container was created
+ * during the SearchOperation read evaluation. Some operations need the full
+ * entry and not the filtered entry to perform their evaluations, because they
+ * might depend attribute types and values filtered out.
+ *
+ * This method is used to replace the current resource entry with that saved
+ * entry and back.
+ *
+ * @param val Specifies if the saved entry should be used or not. True if it
+ * should be used, false if the original resource entry should be used.
+ *
+ */
+ public void useFullResourceEntry(boolean val);
}
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 7521308..505937e 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
@@ -589,7 +589,7 @@
Entry e=container.getResourceEntry();
List<AttributeType> typeList=getAllAttrs(e);
for(AttributeType attrType : typeList) {
- if(!container.hasACIEvalAttributes() && !attrType.isOperational())
+ if(container.hasACIAllAttributes() && !attrType.isOperational())
continue;
container.setCurrentAttributeType(attrType);
if(!accessAllowed(container)) {
@@ -887,14 +887,19 @@
if(!(ret=skipAccessCheck(operation))) {
ret=testFilter(operationContainer, operation.getFilter());
if (ret) {
+ operationContainer.clearACIEvalAttributesRule(ACI_NULL);
operationContainer.setRights(ACI_READ);
ret=accessAllowedEntry(operationContainer);
- if(ret && !operationContainer.hasACIEvalAttributes())
+ if(ret) {
+ if(!operationContainer.hasACIEvalAttributes())
operation.setAttachment(ALL_ATTRS_MATCHED, ALL_ATTRS_MATCHED);
+ }
}
}
- if(ret && operation.getAttachment(OID_GET_EFFECTIVE_RIGHTS) != null)
- operation.setAttachment(ALL_ATTRS_RESOURCE_ENTRY, entry );
+ //Save a copy of the full resource entry for possible
+ //userattr bind rule or geteffectiveright's evaluations in the filterEnty
+ //method.
+ operation.setAttachment(ALL_ATTRS_RESOURCE_ENTRY, entry );
return ret;
}
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 f70e3bb..d6fb958 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
@@ -176,7 +176,7 @@
* can be skipped, is when a single ACI matched using a targetattr
* all attributes rule.
*
- * @param v The flag to set the mask to.
+ * @param v The mask to this value.
*/
void setACIEvalAttributesRule(int v);
@@ -193,9 +193,11 @@
/**
* Used to clear the mask used to detect if access checking needs to be
- * performed on individual non-operational attributes types.
+ * performed on individual non-operational attributes types. The specified
+ * value is cleared from the mask or if the value equals 0 the mask is
+ * completely cleared.
*
- * @param v The flag to clear (always ACI_ATTR_STAR_MATCHED)
+ * @param v The flag to clear or 0 to set the mask to 0.
*/
public void clearACIEvalAttributesRule(int v);
}
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 c3295fc..2e910a1 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
@@ -175,7 +175,11 @@
*/
public EnumEvalResult evaluate(AciEvalContext evalCtx) {
EnumEvalResult matched;
-
+ //The working resource entry might be filtered and not have an
+ //attribute type that is needed to perform these evaluations. The
+ //evalCtx has a copy of the non-filtered entry, switch to it for these
+ //evaluations.
+ evalCtx.useFullResourceEntry(true);
switch(userAttrType) {
case ROLEDN:
case GROUPDN:
@@ -190,6 +194,8 @@
default:
matched=evalVAL(evalCtx);
}
+ //Switch back to the working resource entry.
+ evalCtx.useFullResourceEntry(false);
return matched;
}
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 da90cbd..fe96c12 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
@@ -38,6 +38,7 @@
public class TargetAttrTestCase extends AciTestCase {
private static String attrList="sn uid l";
+ private static String attrList1="sn uid";
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";
@@ -59,13 +60,13 @@
String nonOpAttrAci = "(targetattr=\"*\")" +
"(version 3.0;acl \"read/search non-operational attr\";" +
"allow (search, read) " +
- "userdn=\"ldap:///uid=user.3,ou=People,o=test\";)";
+ "userattr=\"l#Austin\";)";
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\";)";
+ "userattr=\"l#Austin\";)";
@BeforeClass
public void setupClass() throws Exception {
@@ -91,18 +92,25 @@
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);
+ user1, filter, attrList1);
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");
+ String aciLdif2=makeAddAciLdif("aci", user1, userAttrAci1);
+ modEntries(aciLdif2, DIR_MGR_DN, PWD);
+ String userResults2 =
+ LDAPSearchParams(user3, PWD, null, null, null,
+ user1, filter, attrList);
+ Assert.assertFalse(userResults2.equals(""));
+ HashMap<String, String> attrMap2=getAttrMap(userResults2);
+ checkAttributeVal(attrMap2, "l", "Austin");
+ checkAttributeVal(attrMap2, "sn", "1");
+ checkAttributeVal(attrMap2, "uid", "user.1");
+ deleteAttrFromEntry(user1, "aci");
}
/**
--
Gitblit v1.10.0