/**
  * 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);
 }
  /**
   * Tests performing an internal search using the CRITICAL server-side sort control with an
   * undefined attribute type.
   *
   * @throws Exception If an unexpected problem occurred.
   */
  @Test()
  public void testCriticalSortWithUndefinedAttribute() throws Exception {
    populateDB();

    InternalClientConnection conn = InternalClientConnection.getRootConnection();

    ArrayList<Control> requestControls = new ArrayList<Control>();
    requestControls.add(new ServerSideSortRequestControl(true, "undefined"));

    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.UNAVAILABLE_CRITICAL_EXTENSION);
  }
  /**
   * Tests performing an internal search using the server-side sort control with an undefined
   * ordering rule.
   *
   * @throws Exception If an unexpected problem occurred.
   */
  @Test()
  public void testInternalSearchUndefinedOrderingRule() throws Exception {
    populateDB();

    InternalClientConnection conn = InternalClientConnection.getRootConnection();

    ArrayList<Control> requestControls = new ArrayList<Control>();
    requestControls.add(new ServerSideSortRequestControl(true, "givenName:undefinedOrderingMatch"));

    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();
    assertFalse(internalSearch.getResultCode() == ResultCode.SUCCESS);
  }
  @BeforeClass()
  public void setUp() throws Exception {
    TestCaseUtils.startServer();
    TestCaseUtils.clearJEBackend(false, "userRoot", SUFFIX);

    InternalClientConnection connection = InternalClientConnection.getRootConnection();

    // Add suffix entry.
    DN suffixDN = DN.decode(SUFFIX);
    if (DirectoryServer.getEntry(suffixDN) == null) {
      Entry suffixEntry = StaticUtils.createEntry(suffixDN);
      AddOperation addOperation =
          connection.processAdd(
              suffixEntry.getDN(),
              suffixEntry.getObjectClasses(),
              suffixEntry.getUserAttributes(),
              suffixEntry.getOperationalAttributes());
      assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
      assertNotNull(DirectoryServer.getEntry(suffixEntry.getDN()));
    }

    // Add base entry.
    DN baseDN = DN.decode(BASE);
    if (DirectoryServer.getEntry(baseDN) == null) {
      Entry baseEntry = StaticUtils.createEntry(baseDN);
      AddOperation addOperation =
          connection.processAdd(
              baseEntry.getDN(),
              baseEntry.getObjectClasses(),
              baseEntry.getUserAttributes(),
              baseEntry.getOperationalAttributes());
      assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
      assertNotNull(DirectoryServer.getEntry(baseEntry.getDN()));
    }

    // Add test entry.
    Entry testEntry =
        TestCaseUtils.makeEntry(
            "dn: uid=rogasawara," + BASE,
            "objectclass: top",
            "objectclass: person",
            "objectclass: organizationalPerson",
            "objectclass: inetOrgPerson",
            "uid: rogasawara",
            "userpassword: password",
            "mail: [email protected]",
            "givenname: Rodney",
            "sn: Ogasawara",
            "cn: Rodney Ogasawara",
            "title: Sales, Director");
    AddOperation addOperation =
        connection.processAdd(
            testEntry.getDN(),
            testEntry.getObjectClasses(),
            testEntry.getUserAttributes(),
            testEntry.getOperationalAttributes());
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    assertNotNull(DirectoryServer.getEntry(testEntry.getDN()));
  }
  /**
   * 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 use of the StartTLS extended operation to communicate with the server in conjunction
   * with SASL EXTERNAL authentication and using a client trust store to validate the server
   * certificate.
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test()
  public void testStartTLSExternalAuthTrustStore() throws Exception {
    TestCaseUtils.initializeTestBackend(true);

    Entry e =
        TestCaseUtils.makeEntry(
            "dn: cn=Test User,o=test",
            "objectClass: top",
            "objectClass: person",
            "objectClass: organizationalPerson",
            "objectClass: inetOrgPerson",
            "cn: Test User",
            "givenName: Test",
            "sn: User");

    InternalClientConnection conn = InternalClientConnection.getRootConnection();
    AddOperation addOperation =
        conn.processAdd(
            e.getDN(), e.getObjectClasses(), e.getUserAttributes(), e.getOperationalAttributes());
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);

    String keyStorePath =
        DirectoryServer.getInstanceRoot()
            + File.separator
            + "config"
            + File.separator
            + "client.keystore";
    String trustStorePath =
        DirectoryServer.getInstanceRoot()
            + File.separator
            + "config"
            + File.separator
            + "client.truststore";

    String[] args = {
      "--noPropertiesFile",
      "-h",
      "127.0.0.1",
      "-p",
      String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-q",
      "-K",
      keyStorePath,
      "-W",
      "password",
      "-P",
      trustStorePath,
      "-r",
      "-b",
      "",
      "-s",
      "base",
      "(objectClass=*)"
    };

    assertEquals(LDAPSearch.mainSearch(args, false, null, System.err), 0);
  }
예제 #7
0
  /**
   * Process all ACIs under the "cn=config" naming context and adds them to the ACI list cache. It
   * also logs messages about the number of ACIs added to the cache. This method is called once at
   * startup. It will put the server in lockdown mode if needed.
   *
   * @throws InitializationException If there is an error searching for the ACIs in the naming
   *     context.
   */
  private void processConfigAcis() throws InitializationException {
    LinkedHashSet<String> requestAttrs = new LinkedHashSet<String>(1);
    requestAttrs.add("aci");
    LinkedList<Message> failedACIMsgs = new LinkedList<Message>();
    InternalClientConnection conn = InternalClientConnection.getRootConnection();

    ConfigHandler configBackend = DirectoryServer.getConfigHandler();
    for (DN baseDN : configBackend.getBaseDNs()) {
      try {
        if (!configBackend.entryExists(baseDN)) {
          continue;
        }
      } catch (Exception e) {
        if (debugEnabled()) {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }

        // FIXME -- Is there anything that we need to do here?
        continue;
      }

      try {
        InternalSearchOperation internalSearch =
            new InternalSearchOperation(
                conn,
                InternalClientConnection.nextOperationID(),
                InternalClientConnection.nextMessageID(),
                null,
                baseDN,
                SearchScope.WHOLE_SUBTREE,
                DereferencePolicy.NEVER_DEREF_ALIASES,
                0,
                0,
                false,
                SearchFilter.createFilterFromString("aci=*"),
                requestAttrs,
                null);
        LocalBackendSearchOperation localSearch = new LocalBackendSearchOperation(internalSearch);

        configBackend.search(localSearch);

        if (!internalSearch.getSearchEntries().isEmpty()) {
          int validAcis = aciList.addAci(internalSearch.getSearchEntries(), failedACIMsgs);
          if (!failedACIMsgs.isEmpty()) {
            aciListenerMgr.logMsgsSetLockDownMode(failedACIMsgs);
          }
          Message message =
              INFO_ACI_ADD_LIST_ACIS.get(Integer.toString(validAcis), String.valueOf(baseDN));
          logError(message);
        }
      } catch (Exception e) {
        Message message = INFO_ACI_HANDLER_FAIL_PROCESS_ACI.get();
        throw new InitializationException(message, e);
      }
    }
  }
  /**
   * Tests whether an authenticated BIND request will be allowed with the default configuration
   * settings for "ds-cfg-reject-unauthenticated-requests" .
   */
  @Test()
  public void testAuthBindDefCfg() {
    DirectoryServer.setRejectUnauthenticatedRequests(false);

    InternalClientConnection conn = new InternalClientConnection(new AuthenticationInfo());
    ByteString user = ByteString.valueOf("cn=Directory Manager");
    ByteString password = ByteString.valueOf("password");
    BindOperation bindOperation = conn.processSimpleBind(user, password);
    assertEquals(bindOperation.getResultCode(), ResultCode.SUCCESS);
  }
  /**
   * Ensures that password policy creation will fail when given an invalid configuration.
   *
   * @param e The entry containing an invalid password policy configuration.
   * @throws Exception If an unexpected problem occurs.
   */
  @Test(dataProvider = "invalidConfigs")
  public void testInvalidConfigurations(Entry e) throws Exception {
    InternalClientConnection connection = InternalClientConnection.getRootConnection();

    AddOperation addOperation =
        connection.processAdd(
            e.getDN(), e.getObjectClasses(), e.getUserAttributes(), e.getOperationalAttributes());
    assertTrue(addOperation.getResultCode() != ResultCode.SUCCESS);
    assertNull(DirectoryServer.getEntry(e.getDN()));
  }
  /**
   * 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 whether the Who Am I? extended operation with an internal authenticated connection
   * succeeds with new setting of "ds-cfg-reject-unauthenticated-requests".
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test
  public void testAuthWAINewCfg() throws Exception {
    try {
      DirectoryServer.setRejectUnauthenticatedRequests(true);

      InternalClientConnection conn = InternalClientConnection.getRootConnection();
      ExtendedOperation extOp = conn.processExtendedOperation(OID_WHO_AM_I_REQUEST, null);
      assertEquals(extOp.getResultCode(), ResultCode.SUCCESS);
      assertNotNull(extOp.getResponseValue());
    } finally {
      DirectoryServer.setRejectUnauthenticatedRequests(false);
    }
  }
  /**
   * 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);
  }
  /**
   * Performs a successful LDAP bind using CRAM-MD5 using the dn: form of the authentication ID
   * using a long password (longer than 64 bytes).
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test()
  public void testLDAPBindSuccessWithDNAndLongPassword() throws Exception {
    TestCaseUtils.initializeTestBackend(true);

    String password = "******";

    Entry e =
        TestCaseUtils.makeEntry(
            "dn: uid=test.user,o=test",
            "objectClass: top",
            "objectClass: person",
            "objectClass: organizationalPerson",
            "objectClass: inetOrgPerson",
            "uid: test.user",
            "givenName: Test",
            "sn: User",
            "cn: Test User",
            "userPassword: "******"ds-pwp-password-policy-dn: cn=Clear UserPassword Policy,"
                + "cn=Password Policies,cn=config");

    InternalClientConnection conn = InternalClientConnection.getRootConnection();
    AddOperation addOperation =
        conn.processAdd(
            e.getDN(), e.getObjectClasses(),
            e.getUserAttributes(), e.getOperationalAttributes());
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);

    String[] args = {
      "--noPropertiesFile",
      "-h",
      "127.0.0.1",
      "-p",
      String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-o",
      "mech=CRAM-MD5",
      "-o",
      "authid=dn:uid=test.user,o=test",
      "-w",
      password,
      "-b",
      "",
      "-s",
      "base",
      "(objectClass=*)"
    };
    assertEquals(LDAPSearch.mainSearch(args, false, null, System.err), 0);
  }
  @Test()
  public void testInvalidRequest() throws Exception {
    CryptoManagerImpl cm = DirectoryServer.getCryptoManager();

    String symmetricKey = "1";
    String instanceKeyID = cm.getInstanceKeyID();

    ByteString requestValue =
        GetSymmetricKeyExtendedOperation.encodeRequestValue(symmetricKey, instanceKeyID);

    InternalClientConnection internalConnection = InternalClientConnection.getRootConnection();
    ExtendedOperation extendedOperation =
        internalConnection.processExtendedOperation(
            ServerConstants.OID_GET_SYMMETRIC_KEY_EXTENDED_OP, requestValue);

    assertFalse(extendedOperation.getResultCode() == ResultCode.SUCCESS);
  }
  /**
   * 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);
    }
  }
  /**
   * Performs a failed LDAP bind using CRAM-MD5 using the dn: form of the authentication ID with the
   * DN of a user that doesn't exist.
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test()
  public void testLDAPBindFailNoSuchUser() throws Exception {
    TestCaseUtils.initializeTestBackend(true);

    Entry e =
        TestCaseUtils.makeEntry(
            "dn: uid=test.user,o=test",
            "objectClass: top",
            "objectClass: person",
            "objectClass: organizationalPerson",
            "objectClass: inetOrgPerson",
            "uid: test.user",
            "givenName: Test",
            "sn: User",
            "cn: Test User",
            "userPassword: password");

    InternalClientConnection conn = InternalClientConnection.getRootConnection();
    AddOperation addOperation =
        conn.processAdd(
            e.getDN(), e.getObjectClasses(),
            e.getUserAttributes(), e.getOperationalAttributes());
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);

    String[] args = {
      "--noPropertiesFile",
      "-h",
      "127.0.0.1",
      "-p",
      String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-o",
      "mech=CRAM-MD5",
      "-o",
      "authid=dn:uid=doesntexist,o=test",
      "-w",
      "password",
      "-b",
      "",
      "-s",
      "base",
      "(objectClass=*)"
    };
    assertFalse(LDAPSearch.mainSearch(args, false, null, null) == 0);
  }
  /**
   * Tests performing an internal search using the non-critical server-side sort control to sort the
   * entries
   *
   * @throws Exception If an unexpected problem occurred.
   */
  @Test()
  public void testNonCriticalSortWithUndefinedAttribute() throws Exception {
    populateDB();
    InternalClientConnection conn = InternalClientConnection.getRootConnection();

    ArrayList<Control> requestControls = new ArrayList<Control>();
    requestControls.add(new ServerSideSortRequestControl(false, "bad_sort:caseExactOrderingMatch"));

    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);
    List<Control> responseControls = internalSearch.getResponseControls();
    assertNotNull(responseControls);
    assertEquals(responseControls.size(), 1);

    ServerSideSortResponseControl responseControl;
    Control c = responseControls.get(0);
    if (c instanceof ServerSideSortResponseControl) {
      responseControl = (ServerSideSortResponseControl) c;
    } else {
      responseControl =
          ServerSideSortResponseControl.DECODER.decode(
              c.isCritical(), ((LDAPControl) c).getValue());
    }
    assertEquals(responseControl.getResultCode(), 16);
  }
  @Test(enabled = true)
  public void testValidRequest() throws Exception {
    final CryptoManagerImpl cm = DirectoryServer.getCryptoManager();
    final String secretMessage = "zyxwvutsrqponmlkjihgfedcba";
    final String cipherTransformationName = "AES/CBC/PKCS5Padding";
    final int cipherKeyLength = 128;

    CryptoManagerImpl.publishInstanceKeyEntryInADS();

    // Initial encryption ensures a cipher key entry is in ADS.
    cm.encrypt(cipherTransformationName, cipherKeyLength, secretMessage.getBytes());

    // Retrieve all uncompromised cipher key entries corresponding to the
    // specified transformation and key length.
    final String baseDNStr // TODO: is this DN defined elsewhere as a constant?
        = "cn=secret keys," + ADSContext.getAdministrationSuffixDN();
    final DN baseDN = DN.decode(baseDNStr);
    final String FILTER_OC_INSTANCE_KEY =
        new StringBuilder("(objectclass=")
            .append(ConfigConstants.OC_CRYPTO_CIPHER_KEY)
            .append(")")
            .toString();
    final String FILTER_NOT_COMPROMISED =
        new StringBuilder("(!(")
            .append(ConfigConstants.ATTR_CRYPTO_KEY_COMPROMISED_TIME)
            .append("=*))")
            .toString();
    final String FILTER_CIPHER_TRANSFORMATION_NAME =
        new StringBuilder("(")
            .append(ConfigConstants.ATTR_CRYPTO_CIPHER_TRANSFORMATION_NAME)
            .append("=")
            .append(cipherTransformationName)
            .append(")")
            .toString();
    final String FILTER_CIPHER_KEY_LENGTH =
        new StringBuilder("(")
            .append(ConfigConstants.ATTR_CRYPTO_KEY_LENGTH_BITS)
            .append("=")
            .append(String.valueOf(cipherKeyLength))
            .append(")")
            .toString();
    final String searchFilter =
        new StringBuilder("(&")
            .append(FILTER_OC_INSTANCE_KEY)
            .append(FILTER_NOT_COMPROMISED)
            .append(FILTER_CIPHER_TRANSFORMATION_NAME)
            .append(FILTER_CIPHER_KEY_LENGTH)
            .append(")")
            .toString();
    final LinkedHashSet<String> requestedAttributes = new LinkedHashSet<String>();
    requestedAttributes.add(ConfigConstants.ATTR_CRYPTO_SYMMETRIC_KEY);
    final InternalClientConnection icc = InternalClientConnection.getRootConnection();
    InternalSearchOperation searchOp =
        icc.processSearch(
            baseDN,
            SearchScope.SINGLE_LEVEL,
            DereferencePolicy.NEVER_DEREF_ALIASES,
            /* size limit */ 0, /* time limit */
            0,
            /* types only */ false,
            SearchFilter.createFilterFromString(searchFilter),
            requestedAttributes);
    assertTrue(0 < searchOp.getSearchEntries().size());

    final InternalClientConnection internalConnection =
        InternalClientConnection.getRootConnection();
    final String instanceKeyID = cm.getInstanceKeyID();
    final AttributeType attrSymmetricKey =
        DirectoryServer.getAttributeType(ConfigConstants.ATTR_CRYPTO_SYMMETRIC_KEY);
    for (Entry e : searchOp.getSearchEntries()) {
      final String symmetricKeyAttributeValue =
          e.getAttributeValue(attrSymmetricKey, DirectoryStringSyntax.DECODER);
      final ByteString requestValue =
          GetSymmetricKeyExtendedOperation.encodeRequestValue(
              symmetricKeyAttributeValue, instanceKeyID);
      final ExtendedOperation extendedOperation =
          internalConnection.processExtendedOperation(
              ServerConstants.OID_GET_SYMMETRIC_KEY_EXTENDED_OP, requestValue);
      assertEquals(extendedOperation.getResultCode(), ResultCode.SUCCESS);
      // The key should be re-wrapped, and hence have a different binary
      // representation....
      final String responseValue = extendedOperation.getResponseValue().toString();
      assertFalse(symmetricKeyAttributeValue.equals(responseValue));
      // ... but the keyIDs should be equal (ideally, the validity of
      // the returned value would be checked by decoding the
      // returned ds-cfg-symmetric-key attribute value; however, there
      // is no non-private method to call.
      assertEquals(responseValue.split(":")[0], symmetricKeyAttributeValue.split(":")[0]);
    }
  }
  /** Tests the maximum persistent search limit imposed by the server. */
  @Test
  public void testMaxPSearch() throws Exception {
    TestCaseUtils.initializeTestBackend(true);
    // Modify the configuration to allow only 1 concurrent persistent search.
    InternalClientConnection conn = getRootConnection();

    LDAPAttribute attr = new LDAPAttribute("ds-cfg-max-psearches", "1");

    ArrayList<RawModification> mods = new ArrayList<>();
    mods.add(new LDAPModification(ModificationType.REPLACE, attr));

    ModifyOperation modifyOperation = conn.processModify(ByteString.valueOf("cn=config"), mods);
    assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);

    // Create a persistent search request.
    Set<PersistentSearchChangeType> changeTypes = EnumSet.of(ADD, DELETE, MODIFY, MODIFY_DN);
    SearchRequest request =
        newSearchRequest(DN.valueOf("o=test"), SearchScope.BASE_OBJECT)
            .setTypesOnly(true)
            .addAttribute("cn")
            .addControl(new PersistentSearchControl(changeTypes, true, true));
    final InternalSearchOperation search = conn.processSearch(request);

    Thread t =
        new Thread(
            new Runnable() {
              @Override
              public void run() {
                try {
                  search.run();
                } catch (Exception ex) {
                }
              }
            },
            "Persistent Search Test");
    t.start();
    t.join(2000);
    // Create a persistent search request.
    final String[] args = {
      "-D",
      "cn=Directory Manager",
      "-w",
      "password",
      "-h",
      "127.0.0.1",
      "-p",
      String.valueOf(TestCaseUtils.getServerLdapPort()),
      "-b",
      "o=test",
      "-s",
      "sub",
      "-C",
      "ps:add:true:true",
      "--noPropertiesFile",
      "(objectClass=*)"
    };

    assertEquals(LDAPSearch.mainSearch(args, false, true, null, System.err), 11);
    // cancel the persisting persistent search.
    search.cancel(new CancelRequest(true, LocalizableMessage.EMPTY));
  }
  /**
   * Tests performing an internal search using the server-side sort control to sort the entries in
   * order of ascending givenName and descending sn values.
   *
   * @throws Exception If an unexpected problem occurred.
   */
  @Test()
  public void testInternalSearchGivenNameAscendingSnDescending() throws Exception {
    populateDB();

    InternalClientConnection conn = InternalClientConnection.getRootConnection();

    ArrayList<Control> requestControls = new ArrayList<Control>();
    requestControls.add(new ServerSideSortRequestControl("givenName,-sn"));

    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, higher sn
    expectedDNOrder.add(albertSmithDN); // Albert, lower sn
    expectedDNOrder.add(lowercaseMcGeeDN); // lowercase
    expectedDNOrder.add(margaretJonesDN); // Maggie
    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);
    assertEquals(responseControls.size(), 1);

    ServerSideSortResponseControl responseControl;
    Control c = responseControls.get(0);
    if (c instanceof ServerSideSortResponseControl) {
      responseControl = (ServerSideSortResponseControl) c;
    } else {
      responseControl =
          ServerSideSortResponseControl.DECODER.decode(
              c.isCritical(), ((LDAPControl) c).getValue());
    }
    assertEquals(responseControl.getResultCode(), 0);
    assertNull(responseControl.getAttributeType());
    responseControl.toString();
  }
  /**
   * Ensures that password policy constructed from subentry is active and has a valid configuration.
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test()
  public void testValidConfiguration() throws Exception {
    PasswordPolicy defaultPolicy = DirectoryServer.getDefaultPasswordPolicy();
    assertNotNull(defaultPolicy);

    // The values are selected on a basis that they
    // should differ from default password policy.
    Entry policyEntry =
        TestCaseUtils.makeEntry(
            "dn: cn=Temp Policy," + SUFFIX,
            "objectClass: top",
            "objectClass: pwdPolicy",
            "objectClass: subentry",
            "cn: Temp Policy",
            "subtreeSpecification: { base \"ou=people\" }",
            "pwdLockoutDuration: 300",
            "pwdMaxFailure: 3",
            "pwdMustChange: TRUE",
            "pwdAttribute: authPassword",
            "pwdMinAge: 600",
            "pwdMaxAge: 2147483647",
            "pwdInHistory: 5",
            "pwdExpireWarning: 864000",
            "pwdGraceAuthNLimit: 3",
            "pwdFailureCountInterval: 3600",
            "pwdAllowUserChange: FALSE",
            "pwdSafeModify: TRUE");

    InternalClientConnection connection = InternalClientConnection.getRootConnection();

    AddOperation addOperation =
        connection.processAdd(
            policyEntry.getDN(),
            policyEntry.getObjectClasses(),
            policyEntry.getUserAttributes(),
            policyEntry.getOperationalAttributes());
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    assertNotNull(DirectoryServer.getEntry(policyEntry.getDN()));

    PasswordPolicy policy =
        (PasswordPolicy)
            DirectoryServer.getAuthenticationPolicy(DN.decode("cn=Temp Policy," + SUFFIX));
    assertNotNull(policy);

    // Check all pwp attributes for correct values.
    assertEquals(policy.getLockoutDuration(), 300);
    assertEquals(policy.getLockoutFailureCount(), 3);
    assertEquals(policy.isForceChangeOnReset(), true);
    assertTrue(policy.getPasswordAttribute().getPrimaryName().equalsIgnoreCase("authPassword"));
    assertEquals(policy.getMinPasswordAge(), 600);
    assertEquals(policy.getMaxPasswordAge(), 2147483647);
    assertEquals(policy.getPasswordHistoryCount(), 5);
    assertEquals(policy.getPasswordExpirationWarningInterval(), 864000);
    assertEquals(policy.getGraceLoginCount(), 3);
    assertEquals(policy.getLockoutFailureExpirationInterval(), 3600);
    assertEquals(policy.isAllowUserPasswordChanges(), false);
    assertEquals(policy.isPasswordChangeRequiresCurrentPassword(), true);

    /* Check the password validator attributes for correct values.
     * The default unit-test config has a single Password validator which is
     * enabled for the default password policy.
     */
    Collection<PasswordValidator<?>> validators = policy.getPasswordValidators();
    assertEquals(validators.size(), 1);
    for (PasswordValidator<?> validator : validators) {
      assertTrue(
          validator.toString().startsWith("org.opends.server.extensions.TestPasswordValidator"));
    }

    // Make sure this policy applies to the test entry
    // its supposed to target and that its the same
    // policy object as previously tested.
    Entry testEntry = DirectoryServer.getEntry(DN.decode("uid=rogasawara," + BASE));
    assertNotNull(testEntry);

    AuthenticationPolicy statePolicy = AuthenticationPolicy.forUser(testEntry, false);
    assertNotNull(statePolicy);
    assertEquals(policy, statePolicy);

    // Make sure this policy is gone and default
    // policy is in effect instead.
    TestCaseUtils.deleteEntry(policyEntry.getDN());
    statePolicy = AuthenticationPolicy.forUser(testEntry, false);
    assertNotNull(statePolicy);
    assertEquals(defaultPolicy, statePolicy);
  }
  /**
   * 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);
  }
  /**
   * 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);
  }
  /**
   * Ensures that password policy constructed from subentry, containing a password validator
   * reference, is active and has a valid configuration.
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test()
  public void testValidConfigurationWithValidator() throws Exception {
    PasswordPolicy defaultPolicy = DirectoryServer.getDefaultPasswordPolicy();
    assertNotNull(defaultPolicy);

    // The values are selected on a basis that they
    // should differ from default password policy.
    Entry policyEntry =
        TestCaseUtils.makeEntry(
            "dn: cn=Temp Validator Policy," + SUFFIX,
            "objectClass: top",
            "objectClass: pwdPolicy",
            "objectClass: pwdValidatorPolicy",
            "objectClass: subentry",
            "cn: Temp Policy",
            "subtreeSpecification: { base \"ou=people\" }",
            "pwdLockoutDuration: 300",
            "pwdMaxFailure: 3",
            "pwdMustChange: TRUE",
            "pwdAttribute: authPassword",
            "pwdMinAge: 600",
            "pwdMaxAge: 2147483647",
            "pwdInHistory: 5",
            "pwdExpireWarning: 864000",
            "pwdGraceAuthNLimit: 3",
            "pwdFailureCountInterval: 3600",
            "pwdAllowUserChange: FALSE",
            "pwdSafeModify: TRUE",
            "ds-cfg-password-validator: cn=Unique Characters,cn=Password Validators,cn=config",
            "ds-cfg-password-validator: cn=Length-Based Password Validator,cn=Password Validators,cn=config");

    InternalClientConnection connection = InternalClientConnection.getRootConnection();

    AddOperation addOperation =
        connection.processAdd(
            policyEntry.getDN(),
            policyEntry.getObjectClasses(),
            policyEntry.getUserAttributes(),
            policyEntry.getOperationalAttributes());
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    assertNotNull(DirectoryServer.getEntry(policyEntry.getDN()));

    PasswordPolicy policy =
        (PasswordPolicy)
            DirectoryServer.getAuthenticationPolicy(
                DN.decode("cn=Temp Validator Policy," + SUFFIX));
    assertNotNull(policy);

    // Check the password validator attributes for correct values.
    Collection<PasswordValidator<?>> validators = policy.getPasswordValidators();
    assertFalse(validators.isEmpty());
    assertEquals(validators.size(), 2);

    // Make sure this policy applies to the test entry
    // its supposed to target and that its the same
    // policy object as previously tested.
    Entry testEntry = DirectoryServer.getEntry(DN.decode("uid=rogasawara," + BASE));
    assertNotNull(testEntry);

    AuthenticationPolicy statePolicy = AuthenticationPolicy.forUser(testEntry, false);
    assertNotNull(statePolicy);
    assertEquals(policy, statePolicy);

    // Make sure this policy is gone and default
    // policy is in effect instead.
    TestCaseUtils.deleteEntry(policyEntry.getDN());
    statePolicy = AuthenticationPolicy.forUser(testEntry, false);
    assertNotNull(statePolicy);
    assertEquals(defaultPolicy, statePolicy);
  }
  /**
   * Ensures that password policy pwdPolicySubentry operational attribute reflects active password
   * policy for a given user entry.
   *
   * @throws Exception If an unexpected problem occurs.
   */
  @Test()
  public void testPasswordPolicySubentryAttribute() throws Exception {
    PasswordPolicy defaultPolicy = DirectoryServer.getDefaultPasswordPolicy();
    assertNotNull(defaultPolicy);

    Entry testEntry = DirectoryServer.getEntry(DN.decode("uid=rogasawara," + BASE));
    assertNotNull(testEntry);

    AttributeType attrType = DirectoryServer.getAttributeType("pwdpolicysubentry");

    // Make sure that default policy is in effect
    // for the user entry.
    assertTrue(testEntry.hasAttribute(attrType));
    assertTrue(
        testEntry.hasValue(
            attrType, null, AttributeValues.create(attrType, defaultPolicy.getDN().toString())));

    // Add new subentry policy with the
    // scope to apply to the user entry.
    Entry policyEntry =
        TestCaseUtils.makeEntry(
            "dn: cn=Temp Policy," + SUFFIX,
            "objectClass: top",
            "objectClass: pwdPolicy",
            "objectClass: subentry",
            "cn: Temp Policy",
            "subtreeSpecification: { base \"ou=people\" }",
            "pwdLockoutDuration: 300",
            "pwdMaxFailure: 3",
            "pwdMustChange: true",
            "pwdAttribute: userPassword");

    InternalClientConnection connection = InternalClientConnection.getRootConnection();

    AddOperation addOperation =
        connection.processAdd(
            policyEntry.getDN(),
            policyEntry.getObjectClasses(),
            policyEntry.getUserAttributes(),
            policyEntry.getOperationalAttributes());
    assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS);
    assertNotNull(DirectoryServer.getEntry(policyEntry.getDN()));

    // Make sure just added policy is in effect.
    testEntry = DirectoryServer.getEntry(DN.decode("uid=rogasawara," + BASE));
    assertNotNull(testEntry);

    assertTrue(testEntry.hasAttribute(attrType));
    assertTrue(
        testEntry.hasValue(
            attrType, null, AttributeValues.create(attrType, "cn=Temp Policy," + SUFFIX)));

    // Remove subentry policy and make sure
    // default policy is in effect again.
    TestCaseUtils.deleteEntry(policyEntry.getDN());

    testEntry = DirectoryServer.getEntry(DN.decode("uid=rogasawara," + BASE));
    assertNotNull(testEntry);

    assertTrue(testEntry.hasAttribute(attrType));
    assertTrue(
        testEntry.hasValue(
            attrType, null, AttributeValues.create(attrType, defaultPolicy.getDN().toString())));
  }
 /**
  * Removes the test group from the server.
  *
  * @throws Exception If an unexpected problem occurs.
  */
 private void removeGroups() throws Exception {
   InternalClientConnection conn = InternalClientConnection.getRootConnection();
   conn.processDelete(DN.decode("cn=Test Group,o=Test"));
   conn.processDelete(DN.decode("cn=Example Group,o=Test"));
 }
예제 #27
0
 /**
  * Returns a new root connection factory.
  *
  * @return A new root connection factory.
  */
 public static ConnectionFactory newRootConnectionFactory() {
   InternalClientConnection icc = InternalClientConnection.getRootConnection();
   return newConnectionFactory(icc);
 }
예제 #28
0
 /**
  * Returns a new root connection.
  *
  * @return A new root connection.
  */
 public static Connection newRootConnection() {
   return newConnection(InternalClientConnection.getRootConnection());
 }