mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Mark Craig
03.44.2012 cf136586c780f03c81e504ec2b8018a0598a9c28
opendj3/src/main/docbkx/dev-guide/chap-controls.xml
@@ -86,30 +86,43 @@
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>
  <para>The following excerpt shows couple of methods to check whether the
  directory server supports a control.</para>
  <programlisting language="java">
final LDAPConnectionFactory factory = new LDAPConnectionFactory(
  host, port);
Connection connection = null;
/**
 * Controls supported by the LDAP server.
 */
private static Collection&lt;String> controls;
try
{
  connection = factory.getConnection();
/**
 * Populate the list of supported LDAP control OIDs.
 *
 * @param connection
 *            Active connection to the LDAP server.
 * @throws ErrorResultException
 *             Failed to get list of controls.
 */
static void checkSupportedControls(Connection connection)
        throws ErrorResultException {
    controls = RootDSE.readRootDSE(connection).getSupportedControls();
}
  // Perform an anonymous search on the root DSE.
  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>
/**
 * Check whether a control is supported. Call {@code checkSupportedControls}
 * first.
 *
 * @param control
 *            Check support for this control, provided by OID.
 * @return True if the control is supported.
 */
static boolean isSupported(final String control) {
    if (controls != null &amp;&amp; !controls.isEmpty()) {
        return controls.contains(control);
    }
    return false;
}
</programlisting>
 </section>
 
 <section xml:id="use-assertion-request-control">
@@ -125,11 +138,11 @@
if (isSupported(AssertionRequestControl.OID)) {
    // Modify Babs Jensen's description if her entry does not have
    // a description, yet.
    String dn = "uid=bjensen,ou=People,dc=example,dc=com";
    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.addControl(AssertionRequestControl.newControl(true, Filter
            .valueOf("!(description=*)")));
    request.addModification(ModificationType.ADD, "description",
            "Created with the help of the LDAP assertion control");
@@ -140,26 +153,223 @@
        writer.writeEntry(connection.readEntry(dn, "description"));
        writer.close();
    } catch (final IOException e) {
        // Ignore.
        e.printStackTrace();
    }
}</programlisting>
  <para>OpenDJ directory server supports the LDAP assertion control.</para>
  <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>
 </section>
 <section xml:id="use-authorization-identity-control">
  <title>Authorization Identity Controls</title>
  <para>TODO</para>
  <para>The <link xlink:href="http://tools.ietf.org/html/rfc3829"
  xlink:show="new">LDAP Authorization Identity Controls</link> let you get the
  authorization identity established when you bind to the directory server.
  The following excerpt shows simple use of the controls.</para>
  <programlisting language="java">
if (isSupported(AuthorizationIdentityRequestControl.OID)) {
    final String name = "uid=bjensen,ou=People,dc=example,dc=com";
    final char[] password = "hifalutin".toCharArray();
    System.out.println("Binding as " + name);
    BindRequest request = Requests.newSimpleBindRequest(name, password);
    request.addControl(AuthorizationIdentityRequestControl.newControl(true));
    final BindResult result = connection.bind(request);
    try {
        final AuthorizationIdentityResponseControl control =
                result.getControl(AuthorizationIdentityResponseControl.DECODER,
                        new DecodeOptions());
        System.out.println("Authorization ID returned: "
                        + control.getAuthorizationID());
    } catch (final DecodeException e) {
        e.printStackTrace();
    }
}</programlisting>
  <para>OpenDJ directory server supports the LDAP Authorization Identity
  Controls:</para>
  <programlisting>Binding as uid=bjensen,ou=People,dc=example,dc=com
Authorization ID returned: dn:uid=bjensen,ou=People,dc=example,dc=com</programlisting>
 </section>
 
 <section xml:id="use-entry-change-notification-control">
  <title>Entry Change Notification Response Controls</title>
  <para>TODO</para>
  <para>When performing a persistent search, your application can retrieve
  information using this response control about why the directory server
  returned the entry. See the Internet-Draft on <link xlink:show="new"
  xlink:href="tools.ietf.org/html/draft-ietf-ldapext-psearch">persistent
  searches</link> for background information.</para>
  <programlisting language="java">
if (isSupported(PersistentSearchRequestControl.OID)) {
    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));
    final ConnectionEntryReader reader = connection.search(request);
    try {
        while (reader.hasNext()) {
            if (!reader.isReference()) {
                final SearchResultEntry entry = reader.readEntry();
                System.out.println("Entry changed: "
                        + entry.getName().toString());
                EntryChangeNotificationResponseControl control =
                        entry.getControl(
                                EntryChangeNotificationResponseControl.DECODER,
                                new DecodeOptions());
                PersistentSearchChangeType type = control.getChangeType();
                System.out.println("Change type: " + type.toString());
                if (type.equals(PersistentSearchChangeType.MODIFY_DN)) {
                    System.out.println("Previous DN: "
                            + control.getPreviousName().toString());
                }
                System.out.println("Change number: "
                        + control.getChangeNumber());
                System.out.println(); // Add a blank line.
           }
        }
    } catch (final DecodeException e) {
        e.printStackTrace();
    } catch (final ErrorResultIOException e) {
        e.printStackTrace();
    } catch (final SearchResultReferenceIOException e) {
        e.printStackTrace();
    }
}
</programlisting>
  <para>OpenDJ directory server supports persistent searches and the entry
  change notification response control. When another application renames
  Anne-Louise Barnes's entry, the sample code picks up information from the
  entry change notification response control:</para>
  <programlisting>Entry changed: uid=bdobbs,ou=People,dc=example,dc=com
Change type: modifyDN
Previous DN: uid=abarnes,ou=People,dc=example,dc=com
Change number: -1</programlisting>
 </section>
 
 <section xml:id="use-get-effective-rights-control">
  <title>Get Effective Rights Request Control</title>
  <para>TODO</para>
  <title>GetEffectiveRights Request Control</title>
  <para>Your application can attach the GetEffectiveRights request control to
  a search in order to determine what access a user has to perform operations
  on entries found. See the Internet-Draft on the <link xlink:show="new"
  xlink:href="http://tools.ietf.org/html/draft-ietf-ldapext-acl-model">Access
  Control Model for LDAP</link> for background.</para>
  <programlisting language="java">
if (isSupported(GetEffectiveRightsRequestControl.OID)) {
    final String authDN = "uid=kvaughan,ou=People,dc=example,dc=com";
    SearchRequest request =
            Requests.newSearchRequest(
                    "dc=example,dc=com", SearchScope.WHOLE_SUBTREE,
                    "(uid=bjensen)", "cn", "aclRights", "aclRightsInfo");
    request.addControl(
            GetEffectiveRightsRequestControl.newControl(true, authDN, "cn"));
    final ConnectionEntryReader reader = connection.search(request);
    final LDIFEntryWriter writer = new LDIFEntryWriter(System.out);
    try {
        while (reader.hasNext()) {
            if (!reader.isReference()) {
                final SearchResultEntry entry = reader.readEntry();
                writer.writeEntry(entry);
            }
        }
        writer.close();
    } catch (final ErrorResultIOException e) {
        e.printStackTrace();
    } catch (final SearchResultReferenceIOException e) {
        e.printStackTrace();
    } catch (final IOException e) {
        e.printStackTrace();
    }
}
</programlisting>
  <para>OpenDJ SDK currently implements the request control, but not the
  response control. The results are shown as values of the
  <literal>aclRights</literal> and more verbose <literal>aclRightsInfo</literal>
  attributes.</para>
  <programlisting language="ldif">
dn: uid=bjensen,ou=People,dc=example,dc=com
aclRightsInfo;logs;attributeLevel;selfwrite_delete;cn: acl_summary(main)
 : access allowed(write) on entry/attr(uid=bjensen,ou=People,dc=example,dc=com
 , distinguishedName) to (uid=kvaughan,ou=People,dc=example,dc=com) (not proxied
 ) ( reason: evaluated allow , deciding_aci: allow all Admin group)
aclRightsInfo;logs;entryLevel;read: acl_summary(main): access allowed(read
 ) on entry/attr(uid=bjensen,ou=People,dc=example,dc=com, objectClass) to (
 uid=kvaughan,ou=People,dc=example,dc=com) (not proxied) ( reason
 : evaluated allow , deciding_aci: Anonymous read-search access)
aclRightsInfo;logs;attributeLevel;proxy;cn: acl_summary(main)
 : access not allowed(proxy) on entry/attr(uid=bjensen,ou=People,dc=example,
 dc=com, cn) to (uid=kvaughan,ou=People,dc=example,dc=com) (not proxied
 ) (reason: no acis matched the subject )
aclRights;attributeLevel;cn: search:1,read:1,compare:1,write:1,selfwrite_add:1,
 selfwrite_delete:1,proxy:0
aclRightsInfo;logs;attributeLevel;write;cn: acl_summary(main): access allowed
 (write) on entry/attr(uid=bjensen,ou=People,dc=example,dc=com, cn) to (
 uid=kvaughan,ou=People,dc=example,dc=com) (not proxied
 ) ( reason: evaluated allow , deciding_aci: allow all Admin group)
aclRights;entryLevel: add:1,delete:1,read:1,write:1,proxy:0
aclRightsInfo;logs;attributeLevel;search;cn: acl_summary(main): access allowed(
 search) on entry/attr(uid=bjensen,ou=People,dc=example,dc=com, cn) to (
 uid=kvaughan,ou=People,dc=example,dc=com) (not proxied
 ) ( reason: evaluated allow , deciding_aci: Anonymous read-search access)
aclRightsInfo;logs;entryLevel;write: acl_summary(main): access allowed(write
 ) on entry/attr(uid=bjensen,ou=People,dc=example,dc=com, NULL) to (
 uid=kvaughan,ou=People,dc=example,dc=com) (not proxied
 ) ( reason: evaluated allow , deciding_aci: allow all Admin group)
aclRightsInfo;logs;attributeLevel;selfwrite_add;cn: acl_summary(main
 ): access allowed(write) on entry/attr(uid=bjensen,ou=People,dc=example,
 dc=com, distinguishedName) to (uid=kvaughan,ou=People,dc=example,dc=com) (
 not proxied) ( reason: evaluated allow , deciding_aci: allow all Admin group)
aclRightsInfo;logs;entryLevel;add: acl_summary(main): access allowed(add
 ) on entry/attr(uid=bjensen,ou=People,dc=example,dc=com, NULL) to (
 uid=kvaughan,ou=People,dc=example,dc=com) (not proxied
 ) ( reason: evaluated allow , deciding_aci: allow all Admin group)
aclRightsInfo;logs;attributeLevel;read;cn: acl_summary(main): access allowed(
 read) on entry/attr(uid=bjensen,ou=People,dc=example,dc=com, cn) to (
 uid=kvaughan,ou=People,dc=example,dc=com) (not proxied
 ) ( reason: evaluated allow , deciding_aci: Anonymous read-search access)
cn: Barbara Jensen
cn: Babs Jensen
aclRightsInfo;logs;entryLevel;proxy: acl_summary(main): access not allowed(
 proxy) on entry/attr(uid=bjensen,ou=People,dc=example,dc=com, NULL) to (
 uid=kvaughan,ou=People,dc=example,dc=com) (not proxied
 ) ( reason: no acis matched the subject )
aclRightsInfo;logs;attributeLevel;compare;cn: acl_summary(main): access allowed
 (compare) on entry/attr(uid=bjensen,ou=People,dc=example,dc=com, cn) to (
 uid=kvaughan,ou=People,dc=example,dc=com) (not proxied
 ) ( reason: evaluated allow , deciding_aci: Anonymous read-search access)
aclRightsInfo;logs;entryLevel;delete: acl_summary(main): access allowed(
 delete) on entry/attr(uid=bjensen,ou=People,dc=example,dc=com, NULL) to (
 uid=kvaughan,ou=People,dc=example,dc=com) (not proxied
 ) ( reason: evaluated allow , deciding_aci: allow all Admin group)
</programlisting>
 </section>
 
 <section xml:id="use-manage-dsait-control-control">
@@ -194,7 +404,8 @@
 
 <section xml:id="use-persistent-search-request-control">
  <title>Persistent Search Request Control</title>
  <para>TODO</para>
  <para>See <xref linkend="use-entry-change-notification-control" />.</para>
 </section>
 
 <section xml:id="use-post-read-control">