mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

dugan
22.47.2007 df0a434d42e18e7cef08c9fa804bb0927a3b6a79
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.
6 files modified
108 ■■■■ changed files
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciContainer.java 41 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciEvalContext.java 16 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java 13 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciTargetMatchContext.java 8 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/UserAttr.java 8 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java 22 ●●●●● patch | view | raw | blame | history
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");
  }
  /**