/**
   * Tests the second constructor, which creates an instance of the control using a processed DN.
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test()
  public void testConstructor2() throws Exception {
    // Try a DN of "null", which is not valid and will fail on the attempt to
    // create the control
    ProxiedAuthV1Control proxyControl;
    try {
      proxyControl = new ProxiedAuthV1Control((DN) null);
      throw new AssertionError(
          "Expected a failure when creating a proxied "
              + "auth V1 control with a null octet string.");
    } catch (Throwable t) {
    }

    // Try an empty DN, which is acceptable.
    proxyControl = new ProxiedAuthV1Control(DN.nullDN());
    assertTrue(proxyControl.getOID().equals(OID_PROXIED_AUTH_V1));
    assertTrue(proxyControl.isCritical());
    assertTrue(proxyControl.getAuthorizationDN().isNullDN());

    // Try a valid DN, which is acceptable.
    proxyControl = new ProxiedAuthV1Control(DN.decode("uid=test,o=test"));
    assertTrue(proxyControl.getOID().equals(OID_PROXIED_AUTH_V1));
    assertTrue(proxyControl.isCritical());
    assertEquals(proxyControl.getAuthorizationDN(), DN.decode("uid=test,o=test"));
  }
  /**
   * Verifies that the server will reject a CRAM-MD5 bind with credentials containing a malformed
   * digest.
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test()
  public void testMalformedDigest() throws Exception {
    InternalClientConnection conn = new InternalClientConnection(new AuthenticationInfo());
    BindOperation bindOperation = conn.processSASLBind(DN.nullDN(), SASL_MECHANISM_CRAM_MD5, null);
    assertEquals(bindOperation.getResultCode(), ResultCode.SASL_BIND_IN_PROGRESS);

    ByteString creds = ByteString.valueOf("dn:cn=Directory Manager malformeddigest");
    bindOperation = conn.processSASLBind(DN.nullDN(), SASL_MECHANISM_CRAM_MD5, creds);
    assertFalse(bindOperation.getResultCode() == ResultCode.SUCCESS);
  }
  /**
   * Tests the {@code getAuthorizationDN} and {@code setRawAuthorizationDN} methods.
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test()
  public void testGetAndSetAuthorizationDN() throws Exception {
    ProxiedAuthV1Control proxyControl = new ProxiedAuthV1Control(DN.nullDN());
    assertEquals(proxyControl.getRawAuthorizationDN(), ByteString.valueOf(""));
    assertEquals(proxyControl.getAuthorizationDN(), DN.nullDN());

    proxyControl = new ProxiedAuthV1Control(DN.decode("uid=test,o=test"));
    assertEquals(proxyControl.getRawAuthorizationDN(), ByteString.valueOf("uid=test,o=test"));
    assertEquals(proxyControl.getAuthorizationDN(), DN.decode("uid=test,o=test"));
  }
Example #4
0
 /**
  * This sets the error state when the user has attempted a fiendishly complex and stoopid request
  * that requires a mixture of 'deleteOldRDN=false' and 'deleteOldRDN=true'. Since JX does not
  * handle indeterminate quantum states, we throw an error instead.
  *
  * @param oldDN
  * @param newDN
  * @return
  */
 private boolean setWierdoRDNError(DN oldDN, DN newDN) {
   String msg =
       CBIntText.get(
               "The rename operation is too complex to proceed.  Try to break it up into smaller stages.")
           + "\n    "
           + oldDN.toString()
           + "\n => "
           + newDN.toString();
   return error(msg, new NamingException(msg));
 }
 /**
  * Verifies that the server will reject a CRAM-MD5 bind in which the first message contains SASL
  * credentials (which isn't allowed).
  *
  * @throws Exception If an unexpected problem occurs.
  */
 @Test()
 public void testOutOfSequenceBind() throws Exception {
   InternalClientConnection conn = new InternalClientConnection(new AuthenticationInfo());
   BindOperation bindOperation =
       conn.processSASLBind(DN.nullDN(), SASL_MECHANISM_CRAM_MD5, ByteString.valueOf("invalid"));
   assertFalse(bindOperation.getResultCode() == ResultCode.SUCCESS);
 }
Example #6
0
  // We initialize these for each new AciHandler so that we can clear
  // out the stale references that can occur during an in-core restart.
  private static void initStatics() {
    if ((aciType = DirectoryServer.getAttributeType("aci")) == null) {
      aciType = DirectoryServer.getDefaultAttributeType("aci");
    }

    if ((globalAciType = DirectoryServer.getAttributeType(ATTR_AUTHZ_GLOBAL_ACI)) == null) {
      globalAciType = DirectoryServer.getDefaultAttributeType(ATTR_AUTHZ_GLOBAL_ACI);
    }

    if ((debugSearchIndex =
            DirectoryServer.getAttributeType(EntryContainer.ATTR_DEBUG_SEARCH_INDEX))
        == null) {
      debugSearchIndex =
          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) {
      // Should never happen.
    }
  }
  /**
   * Attempt to read a single entry.
   *
   * @throws Exception If the test failed unexpectedly.
   */
  @Test(dependsOnMethods = {"testReadEntryEmptyStream"})
  public void testReadEntrySingle() throws Exception {
    final String ldifString =
        "dn: cn=john, dc=foo, dc=com\n"
            + "objectClass: top\n"
            + "objectClass: person\n"
            + "cn: john\n"
            + "sn: smith\n";

    LDIFReader reader = createLDIFReader(ldifString);

    try {
      Entry entry = reader.readEntry();
      Assert.assertNotNull(entry);

      Assert.assertEquals(entry.getDN(), DN.decode("cn=john, dc=foo, dc=com"));
      Assert.assertTrue(entry.hasObjectClass(OC_TOP));
      Assert.assertTrue(entry.hasObjectClass(OC_PERSON));
      Assert.assertTrue(entry.hasValue(AT_CN, null, AttributeValues.create(AT_CN, "john")));
      Assert.assertTrue(entry.hasValue(AT_SN, null, AttributeValues.create(AT_SN, "smith")));

      Assert.assertNull(reader.readEntry());

      Assert.assertEquals(reader.getEntriesIgnored(), 0);
      Assert.assertEquals(reader.getEntriesRead(), 1);
      Assert.assertEquals(reader.getEntriesRejected(), 0);
      Assert.assertEquals(reader.getLastEntryLineNumber(), 1);
    } finally {
      reader.close();
    }
  }
  /**
   * Tests whether an Unauthenticated BIND request will be allowed with the default configuration
   * settings for "ds-cfg-reject-unauthenticated-requests".
   */
  @Test()
  public void testUnauthBindDefCfg() {
    DirectoryServer.setRejectUnauthenticatedRequests(false);

    InternalClientConnection conn = new InternalClientConnection(new AuthenticationInfo());
    BindOperation bindOperation = conn.processSimpleBind(DN.nullDN(), null);
    assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS);
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method for a user that doesn't exist in the
   * directory data.
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test(expectedExceptions = {DirectoryException.class})
  public void testGetValidatedAuthorizationNonExistingNormalUser() throws Exception {
    TestCaseUtils.initializeTestBackend(true);

    ProxiedAuthV1Control proxyControl = new ProxiedAuthV1Control(DN.decode("uid=test,o=test"));

    proxyControl.getAuthorizationEntry();
  }
  /**
   * Generates an entry for a backup directory based on the provided DN. The DN must contain an RDN
   * component that specifies the path to the backup directory, and that directory must exist and be
   * a valid backup directory.
   *
   * @param entryDN The DN of the backup directory entry to retrieve.
   * @return The requested backup directory entry.
   * @throws DirectoryException If the specified directory does not exist or is not a valid backup
   *     directory, or if the DN does not specify any backup directory.
   */
  private Entry getBackupDirectoryEntry(DN entryDN) throws DirectoryException {
    // Make sure that the DN specifies a backup directory.
    AttributeType t = DirectoryServer.getAttributeType(ATTR_BACKUP_DIRECTORY_PATH, true);
    AttributeValue v = entryDN.getRDN().getAttributeValue(t);
    if (v == null) {
      Message message = ERR_BACKUP_DN_DOES_NOT_SPECIFY_DIRECTORY.get(String.valueOf(entryDN));
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message, backupBaseDN, null);
    }

    // Get a handle to the backup directory and the information that it
    // contains.
    BackupDirectory backupDirectory;
    try {
      backupDirectory = BackupDirectory.readBackupDirectoryDescriptor(v.getValue().toString());
    } catch (ConfigException ce) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, ce);
      }

      Message message =
          ERR_BACKUP_INVALID_BACKUP_DIRECTORY.get(String.valueOf(entryDN), ce.getMessage());
      throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message);
    } catch (Exception e) {
      if (debugEnabled()) {
        TRACER.debugCaught(DebugLogLevel.ERROR, e);
      }

      Message message = ERR_BACKUP_ERROR_GETTING_BACKUP_DIRECTORY.get(getExceptionMessage(e));
      throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), message);
    }

    // Construct the backup directory entry to return.
    LinkedHashMap<ObjectClass, String> ocMap = new LinkedHashMap<ObjectClass, String>(2);
    ocMap.put(DirectoryServer.getTopObjectClass(), OC_TOP);

    ObjectClass backupDirOC = DirectoryServer.getObjectClass(OC_BACKUP_DIRECTORY, true);
    ocMap.put(backupDirOC, OC_BACKUP_DIRECTORY);

    LinkedHashMap<AttributeType, List<Attribute>> opAttrs =
        new LinkedHashMap<AttributeType, List<Attribute>>(0);
    LinkedHashMap<AttributeType, List<Attribute>> userAttrs =
        new LinkedHashMap<AttributeType, List<Attribute>>(3);

    ArrayList<Attribute> attrList = new ArrayList<Attribute>(1);
    attrList.add(Attributes.create(t, v));
    userAttrs.put(t, attrList);

    t = DirectoryServer.getAttributeType(ATTR_BACKUP_BACKEND_DN, true);
    attrList = new ArrayList<Attribute>(1);
    attrList.add(
        Attributes.create(
            t, AttributeValues.create(t, backupDirectory.getConfigEntryDN().toString())));
    userAttrs.put(t, attrList);

    Entry e = new Entry(entryDN, ocMap, userAttrs, opAttrs);
    e.processVirtualAttributes();
    return e;
  }
 /**
  * Tests the {@code appliesToEntry} method.
  *
  * @param rule The rule for which to perform the test.
  * @param appliesToEntry Indicates whether the provided rule applies to a minimal "o=test" entry.
  * @throws Exception If an unexpected problem occurs.
  */
 @Test(dataProvider = "testRules")
 public void testAppliesToEntry(VirtualAttributeRule rule, boolean appliesToEntry)
     throws Exception {
   TestCaseUtils.initializeTestBackend(true);
   addGroups();
   assertEquals(
       rule.appliesToEntry(DirectoryConfig.getEntry(DN.decode("o=test"))), appliesToEntry);
   removeGroups();
 }
  /** Opens a dialog that displays the operational attributes of the current entry. */
  public void displayOperationalAttributes() {
    JXplorerBrowser jx = null;

    if (owner instanceof JXplorerBrowser) jx = (JXplorerBrowser) owner;
    else return;

    showingOperationalAttributes = !showingOperationalAttributes;

    // EJP 17 August 2010.
    // CB 14 August 2012 - some directories (looking at you Active Directory) don't support the '+'
    // operator... so do it manually as well...
    String[] opAttrs = {
      "+",
      "createTimeStamp",
      "creatorsName",
      "entryFlags",
      "federationBoundary",
      "localEntryID",
      "modifiersName",
      "modifyTimeStamp",
      "structuralObjectClass",
      "subordinateCount",
      "subschemaSubentry"
    };
    DXEntry entry = null;

    if (showingOperationalAttributes) {
      try {
        entry = (jx.getSearchBroker()).unthreadedReadEntry(currentDN, opAttrs);
        StringBuffer buffy = new StringBuffer("DN: " + currentDN.toString() + "\n\n");

        // Get the attribute values...
        // EJP 17 August 2010: use the actual attributes returned.
        NamingEnumeration ne = null;

        try {
          ne = entry.getAll();
          while (ne.hasMore()) {
            DXAttribute att = (DXAttribute) ne.next();
            buffy.append(att.getName() + ": " + att.get().toString() + "\n");

            tableData.insertOperationalAttribute(att);
          }
        } finally {
          if (ne != null) ne.close();
        }

        tableData.fireTableDataChanged();
      } catch (NamingException e) {
        CBUtility.error(
            TableAttributeEditor.this, CBIntText.get("Unable to read entry " + currentDN), e);
      }
    } else {
      tableData.removeOperationalAttributes();
      tableData.fireTableDataChanged();
    }
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method for a normal user that exists in the
   * directory data and doesn't have any restrictions on its use.
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test()
  public void testGetValidatedAuthorizationExistingNormalUser() throws Exception {
    TestCaseUtils.initializeTestBackend(true);
    TestCaseUtils.addEntry(
        "dn: uid=test,o=test",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "uid: test",
        "givenName: Test",
        "sn: User",
        "cn: Test User");

    ProxiedAuthV1Control proxyControl = new ProxiedAuthV1Control(DN.decode("uid=test,o=test"));

    assertEquals(proxyControl.getAuthorizationEntry().getDN(), DN.decode("uid=test,o=test"));
  }
Example #14
0
  /**
   * Update an entry with the designated DN.
   *
   * @param oldSet the old entry containing teh old set of attributes.
   * @param newSet the new entry containing the replacement set of attributes.
   * @return the operation's success status.
   */
  public boolean updateEntry(DXEntry oldSet, DXEntry newSet) {

    try {
      if (DXAttributes.attributesEqual(oldSet, newSet)) return true; // nothing to do.

      DN nodeDN = newSet.getDN();
      RDN newRDN = nodeDN.getLowestRDN();

      DXAttributes adds =
          null; // use modify-add for new attribute values (inc entirely new attribute)
      DXAttributes reps = null; // use modify-replace for changed attribute values
      DXAttributes dels =
          null; // use modify-delete for deleted attribute values (inc deleting entire attribute)

      reps = DXAttributes.getReplacementSet(newRDN, oldSet, newSet);
      dels = DXAttributes.getDeletionSet(newRDN, oldSet, newSet);
      adds = DXAttributes.getAdditionSet(newRDN, oldSet, newSet);

      /*if (false)
      printDebug(oldSet, newSet, adds, reps, dels);*/

      CBUtility.log("updateNode: ", 4);

      ModificationItem[] mods;

      mods = new ModificationItem[dels.size() + reps.size() + adds.size()];

      int modIndex = 0;
      modIndex = loadMods(mods, dels.getAll(), DirContext.REMOVE_ATTRIBUTE, modIndex);
      modIndex = loadMods(mods, adds.getAll(), DirContext.ADD_ATTRIBUTE, modIndex);
      modIndex = loadMods(mods, reps.getAll(), DirContext.REPLACE_ATTRIBUTE, modIndex);

      return modifyAttributes(nodeDN, mods); // TE: This may fail, returning false.
    } catch (NamingException e) {
      error("Unable to update node " + oldSet.getDN() + "! " + e.toString(), e);
      e.printStackTrace();
      return false;
    } catch (Exception e) {
      error("Unexpected Error updating node " + oldSet.getDN() + "! " + e.toString(), e);
      e.printStackTrace();
      return false;
    }
  }
  /**
   * Tests the {@code toString} methods.
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test()
  public void testToString() throws Exception {
    // The default toString() calls the version that takes a string builder
    // argument, so we only need to use the default version to cover both cases.
    ProxiedAuthV1Control proxyControl =
        new ProxiedAuthV1Control(ByteString.valueOf("uid=test,o=test"));
    proxyControl.toString();

    proxyControl = new ProxiedAuthV1Control(DN.decode("uid=test,o=test"));
    proxyControl.toString();
  }
Example #16
0
  /**
   * If the entry has changed its name, make the required calls to set up the display tree and make
   * the directory changes.
   *
   * @param oldEntry the old entry containing teh old set of attributes.
   * @param newEntry the new entry containing the replacement set of attributes.
   */
  private boolean handleAnyNameChange(DXEntry oldEntry, DXEntry newEntry) {
    // check for 'simple' rename from the tree, with no attributes involved.
    RDN oldRDN = oldEntry.getRDN();
    RDN newRDN = newEntry.getRDN();

    DN oldDN = oldEntry.getDN();
    DN newDN = newEntry.getDN();

    if (oldDN.equals(newDN)) return true; // nothing to see here, just move along.

    if (oldEntry.size() == 0
        && newEntry.size() == 0) // a very simple rename, probably from the tree
    {
      return moveTree(oldDN, newDN);
    } else if (oldRDN.isMultiValued() == false && newRDN.isMultiValued() == false) {
      return renameSingleValuedRDNS(oldEntry, newEntry);
    } else {
      return renameComplexMultiValuedRDNs(oldEntry, newEntry);
    }
  }
  /**
   * Indicates whether to include the entry with the specified DN in the import.
   *
   * @param dn The DN of the entry for which to make the determination.
   * @return <CODE>true</CODE> if the entry with the specified DN should be included in the import,
   *     or <CODE>false</CODE> if not.
   */
  public boolean includeEntry(DN dn) {
    if (!excludeBranches.isEmpty()) {
      for (DN excludeBranch : excludeBranches) {
        if (excludeBranch.isAncestorOf(dn)) {
          return false;
        }
      }
    }

    if (!includeBranches.isEmpty()) {
      for (DN includeBranch : includeBranches) {
        if (includeBranch.isAncestorOf(dn)) {
          return true;
        }
      }

      return false;
    }

    return true;
  }
  /** {@inheritDoc} */
  @Override
  public Entry getEntry(DN entryDN) throws DirectoryException {
    // If the requested entry was null, then throw an exception.
    if (entryDN == null) {
      throw new DirectoryException(
          DirectoryServer.getServerErrorResultCode(),
          ERR_BACKEND_GET_ENTRY_NULL.get(getBackendID()));
    }

    // If the requested entry was the backend base entry, then retrieve it.
    if (entryDN.equals(backupBaseDN)) {
      return backupBaseEntry.duplicate(true);
    }

    // See if the requested entry was one level below the backend base entry.
    // If so, then it must point to a backup directory.  Otherwise, it must be
    // two levels below the backup base entry and must point to a specific
    // backup.
    DN parentDN = entryDN.getParentDNInSuffix();
    if (parentDN == null) {
      Message message = ERR_BACKUP_INVALID_BASE.get(String.valueOf(entryDN));
      throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message);
    } else if (parentDN.equals(backupBaseDN)) {
      return getBackupDirectoryEntry(entryDN);
    } else if (backupBaseDN.equals(parentDN.getParentDNInSuffix())) {
      return getBackupEntry(entryDN);
    } else {
      Message message = ERR_BACKUP_INVALID_BASE.get(String.valueOf(entryDN));
      throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message, backupBaseDN, null);
    }
  }
  /**
   * Tests the {@code decodeControl} method when the control value is a valid octet string that
   * contains an valid non-empty DN.
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test()
  public void testDecodeControlValueNonEmptyDN() throws Exception {
    ByteStringBuilder bsb = new ByteStringBuilder();
    ASN1Writer writer = ASN1.getWriter(bsb);
    writer.writeStartSequence();
    writer.writeOctetString("uid=test,o=test");
    writer.writeEndSequence();
    LDAPControl c = new LDAPControl(OID_PROXIED_AUTH_V1, true, bsb.toByteString());

    ProxiedAuthV1Control proxyControl =
        ProxiedAuthV1Control.DECODER.decode(c.isCritical(), c.getValue());
    assertEquals(proxyControl.getAuthorizationDN(), DN.decode("uid=test,o=test"));
  }
  /**
   * Tests performing an internal search using the VLV control to retrieve a subset of the entries
   * using an assertion value that is after all values in the list.
   *
   * @throws Exception If an unexpected problem occurred.
   */
  @Test()
  public void testInternalSearchByValueAfterAll() throws Exception {
    populateDB();

    InternalClientConnection conn = InternalClientConnection.getRootConnection();

    ArrayList<Control> requestControls = new ArrayList<Control>();
    requestControls.add(new ServerSideSortRequestControl("sn"));
    requestControls.add(new VLVRequestControl(0, 3, ByteString.valueOf("zz")));

    InternalSearchOperation internalSearch =
        new InternalSearchOperation(
            conn,
            InternalClientConnection.nextOperationID(),
            InternalClientConnection.nextMessageID(),
            requestControls,
            DN.decode("dc=example,dc=com"),
            SearchScope.WHOLE_SUBTREE,
            DereferencePolicy.NEVER_DEREF_ALIASES,
            0,
            0,
            false,
            SearchFilter.createFilterFromString("(objectClass=person)"),
            null,
            null);

    internalSearch.run();

    // It will be successful because the control isn't critical.
    assertEquals(internalSearch.getResultCode(), ResultCode.SUCCESS);

    List<Control> responseControls = internalSearch.getResponseControls();
    assertNotNull(responseControls);

    VLVResponseControl vlvResponse = null;
    for (Control c : responseControls) {
      if (c.getOID().equals(OID_VLV_RESPONSE_CONTROL)) {
        if (c instanceof LDAPControl) {
          vlvResponse =
              VLVResponseControl.DECODER.decode(c.isCritical(), ((LDAPControl) c).getValue());
        } else {
          vlvResponse = (VLVResponseControl) c;
        }
      }
    }

    assertNotNull(vlvResponse);
    assertEquals(vlvResponse.getVLVResultCode(), LDAPResultCode.SUCCESS);
    assertEquals(vlvResponse.getTargetPosition(), 10);
    assertEquals(vlvResponse.getContentCount(), 9);
  }
  /**
   * Make sure that the server is running.
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @BeforeClass()
  public void startServer() throws Exception {
    TestCaseUtils.startServer();

    givenNameType = DirectoryServer.getAttributeType("givenname", false);
    assertNotNull(givenNameType);

    snType = DirectoryServer.getAttributeType("sn", false);
    assertNotNull(snType);

    aaccfJohnsonDN = DN.decode("uid=aaccf.johnson,dc=example,dc=com");
    aaronZimmermanDN = DN.decode("uid=aaron.zimmerman,dc=example,dc=com");
    albertSmithDN = DN.decode("uid=albert.smith,dc=example,dc=com");
    albertZimmermanDN = DN.decode("uid=albert.zimmerman,dc=example,dc=com");
    lowercaseMcGeeDN = DN.decode("uid=lowercase.mcgee,dc=example,dc=com");
    margaretJonesDN = DN.decode("uid=margaret.jones,dc=example,dc=com");
    maryJonesDN = DN.decode("uid=mary.jones,dc=example,dc=com");
    samZweckDN = DN.decode("uid=sam.zweck,dc=example,dc=com");
    zorroDN = DN.decode("uid=zorro,dc=example,dc=com");
  }
Example #22
0
 /**
  * Process all global ACI attribute types found in the configuration entry and adds them to that
  * ACI list cache. It also logs messages about the number of ACI attribute types added to the
  * cache. This method is called once at startup. It also will put the server into lockdown mode if
  * needed.
  *
  * @param configuration The config handler containing the ACI configuration information.
  * @throws InitializationException If there is an error reading the global ACIs from the
  *     configuration entry.
  */
 private void processGlobalAcis(DseeCompatAccessControlHandlerCfg configuration)
     throws InitializationException {
   SortedSet<Aci> globalAcis = configuration.getGlobalACI();
   try {
     if (globalAcis != null) {
       aciList.addAci(DN.nullDN(), globalAcis);
       Message message = INFO_ACI_ADD_LIST_GLOBAL_ACIS.get(Integer.toString(globalAcis.size()));
       logError(message);
     }
   } catch (Exception e) {
     if (debugEnabled()) {
       TRACER.debugCaught(DebugLogLevel.ERROR, e);
     }
     Message message =
         INFO_ACI_HANDLER_FAIL_PROCESS_GLOBAL_ACI.get(String.valueOf(configuration.dn()));
     throw new InitializationException(message, e);
   }
 }
  /**
   * Tests whether authenticated and unauthenticated BIND requests will be allowed with the new
   * configuration settings for "ds-cfg-reject-unauthenticated-requests" .
   */
  @Test
  public void testBindNewCfg() {
    try {
      DirectoryServer.setRejectUnauthenticatedRequests(true);

      InternalClientConnection conn = new InternalClientConnection(new AuthenticationInfo());
      ByteString user = ByteString.valueOf("cn=Directory Manager");
      ByteString password = ByteString.valueOf("password");
      // Unauthenticated BIND request.
      BindOperation bindOperation = conn.processSimpleBind(DN.nullDN(), null);
      assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS);
      // Authenticated BIND request.
      bindOperation = conn.processSimpleBind(user, password);
      assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS);
    } finally {
      DirectoryServer.setRejectUnauthenticatedRequests(false);
    }
  }
  /**
   * Tests the {@code getValidatedAuthorizationDN} method for a disabled user.
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test(expectedExceptions = {DirectoryException.class})
  public void testGetValidatedAuthorizationDisabledUser() throws Exception {
    TestCaseUtils.initializeTestBackend(true);
    TestCaseUtils.addEntry(
        "dn: uid=test,o=test",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "uid: test",
        "givenName: Test",
        "sn: User",
        "cn: Test User",
        "ds-pwp-account-disabled: true");

    ProxiedAuthV1Control proxyControl = new ProxiedAuthV1Control(DN.decode("uid=test,o=test"));

    proxyControl.getAuthorizationEntry();
  }
  /**
   * Performs the processing necessary for an anonymous simple bind.
   *
   * @return {@code true} if processing should continue for the operation, or {@code false} if not.
   * @throws DirectoryException If a problem occurs that should cause the bind operation to fail.
   */
  protected boolean processAnonymousSimpleBind() throws DirectoryException {
    // If the server is in lockdown mode, then fail.
    if (DirectoryServer.lockdownMode()) {
      throw new DirectoryException(
          ResultCode.INVALID_CREDENTIALS, ERR_BIND_REJECTED_LOCKDOWN_MODE.get());
    }

    // If there is a bind DN, then see whether that is acceptable.
    if (DirectoryServer.bindWithDNRequiresPassword() && bindDN != null && !bindDN.isRootDN()) {
      throw new DirectoryException(
          ResultCode.UNWILLING_TO_PERFORM, ERR_BIND_DN_BUT_NO_PASSWORD.get());
    }

    // Invoke pre-operation plugins.
    if (!invokePreOpPlugins()) {
      return false;
    }

    setResultCode(ResultCode.SUCCESS);
    setAuthenticationInfo(new AuthenticationInfo());
    return true;
  }
Example #26
0
 /**
  * Test the attribute types of the search filter for access. This method supports the search
  * right.
  *
  * @param container The container used in the access evaluation.
  * @param filter The filter to check access on.
  * @return True if all attribute types in the filter have access.
  * @throws DirectoryException If there is a problem matching the entry using the provided filter.
  */
 private boolean testFilter(AciLDAPOperationContainer container, SearchFilter filter)
     throws DirectoryException {
   boolean ret = true;
   // If the resource entry has a dn equal to "cn=debugsearch" and it
   // contains the special attribute type "debugsearchindex", then the
   // resource entry is a pseudo entry created for debug purposes.
   // Return true if that is the case.
   if (debugSearchIndexDN.equals(container.getResourceDN())
       && container.getResourceEntry().hasAttribute(debugSearchIndex)) {
     return true;
   }
   switch (filter.getFilterType()) {
     case AND:
     case OR:
       {
         for (SearchFilter f : filter.getFilterComponents()) {
           if (!testFilter(container, f)) {
             return false;
           }
         }
         break;
       }
     case NOT:
       {
         SearchFilter f = filter.getNotComponent();
         ret = testFilter(container, f);
         break;
       }
     default:
       {
         AttributeType attrType = filter.getAttributeType();
         container.setCurrentAttributeType(attrType);
         ret = accessAllowed(container);
       }
   }
   return ret;
 }
  /**
   * Attempt to read a change containing a file-based attribute.
   *
   * @throws Exception If the test failed unexpectedly.
   */
  @Test(dependsOnMethods = {"testReadChangeMultiple"})
  public void testReadChangeWithFileBaseAttribute() throws Exception {
    StringBuilder buffer = new StringBuilder(TEMP_FILE_LDIF);
    buffer.append(TEMP_FILE.getCanonicalPath());
    buffer.append("\n");
    LDIFReader reader = createLDIFReader(buffer.toString());

    try {
      ChangeRecordEntry change = reader.readChangeRecord(false);
      Assert.assertTrue(change instanceof AddChangeRecordEntry);
      AddChangeRecordEntry add = (AddChangeRecordEntry) change;

      DN dn = DN.decode("cn=john smith, dc=com");
      Assert.assertEquals(add.getDN(), dn);

      Attribute attr = Attributes.create("description", TEMP_FILE_STRING);
      Assert.assertTrue(add.getAttributes().contains(attr));

      // Check final state.
      Assert.assertNull(reader.readChangeRecord(false));
    } finally {
      reader.close();
    }
  }
  /**
   * Tests performing an internal search using the VLV control to retrieve a subset of the entries
   * using an assertion value before any actual value in the list.
   *
   * @throws Exception If an unexpected problem occurred.
   */
  @Test()
  public void testInternalSearchByValueBeforeAll() throws Exception {
    populateDB();

    InternalClientConnection conn = InternalClientConnection.getRootConnection();

    ArrayList<Control> requestControls = new ArrayList<Control>();
    requestControls.add(new ServerSideSortRequestControl("givenName"));
    requestControls.add(new VLVRequestControl(0, 3, ByteString.valueOf("a")));

    InternalSearchOperation internalSearch =
        new InternalSearchOperation(
            conn,
            InternalClientConnection.nextOperationID(),
            InternalClientConnection.nextMessageID(),
            requestControls,
            DN.decode("dc=example,dc=com"),
            SearchScope.WHOLE_SUBTREE,
            DereferencePolicy.NEVER_DEREF_ALIASES,
            0,
            0,
            false,
            SearchFilter.createFilterFromString("(objectClass=person)"),
            null,
            null);

    internalSearch.run();
    assertEquals(internalSearch.getResultCode(), ResultCode.SUCCESS);

    ArrayList<DN> expectedDNOrder = new ArrayList<DN>();
    expectedDNOrder.add(aaccfJohnsonDN); // Aaccf
    expectedDNOrder.add(aaronZimmermanDN); // Aaron
    expectedDNOrder.add(albertZimmermanDN); // Albert, lower entry ID
    expectedDNOrder.add(albertSmithDN); // Albert, higher entry ID

    ArrayList<DN> returnedDNOrder = new ArrayList<DN>();
    for (Entry e : internalSearch.getSearchEntries()) {
      returnedDNOrder.add(e.getDN());
    }

    assertEquals(returnedDNOrder, expectedDNOrder);

    List<Control> responseControls = internalSearch.getResponseControls();
    assertNotNull(responseControls);
    assertEquals(responseControls.size(), 2);

    ServerSideSortResponseControl sortResponse = null;
    VLVResponseControl vlvResponse = null;
    for (Control c : responseControls) {
      if (c.getOID().equals(OID_SERVER_SIDE_SORT_RESPONSE_CONTROL)) {
        if (c instanceof LDAPControl) {
          sortResponse =
              ServerSideSortResponseControl.DECODER.decode(
                  c.isCritical(), ((LDAPControl) c).getValue());
        } else {
          sortResponse = (ServerSideSortResponseControl) c;
        }
      } else if (c.getOID().equals(OID_VLV_RESPONSE_CONTROL)) {
        if (c instanceof LDAPControl) {
          vlvResponse =
              VLVResponseControl.DECODER.decode(c.isCritical(), ((LDAPControl) c).getValue());
        } else {
          vlvResponse = (VLVResponseControl) c;
        }
      } else {
        fail("Response control with unexpected OID " + c.getOID());
      }
    }

    assertNotNull(sortResponse);
    assertEquals(sortResponse.getResultCode(), 0);

    assertNotNull(vlvResponse);
    assertEquals(vlvResponse.getVLVResultCode(), 0);
    assertEquals(vlvResponse.getTargetPosition(), 1);
    assertEquals(vlvResponse.getContentCount(), 9);
  }
  /**
   * Tests performing an internal search using the VLV control with a start start position beyond
   * the end of the result set.
   *
   * @throws Exception If an unexpected problem occurred.
   */
  @Test()
  public void testInternalSearchByOffsetStartPositionTooHigh() throws Exception {
    populateDB();

    InternalClientConnection conn = InternalClientConnection.getRootConnection();

    ArrayList<Control> requestControls = new ArrayList<Control>();
    requestControls.add(new ServerSideSortRequestControl("givenName"));
    requestControls.add(new VLVRequestControl(3, 3, 30, 0));

    InternalSearchOperation internalSearch =
        new InternalSearchOperation(
            conn,
            InternalClientConnection.nextOperationID(),
            InternalClientConnection.nextMessageID(),
            requestControls,
            DN.decode("dc=example,dc=com"),
            SearchScope.WHOLE_SUBTREE,
            DereferencePolicy.NEVER_DEREF_ALIASES,
            0,
            0,
            false,
            SearchFilter.createFilterFromString("(objectClass=person)"),
            null,
            null);

    internalSearch.run();

    assertEquals(internalSearch.getResultCode(), ResultCode.SUCCESS);

    ArrayList<DN> expectedDNOrder = new ArrayList<DN>();
    expectedDNOrder.add(maryJonesDN); // Mary
    expectedDNOrder.add(samZweckDN); // Sam
    expectedDNOrder.add(zorroDN); // No first name

    ArrayList<DN> returnedDNOrder = new ArrayList<DN>();
    for (Entry e : internalSearch.getSearchEntries()) {
      returnedDNOrder.add(e.getDN());
    }

    assertEquals(returnedDNOrder, expectedDNOrder);

    List<Control> responseControls = internalSearch.getResponseControls();
    assertNotNull(responseControls);

    VLVResponseControl vlvResponse = null;
    for (Control c : responseControls) {
      if (c.getOID().equals(OID_VLV_RESPONSE_CONTROL)) {
        if (c instanceof LDAPControl) {
          vlvResponse =
              VLVResponseControl.DECODER.decode(c.isCritical(), ((LDAPControl) c).getValue());
        } else {
          vlvResponse = (VLVResponseControl) c;
        }
      }
    }

    assertNotNull(vlvResponse);
    assertEquals(vlvResponse.getVLVResultCode(), LDAPResultCode.SUCCESS);
    assertEquals(vlvResponse.getTargetPosition(), 10);
    assertEquals(vlvResponse.getContentCount(), 9);
  }
Example #30
0
  /**
   * Checks to see if a LDAP modification is allowed access.
   *
   * @param container The structure containing the LDAP modifications
   * @param operation The operation to check modify privileges on. operation to check and the
   *     evaluation context to apply the check against.
   * @param skipAccessCheck True if access checking should be skipped.
   * @return True if access is allowed.
   * @throws DirectoryException If a modified ACI could not be decoded.
   */
  private boolean aciCheckMods(
      AciLDAPOperationContainer container,
      LocalBackendModifyOperation operation,
      boolean skipAccessCheck)
      throws DirectoryException {
    Entry resourceEntry = container.getResourceEntry();
    DN dn = resourceEntry.getDN();
    List<Modification> modifications = operation.getModifications();

    for (Modification m : modifications) {
      Attribute modAttr = m.getAttribute();
      AttributeType modAttrType = modAttr.getAttributeType();

      if (modAttrType.equals(aciType)) {
        /*
         * Check that the operation has modify privileges if it contains
         * an "aci" attribute type.
         */
        if (!operation.getClientConnection().hasPrivilege(Privilege.MODIFY_ACL, operation)) {
          Message message =
              INFO_ACI_MODIFY_FAILED_PRIVILEGE.get(
                  String.valueOf(container.getResourceDN()),
                  String.valueOf(container.getClientDN()));
          logError(message);
          return false;
        }
      }
      // This access check handles the case where all attributes of this
      // type are being replaced or deleted. If only a subset is being
      // deleted than this access check is skipped.
      ModificationType modType = m.getModificationType();
      if (((modType == ModificationType.DELETE) && modAttr.isEmpty())
          || ((modType == ModificationType.REPLACE) || (modType == ModificationType.INCREMENT))) {
        /*
         * Check if we have rights to delete all values of an attribute
         * type in the resource entry.
         */
        if (resourceEntry.hasAttribute(modAttrType)) {
          container.setCurrentAttributeType(modAttrType);
          List<Attribute> attrList = resourceEntry.getAttribute(modAttrType, modAttr.getOptions());
          if (attrList != null) {
            for (Attribute a : attrList) {
              for (AttributeValue v : a) {
                container.setCurrentAttributeValue(v);
                container.setRights(ACI_WRITE_DELETE);
                if (!skipAccessCheck && !accessAllowed(container)) {
                  return false;
                }
              }
            }
          }
        }
      }

      if (!modAttr.isEmpty()) {
        for (AttributeValue v : modAttr) {
          container.setCurrentAttributeType(modAttrType);
          switch (m.getModificationType()) {
            case ADD:
            case REPLACE:
              container.setCurrentAttributeValue(v);
              container.setRights(ACI_WRITE_ADD);
              if (!skipAccessCheck && !accessAllowed(container)) {
                return false;
              }
              break;
            case DELETE:
              container.setCurrentAttributeValue(v);
              container.setRights(ACI_WRITE_DELETE);
              if (!skipAccessCheck && !accessAllowed(container)) {
                return false;
              }
              break;
            case INCREMENT:
              Entry modifiedEntry = operation.getModifiedEntry();
              List<Attribute> modifiedAttrs =
                  modifiedEntry.getAttribute(modAttrType, modAttr.getOptions());
              if (modifiedAttrs != null) {
                for (Attribute attr : modifiedAttrs) {
                  for (AttributeValue val : attr) {
                    container.setCurrentAttributeValue(val);
                    container.setRights(ACI_WRITE_ADD);
                    if (!skipAccessCheck && !accessAllowed(container)) {
                      return false;
                    }
                  }
                }
              }
              break;
          }
          /*
           * Check if the modification type has an "aci" attribute type.
           * If so, check the syntax of that attribute value. Fail the
           * the operation if the syntax check fails.
           */
          if (modAttrType.equals(aciType) || modAttrType.equals(globalAciType)) {
            try {
              // A global ACI needs a NULL DN, not the DN of the
              // modification.
              if (modAttrType.equals(globalAciType)) {
                dn = DN.nullDN();
              }
              Aci.decode(v.getValue(), dn);
            } catch (AciException ex) {
              Message message =
                  WARN_ACI_MODIFY_FAILED_DECODE.get(String.valueOf(dn), ex.getMessage());
              throw new DirectoryException(ResultCode.INVALID_ATTRIBUTE_SYNTAX, message);
            }
          }
        }
      }
    }
    return true;
  }