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

Mark Craig
23.11.2012 fb6729d0b5de7067ff7f5752f108140f3645d302
A bit more on search base, scope, and filters
1 files added
1 files modified
191 ■■■■■ changed files
opendj3/src/main/docbkx/dev-guide/chap-reading.xml 191 ●●●●● patch | view | raw | blame | history
opendj3/src/main/docbkx/dev-guide/images/ldap-tree.png patch | view | raw | blame | history
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'
@@ -144,9 +144,196 @@
}</programlisting>
 </section>
 
 <section xml:id="basedn-and-scope">
  <title>Setting Search Base &amp; 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>&lt;=</term>
    <listitem>
     <para>Greater than or equal to comparison, which works
     alphanumerically.</para>
    </listitem>
   </varlistentry>
   <varlistentry>
    <term>&gt;=</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>&amp;</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>(&amp;(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>(&amp;(sn=Jensen)(!(givenName=Barbara)))</literal>.</para>
    </listitem>
   </varlistentry>
  </variablelist>
 </section>
 <section xml:id="send-search-request">
opendj3/src/main/docbkx/dev-guide/images/ldap-tree.png