From 2dddd0e4b83f2fbe48431098ee624e763c49e975 Mon Sep 17 00:00:00 2001
From: Mark Craig <mark.craig@forgerock.com>
Date: Mon, 02 Jan 2012 16:50:03 +0000
Subject: [PATCH] Some information on reading the root DSE
---
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/getinfo/Main.java | 193 +++++++++++++++++++++
opendj3/src/main/docbkx/dev-guide/chap-extended-ops.xml | 48 +++++
opendj3/src/main/docbkx/dev-guide/chap-getting-directory-info.xml | 141 +++++++++++++++
opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/getinfo/package-info.java | 34 +++
opendj3/src/main/docbkx/dev-guide/chap-controls.xml | 68 +++++++
5 files changed, 477 insertions(+), 7 deletions(-)
diff --git a/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/getinfo/Main.java b/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/getinfo/Main.java
new file mode 100644
index 0000000..5ca3b6a
--- /dev/null
+++ b/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/getinfo/Main.java
@@ -0,0 +1,193 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opendj3/legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opendj3/legal-notices/CDDLv1_0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2012 ForgeRock AS
+ */
+package org.forgerock.opendj.examples.getinfo;
+
+import java.io.IOException;
+
+import org.forgerock.i18n.LocalizedIllegalArgumentException;
+import org.forgerock.opendj.ldap.Connection;
+import org.forgerock.opendj.ldap.ErrorResultException;
+import org.forgerock.opendj.ldap.LDAPConnectionFactory;
+import org.forgerock.opendj.ldap.ResultCode;
+import org.forgerock.opendj.ldap.SearchScope;
+import org.forgerock.opendj.ldap.responses.SearchResultEntry;
+import org.forgerock.opendj.ldif.LDIFEntryWriter;
+
+
+
+/**
+ * Demonstrates accessing server information about capabilities and schema.
+ */
+public final class Main
+{
+ // Connection information
+ private static String host;
+ private static int port;
+ // The kind of server information to request (all, controls, extops)
+ private static String infoType;
+
+
+
+ /**
+ * Access the directory over LDAP to request information about capabilities
+ * and schema.
+ *
+ * @param args The command line arguments
+ */
+ public static void main(final String[] args)
+ {
+ parseArgs(args);
+ connect();
+ }
+
+
+
+ /**
+ * Authenticate over LDAP.
+ */
+ private static void connect()
+ {
+ final LDAPConnectionFactory factory = new LDAPConnectionFactory(
+ host, port);
+ Connection connection = null;
+
+ try
+ {
+ connection = factory.getConnection();
+ connection.bind("", "".toCharArray()); // Anonymous bind
+
+ final String attributeList;
+ if (infoType.toLowerCase().equals("controls"))
+ attributeList = "supportedControl";
+ else if (infoType.toLowerCase().equals("extops"))
+ attributeList = "supportedExtension";
+ else
+ attributeList = "+"; // All operational attributes
+
+ final SearchResultEntry entry = connection.searchSingleEntry(
+ "", // DN is "" for root DSE.
+ SearchScope.BASE_OBJECT, // Read only the root DSE.
+ "objectclass=*", // Every object matches this filter.
+ attributeList); // Return these requested attributes.
+
+ final LDIFEntryWriter writer = new LDIFEntryWriter(System.out);
+ writer.writeComment("Root DSE for LDAP server at " + host + ":" + port);
+ if (entry != null) writer.writeEntry(entry);
+ writer.flush();
+ }
+ catch (final ErrorResultException e)
+ {
+ System.err.println(e.getMessage());
+ System.exit(e.getResult().getResultCode().intValue());
+ return;
+ }
+ catch (final InterruptedException e)
+ {
+ System.err.println(e.getMessage());
+ System.exit(ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue());
+ return;
+ }
+ catch (LocalizedIllegalArgumentException e)
+ {
+ System.err.println(e.getMessageObject().toString());
+ System.exit(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
+ return;
+ }
+ catch (UnsupportedOperationException e)
+ {
+ System.err.println(e.getMessage());
+ System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue());
+ return;
+ }
+ catch (IllegalStateException e)
+ {
+ System.err.println(e.getMessage());
+ System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue());
+ return;
+ }
+ catch (IOException e)
+ {
+ System.err.println(e.getMessage());
+ System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue());
+ return;
+ }
+ finally
+ {
+ if (connection != null) connection.close();
+ }
+ }
+
+
+
+ /**
+ * Parse command line arguments.
+ * @param args host port bind-dn bind-password info-type
+ */
+ private static void parseArgs(String[] args)
+ {
+ if (args.length != 3) giveUp();
+
+ host = args[0];
+ port = Integer.parseInt(args[1]);
+ infoType = args[2]; // all, controls, or extops
+ if (!
+ (
+ infoType.toLowerCase().equals("all") ||
+ infoType.toLowerCase().equals("controls") ||
+ infoType.toLowerCase().equals("extops")
+ )
+ )
+ giveUp();
+ }
+
+
+
+ private static void giveUp()
+ {
+ printUsage();
+ System.exit(1);
+ }
+
+
+
+ private static void printUsage()
+ {
+ System.err.println(
+ "Usage: host port info-type");
+ System.err.println(
+ "\tAll arguments are required.");
+ System.err.println(
+ "\tinfo-type to get can be either all, controls, or extops.");
+ }
+
+
+
+ private Main()
+ {
+ // Not used.
+ }
+}
diff --git a/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/getinfo/package-info.java b/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/getinfo/package-info.java
new file mode 100644
index 0000000..8a0a6b1
--- /dev/null
+++ b/opendj3/opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/getinfo/package-info.java
@@ -0,0 +1,34 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opendj3/legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opendj3/legal-notices/CDDLv1_0.txt. If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ * Copyright 2012 ForgeRock AS
+ */
+
+/**
+ * Demonstrates accessing server information about capabilities and schema.
+ */
+package org.forgerock.opendj.examples.getinfo;
+
+
+
diff --git a/opendj3/src/main/docbkx/dev-guide/chap-controls.xml b/opendj3/src/main/docbkx/dev-guide/chap-controls.xml
index cfe5a15..9a419f4 100644
--- a/opendj3/src/main/docbkx/dev-guide/chap-controls.xml
+++ b/opendj3/src/main/docbkx/dev-guide/chap-controls.xml
@@ -20,7 +20,7 @@
!
! CCPL HEADER END
!
- ! Copyright 2011 ForgeRock AS
+ ! Copyright 2011-2012 ForgeRock AS
!
-->
<chapter xml:id='chap-controls'
@@ -45,7 +45,71 @@
<section xml:id="get-supported-controls">
<title>Determining Supported Controls</title>
- <para>TODO</para>
+
+ <para>For OpenDJ, the controls supported are listed in the
+ <citetitle>Administration Guide</citetitle> appendix, <link
+ xlink:href="admin-guide#appendix-controls"
+ xlink:role="http://docbook.org/xlink/role/olink"><citetitle>LDAP
+ Controls</citetitle></link>. You can access the list of OIDs for
+ supported LDAP controls by reading the <literal>supportedControl</literal>
+ attribute of the root DSE.</para>
+
+ <screen>$ ldapsearch
+ --baseDN ""
+ --searchScope base
+ --port 1389
+ "(objectclass=*)" supportedControl
+dn:
+supportedControl: 1.2.826.0.1.3344810.2.3
+supportedControl: 1.2.840.113556.1.4.1413
+supportedControl: 1.2.840.113556.1.4.319
+supportedControl: 1.2.840.113556.1.4.473
+supportedControl: 1.2.840.113556.1.4.805
+supportedControl: 1.3.6.1.1.12
+supportedControl: 1.3.6.1.1.13.1
+supportedControl: 1.3.6.1.1.13.2
+supportedControl: 1.3.6.1.4.1.26027.1.5.2
+supportedControl: 1.3.6.1.4.1.42.2.27.8.5.1
+supportedControl: 1.3.6.1.4.1.42.2.27.9.5.2
+supportedControl: 1.3.6.1.4.1.42.2.27.9.5.8
+supportedControl: 1.3.6.1.4.1.4203.1.10.1
+supportedControl: 1.3.6.1.4.1.4203.1.10.2
+supportedControl: 1.3.6.1.4.1.7628.5.101.1
+supportedControl: 2.16.840.1.113730.3.4.12
+supportedControl: 2.16.840.1.113730.3.4.16
+supportedControl: 2.16.840.1.113730.3.4.17
+supportedControl: 2.16.840.1.113730.3.4.18
+supportedControl: 2.16.840.1.113730.3.4.19
+supportedControl: 2.16.840.1.113730.3.4.2
+supportedControl: 2.16.840.1.113730.3.4.3
+supportedControl: 2.16.840.1.113730.3.4.4
+supportedControl: 2.16.840.1.113730.3.4.5
+supportedControl: 2.16.840.1.113730.3.4.9</screen>
+
+ <para>The following excerpt shows the Java equivalent of the preceding
+ command.</para>
+
+ <programlisting language="java">
+final LDAPConnectionFactory factory = new LDAPConnectionFactory(
+ host, port);
+Connection connection = null;
+
+try
+{
+ connection = factory.getConnection();
+ connection.bind("", "".toCharArray());
+
+ final SearchResultEntry entry = connection.searchSingleEntry(
+ "", // DN is "" for root DSE.
+ SearchScope.BASE_OBJECT, // Read only the root DSE.
+ "objectclass=*", // Every object matches this filter.
+ "supportedControl"); // Check supported controls.
+
+ final LDIFEntryWriter writer = new LDIFEntryWriter(System.out);
+ writer.writeComment("Supported controls for server " + host + ":" + port);
+ if (entry != null) writer.writeEntry(entry);
+ writer.flush();
+}</programlisting>
</section>
<section xml:id="use-assertion-request-control">
diff --git a/opendj3/src/main/docbkx/dev-guide/chap-extended-ops.xml b/opendj3/src/main/docbkx/dev-guide/chap-extended-ops.xml
index 4a3df2f..2bb50ea 100644
--- a/opendj3/src/main/docbkx/dev-guide/chap-extended-ops.xml
+++ b/opendj3/src/main/docbkx/dev-guide/chap-extended-ops.xml
@@ -41,7 +41,53 @@
<section xml:id="get-supported-extended-operations">
<title>Determining Supported Extended Operations</title>
- <para>TODO</para>
+
+ <para>For OpenDJ, the extended operations supported are listed in the
+ <citetitle>Administration Guide</citetitle> appendix, <link
+ xlink:href="admin-guide#appendix-extended-ops"
+ xlink:role="http://docbook.org/xlink/role/olink"><citetitle>LDAP Extended
+ Operations</citetitle></link>. You can access the list of OIDs for
+ supported LDAP controls by reading the <literal>supportedExtension</literal>
+ attribute of the root DSE.</para>
+
+ <screen>$ ldapsearch
+ --baseDN ""
+ --searchScope base
+ --port 1389
+ "(objectclass=*)" supportedExtension
+dn:
+supportedExtension: 1.3.6.1.1.8
+supportedExtension: 1.3.6.1.4.1.26027.1.6.1
+supportedExtension: 1.3.6.1.4.1.26027.1.6.2
+supportedExtension: 1.3.6.1.4.1.26027.1.6.3
+supportedExtension: 1.3.6.1.4.1.4203.1.11.1
+supportedExtension: 1.3.6.1.4.1.4203.1.11.3
+supportedExtension: 1.3.6.1.4.1.1466.20037</screen>
+
+ <para>The following excerpt shows the Java equivalent of the preceding
+ command.</para>
+
+ <programlisting language="java">
+final LDAPConnectionFactory factory = new LDAPConnectionFactory(
+ host, port);
+Connection connection = null;
+
+try
+{
+ connection = factory.getConnection();
+ connection.bind("", "".toCharArray());
+
+ final SearchResultEntry entry = connection.searchSingleEntry(
+ "", // DN is "" for root DSE.
+ SearchScope.BASE_OBJECT, // Read only the root DSE.
+ "objectclass=*", // Every object matches this filter.
+ "supportedExtension"); // Check supported extended operations.
+
+ final LDIFEntryWriter writer = new LDIFEntryWriter(System.out);
+ writer.writeComment("Supported extended ops for server " + host + ":" + port);
+ if (entry != null) writer.writeEntry(entry);
+ writer.flush();
+}</programlisting>
</section>
<section xml:id="use-cancel-extended-operation">
diff --git a/opendj3/src/main/docbkx/dev-guide/chap-getting-directory-info.xml b/opendj3/src/main/docbkx/dev-guide/chap-getting-directory-info.xml
index d87860b..fdece0b 100644
--- a/opendj3/src/main/docbkx/dev-guide/chap-getting-directory-info.xml
+++ b/opendj3/src/main/docbkx/dev-guide/chap-getting-directory-info.xml
@@ -20,7 +20,7 @@
!
! CCPL HEADER END
!
- ! Copyright 2011 ForgeRock AS
+ ! Copyright 2011-2012 ForgeRock AS
!
-->
<chapter xml:id='chap-getting-directory-info'
@@ -38,16 +38,149 @@
<section xml:id="read-root-dse">
<title>Reading Root DSEs</title>
- <para>TODO</para>
+
+ <para>The directory with distinguished name <literal>""</literal> (empty
+ string) is called the <firstterm>root DSE</firstterm>. DSE stands for
+ DSA-Specific Entry. DSA stands for Directory Server Agent, a single
+ directory server.</para>
+
+ <para>The root DSE serves to expose information over LDAP about what the
+ directory server supports in terms of LDAP controls, auth password schemes,
+ SASL mechanisms, LDAP protocol versions, naming contexts, features, LDAP
+ extended operations, and so forth. The root DSE holds all the information
+ as values of LDAP attributes. OpenDJ defines these attributes as operational.
+ In other words, OpenDJ only returns the attributes if you either request
+ them specifically, or request all operational attributes.</para>
+
+ <para>To access the list of what an OpenDJ server supports, for example,
+ get all operational attributes from the root DSE entry as in the following
+ excerpt.</para>
+
+ <programlisting language="java">
+final LDAPConnectionFactory factory = new LDAPConnectionFactory(
+ host, port);
+Connection connection = null;
+
+try
+{
+ connection = factory.getConnection();
+ connection.bind("", "".toCharArray());
+
+ final SearchResultEntry entry = connection.searchSingleEntry(
+ "", // DN is "" for root DSE.
+ SearchScope.BASE_OBJECT, // Read only the root DSE.
+ "objectclass=*", // Every object matches this filter.
+ "+"); // Return all operational attributes.
+
+ final LDIFEntryWriter writer = new LDIFEntryWriter(System.out);
+ writer.writeComment("Root DSE for LDAP server at " + host + ":" + port);
+ if (entry != null) writer.writeEntry(entry);
+ writer.flush();
+}</programlisting>
+
+ <para>Notice that by default you can access the root DSE after authenticating
+ anonymously. When you look at the entry in LDIF, you see that supported
+ capabilities are generally identified by object identifier (OID).</para>
+
+ <screen># Root DSE for LDAP server at localhost:1389
+dn:
+supportedControl: 1.2.826.0.1.3344810.2.3
+supportedControl: 1.2.840.113556.1.4.1413
+supportedControl: 1.2.840.113556.1.4.319
+supportedControl: 1.2.840.113556.1.4.473
+supportedControl: 1.2.840.113556.1.4.805
+supportedControl: 1.3.6.1.1.12
+supportedControl: 1.3.6.1.1.13.1
+supportedControl: 1.3.6.1.1.13.2
+supportedControl: 1.3.6.1.4.1.26027.1.5.2
+supportedControl: 1.3.6.1.4.1.42.2.27.8.5.1
+supportedControl: 1.3.6.1.4.1.42.2.27.9.5.2
+supportedControl: 1.3.6.1.4.1.42.2.27.9.5.8
+supportedControl: 1.3.6.1.4.1.4203.1.10.1
+supportedControl: 1.3.6.1.4.1.4203.1.10.2
+supportedControl: 1.3.6.1.4.1.7628.5.101.1
+supportedControl: 2.16.840.1.113730.3.4.12
+supportedControl: 2.16.840.1.113730.3.4.16
+supportedControl: 2.16.840.1.113730.3.4.17
+supportedControl: 2.16.840.1.113730.3.4.18
+supportedControl: 2.16.840.1.113730.3.4.19
+supportedControl: 2.16.840.1.113730.3.4.2
+supportedControl: 2.16.840.1.113730.3.4.3
+supportedControl: 2.16.840.1.113730.3.4.4
+supportedControl: 2.16.840.1.113730.3.4.5
+supportedControl: 2.16.840.1.113730.3.4.9
+supportedAuthPasswordSchemes: MD5
+supportedAuthPasswordSchemes: SHA1
+supportedAuthPasswordSchemes: SHA256
+supportedAuthPasswordSchemes: SHA512
+supportedAuthPasswordSchemes: SHA384
+supportedSASLMechanisms: PLAIN
+supportedSASLMechanisms: EXTERNAL
+supportedSASLMechanisms: DIGEST-MD5
+supportedSASLMechanisms: CRAM-MD5
+supportedLDAPVersion: 2
+supportedLDAPVersion: 3
+pwdPolicySubentry: cn=Default Password Policy,cn=Password Policies,cn=config
+supportedFeatures: 1.3.6.1.1.14
+supportedFeatures: 1.3.6.1.4.1.4203.1.5.1
+supportedFeatures: 1.3.6.1.4.1.4203.1.5.2
+supportedFeatures: 1.3.6.1.4.1.4203.1.5.3
+subschemaSubentry: cn=schema
+ds-private-naming-contexts: cn=admin data
+ds-private-naming-contexts: cn=ads-truststore
+ds-private-naming-contexts: cn=backups
+ds-private-naming-contexts: cn=config
+ds-private-naming-contexts: cn=monitor
+ds-private-naming-contexts: cn=schema
+ds-private-naming-contexts: cn=tasks
+numSubordinates: 1
+structuralObjectClass: ds-root-dse
+namingContexts: dc=example,dc=com
+supportedExtension: 1.3.6.1.1.8
+supportedExtension: 1.3.6.1.4.1.26027.1.6.1
+supportedExtension: 1.3.6.1.4.1.26027.1.6.2
+supportedExtension: 1.3.6.1.4.1.26027.1.6.3
+supportedExtension: 1.3.6.1.4.1.4203.1.11.1
+supportedExtension: 1.3.6.1.4.1.4203.1.11.3
+supportedExtension: 1.3.6.1.4.1.1466.20037
+vendorName: ForgeRock AS.
+vendorVersion: OpenDJ 2.5.0
+hasSubordinates: true
+entryUUID: d41d8cd9-8f00-3204-a980-0998ecf8427e
+entryDN: </screen>
+
+ <para>Three key pieces of information in the entry shown above are attribute
+ values for <literal>namingContexts</literal> (showing the base DNs under
+ which your application can look for user data),
+ <literal>subschemaSubentry</literal> (indicating where the LDAP schema are
+ stored), and <literal>supportedLDAPVersion</literal> (with OpenDJ seen to
+ support both LDAPv2 and LDAPv3).</para>
</section>
<section xml:id="check-ldapv3-support">
<title>Checking For LDAPv3 Support</title>
- <para>TODO</para>
+
+ <para>As shown in the previous section, you can check that the root DSE
+ attribute <literal>supportedLDAPVersion</literal> has a value of 3.</para>
+
+ <para>LDAPv3 has been available since 1997. Client applications built with
+ OpenDJ SDK use LDAPv3.</para>
</section>
<section xml:id="get-schema-information">
<title>Getting Schema Information</title>
- <para>TODO</para>
+
+ <para>The root DSE attribute <literal>subschemaSubentry</literal> shows
+ the DN of the entry holding LDAP schema definitions. LDAP schema defines the
+ object classes, attributes types, attribute value syntaxes, matching rules
+ and so on that constrain entries held by the LDAP server.</para>
+
+ <para>The <literal>org.forgerock.opendj.ldap.schema</literal> package
+ is devoted to constructing and querying LDAP schemas. The
+ <literal>Schema</literal> class for example lets you
+ <literal>readSchemaForEntry()</literal> to get the relevant schema from the
+ subschema subentry, and then <literal>validateEntry()</literal> to check
+ an entry your application has constructed before sending the entry to the
+ server.</para>
</section>
</chapter>
\ No newline at end of file
--
Gitblit v1.10.0