From b35a99489a13b3ac380a8f855a1dd94225e804de Mon Sep 17 00:00:00 2001
From: Mark Craig <mark.craig@forgerock.com>
Date: Fri, 04 May 2012 14:14:59 +0000
Subject: [PATCH] Adding content to the chapter on LDAP controls; not quite done yet
---
opendj3/src/main/docbkx/dev-guide/chap-controls.xml | 568 ++++++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 506 insertions(+), 62 deletions(-)
diff --git a/opendj3/src/main/docbkx/dev-guide/chap-controls.xml b/opendj3/src/main/docbkx/dev-guide/chap-controls.xml
index 962cb2e..a9a665e 100644
--- a/opendj3/src/main/docbkx/dev-guide/chap-controls.xml
+++ b/opendj3/src/main/docbkx/dev-guide/chap-controls.xml
@@ -42,7 +42,7 @@
<emphasis>request controls</emphasis>, and those sent by servers are termed
<emphasis>response controls</emphasis>.</para>
</section>
-
+
<section xml:id="get-supported-controls">
<title>Determining Supported Controls</title>
@@ -124,7 +124,7 @@
}
</programlisting>
</section>
-
+
<section xml:id="use-assertion-request-control">
<title>Assertion Request Control</title>
@@ -136,31 +136,31 @@
<programlisting language="java">
if (isSupported(AssertionRequestControl.OID)) {
- // Modify Babs Jensen's description if her entry does not have
- // a description, yet.
final String dn = "uid=bjensen,ou=People,dc=example,dc=com";
- ModifyRequest request = Requests.newModifyRequest(dn);
- request.addControl(AssertionRequestControl.newControl(true, Filter
- .valueOf("!(description=*)")));
- request.addModification(ModificationType.ADD, "description",
- "Created with the help of the LDAP assertion control");
+ final ModifyRequest request =
+ Requests.newModifyRequest(dn)
+ .addControl(AssertionRequestControl.newControl(
+ true, Filter.valueOf("!(description=*)")))
+ .addModification(ModificationType.ADD, "description",
+ "Created using LDAP assertion control");
connection.modify(request);
- LDIFEntryWriter writer = new LDIFEntryWriter(System.out);
+ final LDIFEntryWriter writer = new LDIFEntryWriter(System.out);
try {
writer.writeEntry(connection.readEntry(dn, "description"));
writer.close();
} catch (final IOException e) {
e.printStackTrace();
}
-}</programlisting>
+}
+</programlisting>
<para>OpenDJ directory server supports the LDAP assertion control:</para>
<programlisting language="ldif">dn: uid=bjensen,ou=People,dc=example,dc=com
-description: Created with the help of the LDAP assertion control</programlisting>
+description: Created using LDAP assertion control</programlisting>
</section>
<section xml:id="use-authorization-identity-control">
@@ -173,12 +173,13 @@
<programlisting language="java">
if (isSupported(AuthorizationIdentityRequestControl.OID)) {
- final String name = "uid=bjensen,ou=People,dc=example,dc=com";
- final char[] password = "hifalutin".toCharArray();
+ final String dn = "uid=bjensen,ou=People,dc=example,dc=com";
+ final char[] pwd = "hifalutin".toCharArray();
- System.out.println("Binding as " + name);
- BindRequest request = Requests.newSimpleBindRequest(name, password);
- request.addControl(AuthorizationIdentityRequestControl.newControl(true));
+ System.out.println("Binding as " + dn);
+ final BindRequest request =
+ Requests.newSimpleBindRequest(dn, pwd)
+ .addControl(AuthorizationIdentityRequestControl.newControl(true));
final BindResult result = connection.bind(request);
try {
@@ -190,7 +191,8 @@
} catch (final DecodeException e) {
e.printStackTrace();
}
-}</programlisting>
+}
+</programlisting>
<para>OpenDJ directory server supports the LDAP Authorization Identity
Controls:</para>
@@ -210,18 +212,16 @@
<programlisting language="java">
if (isSupported(PersistentSearchRequestControl.OID)) {
- SearchRequest request =
+ final SearchRequest request =
Requests.newSearchRequest(
- "dc=example,dc=com",
- SearchScope.WHOLE_SUBTREE,
- "(objectclass=inetOrgPerson)",
- "cn");
- request.addControl(PersistentSearchRequestControl.newControl(
- true, true, true, // isCritical, changesOnly, returnECs
- PersistentSearchChangeType.ADD,
- PersistentSearchChangeType.DELETE,
- PersistentSearchChangeType.MODIFY,
- PersistentSearchChangeType.MODIFY_DN));
+ "dc=example,dc=com", SearchScope.WHOLE_SUBTREE,
+ "(objectclass=inetOrgPerson)", "cn")
+ .addControl(PersistentSearchRequestControl.newControl(
+ true, true, true, // critical,changesOnly,returnECs
+ PersistentSearchChangeType.ADD,
+ PersistentSearchChangeType.DELETE,
+ PersistentSearchChangeType.MODIFY,
+ PersistentSearchChangeType.MODIFY_DN));
final ConnectionEntryReader reader = connection.search(request);
@@ -267,8 +267,14 @@
Change type: modifyDN
Previous DN: uid=abarnes,ou=People,dc=example,dc=com
Change number: -1</programlisting>
+
+ <para>In this case, <literal>Change number: -1</literal> because the server
+ did not set a change number value. OpenDJ directory server does not set the
+ change number value in the response control. If you need to track the order
+ of changes with OpenDJ directory server, read the external change log instead
+ of using the entry change notification response control.</para>
</section>
-
+
<section xml:id="use-get-effective-rights-control">
<title>GetEffectiveRights Request Control</title>
@@ -282,12 +288,12 @@
if (isSupported(GetEffectiveRightsRequestControl.OID)) {
final String authDN = "uid=kvaughan,ou=People,dc=example,dc=com";
- SearchRequest request =
+ final SearchRequest request =
Requests.newSearchRequest(
"dc=example,dc=com", SearchScope.WHOLE_SUBTREE,
- "(uid=bjensen)", "cn", "aclRights", "aclRightsInfo");
- request.addControl(
- GetEffectiveRightsRequestControl.newControl(true, authDN, "cn"));
+ "(uid=bjensen)", "cn", "aclRights", "aclRightsInfo")
+ .addControl(GetEffectiveRightsRequestControl.newControl(
+ true, authDN, "cn"));
final ConnectionEntryReader reader = connection.search(request);
final LDIFEntryWriter writer = new LDIFEntryWriter(System.out);
@@ -371,7 +377,7 @@
) ( reason: evaluated allow , deciding_aci: allow all Admin group)
</programlisting>
</section>
-
+
<section xml:id="use-managedsait-control">
<title>ManageDsaIT Request Control</title>
@@ -417,7 +423,7 @@
<para>OpenDJ directory server supports the ManageDsaIT Request Control.</para>
</section>
-
+
<section xml:id="use-matched-values-request-control">
<title>Matched Values Request Control</title>
@@ -435,11 +441,11 @@
<programlisting language="java">
if (isSupported(MatchedValuesRequestControl.OID)) {
final String dn = "uid=bjensen,ou=People,dc=example,dc=com";
- SearchRequest request =
+ final SearchRequest request =
Requests.newSearchRequest(dn, SearchScope.BASE_OBJECT,
- "(objectclass=*)", "cn");
- final String filter = "cn=Babs Jensen";
- request.addControl(MatchedValuesRequestControl.newControl(true, filter));
+ "(objectclass=*)", "cn")
+ .addControl(MatchedValuesRequestControl.newControl(
+ true, "(cn=Babs Jensen)"));
final SearchResultEntry entry = connection.searchSingleEntry(request);
System.out.println("Reading entry with matched values request.");
@@ -461,73 +467,511 @@
cn: Babs Jensen
</programlisting>
</section>
-
+
<section xml:id="use-password-expired-control">
<title>Password Expired Response Control</title>
- <para>TODO</para>
+
+ <para>A directory server can return the Password Expired Response Control,
+ described in the Internet-Draft <link xlink:show="new"
+ xlink:href="http://tools.ietf.org/html/draft-vchu-ldap-pwd-policy"><citetitle
+ >Password Policy for LDAP Directories</citetitle></link>, when a bind fails
+ because the password has expired. In order to see this, you must configure
+ the directory to expire Barbara Jensen's password.</para>
+
+ <programlisting language="java">
+if (isSupported(PasswordExpiredResponseControl.OID)) {
+ final String dn = "uid=bjensen,ou=People,dc=example,dc=com";
+ final char[] pwd = "hifalutin".toCharArray();
+
+ try {
+ connection.bind(dn, pwd);
+ } catch (ErrorResultException e) {
+ final Result result = e.getResult();
+ try {
+ final PasswordExpiredResponseControl control =
+ result.getControl(PasswordExpiredResponseControl.DECODER,
+ new DecodeOptions());
+ if (!(control == null) && control.hasValue()) {
+ System.out.println("Password expired for " + dn);
+ }
+ } catch (DecodeException de) {
+ de.printStackTrace();
+ }
+ }
+}
+</programlisting>
+
+ <para>OpenDJ directory server supports the Password Expired Response Control.
+ To obtain the following output from the excerpt, you can change the default
+ password policy configuration to set a short maximum password age, change
+ Barbara Jensen's password, and wait for it to expire.</para>
+
+ <programlisting
+ >Password expired for uid=bjensen,ou=People,dc=example,dc=com</programlisting>
</section>
-
+
<section xml:id="use-password-expiring-control">
<title>Password Expiring Response Control</title>
- <para>TODO</para>
+
+ <para>The Password Expiring Response Control, described in the Internet-Draft
+ <link xlink:href="http://tools.ietf.org/html/draft-vchu-ldap-pwd-policy"
+ xlink:show="new" ><citetitle>Password Policy for LDAP
+ Directories</citetitle></link>, warns your application during a bind
+ that the password used will soon expire.</para>
+
+ <programlisting language="java">
+if (isSupported(PasswordExpiringResponseControl.OID)) {
+ final String dn = "uid=bjensen,ou=People,dc=example,dc=com";
+ final char[] pwd = "hifalutin".toCharArray();
+
+ final BindResult result = connection.bind(dn, pwd);
+ try {
+ final PasswordExpiringResponseControl control =
+ result.getControl(PasswordExpiringResponseControl.DECODER,
+ new DecodeOptions());
+ if (!(control == null) && control.hasValue()) {
+ System.out.println("Password for " + dn + " expires in "
+ + control.getSecondsUntilExpiration() + " seconds.");
+ }
+ } catch (DecodeException de) {
+ de.printStackTrace();
+ }
+}
+</programlisting>
+
+ <para>OpenDJ directory server supports the Password Expiring Response Control.
+ To obtain the following output from the excerpt, you can change the default
+ password policy configuration to set a maximum password age and a warning
+ interval, change Barbara Jensen's password, and wait until you enter the
+ warning interval before password expiration.</para>
+
+ <programlisting>Password for uid=bjensen,ou=People,dc=example,dc=com
+ expires in 237 seconds.</programlisting>
</section>
<section xml:id="use-password-policy-controls">
<title>Password Policy Controls</title>
- <para>TODO</para>
+
+ <para>The Behera Internet-Draft, <link xlink:show="new"
+ xlink:href="http://tools.ietf.org/html/draft-behera-ldap-password-policy"
+ ><citetitle>Password Policy for LDAP Directories</citetitle></link>, describes
+ Password Policy Request and Response Controls. You send the request control
+ with a request to let the directory server know that your application can
+ handle the response control. The directory server sends the response control
+ on applicable operations to communicate warnings and errors.</para>
+
+ <programlisting language="java">
+if (isSupported(PasswordPolicyRequestControl.OID)) {
+ final String dn = "uid=bjensen,ou=People,dc=example,dc=com";
+ final char[] pwd = "hifalutin".toCharArray();
+
+ try {
+ final BindRequest request = Requests.newSimpleBindRequest(dn, pwd)
+ .addControl(PasswordPolicyRequestControl.newControl(true));
+
+ final BindResult result = connection.bind(request);
+
+ final PasswordPolicyResponseControl control =
+ result.getControl(PasswordPolicyResponseControl.DECODER,
+ new DecodeOptions());
+ if (!(control == null) && !(control.getWarningType() == null)) {
+ System.out.println("Password policy warning "
+ + control.getWarningType().toString() + ", value "
+ + control.getWarningValue() + " for " + dn);
+ }
+ } catch (ErrorResultException e) {
+ final Result result = e.getResult();
+ try {
+ final PasswordPolicyResponseControl control =
+ result.getControl(PasswordPolicyResponseControl.DECODER,
+ new DecodeOptions());
+ if (!(control == null)) {
+ System.out.println("Password policy error "
+ + control.getErrorType().toString() + " for " + dn);
+ }
+ } catch (DecodeException de) {
+ de.printStackTrace();
+ }
+ } catch (DecodeException e) {
+ e.printStackTrace();
+ }
+}
+</programlisting>
+
+ <para>OpenDJ directory server supports the Password Policy Controls. To obtain
+ the output from the excerpt, you can change the default password policy
+ configuration to set a maximum password age and a warning interval, change
+ Barbara Jensen's password, and then run the example during the warning
+ interval and after the password has expired.</para>
+
+ <para>For a warning:</para>
+ <programlisting>Password policy warning timeBeforeExpiration, value 237 for
+ uid=bjensen,ou=People,dc=example,dc=com</programlisting>
+
+ <para>For an error:</para>
+ <programlisting>Password policy error passwordExpired for
+ uid=bjensen,ou=People,dc=example,dc=com</programlisting>
</section>
-
+
<section xml:id="use-permissive-modify-request-control">
<title>Permissive Modify Request Control</title>
- <para>TODO</para>
+
+ <para>Microsoft defined a Permissive Modify Request Control that relaxes
+ some constraints when your application performs a modify operation and
+ tries to <literal>add</literal> an attribute that already exists, or to
+ <literal>delete</literal> an attribute that does not exist.</para>
+
+ <programlisting language="java">
+if (isSupported(PermissiveModifyRequestControl.OID)) {
+ final String dn = "uid=bjensen,ou=People,dc=example,dc=com";
+
+ final ModifyRequest request =
+ Requests.newModifyRequest(dn)
+ .addControl(PermissiveModifyRequestControl.newControl(true))
+ .addModification(ModificationType.ADD, "uid", "bjensen");
+
+ connection.modify(request);
+ System.out.println("Permissive modify did not complain about "
+ + "attempt to add uid: bjensen to " + dn + ".");
+}
+</programlisting>
+
+ <para>OpenDJ directory server supports the Permissive Modify Request
+ Control:</para>
+
+ <programlisting>Permissive modify did not complain about attempt to add
+ uid: bjensen to uid=bjensen,ou=People,dc=example,dc=com.</programlisting>
</section>
-
+
<section xml:id="use-persistent-search-request-control">
<title>Persistent Search Request Control</title>
<para>See <xref linkend="use-entry-change-notification-control" />.</para>
</section>
-
+
<section xml:id="use-post-read-control">
<title>Post-Read Controls</title>
- <para>TODO</para>
+
+ <para>RFC 4527, <link xlink:href="http://tools.ietf.org/html/rfc4527"
+ xlink:show="new"><citetitle>LDAP Read Entry Controls</citetitle></link>,
+ describes the post-read controls that let your application get the content
+ of an entry immediately after modifications are applied.</para>
+
+ <programlisting language="java">
+if (isSupported(PostReadRequestControl.OID)) {
+ final String dn = "uid=bjensen,ou=People,dc=example,dc=com";
+
+ final ModifyRequest request =
+ Requests.newModifyRequest(dn)
+ .addControl(PostReadRequestControl.newControl(true, "description"))
+ .addModification(ModificationType.REPLACE,
+ "description", "Using the PostReadRequestControl");
+
+ final Result result = connection.modify(request);
+ try {
+ final PostReadResponseControl control =
+ result.getControl(PostReadResponseControl.DECODER,
+ new DecodeOptions());
+ final Entry entry = control.getEntry();
+
+ final LDIFEntryWriter writer = new LDIFEntryWriter(System.out);
+ writer.writeEntry(entry);
+ writer.close();
+ } catch (DecodeException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+}
+</programlisting>
+
+ <para>OpenDJ directory server supports these controls:</para>
+
+ <programlisting language="ldif">dn: uid=bjensen,ou=People,dc=example,dc=com
+description: Using the PostReadRequestControl</programlisting>
</section>
-
+
<section xml:id="use-pre-read-control">
<title>Pre-Read Controls</title>
- <para>TODO</para>
+
+ <para>RFC 4527, <link xlink:href="http://tools.ietf.org/html/rfc4527"
+ xlink:show="new"><citetitle>LDAP Read Entry Controls</citetitle></link>,
+ describes the pre-read controls that let your application get the content
+ of an entry immediately before modifications are applied.</para>
+
+ <programlisting language="java">
+if (isSupported(PreReadRequestControl.OID)) {
+ final String dn = "uid=bjensen,ou=People,dc=example,dc=com";
+
+ final ModifyRequest request =
+ Requests.newModifyRequest(dn)
+ .addControl(PreReadRequestControl.newControl(true, "mail"))
+ .addModification(
+ ModificationType.REPLACE, "mail", "modified@example.com");
+
+ final Result result = connection.modify(request);
+ try {
+ final PreReadResponseControl control =
+ result.getControl(PreReadResponseControl.DECODER,
+ new DecodeOptions());
+ final Entry entry = control.getEntry();
+
+ final LDIFEntryWriter writer = new LDIFEntryWriter(System.out);
+ writer.writeEntry(entry);
+ writer.close();
+ } catch (DecodeException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+}
+</programlisting>
+
+ <para>OpenDJ directory server supports these controls:</para>
+
+ <programlisting language="ldif">dn: uid=bjensen,ou=People,dc=example,dc=com
+mail: bjensen@example.com</programlisting>
</section>
-
+
<section xml:id="use-proxy-authz-control">
<title>Proxied Authorization Request Controls</title>
- <para>TODO</para>
+
+ <para>Proxied authorization provides a standard control as defined in
+ <link xlink:href="http://tools.ietf.org/html/rfc4370" xlink:show="new">RFC
+ 4370</link> (and an earlier Internet-Draft) for binding with the user
+ credentials of a proxy, who carries out LDAP operations on behalf of other
+ users. You might use proxied authorization, for example, to have your
+ application bind with its credentials, and then carry out operations as the
+ users who login to the application.</para>
+
+ <programlisting language="java">
+if (isSupported(ProxiedAuthV2RequestControl.OID)) {
+ final String bindDN = "cn=My App,ou=Apps,dc=example,dc=com";
+ final String targetDn = "uid=bjensen,ou=People,dc=example,dc=com";
+ final String authzId = "dn:uid=kvaughan,ou=People,dc=example,dc=com";
+
+ final ModifyRequest request =
+ Requests.newModifyRequest(targetDn)
+ .addControl(ProxiedAuthV2RequestControl.newControl(authzId))
+ .addModification(ModificationType.REPLACE, "description",
+ "Done with proxied authz");
+
+ connection.bind(bindDN, "password".toCharArray());
+ connection.modify(request);
+ final Entry entry = connection.readEntry(targetDn, "description");
+
+ final LDIFEntryWriter writer = new LDIFEntryWriter(System.out);
+ try {
+ writer.writeEntry(entry);
+ writer.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+}</programlisting>
+
+ <para>OpenDJ supports proxied authorization, and the example works with the
+ sample data:</para>
+
+ <programlisting language="ldif">dn: uid=bjensen,ou=People,dc=example,dc=com
+description: Done with proxied authz</programlisting>
</section>
-
+
<section xml:id="use-server-side-sort-control">
<title>Server-Side Sort Controls</title>
- <para>TODO</para>
+
+ <para>The server-side sort controls are described in RFC 2891, <link
+ xlink:show="new" xlink:href="http://tools.ietf.org/html/rfc2891"><citetitle
+ >LDAP Control Extension for Server Side Sorting of Search
+ Results</citetitle></link>. If possible, sort on the client side instead to
+ reduce load on the server. If not, then you can request a server-side
+ sort.</para>
+
+ <programlisting language="java">
+static void useServerSideSortRequestControl(Connection connection)
+ throws ErrorResultException {
+ if (isSupported(ServerSideSortRequestControl.OID)) {
+ final SearchRequest request =
+ Requests.newSearchRequest("dc=example,dc=com",
+ SearchScope.WHOLE_SUBTREE, "(sn=Jensen)", "cn")
+ .addControl(ServerSideSortRequestControl.newControl(
+ true, new SortKey("cn")));
+
+ final SearchResultHandler resultHandler = new MySearchResultHandler();
+ final Result result = connection.search(request, resultHandler);
+
+ try {
+ final ServerSideSortResponseControl control =
+ result.getControl(ServerSideSortResponseControl.DECODER,
+ new DecodeOptions());
+ if (control != null && control.getResult() == ResultCode.SUCCESS) {
+ System.out.println("# Entries are sorted.");
+ // FIXME: But the order is backwards!
+ } else {
+ System.out.println("# Entries not necessarily sorted");
+ }
+ } catch (DecodeException e) {
+ e.printStackTrace();
+ }
+ } else {
+ System.out.println("ServerSideSortRequestControl not supported");
+ }
+}
+
+private static class MySearchResultHandler implements SearchResultHandler {
+
+ @Override
+ public void handleErrorResult(ErrorResultException error) {
+ // Ignore.
+ }
+
+ @Override
+ public void handleResult(Result result) {
+ // Ignore.
+ }
+
+ @Override
+ public boolean handleEntry(SearchResultEntry entry) {
+ final LDIFEntryWriter writer = new LDIFEntryWriter(System.out);
+ try {
+ writer.writeEntry(entry);
+ writer.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean handleReference(SearchResultReference reference) {
+ System.out.println("Got a reference: " + reference.toString());
+ return false;
+ }
+}
+</programlisting>
+
+ <para>OpenDJ directory server supports server-side sorting:</para>
+
+ <programlisting language="ldif">dn: uid=ajensen,ou=People,dc=example,dc=com
+cn: Allison Jensen
+
+dn: uid=bjensen,ou=People,dc=example,dc=com
+cn: Barbara Jensen
+cn: Babs Jensen
+
+dn: uid=bjense2,ou=People,dc=example,dc=com
+cn: Bjorn Jensen
+
+dn: uid=gjensen,ou=People,dc=example,dc=com
+cn: Gern Jensen
+
+dn: uid=jjensen,ou=People,dc=example,dc=com
+cn: Jody Jensen
+
+dn: uid=kjensen,ou=People,dc=example,dc=com
+cn: Kurt Jensen
+
+dn: uid=rjense2,ou=People,dc=example,dc=com
+cn: Randy Jensen
+
+dn: uid=rjensen,ou=People,dc=example,dc=com
+cn: Richard Jensen
+
+dn: uid=tjensen,ou=People,dc=example,dc=com
+cn: Ted Jensen
+
+# Entries are sorted.</programlisting>
</section>
-
+
<section xml:id="use-simple-paged-results-control">
<title>Simple Paged Results Control</title>
- <para>TODO</para>
+
+ <para>RFC 2696, <link xlink:href="http://tools.ietf.org/html/rfc2696"
+ xlink:show="new"><citetitle>LDAP Control Extension for Simple Paged Results
+ Manipulation</citetitle></link>, defines a control for simple paging of
+ search results that works with a cookie mechanism.</para>
+
+ <programlisting language="java">
+if (isSupported(SimplePagedResultsControl.OID)) {
+ ByteString cookie = ByteString.empty();
+ SearchRequest request;
+ final SearchResultHandler resultHandler = new MySearchResultHandler();
+ Result result;
+
+ int page = 1;
+ do {
+ System.out.println("# Simple paged results: Page " + page);
+
+ request =
+ Requests.newSearchRequest("dc=example,dc=com",
+ SearchScope.WHOLE_SUBTREE, "(sn=Jensen)", "cn")
+ .addControl(SimplePagedResultsControl.newControl(
+ true, 3, cookie));
+
+ result = connection.search(request, resultHandler);
+ try {
+ SimplePagedResultsControl control =
+ result.getControl(SimplePagedResultsControl.DECODER,
+ new DecodeOptions());
+ cookie = control.getCookie();
+ } catch (DecodeException e) {
+ e.printStackTrace();
+ }
+
+ ++page;
+ } while (cookie.length() != 0);
+}
+</programlisting>
+
+ <para>OpenDJ directory server supports getting simple paged results:</para>
+
+ <programlisting language="ldif"># Simple paged results: Page 1
+dn: uid=ajensen,ou=People,dc=example,dc=com
+cn: Allison Jensen
+
+dn: uid=bjense2,ou=People,dc=example,dc=com
+cn: Bjorn Jensen
+
+dn: uid=bjensen,ou=People,dc=example,dc=com
+cn: Barbara Jensen
+cn: Babs Jensen
+
+# Simple paged results: Page 2
+dn: uid=gjensen,ou=People,dc=example,dc=com
+cn: Gern Jensen
+
+dn: uid=jjensen,ou=People,dc=example,dc=com
+cn: Jody Jensen
+
+dn: uid=kjensen,ou=People,dc=example,dc=com
+cn: Kurt Jensen
+
+# Simple paged results: Page 3
+dn: uid=rjense2,ou=People,dc=example,dc=com
+cn: Randy Jensen
+
+dn: uid=rjensen,ou=People,dc=example,dc=com
+cn: Richard Jensen
+
+dn: uid=tjensen,ou=People,dc=example,dc=com
+cn: Ted Jensen
+</programlisting>
</section>
-
+
<section xml:id="use-subentry-request-control">
<title>Sub-entries Request Control</title>
<para>TODO</para>
</section>
-
+
<section xml:id="use-subtree-delete-control">
<title>Subtree Delete Request Control</title>
<para>TODO</para>
</section>
-
+
<section xml:id="use-vlv-control">
<title>Virtual List View Controls</title>
<para>TODO</para>
</section>
-
+
<section xml:id="custom-control">
<title>Custom Controls</title>
<para>TODO</para>
--
Gitblit v1.10.0