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

dugan
01.15.2007 571884cec31d00f0c1b9de186fb1bbac17d289d5
Add ACI support to control whether a  "smart referral" (named subordinate references -- RFC 3296)
may be returned to a client. Smart referral entries contain the referral objectclass and
have one or more "ref" attributes containing LDAP URLS. The ref attribute type has usage
distributedOperation, so the operational shorthand '+' character can be used to match it:

(targetattr="+")(version 3.0; acl "ref wild-card"; allow(read) userdn="ldap:///anyone";)

or it can be explicitly used:

(targetattr="ref")(version 3.0; acl "ref"; allow(read) userdn="ldap:///anyone";)

It is also possible to add an ACI on the referral entry itself:

dn: uid=smart, ou=People, dc=example, dc=com
objectclass: top
objectClass: extensibleobject
objectClass: referral
ref: ldap://kansashost/OU=People,O=Kansas,C=US
ref: ldap://texashost/OU=People,O=Texas,C=US
aci: (targetattr = "ref")(version 3.0; acl "add_aci"; allow (read) userdn="ldap://anyone";)
1 files added
16 files modified
387 ■■■■ changed files
opendj-sdk/opends/src/server/org/opends/server/api/AccessControlHandler.java 10 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java 49 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java 12 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/backends/jeb/DN2URI.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/core/DefaultAccessControlHandler.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/core/SearchOperation.java 4 ●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java 4 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationWrapper.java 4 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/types/operation/PreOperationSearchOperation.java 5 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/types/operation/PreParseSearchOperation.java 14 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java 57 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AlternateRootDN.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/ExtOpTestCase.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/GetEffectiveRightsTestCase.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/ReferencesTestCase.java 214 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetControlTestCase.java 2 ●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/api/AccessControlHandler.java
@@ -308,7 +308,10 @@
  /**
   * Indicates whether the provided search result reference may be
   * sent to the client.
   * sent to the client based on the access control configuration.
   *
   * @param  dn         A DN that can be used in the access
   *                    determination.
   *
   * @param  searchOperation  The search operation with which the
   *                          provided reference is associated.
@@ -319,8 +322,9 @@
   *          the reference to be returned to the client, or
   *          {@code false} if not.
   */
  public abstract boolean maySend(SearchOperation searchOperation,
                               SearchResultReference searchReference);
  public abstract boolean maySend(DN dn,
                             SearchOperation searchOperation,
                             SearchResultReference searchReference);
}
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciHandler.java
@@ -97,6 +97,12 @@
   */
  static AttributeType debugSearchIndex;
  /**
   * Attribute type corresponding to the "ref" attribute type. Used in the
   * search reference access check.
   */
  static AttributeType refAttrType;
 /*
  * DN corresponding to "debugsearchindex" attribute type.
  */
@@ -149,6 +155,14 @@
       DirectoryServer.
               getDefaultAttributeType(EntryContainer.ATTR_DEBUG_SEARCH_INDEX);
     }
     if((refAttrType =
             DirectoryServer.
                     getAttributeType(ATTR_REFERRAL_URL)) == null) {
       refAttrType =
               DirectoryServer.
                       getDefaultAttributeType(ATTR_REFERRAL_URL);
     }
     try {
       debugSearchIndexDN=DN.decode("cn=debugsearch");
     } catch (DirectoryException ex) {
@@ -1232,26 +1246,39 @@
         new AciLDAPOperationContainer(operation, e, (ACI_READ | ACI_EXT_OP));
      ret=accessAllowed(operationContainer);
    }
    if(operation.getRequestOID().equals(OID_PROXIED_AUTH_V2) ||
            operation.getRequestOID().equals(OID_PROXIED_AUTH_V1))
       operation.
              setAttachment(ORIG_AUTH_ENTRY, operation.getAuthorizationEntry());
    return ret;
  }
  //Not planned to be implemented methods.
   /**
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean maySend(SearchOperation operation,
      SearchResultReference reference) {
    //TODO: Deferred.
    return true;
  public boolean maySend(DN dn, SearchOperation operation,
                         SearchResultReference reference) {
    boolean ret;
    if(!(ret=skipAccessCheck(operation))) {
      Entry e = new Entry(dn, null, null, null);
      LinkedHashSet<AttributeValue> vals = new LinkedHashSet<AttributeValue>();
      List<String> URLStrings=reference.getReferralURLs();
      //Load the values, a bind rule might want to evaluate them.
      for(String URLString : URLStrings) {
        vals.add(new AttributeValue(refAttrType, URLString));
      }
      Attribute attr =
                     new Attribute(refAttrType, ATTR_REFERRAL_URL, vals);
      e.addAttribute(attr,null);
      SearchResultEntry se=new  SearchResultEntry(e);
      AciLDAPOperationContainer operationContainer =
              new AciLDAPOperationContainer(operation,
                                           (ACI_READ), se);
      operationContainer.setCurrentAttributeType(refAttrType);
      ret=accessAllowed(operationContainer);
    }
    return ret;
  }
  /**
   * {@inheritDoc}
   */
opendj-sdk/opends/src/server/org/opends/server/authorization/dseecompat/AciListenerManager.java
@@ -46,10 +46,8 @@
import static org.opends.server.messages.MessageHandler.getMessage;
import org.opends.server.core.DirectoryServer;
import static org.opends.server.util.ServerConstants.*;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.LinkedList;
import java.util.LinkedHashMap;
import java.util.*;
/**
 * The AciListenerManager updates an ACI list after each
@@ -216,6 +214,10 @@
      InternalClientConnection conn =
           InternalClientConnection.getRootConnection();
      LinkedList<String>failedACIMsgs=new LinkedList<String>();
      //Add manageDsaIT control so any ACIs in referral entries will be
      //picked up.
      ArrayList<Control> controls = new ArrayList<Control>(1);
      controls.add(new Control(OID_MANAGE_DSAIT_CONTROL, true));
      for (DN baseDN : backend.getBaseDNs()) {
        try {
          if (! backend.entryExists(baseDN))  {
@@ -233,7 +235,7 @@
                  conn,
                  InternalClientConnection.nextOperationID(),
                  InternalClientConnection.nextMessageID(),
                  null, baseDN, SearchScope.WHOLE_SUBTREE,
                  controls, baseDN, SearchScope.WHOLE_SUBTREE,
                  DereferencePolicy.NEVER_DEREF_ALIASES,
                  0, 0, false, aciFilter, attrs, null);
        LocalBackendSearchOperation localInternalSearch =
opendj-sdk/opends/src/server/org/opends/server/backends/jeb/DN2URI.java
@@ -667,7 +667,7 @@
          } while (status == OperationStatus.SUCCESS);
          SearchResultReference reference = new SearchResultReference(URIList);
          if (!searchOp.returnReference(reference))
          if (!searchOp.returnReference(dn, reference))
          {
            return false;
          }
opendj-sdk/opends/src/server/org/opends/server/core/DefaultAccessControlHandler.java
@@ -216,7 +216,7 @@
   * {@inheritDoc}
   */
  @Override
  public boolean maySend(SearchOperation searchOperation,
  public boolean maySend(DN dn, SearchOperation searchOperation,
                         SearchResultReference searchReference)
  {
    return true;
opendj-sdk/opends/src/server/org/opends/server/core/SearchOperation.java
@@ -258,13 +258,15 @@
   * should be performed to potentially send it back to the client.
   *
   * @param  reference  The search reference to send to the client.
   * @param  dn         The DN related to the specified search reference.
   *
   * @return  <CODE>true</CODE> if the caller should continue processing the
   *          search request and sending additional entries and references , or
   *          <CODE>false</CODE> if not for some reason (e.g., the size limit
   *          has been reached or the search has been abandoned).
   */
  public abstract boolean returnReference(SearchResultReference reference);
  public abstract boolean returnReference(DN dn,
                                          SearchResultReference reference);
  /**
   * Sends the search result done message to the client.  Note that this method
opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationBasis.java
@@ -1040,7 +1040,7 @@
  /**
   * {@inheritDoc}
   */
  public final boolean returnReference(SearchResultReference reference)
  public final boolean returnReference(DN dn, SearchResultReference reference)
  {
    // See if the operation has been abandoned.  If so, then don't send the
    // reference and indicate that the search should end.
@@ -1073,7 +1073,7 @@
    // See if the client has permission to read this reference.
    if (AccessControlConfigManager.getInstance()
        .getAccessControlHandler().maySend(this, reference) == false) {
        .getAccessControlHandler().maySend(dn, this, reference) == false) {
      return true;
    }
opendj-sdk/opends/src/server/org/opends/server/core/SearchOperationWrapper.java
@@ -76,9 +76,9 @@
  /**
   * {@inheritDoc}
   */
  public boolean returnReference(SearchResultReference reference)
  public boolean returnReference(DN dn, SearchResultReference reference)
  {
    return search.returnReference(reference);
    return search.returnReference(dn, reference);
  }
  /**
opendj-sdk/opends/src/server/org/opends/server/types/operation/PreOperationSearchOperation.java
@@ -175,6 +175,8 @@
  /**
   * Returns the provided search result reference to the client.
   *
   * @param   dn        A DN related to the specified search
   *                    reference.
   * @param  reference  The search reference that should be returned.
   *
   * @return  {@code true} if the caller should continue processing
@@ -183,6 +185,7 @@
   *          (e.g., the size limit has been reached or the search has
   *          been abandoned).
   */
  public boolean returnReference(SearchResultReference reference);
  public boolean
  returnReference(DN dn ,SearchResultReference reference);
}
opendj-sdk/opends/src/server/org/opends/server/types/operation/PreParseSearchOperation.java
@@ -31,14 +31,7 @@
import java.util.LinkedHashSet;
import java.util.List;
import org.opends.server.types.ByteString;
import org.opends.server.types.Control;
import org.opends.server.types.DereferencePolicy;
import org.opends.server.types.Entry;
import org.opends.server.types.RawFilter;
import org.opends.server.types.SearchResultReference;
import org.opends.server.types.SearchScope;
import org.opends.server.types.*;
/**
@@ -234,6 +227,8 @@
   * Returns the provided search result reference to the client.
   *
   * @param  reference  The search reference that should be returned.
   * @param  dn         A DN related to the specified search
   *                    reference.
   *
   * @return  {@code true} if the caller should continue processing
   *          the search request and sending additional entries and
@@ -241,6 +236,7 @@
   *          (e.g., the size limit has been reached or the search has
   *          been abandoned).
   */
  public boolean returnReference(SearchResultReference reference);
  public boolean
  returnReference(DN dn, SearchResultReference reference);
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AciTestCase.java
@@ -49,7 +49,8 @@
  public  static final String filter = "(objectclass=*)";
  public static final String ACCESS_HANDLER_DN =
                                       "cn=Access Control Handler,cn=config";
  public static final String refURL=
          "ldap://kansashost/OU=People,O=Kansas,C=US";
  //GLOBAL ACIs
  protected final static String G_READ_ACI =
@@ -227,9 +228,11 @@
    argList.add("-s");
    argList.add("sub");
    argList.add(filter);
    String[] attrs=attr.split("\\s+");
    for(String a : attrs)
     argList.add(a);
    if(attr != null) {
      String[] attrs=attr.split("\\s+");
      for(String a : attrs)
        argList.add(a);
    }
    String[] args = new String[argList.size()];
    oStream.reset();
    int retVal =
@@ -253,6 +256,12 @@
    _LDIFModify(ldif, bindDn, bindPassword, null, false, -1);
  }
  protected void LDIFModify(String ldif, String bindDn, String bindPassword,
                            String ctrlString)
  throws Exception {
    _LDIFModify(ldif, bindDn, bindPassword, ctrlString, false, -1);
  }
  protected void LDIFDelete(String dn, String bindDn, String bindPassword,
                            String controlStr, int rc) {
    _LDIFDelete(dn, bindDn, bindPassword, controlStr, rc);
@@ -413,26 +422,26 @@
  }
  protected void addEntries() throws Exception {
  protected void addEntries(String suffix) throws Exception {
    TestCaseUtils.initializeTestBackend(true);
    TestCaseUtils.addEntries(
            "dn: ou=People,o=test",
            "dn: ou=People," + suffix,
            "objectClass: top",
            "objectClass: organizationalUnit",
            "ou: People",
            "",
            "dn: ou=admins,o=test",
            "dn: ou=admins," + suffix ,
            "objectClass: top",
            "objectClass: organizationalUnit",
            "ou: admins",
            "",
            "dn: cn=group,ou=People,o=test",
            "dn: cn=group,ou=People," + suffix,
            "objectclass: top",
            "objectclass: groupOfNames",
            "cn: group",
            "member: uid=user.3,ou=People,o=test",
            "member: uid=user.3,ou=People," + suffix,
            "",
            "dn: uid=superuser,ou=admins,o=test",
            "dn: uid=superuser,ou=admins," + suffix,
            "objectClass: top",
            "objectClass: person",
            "objectClass: organizationalPerson",
@@ -444,7 +453,7 @@
            "userPassword: password",
            "ds-privilege-name: proxied-auth",
            "",
            "dn: uid=proxyuser,ou=admins,o=test",
            "dn: uid=proxyuser,ou=admins," + suffix,
            "objectClass: top",
            "objectClass: person",
            "objectClass: organizationalPerson",
@@ -455,7 +464,21 @@
            "cn: User 1",
            "userPassword: password",
            "",
            "dn: uid=user.1,ou=People,o=test",
            "dn: uid=smart referral admin,uid=proxyuser,ou=admins," + suffix,
            "objectClass: top",
            "objectClass: extensibleobject",
            "objectClass: referral",
            "ref:" + refURL,
            "ref: ldap://texashost/OU=People,O=Texas,C=US",
            "",
            "dn: uid=smart referral people,ou=people," + suffix,
            "objectClass: top",
            "objectClass: extensibleobject",
            "objectClass: referral",
            "ref:" + refURL,
            "ref: ldap://texashost/OU=People,O=Texas,C=US",
            "",
            "dn: uid=user.1,ou=People," + suffix,
            "objectClass: top",
            "objectClass: person",
            "objectClass: organizationalPerson",
@@ -465,10 +488,10 @@
            "sn: 1",
            "cn: User1",
            "l: Austin",
            "manager: cn=group,ou=People,o=test",
            "manager: cn=group,ou=People," + suffix,
            "userPassword: password",
            "",
            "dn: uid=user.2,ou=People,o=test",
            "dn: uid=user.2,ou=People," + suffix,
            "objectClass: top",
            "objectClass: person",
            "objectClass: organizationalPerson",
@@ -480,7 +503,7 @@
             "l: dallas",
            "userPassword: password",
            "",
            "dn: uid=user.3,ou=People,o=test",
            "dn: uid=user.3,ou=People," + suffix,
            "objectClass: top",
            "objectClass: person",
            "objectClass: organizationalPerson",
@@ -493,7 +516,7 @@
            "userPassword: password",
            "ds-privilege-name: proxied-auth",
            "",
            "dn: uid=user.4,ou=People,o=test",
            "dn: uid=user.4,ou=People," + suffix,
            "objectClass: top",
            "objectClass: person",
            "objectClass: organizationalPerson",
@@ -505,7 +528,7 @@
             "l: ft worth",
            "userPassword: password",
            "",
            "dn: uid=user.5,ou=People,o=test",
            "dn: uid=user.5,ou=People," + suffix,
            "objectClass: top",
            "objectClass: person",
            "objectClass: organizationalPerson",
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/AlternateRootDN.java
@@ -72,7 +72,7 @@
  public void setupClass() throws Exception {
    TestCaseUtils.startServer();
    deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
    addEntries();
    addEntries("o=test");
    addRootEntry();
  }
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/ExtOpTestCase.java
@@ -120,7 +120,7 @@
  public void setupClass() throws Exception {
    TestCaseUtils.startServer();
    deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
    addEntries();
    addEntries("o=test");
  }
   @AfterClass
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/GetEffectiveRightsTestCase.java
@@ -165,7 +165,7 @@
  public void setupClass() throws Exception {
    TestCaseUtils.startServer();
    deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
    addEntries();
    addEntries("o=test");
  }
  @AfterClass
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/ReferencesTestCase.java
New file
@@ -0,0 +1,214 @@
/*
 * 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.AfterClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import org.testng.Assert;
import org.opends.server.TestCaseUtils;
import static org.opends.server.util.ServerConstants.OID_MANAGE_DSAIT_CONTROL;
import static org.opends.server.config.ConfigConstants.ATTR_AUTHZ_GLOBAL_ACI;
import java.util.HashMap;
import java.io.StringReader;
import java.io.BufferedReader;
import java.io.IOException;
/**
 * Unit test to test ACI behavior and Named Subordinate References (RFC 3296).
 * This test needs a jeb backend, the memory backend cannot be used.
 */
public class ReferencesTestCase extends AciTestCase{
  private static String suffix="dc=example,dc=com";
  private static final String level5User="uid=user.5,ou=People," + suffix;
  private static final String adminBase="ou=Admins," + suffix;
  private static final String peopleBase="ou=people," + suffix;
  private static final String smartReferralAdmin=
          "uid=smart referral admin,uid=proxyuser,ou=admins," + suffix;
  private static final String ctrlString = OID_MANAGE_DSAIT_CONTROL + ":false";
  //Allow based on plus operator.
  private static final
  String ALLOW_OC_PLUS = "(targetattr=\"objectclass || +\")" +
          "(version 3.0;acl \"plus\";" +
          "allow (search, read) " +
          "userdn=\"ldap:///" + level5User + "\";)";
  //Allow based on ref name.
  private static final
  String ALLOW_OC = "(targetattr=\"objectclass || ref\")" +
          "(version 3.0;acl \"ref name\";" +
          "allow (search, read) " +
          "userdn=\"ldap:///" + level5User + "\";)";
  //Allow based on target keyword.
  private static final
  String ALLOW_PEOPLE =
          "(target=\"ldap:///" + peopleBase + "\")" +
                  "(targetattr=\"objectclass || ref\")" +
                  "(version 3.0;acl \"target\";" +
                  "allow (search, read) " +
                  "userdn=\"ldap:///" + level5User + "\";)";
  @BeforeClass
  public void setupClass() throws Exception {
    TestCaseUtils.startServer();
    deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
    TestCaseUtils.clearJEBackend(true,"userRoot", suffix);
    addEntries(suffix);
  }
  @AfterClass
  public void tearDown() throws Exception {
    String aciLdif=makeAddLDIF(ATTR_AUTHZ_GLOBAL_ACI, ACCESS_HANDLER_DN,
            G_READ_ACI, G_SELF_MOD, G_SCHEMA, G_DSE, G_USER_OPS, G_CONTROL,
            E_EXTEND_OP);
    LDIFModify(aciLdif, DIR_MGR_DN, PWD);
    TestCaseUtils.clearJEBackend(false,"userRoot", suffix);
  }
  @BeforeMethod
  public void clearBackend() throws Exception {
    deleteAttrFromEntry(adminBase, "aci");
    deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
  }
  /**
   * Test using ACI added to admin base containing "ref" attribute type name
   * specified in targetattr keword.
   *
   * @throws Exception If results are unexpected.
   */
  @Test()
  public void testRef() throws Exception {
    String pwdLdifs =
            makeAddLDIF("aci", adminBase, ALLOW_OC);
    LDIFModify(pwdLdifs, DIR_MGR_DN, PWD);
    String userResults =
            LDAPSearchParams(level5User, PWD, null,null, null,
                    adminBase, filter, null);
    Assert.assertTrue(isRefMap(userResults));
  }
  /**
   * Test using ACI added to actual referral entry (added using ldifmodify
   * passing manageDsaIT control).
   *
   * @throws Exception  If results are unexpected.
   */
  @Test()
  public void testRefAci() throws Exception {
    String pwdLdifs =
            makeAddLDIF("aci", smartReferralAdmin, ALLOW_OC);
    //Add the ACI passing the manageDsaIT control.
    LDIFModify(pwdLdifs, DIR_MGR_DN, PWD, ctrlString);
    String userResults =
            LDAPSearchParams(level5User, PWD, null,null, null,
                    adminBase, filter, null);
    Assert.assertTrue(isRefMap(userResults));
  }
  /**
   * Test global ACI allowing the "ref" attribute type to be returned only if
   * if the search is under the people base. A search under the admin base
   * should not return a reference.
   *
   * @throws Exception If an unexpected result is returned.
   */
  @Test()
  public void testGlobalTargetAci() throws Exception {
    String pwdLdifs =
            makeAddLDIF(ATTR_AUTHZ_GLOBAL_ACI, ACCESS_HANDLER_DN, ALLOW_PEOPLE);
    LDIFModify(pwdLdifs, DIR_MGR_DN, PWD);
    //Fail, ACI only allows people references
    String userResults =
            LDAPSearchParams(level5User, PWD, null,null, null,
                    adminBase, filter, null);
    Assert.assertFalse(isRefMap(userResults));
    //Pass, ACI allows people references
    String userResults1 =
            LDAPSearchParams(level5User, PWD, null,null, null,
                    peopleBase, filter, null);
    Assert.assertTrue(isRefMap(userResults1));
  }
  /**
   * Test global ACI allowing the "ref" attribute type specifed by the
   * plus operator.
   *
   * @throws Exception If an unexpected result us returned.
   */
  @Test()
  public void testGlobalAci() throws Exception {
    String pwdLdifs =
           makeAddLDIF(ATTR_AUTHZ_GLOBAL_ACI, ACCESS_HANDLER_DN, ALLOW_OC_PLUS);
    LDIFModify(pwdLdifs, DIR_MGR_DN, PWD);
    String userResults =
            LDAPSearchParams(level5User, PWD, null,null, null,
                    adminBase, filter, null);
    Assert.assertTrue(isRefMap(userResults));
  }
  /**
   * Simple function that searches for the "SearchReference" string and returns
   * true if it is seen.
   *
   * @param resultString The string containing the results from the search.
   * @return True if the "SearchReference" string is seen in the results.
   */
  protected boolean
  isRefMap(String resultString) {
    boolean ret=false;
    StringReader r=new StringReader(resultString);
    BufferedReader br=new BufferedReader(r);
    try {
      while(true) {
        String s = br.readLine();
        if(s == null)
          break;
        if(s.startsWith("SearchReference")) {
          ret=true;
          break;
        }
      }
    } catch (IOException e) {
      Assert.assertEquals(0, 1,  e.getMessage());
    }
    return ret;
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetAttrTestCase.java
@@ -124,7 +124,7 @@
  public void setupClass() throws Exception {
    TestCaseUtils.startServer();
    deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
    addEntries();
    addEntries("o=test");
  }
  @AfterClass
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/TargetControlTestCase.java
@@ -63,7 +63,7 @@
  public void setupClass() throws Exception {
    TestCaseUtils.startServer();
    deleteAttrFromEntry(ACCESS_HANDLER_DN, ATTR_AUTHZ_GLOBAL_ACI);
    addEntries();
    addEntries("o=test");
  }
  @AfterClass