From afef815443ddf29f679b739ef1b068909caf5e68 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Mon, 03 Oct 2016 12:55:18 +0000
Subject: [PATCH] OPENDJ-3305 Add an option to return naming contexts sub-suffixes in Root DSE

---
 opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java                                       |   12 ++++++
 opendj-server-legacy/src/main/java/org/opends/server/backends/RootDSEBackend.java                                    |   13 +++++-
 opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/RootDSEBackendConfiguration.xml |   24 +++++++++++
 opendj-server-legacy/resource/schema/02-config.ldif                                                                  |    9 ++++
 opendj-server-legacy/src/main/java/org/opends/server/core/BaseDnRegistry.java                                        |   24 +++++++++++-
 5 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/RootDSEBackendConfiguration.xml b/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/RootDSEBackendConfiguration.xml
index 0c0bc53..7a79dde 100644
--- a/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/RootDSEBackendConfiguration.xml
+++ b/opendj-maven-plugin/src/main/resources/config/xml/org/forgerock/opendj/server/config/RootDSEBackendConfiguration.xml
@@ -13,7 +13,7 @@
   information: "Portions Copyright [year] [name of copyright owner]".
 
   Copyright 2007-2008 Sun Microsystems, Inc.
-  Portions Copyright 2011 ForgeRock AS.
+  Portions Copyright 2011-2016 ForgeRock AS.
   ! -->
 <adm:managed-object name="root-dse-backend"
   plural-name="root-dse-backends" package="org.forgerock.opendj.server.config"
@@ -74,4 +74,26 @@
       </ldap:attribute>
     </adm:profile>
   </adm:property>
+  <adm:property name="show-subordinate-naming-contexts" mandatory="true">
+    <adm:synopsis>
+      Indicates whether subordinate naming contexts should be visible in 
+      the namingContexts attribute of the RootDSE. 
+      By default only top level naming contexts are visible
+    </adm:synopsis>
+    <adm:syntax>
+      <adm:boolean />
+    </adm:syntax>
+    <adm:default-behavior>
+      <adm:defined>
+        <adm:value>
+          false
+        </adm:value>
+      </adm:defined>
+    </adm:default-behavior>
+    <adm:profile name="ldap">
+      <ldap:attribute>
+        <ldap:name>ds-cfg-show-subordinate-naming-contexts</ldap:name>
+      </ldap:attribute>
+    </adm:profile>
+  </adm:property>
 </adm:managed-object>
diff --git a/opendj-server-legacy/resource/schema/02-config.ldif b/opendj-server-legacy/resource/schema/02-config.ldif
index 2d47767..8bdd3b4 100644
--- a/opendj-server-legacy/resource/schema/02-config.ldif
+++ b/opendj-server-legacy/resource/schema/02-config.ldif
@@ -3962,6 +3962,12 @@
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
   SINGLE-VALUE
   X-ORIGIN 'OpenDJ Directory Server' )
+attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.201
+  NAME 'ds-cfg-show-subordinate-naming-contexts'
+  EQUALITY booleanMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
+  SINGLE-VALUE
+  X-ORIGIN 'OpenDS Directory Server' )
 objectClasses: ( 1.3.6.1.4.1.26027.1.2.1
   NAME 'ds-cfg-access-control-handler'
   SUP top
@@ -4348,7 +4354,8 @@
   STRUCTURAL
   MUST cn
   MAY ( ds-cfg-subordinate-base-dn $
-        ds-cfg-show-all-attributes )
+        ds-cfg-show-all-attributes $
+        ds-cfg-show-subordinate-naming-contexts)
   X-ORIGIN 'OpenDS Directory Server' )
 objectClasses: ( 1.3.6.1.4.1.26027.1.2.42
   NAME 'ds-cfg-sasl-mechanism-handler'
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/RootDSEBackend.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/RootDSEBackend.java
index 4439ecb..325067c 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/RootDSEBackend.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/RootDSEBackend.java
@@ -109,6 +109,10 @@
    * as user attributes even if they are defined as operational in the schema.
    */
   private boolean showAllAttributes;
+  /**
+   * Indicates whether sub-suffixes should also be included in the list of public naming contexts.
+   */
+  private boolean showSubordinatesNamingContexts;
 
   /** The set of objectclasses that will be used in the root DSE entry. */
   private Map<ObjectClass, String> dseObjectClasses;
@@ -209,6 +213,7 @@
     // Determine whether all root DSE attributes should be treated as user
     // attributes.
     showAllAttributes = currentConfig.isShowAllAttributes();
+    showSubordinatesNamingContexts = currentConfig.isShowSubordinateNamingContexts();
 
     // Construct the set of "static" attributes that will always be present in
     // the root DSE.
@@ -405,8 +410,10 @@
     Map<AttributeType, List<Attribute>> dseUserAttrs = new HashMap<>();
     Map<AttributeType, List<Attribute>> dseOperationalAttrs = new HashMap<>();
 
-    Attribute publicNamingContextAttr = createAttribute(
-        ATTR_NAMING_CONTEXTS, DirectoryServer.getPublicNamingContexts().keySet());
+    Map<DN, Backend<?>> publicNamingContexts = showSubordinatesNamingContexts ?
+        DirectoryServer.getAllPublicNamingContexts() :
+        DirectoryServer.getPublicNamingContexts();
+    Attribute publicNamingContextAttr = createAttribute(ATTR_NAMING_CONTEXTS, publicNamingContexts.keySet());
     addAttribute(publicNamingContextAttr, dseUserAttrs, dseOperationalAttrs);
 
     // Add the "ds-private-naming-contexts" attribute.
@@ -939,7 +946,7 @@
         ccr.addMessage(INFO_ROOTDSE_UPDATED_SHOW_ALL_ATTRS.get(
                 ATTR_ROOTDSE_SHOW_ALL_ATTRIBUTES, showAllAttributes));
       }
-
+      showSubordinatesNamingContexts = cfg.isShowSubordinateNamingContexts();
       userDefinedAttributes = userAttrs;
       ccr.addMessage(INFO_ROOTDSE_USING_NEW_USER_ATTRS.get());
     }
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/BaseDnRegistry.java b/opendj-server-legacy/src/main/java/org/opends/server/core/BaseDnRegistry.java
index 7107b62..37d8a3a 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/BaseDnRegistry.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/BaseDnRegistry.java
@@ -41,6 +41,8 @@
   private final TreeMap<DN, Backend<?>> privateNamingContexts = new TreeMap<>();
   /** The set of public naming contexts registered with the server. */
   private final TreeMap<DN, Backend<?>> publicNamingContexts = new TreeMap<>();
+  /** The set of public naming contexts, including sub-suffixes, registered with the server. */
+  private final TreeMap<DN, Backend<?>> allPublicNamingContexts = new TreeMap<>();
 
   /**
    * Indicates whether this base DN registry is in test mode.
@@ -186,6 +188,10 @@
       }
     }
 
+    if (!isPrivate)
+    {
+      allPublicNamingContexts.put(baseDN, backend);
+    }
     for (DN dn : subordinateBaseDNs)
     {
       publicNamingContexts.remove(dn);
@@ -287,6 +293,7 @@
     // information.
     baseDNs.remove(baseDN);
     publicNamingContexts.remove(baseDN);
+    allPublicNamingContexts.remove(baseDN);
     privateNamingContexts.remove(baseDN);
 
     final LinkedList<LocalizableMessage> errors = new LinkedList<>();
@@ -366,6 +373,7 @@
     final BaseDnRegistry registry = new BaseDnRegistry(true);
     registry.baseDNs.putAll(baseDNs);
     registry.publicNamingContexts.putAll(publicNamingContexts);
+    registry.allPublicNamingContexts.putAll(allPublicNamingContexts);
     registry.privateNamingContexts.putAll(privateNamingContexts);
     return registry;
   }
@@ -392,8 +400,8 @@
   }
 
   /**
-   * Gets the mapping of registered public naming contexts to their
-   * associated backend.
+   * Gets the mapping of registered public naming contexts, not including
+   * sub-suffixes, to their associated backend.
    *
    * @return mapping from naming context to backend
    */
@@ -403,6 +411,17 @@
   }
 
   /**
+   * Gets the mapping of registered public naming contexts, including sub-suffixes,
+   * to their associated backend.
+   *
+   * @return mapping from naming context to backend
+   */
+  Map<DN, Backend<?>> getAllPublicNamingContextsMap()
+  {
+    return this.allPublicNamingContexts;
+  }
+
+  /**
    * Gets the mapping of registered private naming contexts to their
    * associated backend.
    *
@@ -432,5 +451,6 @@
     baseDNs.clear();
     privateNamingContexts.clear();
     publicNamingContexts.clear();
+    allPublicNamingContexts.clear();
   }
 }
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java b/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
index 25c492d..c34cd06 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/core/DirectoryServer.java
@@ -3715,6 +3715,18 @@
   }
 
   /**
+   * Retrieves the set of public naming contexts, including sub-suffixes,
+   * defined in the Directory Server, mapped from the naming context DN
+   * to the corresponding backend.
+   *
+   * @return  The set of public naming contexts defined in the Directory Server.
+   */
+  public static Map<DN, Backend<?>> getAllPublicNamingContexts()
+  {
+    return directoryServer.baseDnRegistry.getAllPublicNamingContextsMap();
+  }
+
+  /**
    * Retrieves the set of private naming contexts defined in the Directory
    * Server, mapped from the naming context DN to the corresponding backend.
    *

--
Gitblit v1.10.0