| opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Controls.java | ●●●●● patch | view | raw | blame | history | |
| opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseGenericControl.java | ●●●●● patch | view | raw | blame | history | |
| opendj-ldap-sdk-examples/src/site/xdoc/index.xml.vm | ●●●●● patch | view | raw | blame | history | |
| src/main/docbkx/dev-guide/chap-controls.xml | ●●●●● patch | view | raw | blame | history | |
| src/site/resources/Example.ldif | ●●●●● patch | view | raw | blame | history |
opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/Controls.java
@@ -20,7 +20,7 @@ * * CDDL HEADER END * * Copyright 2012-2013 ForgeRock AS * Copyright 2012-2014 ForgeRock AS * */ @@ -45,6 +45,7 @@ import org.forgerock.opendj.ldap.SearchResultReferenceIOException; import org.forgerock.opendj.ldap.SearchScope; import org.forgerock.opendj.ldap.SortKey; import org.forgerock.opendj.ldap.controls.ADNotificationRequestControl; import org.forgerock.opendj.ldap.controls.AssertionRequestControl; import org.forgerock.opendj.ldap.controls.AuthorizationIdentityRequestControl; import org.forgerock.opendj.ldap.controls.AuthorizationIdentityResponseControl; @@ -123,6 +124,7 @@ // Uncomment a method to run one of the examples. //useADNotificationRequestControl(connection); //useAssertionControl(connection); useAuthorizationIdentityRequestControl(connection); // For the EntryChangeNotificationResponseControl see @@ -156,6 +158,95 @@ } /** * Use the <a * href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms676877(v=vs.85).aspx" * >Microsoft LDAP Notification control</a> * to register a change notification request for a search * on Microsoft Active Directory. * <p/> * This client binds to Active Directory as * {@code cn=Administrator,cn=users,dc=example,dc=com} * with password {@code password}, * and expects entries under {@code dc=example,dc=com}. * * @param connection Active connection to Active Directory server. * @throws ErrorResultException Operation failed. */ static void useADNotificationRequestControl(Connection connection) throws ErrorResultException { // --- JCite ADNotification --- final String user = "cn=Administrator,cn=users,dc=example,dc=com"; final char[] password = "password".toCharArray(); connection.bind(user, password); final String[] attributes = {"cn", ADNotificationRequestControl.IS_DELETED_ATTR, ADNotificationRequestControl.WHEN_CHANGED_ATTR, ADNotificationRequestControl.WHEN_CREATED_ATTR}; SearchRequest request = Requests.newSearchRequest("dc=example,dc=com", SearchScope.WHOLE_SUBTREE, "(objectclass=*)", attributes) .addControl(ADNotificationRequestControl.newControl(true)); ConnectionEntryReader reader = connection.search(request); try { while (reader.hasNext()) { if (!reader.isReference()) { SearchResultEntry entry = reader.readEntry(); // Updated entry final LDIFEntryWriter writer = new LDIFEntryWriter(System.out); Boolean isDeleted = entry.parseAttribute( ADNotificationRequestControl.IS_DELETED_ATTR ).asBoolean(); if (isDeleted != null && isDeleted) { // Handle entry deletion writer.writeComment("Deleted entry: " + entry.getName().toString()); writer.writeEntry(entry); writer.flush(); } String whenCreated = entry.parseAttribute( ADNotificationRequestControl.WHEN_CREATED_ATTR) .asString(); String whenChanged = entry.parseAttribute( ADNotificationRequestControl.WHEN_CHANGED_ATTR) .asString(); if (whenCreated != null && whenChanged != null) { if (whenCreated.equals(whenChanged)) { // Handle entry addition writer.writeComment("Added entry: " + entry.getName().toString()); writer.writeEntry(entry); writer.flush(); } else { // Handle entry modification writer.writeComment("Modified entry: " + entry.getName().toString()); writer.writeEntry(entry); writer.flush(); } } } else { reader.readReference(); // Read and ignore reference } } } catch (final ErrorResultIOException e) { System.err.println(e.getMessage()); System.exit(e.getCause().getResult().getResultCode().intValue()); } catch (final SearchResultReferenceIOException e) { System.err.println("Got search reference(s): " + e.getReference() .getURIs().toString()); } catch (final IOException e) { System.err.println(e.getMessage()); System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue()); } // --- JCite ADNotification --- } /** * Use the LDAP assertion control to modify Babs Jensen's description if * her entry does not have a description, yet. * opendj-ldap-sdk-examples/src/main/java/org/forgerock/opendj/examples/UseGenericControl.java
New file @@ -0,0 +1,176 @@ /* * 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 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 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 2009-2010 Sun Microsystems, Inc. * Portions copyright 2011-2014 ForgeRock AS */ package org.forgerock.opendj.examples; import org.forgerock.opendj.io.ASN1; import org.forgerock.opendj.io.ASN1Writer; import org.forgerock.opendj.ldap.ByteStringBuilder; import org.forgerock.opendj.ldap.Connection; import org.forgerock.opendj.ldap.DecodeOptions; import org.forgerock.opendj.ldap.Entry; import org.forgerock.opendj.ldap.ErrorResultException; import org.forgerock.opendj.ldap.ErrorResultIOException; import org.forgerock.opendj.ldap.LDAPConnectionFactory; import org.forgerock.opendj.ldap.ModificationType; import org.forgerock.opendj.ldap.ResultCode; import org.forgerock.opendj.ldap.SearchScope; import org.forgerock.opendj.ldap.controls.GenericControl; import org.forgerock.opendj.ldap.controls.PreReadResponseControl; import org.forgerock.opendj.ldap.requests.ModifyRequest; import org.forgerock.opendj.ldap.requests.Requests; import org.forgerock.opendj.ldap.responses.Result; import org.forgerock.opendj.ldap.responses.SearchResultEntry; import org.forgerock.opendj.ldif.LDIFEntryWriter; import java.io.IOException; /** * An example client application which uses * {@link org.forgerock.opendj.ldap.controls.GenericControl} to pass the * pre-read request control from <a href="http://tools.ietf.org/html/rfc4527" * >RFC 4527 - Lightweight Directory Access Protocol (LDAP) Read Entry Controls</a>. * * <p>This example takes the following command line parameters: * * <pre> * <host> <port> <username> <password> <userDN> * </pre> * * <p>This example modifies the description attribute of an entry that * you specify in the <userDN> command line parameter. */ public final class UseGenericControl { /** * Main method. * * @param args The command line arguments: host, port, username, password, * base DN, where the base DN is the root of a naming context. */ public static void main(final String[] args) { if (args.length < 5) { System.err.println("Usage: host port username password userDN"); System.exit(1); } // Parse command line arguments. final String hostName = args[0]; final int port = Integer.parseInt(args[1]); final String userName = args[2]; final String password = args[3]; final String userDN = args[4]; // --- JCite --- // Create an LDIF writer to write entries to stdout. final LDIFEntryWriter writer = new LDIFEntryWriter(System.out); // Connect and bind to the server. final LDAPConnectionFactory factory = new LDAPConnectionFactory(hostName, port); Connection connection = null; // Prepare the value for the GenericControl. // http://tools.ietf.org/html/rfc4527#section-3.1 says: // "The Pre-Read request control is a LDAP Control [RFC4511] whose // controlType is 1.3.6.1.1.13.1 and whose controlValue is a BER-encoded // AttributeSelection [RFC4511], as extended by [RFC3673]." ByteStringBuilder builder = new ByteStringBuilder(); ASN1Writer asn1Writer = ASN1.getWriter(builder); try { asn1Writer.writeStartSequence(); asn1Writer.writeOctetString("description"); asn1Writer.writeEndSequence(); asn1Writer.flush(); asn1Writer.close(); } catch (Exception e) { System.out.println("Failed to prepare control value: " + e.getCause()); System.exit(-1); } try { connection = factory.getConnection(); connection.bind(userName, password.toCharArray()); // Modify the user description. final ModifyRequest request = Requests .newModifyRequest(userDN) .addModification(ModificationType.REPLACE, "description", "A new description") .addControl( GenericControl .newControl( "1.3.6.1.1.13.1", true, builder.toByteString())); final Result result = connection.modify(request); // Display the description before and after the modification. if (result.isSuccess()) { final PreReadResponseControl control = result.getControl( PreReadResponseControl.DECODER, new DecodeOptions() ); final Entry unmodifiedEntry = control.getEntry(); writer.writeComment("Before modification"); writer.writeEntry(unmodifiedEntry); writer.flush(); final SearchResultEntry modifiedEntry = connection.searchSingleEntry( userDN, SearchScope.BASE_OBJECT, "(objectclass=*)", "description"); writer.writeComment("After modification"); writer.writeEntry(modifiedEntry); writer.flush(); } } catch (final ErrorResultException e) { System.err.println(e.getMessage()); System.exit(e.getResult().getResultCode().intValue()); } catch (final ErrorResultIOException e) { System.err.println(e.getMessage()); System.exit(e.getCause().getResult().getResultCode().intValue()); } catch (final IOException e) { System.err.println(e.getMessage()); System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue()); } finally { if (connection != null) { connection.close(); } } // --- JCite --- } private UseGenericControl() { // Not used. } } opendj-ldap-sdk-examples/src/site/xdoc/index.xml.vm
@@ -20,7 +20,7 @@ ! ! CCPL HEADER END ! ! Copyright 2011-2013 ForgeRock AS ! Copyright 2011-2014 ForgeRock AS ! --> <document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" @@ -103,6 +103,10 @@ - illustrates how to add or remove a member from a static group </li> <li> <a href="xref/org/forgerock/opendj/examples/UseGenericControl.html">Use <code>GenericControl</code></a> - illustrates how to use <code>GenericControl</code> to add a pre-read request control </li> <li> <a href="xref/org/forgerock/opendj/examples/GetADChangeNotifications.html">Use <code>GenericControl</code></a> - illustrates how to use <code>GenericControl</code> to get change notifications from Active Directory </li> src/main/docbkx/dev-guide/chap-controls.xml
@@ -20,15 +20,15 @@ ! ! CCPL HEADER END ! ! Copyright 2011-2013 ForgeRock AS ! Copyright 2011-2014 ForgeRock AS ! --> <chapter xml:id='chap-controls' xmlns='http://docbook.org/ns/docbook' version='5.0' xml:lang='en' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd' xmlns:xlink='http://www.w3.org/1999/xlink' xmlns:xinclude='http://www.w3.org/2001/XInclude'> xsi:schemaLocation='http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd' xmlns:xlink='http://www.w3.org/1999/xlink'> <title>Working With Controls</title> <indexterm> <primary>Controls</primary> @@ -350,6 +350,33 @@ </programlisting> </section> <section xml:id="use-ad-notification-request-control"> <title>Microsoft LDAP Server Notification Control</title> <indexterm> <primary>Controls</primary> <secondary>Microsoft LDAP Server Notification Control</secondary> </indexterm> <para> The Microsoft <link xlink:show="new" xlink:href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366983(v=vs.85).aspx" >LDAP Server Notification Control</link> with OID <literal>1.2.840.113556.1.4.528</literal> can be used to register a change notification request for a search on Microsoft Active Directory. </para> <programlisting language="java" >[jcp:org.forgerock.opendj.examples.Controls:--- JCite ADNotification ---]</programlisting> <para> When you run the search against Active Directory and then create, update, and delete a new user Active Directory notifies you of changes to directory data. </para> </section> <section xml:id="use-password-expired-control"> <title>Password Expired Response Control</title> <indexterm> @@ -837,79 +864,32 @@ <literal>GenericControl</literal> class when adding the control to your request.</para> <para>For example, the Microsoft <link xlink:show="new" xlink:href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366983(v=vs.85).aspx" >LDAP Server Notification Control</link> with OID <literal>1.2.840.113556.1.4.528</literal> can be used to register a change notification request for a search on Microsoft Active Directory. You can use a <literal>GenericControl.newControl()</literal> static method to add the request control to your search.</para> <para> The following example uses a <literal>GenericControl</literal> to add a pre-read request control when replacing the description on a user's entry. OpenDJ LDAP SDK already implements the pre-read request control, as shown in <xref linkend="use-pre-read-control" />. The example is of interest mainly because it shows that the values that you pass when using a <literal>GenericControl</literal> must be prepared as indicated in the specification of the control. </para> <programlisting language="java" >[jcp:org.forgerock.opendj.examples.GetADChangeNotifications:--- JCite ---]</programlisting> >[jcp:org.forgerock.opendj.examples.UseGenericControl:--- JCite ---]</programlisting> <para>When you run the search against Active Directory and then create, update, and delete a new user, in this example <literal>CN=New User,CN=Users,DC=ad,DC=example,DC=com</literal>, Active Directory notifies you of changes to directory data.</para> <para> When you run this example against a user entry in OpenDJ directory server, you see something like the following result. </para> <programlisting language="ldif" ># Search result entry: CN=RID Set,CN=WIN2008R2641,OU=Domain Controllers, DC=ad,DC=example,DC=com dn: CN=RID Set,CN=WIN2008R2641,OU=Domain Controllers,DC=ad,DC=example,DC=com objectClass: top objectClass: rIDSet objectGUID:: 178zQQic3EOoBOB1j2QVgQ== uSNChanged: 12446 <programlisting language="ldif"># Before modification dn: uid=bjensen,ou=People,dc=example,dc=com description: Original description # Search result entry: CN=New User,CN=Users,DC=ad,DC=example,DC=com dn: CN=New User,CN=Users,DC=ad,DC=example,DC=com objectClass: top objectClass: person objectClass: organizationalPerson objectClass: user objectGUID:: 7XE/OoJdFEqAegwAi2eNlA== uSNChanged: 12753 # Search result entry: CN=New User,CN=Users,DC=ad,DC=example,DC=com dn: CN=New User,CN=Users,DC=ad,DC=example,DC=com objectClass: top objectClass: person objectClass: organizationalPerson objectClass: user objectGUID:: 7XE/OoJdFEqAegwAi2eNlA== uSNChanged: 12755 # Search result entry: CN=New User,CN=Users,DC=ad,DC=example,DC=com dn: CN=New User,CN=Users,DC=ad,DC=example,DC=com objectClass: top objectClass: person objectClass: organizationalPerson objectClass: user objectGUID:: 7XE/OoJdFEqAegwAi2eNlA== uSNChanged: 12757 # Search result entry: CN=New User,CN=Users,DC=ad,DC=example,DC=com dn: CN=New User,CN=Users,DC=ad,DC=example,DC=com objectClass: top objectClass: person objectClass: organizationalPerson objectClass: user objectGUID:: 7XE/OoJdFEqAegwAi2eNlA== uSNChanged: 12758 # Search result entry: CN=New User\0ADEL:3a3f71ed-5d82-4a14-807a-0c008b678d94, # CN=Deleted Objects,DC=ad,DC=example,DC=com dn: CN=New User\0ADEL:3a3f71ed-5d82-4a14-807a-0c008b678d94,CN=Deleted Objects, DC=ad,DC=example,DC=com objectClass: top objectClass: person objectClass: organizationalPerson objectClass: user objectGUID:: 7XE/OoJdFEqAegwAi2eNlA== isDeleted: TRUE uSNChanged: 12759 </programlisting> # After modification dn: uid=bjensen,ou=People,dc=example,dc=com description: A new description</programlisting> <para>The <literal>GenericControl</literal> class is useful with controls that do not require you to encode complex request values, or decode complex src/site/resources/Example.ldif
@@ -20,7 +20,7 @@ # CDDL HEADER END # # Copyright 2006-2008 Sun Microsystems, Inc. # Portions Copyright 2012-2013 ForgeRock AS # Portions Copyright 2012-2014 ForgeRock AS # # # dc=com sample LDIF file @@ -682,6 +682,7 @@ preferredLanguage: en, ko;q=0.8 uidNumber: 1076 gidNumber: 1000 description: Original description dn: uid=bmaddox,ou=People,dc=example,dc=com objectClass: person