From 85f8dbf0c8c5f34962963e17fa498cbfee35055f Mon Sep 17 00:00:00 2001
From: Jean-Noël Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Fri, 22 Apr 2016 14:40:04 +0000
Subject: [PATCH] OPENDJ-2958 Search on wrong dn under cn=config should fails with NoSuchEntry error

---
 opendj-core/src/main/java/org/forgerock/opendj/ldap/MemoryBackend.java         |   36 ++++++++---------
 opendj-core/src/test/java/org/forgerock/opendj/ldap/MemoryBackendTestCase.java |   27 +++++++++----
 2 files changed, 35 insertions(+), 28 deletions(-)

diff --git a/opendj-core/src/main/java/org/forgerock/opendj/ldap/MemoryBackend.java b/opendj-core/src/main/java/org/forgerock/opendj/ldap/MemoryBackend.java
index 714817d..39b3276 100644
--- a/opendj-core/src/main/java/org/forgerock/opendj/ldap/MemoryBackend.java
+++ b/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) {
diff --git a/opendj-core/src/test/java/org/forgerock/opendj/ldap/MemoryBackendTestCase.java b/opendj-core/src/test/java/org/forgerock/opendj/ldap/MemoryBackendTestCase.java
index f32c608..c5c867a 100644
--- a/opendj-core/src/test/java/org/forgerock/opendj/ldap/MemoryBackendTestCase.java
+++ b/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();

--
Gitblit v1.10.0