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; } } 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); } 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; } 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); } 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; } 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"); } /**