From fb6729d0b5de7067ff7f5752f108140f3645d302 Mon Sep 17 00:00:00 2001
From: Mark Craig <mark.craig@forgerock.com>
Date: Mon, 23 Apr 2012 13:11:11 +0000
Subject: [PATCH] A bit more on search base, scope, and filters
---
opendj3/src/main/docbkx/dev-guide/chap-reading.xml | 193 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 190 insertions(+), 3 deletions(-)
diff --git a/opendj3/src/main/docbkx/dev-guide/chap-reading.xml b/opendj3/src/main/docbkx/dev-guide/chap-reading.xml
index 99b4af2..b7898bb 100644
--- a/opendj3/src/main/docbkx/dev-guide/chap-reading.xml
+++ b/opendj3/src/main/docbkx/dev-guide/chap-reading.xml
@@ -20,7 +20,7 @@
!
! CCPL HEADER END
!
- ! Copyright 2011 ForgeRock AS
+ ! Copyright 2011-2012 ForgeRock AS
!
-->
<chapter xml:id='chap-reading'
@@ -143,10 +143,197 @@
}
}</programlisting>
</section>
-
+
+ <section xml:id="basedn-and-scope">
+ <title>Setting Search Base & Scope</title>
+
+ <para>Directory servers organize entries somewhat like a file system.
+ Directory data is often depicted as an upside-down tree.</para>
+
+ <mediaobject xml:id="figure-ldap-tree">
+ <alt>Directory data is often depicted as an upside-down tree.</alt>
+ <imageobject>
+ <imagedata fileref="images/ldap-tree.png" format="PNG" />
+ </imageobject>
+ <textobject>
+ <para>This figure shows three levels, the base DN for the suffix, a couple
+ of organizational units, and three user entries.</para>
+ </textobject>
+ </mediaobject>
+
+ <para>In the figure shown above, entries are represented by the relevant
+ parts of their DNs. The entry with DN <literal>dc=example,dc=com</literal>
+ is the base entry for a suffix. Under the base entry, you see two
+ organizational units, one for people, <literal>ou=People</literal>, the other
+ for groups, <literal>ou=Groups</literal>. The entries for people include
+ those of Babs Jensen, Kirsten Vaughan, and Sam Carter.</para>
+
+ <para>When you are searching for a person's entry somewhere under
+ <literal>dc=example,dc=com</literal>, you can start from
+ <literal>dc=example,dc=com</literal>, from
+ <literal>ou=People,dc=example,dc=com</literal>, or if you have enough
+ information to pinpoint the user entry and only want to look up another
+ attribute value for example, then directly from the entry such as
+ <literal>cn=Babs Jensen,ou=People,dc=example,dc=com</literal>. The DN of
+ the entry where you choose to start the search is the base DN for the
+ search.</para>
+
+ <itemizedlist>
+ <para>When searching, you also define the scope. Scope defines what entries
+ the server considers when checking for entries that match your search.</para>
+ <listitem>
+ <para>For <literal>SearchScope.BASE_OBJECT</literal> the server considers
+ only the base entry.</para>
+ <para>This is the scope you use if you know the full DN of the object
+ that interests you. For example, if your base DN points to Babs Jensen's
+ entry, <literal>cn=Babs Jensen,ou=People,dc=example,dc=com</literal>, and
+ you want to read some of Babs's attributes, you would set scope to
+ <literal>SearchScope.BASE_OBJECT</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>For <literal>SearchScope.SINGLE_LEVEL</literal> the server considers
+ all entries directly below the base entry.</para>
+ <para>You use this scope if for example you want to discover organizational
+ units under <literal>dc=example,dc=com</literal>, or if you want to find
+ people's entries and you know they are immediately under
+ <literal>ou=People,dc=example,dc=com</literal>.</para>
+ </listitem>
+ <listitem>
+ <para>For <literal>SearchScope.SUBORDINATES</literal> the server considers
+ all entries below the base entry.</para>
+ <para>This scope can be useful if you know that the base DN for your search
+ is an entry that you do not want to match.</para>
+ </listitem>
+ <listitem>
+ <para>For <literal>SearchScope.WHOLE_SUBTREE</literal> (default) the server
+ considers the base entry and all entries below.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>In addition to a base DN and scope, a search request also calls for a
+ search filter.</para>
+ </section>
+
<section xml:id="about-filters">
<title>Working With Search Filters</title>
- <para>TODO</para>
+
+ <para>When you look someone up in the telephone directory, you use the value
+ of one attribute of a person's entry (last name), to recover the person's
+ directory entry, which has other attributes (phone number, address). LDAP
+ works the same way. In LDAP, search requests identify both the scope of the
+ directory entries to consider (for example, all people or all organizations),
+ and also the entries to retrieve based on some attribute value (for example,
+ surname, mail address, phone number, or something else). The way you express
+ the attribute value(s) to match is by using a search filter.</para>
+
+ <para>LDAP search filters define what entries actually match your request.
+ For example, the following simple equality filter says, "Match all entries
+ that have a surname attribute (sn) value equivalent to Jensen."</para>
+
+ <literallayout class="monospaced">(sn=Jensen)</literallayout>
+
+ <para>When you pass the directory server this filter as part of your search
+ request, the directory server checks the entries in scope for your search to
+ see whether they match.<footnote><para>In fact, the directory server probably
+ checks an index first, and might not even accept search requests unless it
+ can use indexes to match your filter rather than checking all entries in
+ scope.</para></footnote> If the directory server finds entries that match,
+ it returns those entries as it finds them.</para>
+
+ <para>The example, <literal>(sn=Jensen)</literal>, shows a string
+ representation of the search filter. The OpenDJ LDAP SDK lets you express
+ your filters as strings, or as <literal>Filter</literal> objects. In both
+ cases, the SDK translates the strings and objects into the binary
+ representation sent to the server over the network.</para>
+
+ <variablelist>
+ <para>Equality is just one of the types of comparisons available in LDAP
+ filters. Comparison operators include the following.</para>
+
+ <varlistentry>
+ <term>=</term>
+ <listitem>
+ <para>Equality comparison, as in <literal>(sn=Jensen)</literal>.</para>
+ <para>This can also be used with substring matches. For example, to match
+ last names starting with <literal>Jen</literal>, use the filter
+ <literal>(sn=Jen*)</literal>. Substrings are more expensive for the
+ directory server to index. Substring searches therefore might not be
+ permitted for many attributes.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><=</term>
+ <listitem>
+ <para>Greater than or equal to comparison, which works
+ alphanumerically.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>>=</term>
+ <listitem>
+ <para>Greater than or equal to comparison, which works
+ alphanumerically.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>=*</term>
+ <listitem>
+ <para>Presence comparison. For example, to match all entries having a
+ <literal>userPassword</literal>, use the filter
+ <literal>(userPassword=*)</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>~=</term>
+ <listitem>
+ <para>Approximate comparison, matching attribute values similar to the
+ value you specify.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>[:dn][:<replaceable>oid</replaceable>]:=</term>
+ <listitem>
+ <para>Extensible match comparison. For example,
+ <literal>(uid:dn:=bjensen)</literal> matches entries where
+ <literal>uid</literal> having the value <literal>bjensen</literal> is
+ a component of the entry DN.
+ <literal>(lastLoginTime:1.3.6.1.4.1.26027.1.4.5:=-13w)</literal> matches
+ entries with a last login time more recent than 13 weeks.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <variablelist>
+ <para>You can use boolean operators to build complex filters when a single
+ filter comparison is not enough to express what to match.</para>
+
+ <varlistentry>
+ <term>&</term>
+ <listitem>
+ <para>This binary operator matches entries that belong to the intersection
+ of the two component filters, for example all users named Barbara whose
+ last name starts with Jen,
+ <literal>(&(givenName=Barbara)(sn=Jen*))</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>|</term>
+ <listitem>
+ <para>This binary operator matches entries that belong to the union of the
+ two component filters, for example all the users named Jensen or Smith,
+ <literal>(|(sn=Jensen)(sn=Smith))</literal>.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>!</term>
+ <listitem>
+ <para>This unary operator matches entries that do not match the filter.
+ Use this in complex filters when you have already narrowed the scope,
+ for example all users named Jensen whose first name is not Barbara,
+ <literal>(&(sn=Jensen)(!(givenName=Barbara)))</literal>.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
</section>
<section xml:id="send-search-request">
--
Gitblit v1.10.0