@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())); }
/** * Test entry. * * @throws Exception If the test failed unexpectedly. */ @Test() public void testEntryToAndFromDatabase() throws Exception { // Make sure that the server is up and running. TestCaseUtils.startServer(); // Convert the test LDIF string to a byte array byte[] originalLDIFBytes = StaticUtils.getBytes(ldifString); LDIFReader reader = new LDIFReader(new LDIFImportConfig(new ByteArrayInputStream(originalLDIFBytes))); Entry entryBefore, entryAfter; while ((entryBefore = reader.readEntry(false)) != null) { ByteString bytes = ID2Entry.entryToDatabase(entryBefore, new DataConfig(false, false, null)); entryAfter = ID2Entry.entryFromDatabase(bytes, DirectoryServer.getDefaultCompressedSchema()); // check DN and number of attributes assertEquals(entryBefore.getAttributes().size(), entryAfter.getAttributes().size()); assertEquals(entryBefore.getDN(), entryAfter.getDN()); // check the object classes were not changed for (String ocBefore : entryBefore.getObjectClasses().values()) { ObjectClass objectClass = DirectoryServer.getObjectClass(ocBefore.toLowerCase()); if (objectClass == null) { objectClass = DirectoryServer.getDefaultObjectClass(ocBefore); } String ocAfter = entryAfter.getObjectClasses().get(objectClass); assertEquals(ocBefore, ocAfter); } // check the user attributes were not changed for (AttributeType attrType : entryBefore.getUserAttributes().keySet()) { List<Attribute> listBefore = entryBefore.getAttribute(attrType); List<Attribute> listAfter = entryAfter.getAttribute(attrType); assertTrue(listAfter != null); assertEquals(listBefore.size(), listAfter.size()); for (Attribute attrBefore : listBefore) { boolean found = false; for (Attribute attrAfter : listAfter) { if (attrAfter.optionsEqual(attrBefore.getOptions())) { // Found the corresponding attribute assertEquals(attrBefore, attrAfter); found = true; } } assertTrue(found); } } } reader.close(); }
/** * Encodes this entry using the V3 encoding. * * @param buffer The buffer to encode into. * @throws DirectoryException If a problem occurs while attempting to encode the entry. */ private void encodeV1(Entry entry, ByteStringBuilder buffer) throws DirectoryException { // The version number will be one byte. buffer.append((byte) 0x01); // TODO: Can we encode the DN directly into buffer? byte[] dnBytes = getBytes(entry.getDN().toString()); buffer.appendBERLength(dnBytes.length); buffer.append(dnBytes); // Encode number of OCs and 0 terminated names. int i = 1; ByteStringBuilder bsb = new ByteStringBuilder(); for (String ocName : entry.getObjectClasses().values()) { bsb.append(ocName); if (i < entry.getObjectClasses().values().size()) { bsb.append((byte) 0x00); } i++; } buffer.appendBERLength(bsb.length()); buffer.append(bsb); // Encode the user attributes in the appropriate manner. encodeV1Attributes(buffer, entry.getUserAttributes()); // The operational attributes will be encoded in the same way as // the user attributes. encodeV1Attributes(buffer, entry.getOperationalAttributes()); }
/** * 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); }
/** * 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())); }
/** * 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); }
/** * Gathers all of the attribute types in an entry along with the "objectclass" attribute type in a * List. The "objectclass" attribute is added to the list first so it is evaluated first. * * @param e Entry to gather the attributes for. * @return List containing the attribute types. */ private List<AttributeType> getAllAttrs(Entry e) { Map<AttributeType, List<Attribute>> attrMap = e.getUserAttributes(); Map<AttributeType, List<Attribute>> opAttrMap = e.getOperationalAttributes(); List<AttributeType> typeList = new LinkedList<AttributeType>(); Attribute attr = e.getObjectClassAttribute(); /* * When a search is not all attributes returned, the "objectclass" * attribute type is missing from the entry. */ if (attr != null) { AttributeType ocType = attr.getAttributeType(); typeList.add(ocType); } typeList.addAll(attrMap.keySet()); typeList.addAll(opAttrMap.keySet()); return typeList; }
/** * 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); }
/** * Encodes this entry using the V3 encoding. * * @param buffer The buffer to encode into. * @throws DirectoryException If a problem occurs while attempting to encode the entry. */ private void encodeV2(Entry entry, ByteStringBuilder buffer, EntryEncodeConfig config) throws DirectoryException { // The version number will be one byte. buffer.append((byte) 0x02); // Get the encoded respresentation of the config. config.encode(buffer); // If we should include the DN, then it will be encoded as a // one-to-five byte length followed by the UTF-8 byte // representation. if (!config.excludeDN()) { // TODO: Can we encode the DN directly into buffer? byte[] dnBytes = getBytes(entry.getDN().toString()); buffer.appendBERLength(dnBytes.length); buffer.append(dnBytes); } // Encode the object classes in the appropriate manner. if (config.compressObjectClassSets()) { config.getCompressedSchema().encodeObjectClasses(buffer, entry.getObjectClasses()); } else { // Encode number of OCs and 0 terminated names. int i = 1; ByteStringBuilder bsb = new ByteStringBuilder(); for (String ocName : entry.getObjectClasses().values()) { bsb.append(ocName); if (i < entry.getObjectClasses().values().size()) { bsb.append((byte) 0x00); } i++; } buffer.appendBERLength(bsb.length()); buffer.append(bsb); } // Encode the user attributes in the appropriate manner. encodeV2Attributes(buffer, entry.getUserAttributes(), config); // The operational attributes will be encoded in the same way as // the user attributes. encodeV2Attributes(buffer, entry.getOperationalAttributes(), config); }
/** * 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()))); }
/** * 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 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); }