/** * 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")); }
/** * 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); }
// 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")); }
/** * 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(); }
/** * 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"); }
/** * 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; }
/** * 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); }
/** * 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; }