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

Jean-Noël Rouvignac
22.24.2016 85f8dbf0c8c5f34962963e17fa498cbfee35055f
OPENDJ-2958 Search on wrong dn under cn=config should fails with NoSuchEntry error

Problem is on the underlying MemoryBackend used by the ConfigurationHandler
(and the later being used by the ConfigurationBackend).

MemoryBackend.searchWithSubordinates() should first verify whether the baseObject exists,
and if not, return NO_SUCH_OBJECT.
MemoryBackendTestCase may have caught this if the InternalConnection (actually AbstractConnection.getSingleEntry())
was a lot more basic and avoided doing elaborate checks.
2 files modified
63 ■■■■■ changed files
opendj-core/src/main/java/org/forgerock/opendj/ldap/MemoryBackend.java 36 ●●●● patch | view | raw | blame | history
opendj-core/src/test/java/org/forgerock/opendj/ldap/MemoryBackendTestCase.java 27 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/MemoryBackend.java
@@ -25,7 +25,7 @@
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import org.forgerock.i18n.LocalizedIllegalArgumentException;
@@ -55,9 +55,8 @@
import org.forgerock.opendj.ldif.EntryReader;
/**
 * A simple in memory back-end which can be used for testing. It is not intended
 * for production use due to various limitations. The back-end implementations
 * supports the following:
 * A simple in memory back-end which can be used for testing.
 * The back-end implementations supports the following:
 * <ul>
 * <li>add, bind (simple), compare, delete, modify, and search operations, but
 * not modifyDN nor extended operations
@@ -442,9 +441,8 @@
                        if (!overwrite && entries.containsKey(dn)) {
                            throw newLdapException(ResultCode.ENTRY_ALREADY_EXISTS,
                                    "Attempted to add the entry '" + dn + "' multiple times");
                        } else {
                            entries.put(dn, entry);
                        }
                        entries.put(dn, entry);
                    }
                } finally {
                    reader.close();
@@ -485,10 +483,15 @@
            final LdapResultHandler<Result> resultHandler, final DN dn, final Matcher matcher,
            final AttributeFilter attributeFilter, final int sizeLimit, SearchScope scope,
            SimplePagedResultsControl pagedResults) throws CancelledResultException, LdapException {
        final NavigableMap<DN, Entry> subtree = entries.subMap(dn, dn.child(RDN.maxValue()));
        if (subtree.isEmpty() || !dn.equals(subtree.firstKey())) {
            resultHandler.handleResult(newResult(ResultCode.NO_SUCH_OBJECT));
            return;
        }
        final int pageSize = pagedResults != null ? pagedResults.getSize() : 0;
        final int offset = (pagedResults != null && !pagedResults.getCookie().isEmpty())
                ? Integer.valueOf(pagedResults.getCookie().toString()) : 0;
        final Map<DN, Entry> subtree = entries.subMap(dn, dn.child(RDN.maxValue()));
        int numberOfResults = 0;
        int position = 0;
        for (final Entry entry : subtree.values()) {
@@ -528,8 +531,9 @@
        }
        final Result result = newResult(ResultCode.SUCCESS);
        if (pageSize > 0) {
            final ByteString cookie = numberOfResults == pageSize ? ByteString.valueOfUtf8(String.valueOf(position))
                    : ByteString.empty();
            final ByteString cookie = numberOfResults == pageSize
                ? ByteString.valueOfUtf8(String.valueOf(position))
                : ByteString.empty();
            result.addControl(SimplePagedResultsControl.newControl(true, 0, cookie));
        }
        resultHandler.handleResult(result);
@@ -544,12 +548,9 @@
            if (preRead != null) {
                if (preRead.isCritical() && before == null) {
                    throw newLdapException(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION);
                } else {
                    final AttributeFilter filter =
                            new AttributeFilter(preRead.getAttributes(), schema);
                    result.addControl(PreReadResponseControl.newControl(filter
                            .filteredViewOf(before)));
                }
                final AttributeFilter filter = new AttributeFilter(preRead.getAttributes(), schema);
                result.addControl(PreReadResponseControl.newControl(filter.filteredViewOf(before)));
            }
            // Add post-read response control if requested.
@@ -558,12 +559,9 @@
            if (postRead != null) {
                if (postRead.isCritical() && after == null) {
                    throw newLdapException(ResultCode.UNAVAILABLE_CRITICAL_EXTENSION);
                } else {
                    final AttributeFilter filter =
                            new AttributeFilter(postRead.getAttributes(), schema);
                    result.addControl(PostReadResponseControl.newControl(filter
                            .filteredViewOf(after)));
                }
                final AttributeFilter filter = new AttributeFilter(postRead.getAttributes(), schema);
                result.addControl(PostReadResponseControl.newControl(filter.filteredViewOf(after)));
            }
            return result;
        } catch (final DecodeException e) {
opendj-core/src/test/java/org/forgerock/opendj/ldap/MemoryBackendTestCase.java
@@ -51,9 +51,7 @@
    @Test
    public void testAdd() throws Exception {
        final Connection connection = getConnection();
        final Entry newDomain =
                valueOfLDIFEntry("dn: dc=new domain,dc=com", "objectClass: domain",
                        "objectClass: top", "dc: new domain");
        final Entry newDomain = newDomain();
        connection.add(newDomain);
        assertThat(connection.readEntry("dc=new domain,dc=com")).isEqualTo(newDomain);
    }
@@ -75,9 +73,7 @@
    @Test
    public void testAddPostRead() throws Exception {
        final Connection connection = getConnection();
        final Entry newDomain =
                valueOfLDIFEntry("dn: dc=new domain,dc=com", "objectClass: domain",
                        "objectClass: top", "dc: new domain");
        final Entry newDomain = newDomain();
        assertThat(
                connection.add(
                        newAddRequest(newDomain)
@@ -89,12 +85,18 @@
    @Test(expectedExceptions = LdapException.class)
    public void testAddPreRead() throws Exception {
        final Connection connection = getConnection();
        final Entry newDomain =
                valueOfLDIFEntry("dn: dc=new domain,dc=com", "objectClass: domain",
                        "objectClass: top", "dc: new domain");
        final Entry newDomain = newDomain();
        connection.add(newAddRequest(newDomain).addControl(PreReadRequestControl.newControl(true)));
    }
    private Entry newDomain() {
        return valueOfLDIFEntry(
            "dn: dc=new domain,dc=com",
            "objectClass: domain",
            "objectClass: top",
            "dc: new domain");
    }
    @Test
    public void testCompareFalse() throws Exception {
        final Connection connection = getConnection();
@@ -484,6 +486,13 @@
                "(uid=missing)");
    }
    @Test(expectedExceptions = EntryNotFoundException.class)
    public void testSearchSubtreeBaseEntryNotFound() throws Exception {
        final Connection connection = getConnection();
        connection.searchSingleEntry("uid=missing,dc=example,dc=com", SearchScope.WHOLE_SUBTREE,
                "(uid=*)");
    }
    @Test
    public void testSearchPagedResults() throws Exception {
        final Connection connection = getConnection();