You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by fe...@apache.org on 2010/08/14 15:11:37 UTC

svn commit: r985486 - in /directory/sandbox/felixk/apacheds-docs/src: advanced-user-guide/ advanced-user-guide/data/ docbkx-stylesheet/fo/ docbkx-stylesheet/html/

Author: felixk
Date: Sat Aug 14 13:11:37 2010
New Revision: 985486

URL: http://svn.apache.org/viewvc?rev=985486&view=rev
Log:
Start with advanced-user-guide

Added:
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-authentication-and-authorization.xml   (with props)
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/data/sasl-gssapi-example.ldif
Modified:
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/book.xml
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-architecture.xml
    directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-community.xml
    directory/sandbox/felixk/apacheds-docs/src/docbkx-stylesheet/fo/docbook.xsl
    directory/sandbox/felixk/apacheds-docs/src/docbkx-stylesheet/html/docbook.xsl

Modified: directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/book.xml
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/book.xml?rev=985486&r1=985485&r2=985486&view=diff
==============================================================================
--- directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/book.xml (original)
+++ directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/book.xml Sat Aug 14 13:11:37 2010
@@ -66,7 +66,8 @@ under the License.</literallayout>
     href="chapter-community.xml" />
   <xi:include
     href="chapter-architecture.xml" />
-
+  <xi:include
+    href="chapter-authentication-and-authorization.xml" />
   <index> ... </index>
 
 </book>

Modified: directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-architecture.xml
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-architecture.xml?rev=985486&r1=985485&r2=985486&view=diff
==============================================================================
--- directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-architecture.xml (original)
+++ directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-architecture.xml Sat Aug 14 13:11:37 2010
@@ -16,24 +16,6 @@
   xmlns:ns3="http://www.w3.org/1999/xhtml"
   xml:lang="en">
   <title>Architecture</title>
-  <itemizedlist>
-    <listitem>
-      <xref
-        linkend="Architectural Overview" />
-    </listitem>
-    <listitem>
-      <xref
-        linkend="Interceptors" />
-    </listitem>
-    <listitem>
-      <xref
-        linkend="The Administrative Model" />
-    </listitem>
-    <listitem>
-      <xref
-        linkend="Supported RFCs" />
-    </listitem>
-  </itemizedlist>
   <section
     id="Architectural Overview">
     <title>Architectural Overview</title>

Added: directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-authentication-and-authorization.xml
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-authentication-and-authorization.xml?rev=985486&view=auto
==============================================================================
--- directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-authentication-and-authorization.xml (added)
+++ directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-authentication-and-authorization.xml Sat Aug 14 13:11:37 2010
@@ -0,0 +1,1408 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file 
+  distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under 
+  the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may 
+  obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to 
+  in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF 
+  ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under 
+  the License. -->
+<chapter
+  version="5.0"
+  xmlns="http://docbook.org/ns/docbook"
+  xmlns:xlink="http://www.w3.org/1999/xlink"
+  xmlns:xi="http://www.w3.org/2001/XInclude"
+  xmlns:ns5="http://www.w3.org/2000/svg"
+  xmlns:ns4="http://www.w3.org/1998/Math/MathML"
+  xmlns:ns3="http://www.w3.org/1999/xhtml"
+  xml:lang="en">
+  <title>Authentication &amp; Authorization</title>
+  <section
+    id="SASL Authentication to ApacheDS">
+    <title>SASL Authentication to ApacheDS</title>
+    <section
+      id="Introduction Authentication">
+      <title>Introduction</title>
+      <para>Apache Directory currently supports the CRAM-MD5, DIGEST-MD5, and GSSAPI SASL mechanisms. SASL is used
+        during LDAP Binds to authenticate users. Additionally, with the DIGEST-MD5 and GSSAPI mechanisms, SASL can also
+        provide message integrity (checksums) and, optionally, message privacy (encryption). When using SASL message
+        privacy, connections do not need SSL to protect communications.</para>
+    </section>
+    <section
+      id="Architecture Authentication">
+      <title>Architecture</title>
+      <para>SASL workflow is implemented in the LDAP Protocol Provider's BindHandler. At the start of a Bind, the
+        BindHandler handles SASL negotiation. During SASL negotiation, the LDAP client is first authenticated. After
+        successful authentication, an LDAP context is established and a SUCCESS message is returned.</para>
+      <programlisting><![CDATA[
+Inbound --> decoder --> BindHandler <--> Backend #1, #2
+Outbound <-- encoder <------'
+    ]]></programlisting>
+      <para>Backend #1 is a lookup to authenticate the user using an administrative (internal) directory context.</para>
+      <para>Backend #2 is an LdapContext establishment for the user that is stored in the user's MINA session.</para>
+      <para>The DIGEST-MD5 and GSSAPI SASL mechanisms can provide message integrity and, optionally, message
+        confidentiality by "wrapping" or "unwrapping" data with a security layer. After the Bind has completed the
+        BindHandler will insert a MINA filter that handles security layer processing into the IoFilterChain for the
+        session that was SASL-authenticated. All subsequent LDAP operations will be wrapped or unwrapped by the
+        SaslFilter (assuming message integrity or privacy are negotiated). For example, a subsequent search would arrive
+        wrapped and thus must be unwrapped by the SaslFilter prior to being ASN.1 decoded into a SearchRequest.
+        Similarly, all outbound responses, including errors and unbinds, will be wrapped by the SaslFilter.</para>
+      <programlisting><![CDATA[
+Inbound --> SaslFilter --> decoder --> SearchHandler <--> backend
+Outbound <-- SaslFilter <-- encoder <-------'
+    ]]></programlisting>
+    </section>
+    <section
+      id="CRAM-MD5">
+      <title>CRAM-MD5</title>
+      <para>Password must be stored as plaintext in the 'userPassword' attribute.</para>
+      <para>Username is matched to 'uid' under a base DN.</para>
+    </section>
+    <section
+      id="DIGEST-MD5">
+      <title>DIGEST-MD5</title>
+      <para>Password must be stored as plaintext in the 'userPassword' attribute.</para>
+      <para>Username is matched to 'uid' under a base DN.</para>
+      <para>Realm must match realms advertised by the LDAP server, but there is no multi-realm support yet.</para>
+    </section>
+    <section
+      id="GSSAPI">
+      <title>GSSAPI</title>
+      <para>Principal name is matched to the 'krb5PrincipalName' attribute under a base DN.</para>
+      <para>No multi-realm support yet.</para>
+      <para>Principal configuration (user, service, krbtgt) can all occur on LDIF load.</para>
+    </section>
+    <section
+      id="Anonymous queries">
+      <title>Anonymous queries</title>
+      <para>RootDSE queries will never require authentication.</para>
+      <screen><![CDATA[
+$ ldapsearch -s base -LLL supportedSASLMechanisms -x
+supportedSASLMechanisms: GSSAPI
+supportedSASLMechanisms: DIGEST-MD5
+supportedSASLMechanisms: CRAM-MD5
+    ]]></screen>
+      <para>
+        When anonymous authentication is
+        <emphasis
+          role="bold">disabled</emphasis>
+        , queries below the RootDSE will require authentication. The following command will fail if anonymous access is
+        disabled.
+      </para>
+      <screen><![CDATA[
+$ ldapsearch -b "dc=example,dc=com" "(uid=hnelson)" -x
+    ]]></screen>
+    </section>
+    <section
+      id="SASL queries">
+      <title>SASL queries</title>
+      <para>CRAM-MD5 is a username/password mechanism.</para>
+      <screen><![CDATA[
+$ ldapsearch -b "dc=example,dc=com" "(uid=hnelson)" -U hnelson -w secret -Y CRAM-MD5
+    ]]></screen>
+      <para>DIGEST-MD5 is a username/password mechanism. DIGEST-MD5 also supports the concept of "realm."</para>
+      <screen><![CDATA[
+$ ldapsearch -b "dc=example,dc=com" "(uid=hnelson)" -U hnelson -w secret -Y DIGEST-MD5 -R example.com
+    ]]></screen>
+      <para>GSSAPI will use the Kerberos credentials of the current user. GSSAPI supports the concept of "realm," but
+        the realm is part of the username, eg 'hnelson@EXAMPLE.COM'.</para>
+      <screen><![CDATA[
+$ ldapsearch -b "dc=example,dc=com" "(uid=hnelson)" -Y GSSAPI
+    ]]></screen>
+    </section>
+    <section
+      id="Resources Authentication">
+      <title>Resources</title>
+      <para>
+        IMAP/POP AUTHorize Extension for Simple Challenge/Response<?linebreak?>
+        <link
+          xlink:href="http://www.ietf.org/rfc/rfc2195.txt">http://www.ietf.org/rfc/rfc2195.txt</link>
+      </para>
+      <para>
+        Using Digest Authentication as a SASL Mechanism<?linebreak?>
+        <link
+          xlink:href="http://www.ietf.org/rfc/rfc2831.txt">http://www.ietf.org/rfc/rfc2831.txt</link>
+      </para>
+      <para>
+        RFC 4422 - Simple Authentication and Security Layer (SASL)<?linebreak?>
+        <link
+          xlink:href="http://www.faqs.org/rfcs/rfc4422.html">http://www.faqs.org/rfcs/rfc4422.html</link><?linebreak?>
+        This document obsoletes RFC 2222.
+      </para>
+      <para>
+        Lightweight Directory Access Protocol (LDAP): Directory Information Models<?linebreak?>
+        <link
+          xlink:href="http://www.faqs.org/rfcs/rfc4512.html">http://www.faqs.org/rfcs/rfc4512.html</link>
+      </para>
+      <para>
+        RFC 4513 - Lightweight Directory Access Protocol (LDAP): Authentication Methods and Security Mechanisms
+      <?linebreak?>
+        <link
+          xlink:href="http://www.faqs.org/rfcs/rfc4513.html">http://www.faqs.org/rfcs/rfc4513.html</link><?linebreak?>
+        This document obsoletes RFC 2251, RFC 2829, and RFC 2830.
+      </para>
+      <para>
+        Simple Authentication and Security Layer (SASL) Mechanisms<?linebreak?>
+        <link
+          xlink:href="http://www.iana.org/assignments/sasl-mechanisms">http://www.iana.org/assignments/sasl-mechanisms</link>
+      </para>
+      <para>
+        RFC 3829 - LDAP Authorization Identity Request and Response Controls<?linebreak?>
+        <link
+          xlink:href="http://www.faqs.org/rfcs/rfc3829.html">http://www.faqs.org/rfcs/rfc3829.html</link>
+      </para>
+    </section>
+  </section>
+  <section
+    id="HOWTO do SASL GSSAPI Authentication to ApacheDS">
+    <title>HOWTO do SASL GSSAPI Authentication to ApacheDS</title>
+    <section
+      id="Introduction SASL GSSAPI">
+      <title>Introduction</title>
+      <para>Apache Directory currently supports the SASL GSSAPI mechanism. SASL GSSAPI allows Kerberos authentication to
+        be used during LDAP Binds. Additionally, the GSSAPI mechanism can provide message integrity (checksums) and,
+        optionally, message privacy (encryption). When using SASL message privacy, connections do not need SSL to
+        protect communications.</para>
+    </section>
+    <section
+      id="Getting Started SASL GSSAPI">
+      <title>Getting Started</title>
+      <orderedlist>
+        <listitem>
+          <para>
+            Make sure you are using ApacheDS 1.5.1, which is currently (4-JUN-2007) only available from the HEAD of
+            trunk in svn. (
+            <xref
+              linkend="Building trunks" />
+            )
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            You can double-check your version of ApacheDS by interrogating the RootDSE for the supported SASL
+            mechanisms. Note the use of the fully-qualified domain name (FQDN), 'ldap.example.com'. Regardless of the
+            enabled authentication mechanisms, you will always be able to query the RootDSE. You must see 'GSSAPI' in
+            this returned list.
+            <screen><![CDATA[
+$ ldapsearch -H ldap://ldap.example.com:10389 -s base -LLL supportedSASLMechanisms -x
+dn:
+supportedSASLMechanisms: GSSAPI
+supportedSASLMechanisms: DIGEST-MD5
+supportedSASLMechanisms: CRAM-MD5
+        ]]></screen>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            (OPTIONAL) Install GSSAPI support for LDAP tools on Linux. By default, some Linux variants do not have SASL
+            GSSAPI support installed. If Cyrus SASL GSSAPI is not present, install it with an RPM maintenance tool such
+            as 'yum'. Note that the SASL support in ApacheDS is unrelated to the SASL library implementation being
+            installed here.
+            <screen><![CDATA[
+$ rpm -qa | grep sasl
+cyrus-sasl-lib-2.1.22-4
+cyrus-sasl-2.1.22-4
+...
+cyrus-sasl-gssapi-2.1.22-4
+        ]]></screen>
+            <screen><![CDATA[
+$ yum install cyrus-sasl-gssapi
+        ]]></screen>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            Open the server.xml for editing.
+            <screen><![CDATA[
+$ cd <trunk>/server-main
+$ vi server.xml
+        ]]></screen>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            Enable GSSAPI as a mechanism. GSSAPI is disabled by default.
+            <programlisting><![CDATA[
+<!-- The list of supported authentication mechanisms.                   -->
+<property name="supportedMechanisms">
+  <list>
+    ...
+    <value>GSSAPI</value>
+  </list>
+</property>
+        ]]></programlisting>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            Set the FQDN of the host. The FQDN must resolve, by hosts file, or DNS. Elements of the SASL GSSAPI
+            mechanism are extremely picky about the FQDN you use. The FQDN should be the top-most entry in your hosts
+            file or matching A and PTR records in DNS. If you are running the client and the server on the same machine,
+            you may need to set the FQDN to be your hostname. You will likely find a sniffer (like WireShark) very handy
+            for figuring out what hostnames are being assumed and whether DNS is working properly.
+            <programlisting><![CDATA[
+<!-- The FQDN of this SASL host, validated during SASL negotiation.     -->
+<property name="saslHost" value="ldap.example.com" />
+        ]]></programlisting>
+          </para>
+        </listitem>
+        <listitem>
+          <para>Set
+            the service principal name that the server-side of the LDAP protocol provider will use to "accept" a GSSAPI
+            context initiated by the LDAP client. The SASL principal MUST follow the name-form
+            ldap/&lt;fqdn&gt;@&lt;realm&gt;. The 'ldap' name component and the @&lt;realm&gt; will be automatically
+            added to the FQDN by the LDAP client. The LDAP client will then use this as the service principal name when
+            requesting a service ticket from a KDC. In our case, the KDC is ApacheDS, itself.
+            <programlisting><![CDATA[
+<!-- The Kerberos principal name for this LDAP service, used by GSSAPI. -->
+<property name="saslPrincipal" value="ldap/ldap.example.com@EXAMPLE.COM" />
+        ]]></programlisting>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            (OPTIONAL) Enforce quality-of-protection (QoP). The QoP level directly maps to the JNDI levels. Listing all
+            possible levels means any level will be accepted. Listing only 'auth-conf' will allow only 'auth-conf'
+            connections. These SASL QoP levels are global; they affect all connections using DIGEST-MD5 or GSSAPI.
+            <table
+              id="SASL QoP levels table">
+              <title>SASL QoP levels</title>
+              <tgroup
+                cols="2">
+                <thead>
+                  <row>
+                    <entry>QoP</entry>
+                    <entry>Description</entry>
+                  </row>
+                </thead>
+                <tbody>
+                  <row>
+                    <entry>auth</entry>
+                    <entry>Use SASL for authentication only (no integrity or confidentiality protection).</entry>
+                  </row>
+                  <row>
+                    <entry>auth-int</entry>
+                    <entry>Use SASL with integrity protection. Integrity basically means "with a checksum." For GSSAPI
+                      integrity is always enabled.</entry>
+                  </row>
+                  <row>
+                    <entry>auth-conf</entry>
+                    <entry>Use SASL with confidentiality protection. Confidentiality means "with encryption."
+                      Confidentiality is sometimes called privacy. When Confidentiality is enabled, you do not need
+                      SSL/TLS to protect connections.</entry>
+                  </row>
+                </tbody>
+              </tgroup>
+            </table>
+            <programlisting><![CDATA[
+<!-- The desired quality-of-protection, used by DIGEST-MD5 and GSSAPI.  -->
+<property name="saslQop">
+  <list>
+    <value>auth</value>
+    <value>auth-int</value>
+    <value>auth-conf</value>
+  </list>
+</property>
+            ]]></programlisting>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            Configure SASL realms. If the realm is not enabled, the connection will be rejected. Note that if your realm
+            does not appear here, you will see an error similar to "Nonexistent realm: dummy.com."
+            <programlisting><![CDATA[
+<!-- The realms serviced by this SASL host, used by DIGEST-MD5 and GSSAPI. -->
+<property name="saslRealms">
+  <list>
+    <value>example.com</value>
+    <value>apache.org</value>
+  </list>
+</property>
+            ]]></programlisting>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            Set the search base DN. The search base DN is where a subtree-scoped DIT search will be performed. This is
+            BOTH where the LDAP service principal must reside, as well as where user principals must reside. That all
+            principals must reside in a single sub-tree is currently (4-JUN-2007) a limitation of the SASL
+            implementation. Work is underway to enable "multi-realm" capability, as well as "split realm" capability.
+            "Split realm" capability will allow you to split principals (users, admins, services, machines) into
+            separate subtrees.
+            <programlisting><![CDATA[
+<!-- The base DN containing users that can be SASL authenticated.       -->
+<property name="searchBaseDn" value="ou=users,dc=example,dc=com" />
+            ]]></programlisting>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            Configure your host so that it knows where to get Kerberos tickets. On linux this is configured in
+            '/etc/krb5.conf'. The minimum config file must list the default Kerberos realm and the location of at least
+            one key distribution center (KDC). With ApacheDS, the KDC and LDAP server are the same, so we'll re-use our
+            'ldap.example.com' hostname here.
+            <programlisting><![CDATA[
+[libdefaults]
+ default_realm = EXAMPLE.COM
+
+[realms]
+ EXAMPLE.COM = {
+  kdc = ldap.example.com
+ }
+
+[domain_realm]
+ .example.com = EXAMPLE.COM
+ example.com = EXAMPLE.COM
+            ]]></programlisting>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            Enable the Kerberos protocol provider. By default, the LDAP protocol is enabled, but the Kerberos protocol
+            is not. You may also change the Kerberos port so that Kerberos can bind if you're logged-in as a non-root
+            user. If you change the default port of '88', you must change the KDC port in the krb5.conf, as well.
+            <programlisting><![CDATA[
+#
+
+<bean id="kdcConfiguration" class="org.apache.directory.server.kerberos.kdc.KdcConfiguration">
+  <!-- Whether to enable the Kerberos protocol.                           -->
+  <property name="enabled" value="true" />
+  <!-- The port to run the Kerberos protocol on.                          -->
+  <property name="ipPort" value="88" />
+</bean>
+            ]]></programlisting>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            Enable the KeyDerivationService. In contrast to the SIMPLE, CRAM-MD5, and DIGEST-MD5 SASL mechanisms,
+            Kerberos authentication is based on symmetric keys. Since a user can't be expected to remember a symmetric
+            key, there are "key derivation functions" that will produce symmetric key material based on the
+            concatenation of the password, realm, and username. Any changes to the user's password must result in new
+            keys being generated. Luckily, ApacheDS has the "KeyDerivationService" interceptor. This service will
+            intercept any adds or modifications to the user's 'userPassword' attribute and generate keys. Service
+            principals typically use random keys, so the interceptor will generate random keys when the special keyword
+            'randomKey' is used. Unlike other combinations of separate LDAP and Kerberos servers, we do not need to
+            export the service principal keys to a keytab file from the KDC and use it to configure the LDAP server.
+            Since ApacheDS' LDAP and Kerberos protocol both have access to the DIT, we simply need to enable the
+            KeyDerivationService and add some principals.
+            <programlisting><![CDATA[
+<bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+  <property name="name" value="keyDerivationService" />
+  <property name="interceptor">
+    <bean class="org.apache.directory.server.core.kerberos.KeyDerivationService" />
+  </property>
+</bean>
+            ]]></programlisting>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            Pre-load principals using an LDIF file. If the LDAP SASL GSSAPI mechanism is enabled but the service
+            principal is not found then you may see a WARN'ing in the server logs. With the KeyDerivationService
+            enabled, you should be able to use LDIFs or LDAP to configure principals on-the-fly. For this example, since
+            the LDIF format is concise, we review some LDIF entries. You will find attached to this page an example
+            LDIF.
+            <link
+              xlink:href="data/sasl-gssapi-example.ldif">Download the LDIF</link>
+            and configure the 'ldifDirectory' in server.xml.
+            <programlisting><![CDATA[
+<property name="ldifDirectory">
+  <value>/path/to/sasl-gssapi-example.ldif</value>
+</property>
+            ]]></programlisting>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            Review the LDIF entries. The metaphor for Kerberos comes from the fact that it is "three-headed"; there is
+            always a KDC principal, service principal, and user principal. All of these principals use the same
+            objectClass'es. The attributes are the minimum to satisfy their respective schema, with the exception of the
+            Kerberos schema. Because we are using the KeyDerivationService, we don't need to specify the Kerberos key,
+            key types, or key version number (kvno); they are automatically added by the interceptor, which will also
+            increment the kvno when the password changes. Looking at the LDIF file you'll see the ASL license, an
+            organizational unit (ou) for our 'users' subcontext, and the following entries:
+            <table
+              id="To be named table">
+              <title>To be named</title>
+              <tgroup
+                cols="4">
+                <thead>
+                  <row>
+                    <entry>Entry RDN</entry>
+                    <entry>Password</entry>
+                    <entry>Principal Name</entry>
+                    <entry>Description</entry>
+                  </row>
+                </thead>
+                <tbody>
+                  <row>
+                    <entry>uid=hnelson</entry>
+                    <entry>userpassword: s3crEt</entry>
+                    <entry>krb5PrincipalName: hnelson@EXAMPLE.COM</entry>
+                    <entry>Our user principal. Note the user password.</entry>
+                  </row>
+                  <row>
+                    <entry>uid=krbtgt</entry>
+                    <entry>userpassword: randomKey</entry>
+                    <entry>krb5PrincipalName: krbtgt/EXAMPLE.COM@EXAMPLE.COM</entry>
+                    <entry>The KDC principal, with a random key.</entry>
+                  </row>
+                  <row>
+                    <entry>uid=hostldap</entry>
+                    <entry>userpassword: randomKey</entry>
+                    <entry>krb5PrincipalName: ldap/ldap.example.com@EXAMPLE.COM</entry>
+                    <entry>The LDAP principal, with a random key.</entry>
+                  </row>
+                </tbody>
+              </tgroup>
+            </table>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            You are now ready to start the server. Upon startup, the server will load the entries from the LDIF.
+            <screen><![CDATA[
+$ cd <trunk>/server-main
+$ ./apacheds.sh
+            ]]></screen>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            Request a ticket-granting ticket (TGT) using 'kinit'. If you have not already "logged in," you must request
+            a fresh TGT. Without a TGT, 'ldapsearch', for example, will fail with error "No credentials cache found."
+            Also, if you don't specify the user principal, kinit will guess the principal name based on the logged-in
+            user and the realm configured in the krb5.conf.
+            <screen><![CDATA[
+$ kinit hnelson@EXAMPLE.COM
+Password for hnelson@EXAMPLE.COM: <s3crEt>
+            ]]></screen>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            You should now be able to query the DIT using Kerberos credentials. GSSAPI will use the Kerberos credentials
+            (TGT) of the current user. GSSAPI supports the concept of "realm," but the realm is part of the username, eg
+            'hnelson@EXAMPLE.COM'. This is in contrast to other SASL mechanisms where the realm is separately and
+            explicitly specified.
+            <screen><![CDATA[
+$ ldapsearch -H ldap://ldap.example.com:10389 -b "dc=example,dc=com" "(uid=hnelson)" -Y GSSAPI
+            ]]></screen>
+          </para>
+        </listitem>
+        <listitem>
+          <para>
+            (OPTIONAL) List your Kerberos credentials. You'll see that in addition to a TGT, you also now have a service
+            ticket for the LDAP server.
+            <screen><![CDATA[
+$ klist -5fea
+Ticket cache: FILE:/tmp/krb5cc_0
+Default principal: hnelson@EXAMPLE.COM
+Valid starting     Expires            Service principal
+06/04/07 20:42:19  06/05/07 20:41:37  krbtgt/EXAMPLE.COM@EXAMPLE.COM
+        Etype (skey, tkt): DES cbc mode with RSA-MD5, DES cbc mode with RSA-MD5
+        Addresses: (none)
+06/04/07 20:42:22  06/05/07 20:41:37  ldap/ldap.example.com@EXAMPLE.COM
+        Etype (skey, tkt): DES cbc mode with RSA-MD5, DES cbc mode with RSA-MD5
+        Addresses: (none)
+            ]]></screen>
+          </para>
+        </listitem>
+      </orderedlist>
+    </section>
+  </section>
+  <section
+    id="Start TLS with ApacheDS">
+    <title>Start TLS with ApacheDS</title>
+    <section
+      id="Introduction TLS">
+      <title>Introduction</title>
+      <para>With Start TLS, the client sends an extended operation to the server that says 'after you send me a positive
+        response to this operation, flip the connection over to TLS'. Start TLS is a mechanism for avoiding the need to
+        listen on a separate port for SSL connections.</para>
+    </section>
+    <section
+      id="Testing LDAP binds with TLS">
+      <title>Testing LDAP binds with TLS</title>
+      <para>
+        The following commands perform anonymous binds with TLS.
+        <screen><![CDATA[
+$ ldapsearch -H ldap://ldap.example.com/ -s base -LLL supportedSASLMechanisms -x -ZZ
+    ]]></screen>
+      </para>
+      <para>
+        can also use TLS (and SSL) with the SASL authentication mechanisms.
+        <screen><![CDATA[
+$ ldapsearch -H ldap://ldap.example.com -b "dc=example,dc=com" "(uid=hnelson)" -ZZ -Y DIGEST-MD5 -U hnelson -R example.com -w secret
+$ ldapsearch -H ldap://ldap.example.com -b "dc=example,dc=com" "(uid=hnelson)" -ZZ -Y CRAM-MD5 -U hnelson -w secret
+$ ldapsearch -H ldap://ldap.example.com -b "dc=example,dc=com" "(uid=hnelson)" -ZZ -Y GSSAPI
+    ]]></screen>
+      </para>
+      <para>Note that SSL certificates may be verified, depending on the LDAP client, so you should use the FQDN of the
+        ldap server that matches the cn in the certificate.</para>
+    </section>
+    <section
+      id="Resources TLS">
+      <title>Resources</title>
+      <para>
+        RFC 2830 - Lightweight Directory Access Protocol (v3): Extension for Transport Layer Security<?linebreak?>
+        <link
+          xlink:href="http://www.faqs.org/rfcs/rfc2830.html">http://www.faqs.org/rfcs/rfc2830.html</link>
+      </para>
+      <para>
+        SSL and Custom Sockets<?linebreak?>
+        <link
+          xlink:href="http://java.sun.com/products/jndi/tutorial/ldap/security/ssl.html">http://java.sun.com/products/jndi/tutorial/ldap/security/ssl.html</link>
+      </para>
+    </section>
+  </section>
+  <section
+    id="Writing a custom authenticator">
+    <title>Writing a custom authenticator</title>
+    <warning>
+      <para>This page is out of date</para>
+    </warning>
+    <section
+      id="Using custom authenticators">
+      <title>Using custom authenticators</title>
+      <para>Authenticator SPI provides a way to implement your own authentication mechanism, for instance simple
+        mechanism using password encryption such as MD5 or SHA1, or SASL mechanism. See the following example:</para>
+      <programlisting><![CDATA[
+import javax.naming.NamingException;
+
+import org.apache.directory.server.core.authn.AbstractAuthenticator;
+import org.apache.directory.server.core.authn.LdapPrincipal;
+import org.apache.directory.server.core.jndi.ServerContext;
+import org.apache.directory.shared.ldap.aci.AuthenticationLevel;
+import org.apache.directory.shared.ldap.name.LdapDN;
+
+public class CustomAuthenticator extends AbstractAuthenticator {
+    public CustomAuthenticator() {
+        // create authenticator that will handle "simple" authentication mechanism
+        super("simple");
+    }
+
+    public void init() throws NamingException {
+        // ...
+    }
+
+    public LdapPrincipal authenticate(LdapDN bindDn, ServerContext ctx) throws NamingException {
+        // ...
+
+        LdapPrincipal principal = AbstractAuthenticator.createLdapPrincipal(bindDn.toNormName(), AuthenticationLevel.SIMPLE);
+        // ..
+        return principal;
+
+    }
+}
+    ]]></programlisting>
+      <para>The authenticator class has to extend the org.apache.directory.server.core.authn.AbstractAuthenticator. This
+        class needs to have a no-argument constructor that calls the super() constructor with parameter the
+        authentication mechanism it is going to handle. In the above example, MyAuthenticator class is going to handle
+        the simple authentication mechanism.</para>
+      <para>You can optionally implement the init() method to initialize your authenticator class. This will be called
+        when the authenticator is loaded by ApacheDS during start-up.</para>
+      <para>When a client performs an authentication, ApacheDS will call the authenticate() method. You can get the
+        client authentication info from the server context. After you authenticate the client, you need to return the
+        authorization id. If the authentication fails, you should throw an LdapNoPermissionException.</para>
+      <para>When there are multiple authenticators registered with the same authentication type, ApacheDS will try to
+        use them in the order it was registered. If one fails it will use the next one, until it finds one that
+        successfully authenticates the client.</para>
+      <para>To tell ApacheDS to load your custom authenticators, you need to specify it in the server.xml. You can also
+        optionally specify the location of a .properties file containing the initialization parameters. See the
+        following example:</para>
+      <para>EXAMPLE BELOW IS NO LONGER VALID WITH XML CONFIGURATION</para>
+      <programlisting><![CDATA[
+server.authenticators=myauthenticator yourauthenticator
+
+server.authenticator.class.myauthenticator=com.mycompany.MyAuthenticator
+server.authenticator.properties.myauthenticator=myauthenticator.properties
+
+server.authenticator.class.yourauthenticator=com.yourcompany.YourAuthenticator
+server.authenticator.properties.yourauthenticator=yourauthenticator.properties
+    ]]></programlisting>
+    </section>
+  </section>
+  <section
+    id="Authorization">
+    <title>Authorization</title>
+    <para>ApacheDS uses an adaptation of the X.500 basic access control scheme in combination with X.500 subentries to
+      control access to entries and attributes within the DIT. This document will show you how to enable the basic
+      access control mechanism and how to define access control information to manage access to protected resources.
+    </para>
+    <section
+      id="Enabling Basic Access Controls">
+      <title>Enabling Basic Access Controls</title>
+      <para>
+        By default the access control subsystem is turned off. Once enabled everything is tightly locked down. Only the
+        special admin user,
+        <emphasis
+          role="bold">'uid=admin,ou=system'</emphasis>
+        , is not affected by permissions. Access to all operations are denied by default until enabled using an ACIItem.
+        For this reason enabling basic access controls is a configuration option.
+      </para>
+      <para>
+        To turn on the basic access control mechanism you need to set the
+        <emphasis
+          role="bold">accessControlEnabled</emphasis>
+        property in the configuration to true. This can be set programatically on the StartupConfiguration or via the
+        server.xml.
+      </para>
+    </section>
+    <section
+      id="Types of ACI (Access Control Information)">
+      <title>Types of ACI (Access Control Information)</title>
+      <para>Three different types of ACI exist. All types use the same specification syntax for an ACIITem. These types
+        differ in their placement and manner of use within the directory.</para>
+      <section
+        id="Entry ACI">
+        <title>Entry ACI</title>
+        <para>
+          Entry ACI are access controls added to entries to protect that entry specifically. Meaning the protoected
+          entry is the entry where the ACI resides. When performing an operation on an entry, ApacheDS checks for the
+          presence of the multivalued operational attribute, entryACI. The values of the
+          <emphasis
+            role="bold">entryACI</emphasis>
+          attribute contain ACIItems.
+        </para>
+        <warning>
+          <para>There is one exception to the rule of consulting entryACI attributes within ApacheDS: add operations do
+            not consult the entryACI within the entry being added. This is a security precaution. If allowed users can
+            arbitrarily add entries where they wanted by putting entryACI into the new entry being added. This could
+            comprimise the DSA.</para>
+        </warning>
+      </section>
+      <section
+        id="Prescriptive ACI">
+        <title>Prescriptive ACI</title>
+        <para>
+          Prescriptive ACI are access controls that are applied to a collection of entries, not just to a single entry.
+          Collections of entries are defined by the subtreeSpecifications of subentries. Hence prescriptive ACI are
+          added to subentries as attributes and are applied by ApacheDS to the entries selected by the subentry's
+          subtreeSpecification. ApacheDS uses the
+          <emphasis
+            role="bold">prescriptiveACI</emphasis>
+          multivalued operational attribute within subentries to contain ACIItems that apply to the entry collection.
+        </para>
+        <para>Prescriptive ACI can save much effort when trying to control access to a collection of resources.
+          Prescriptive ACI can even be specified to apply access controls to entries that do not yet exist within the
+          DIT. They are a very powerful mechanism and for this reason they are the prefered mechanism for managing
+          access to protected resources. ApacheDS is optimized specifically for managing access to collections of
+          entries rather than point entries themselves.</para>
+        <para>Users should try to avoid entry ACIs whenever possible, and use prescriptive ACIs instead. Entry ACIs are
+          more for managing exceptional cases and should not be used excessively.</para>
+        <info>
+          <title>How it works!</title>
+          <para>For every type of LDAP operation ApacheDS checks to see if any access control subentries include the
+            protected entry in their collection. The set of subentries which include the protected entry are discovered
+            very rapidly by the subentry subsystem. The subentry subsystem caches subtreeSpecifications for all
+            subentries within the server so inclusion checks are fast.</para>
+          <para>For each access control subentry in the set, ApacheDS checks within a prescriptive ACI cache for ACI
+            tuples. ApacheDS also caches prescriptive ACI information in a special form called ACI tuples. This is done
+            so ACIItem parsing and conversion to an optimal representations for evaluation is not required at access
+            time. This way access based on prescriptive ACIs is determined very rapidly.</para>
+        </info>
+      </section>
+      <section
+        id="Subentry ACI">
+        <title>Subentry ACI</title>
+        <para>Access to subentries also needs to be controlled. Subentries are special in ApacheDS. Although they
+          subordinate to an administrative entry (entry of an Administrative Point), they are technically considered to
+          be in the same context as their administrative entry. ApacheDS considers the perscriptive ACI applied to the
+          administrative entry, to also apply to its subentries.</para>
+        <para>
+          This however is not the most intuitive mechanism to use for explicitly controlling access to subentries. A
+          more explicit mechanism is used to specify ACIs specifically for protecting subentries. ApacheDS uses the
+          multivalued operational attribute,
+          <emphasis
+            role="bold">subentryACI</emphasis>
+          , within administrative entries to control access to immediately subordinate subentries.
+        </para>
+        <para>Protection policies for ACIs themselves can be managed within the entry of an administrative point.</para>
+      </section>
+    </section>
+    <section
+      id="Some Simple Examples">
+      <title>Some Simple Examples</title>
+      <para>The ACIItem syntax is very expressive and that makes it extremely powerful for specifying complex access
+        control policies. However the syntax is not very easy to grasp for beginners. For this reason we start with
+        simple examples that focus on different protection mechanisms offered by the ACIItem syntax. We do this instead
+        of specifying the grammar which is not the best way to learn a language.</para>
+      <caution>
+        <title>Before you go any further...</title>
+        <para>Please don't go any further until you have read up on the use of Subentries. Knowledge of subentries,
+          subtreeSpecifications, administrative areas, and administrative roles are required to properly digest the
+          following material.</para>
+      </caution>
+      <para>
+        Before going on to these trails you might want to set up an Administrative Area for managing access control via
+        prescriptiveACI. Both subentryACI and prescriptiveACI require the presence of an Administrative Point entry. For
+        more information and code examples see
+        <xref
+          linkend="ACAreas" />
+        .
+      </para>
+      <section
+        id="ACI Trails">
+        <title>ACI Trails</title>
+        <para>Here are some trails that resemble simple HOWTO guides. They're ordered with the most pragmatic usage
+          first. We will add to these trails over time.</para>
+        <table
+          id="ACI Trails table">
+          <title>ACI Trails</title>
+          <tgroup
+            cols="2">
+            <thead>
+              <row>
+                <entry>Trail</entry>
+                <entry>Description</entry>
+              </row>
+            </thead>
+            <tbody>
+              <row>
+                <entry>
+                  <xref
+                    linkend="EnableSearchForAllUsers" />
+                </entry>
+                <entry>access to browse and read all entries and their attributes by authenticated users.</entry>
+              </row>
+              <row>
+                <entry>DenySubentryAccess (TBW)</entry>
+                <entry>Protecting access to subentries themselves.</entry>
+              </row>
+              <row>
+                <entry>
+                  <xref
+                    linkend="AllowSelfPasswordModify" />
+                </entry>
+                <entry>Granting users the rights needed to change their own passwords.</entry>
+              </row>
+              <row>
+                <entry>GrantAddDelModToGroup (TBW)</entry>
+                <entry>Granting add, delete, and modify permissions to a group of users.</entry>
+              </row>
+              <row>
+                <entry>GrantModToEntry (TBW)</entry>
+                <entry>Applying ACI to a single entry.</entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </table>
+      </section>
+    </section>
+    <section
+      id="ACAreas">
+      <title>ACAreas</title>
+      <section
+        id="Introduction ACAreas">
+        <title>Introduction</title>
+        <para>
+          This guide will show you how to create an Access Control Specific Area and Access Control Inner Areas for
+          administering access controls within ApacheDS. Basic knowledge of the X.500 administrative model is presumed
+          along with an understanding of the Basic Access Control Scheme in X.501. For quick primers please take a look
+          at the following documentation:
+          <itemizedlist>
+            <listitem>
+              <para>
+                <xref
+                  linkend="Subentries" />
+                and the
+                <xref
+                  linkend="The Administrative Model" />
+              </para>
+            </listitem>
+            <listitem>
+              <para>
+                <xref
+                  linkend="Authorization" />
+              </para>
+            </listitem>
+          </itemizedlist>
+        </para>
+      </section>
+      <section
+        id="Creating Access Control Specific Areas (ACSA)">
+        <title>Creating Access Control Specific Areas (ACSA)</title>
+        <para>An access control specific area is an Autonomous Administrative Area (AAA) for managing access control
+          specific aspects of a subtree within the DIT. Like all administrative areas, an access control specific area
+          is rooted at a vertex entry called the Administrative Point (AP). The ACSA spans down until leaf entries are
+          encountered or until another ACSA is encountered. Access control specific areas do not overlap.</para>
+        <para>Under the AP, you can add subentries that contain prescriptiveACI attributes. Zero or more subentries can
+          be added, each with one or more prescriptiveACI. These subentries apply access control information (ACI) in
+          these prescriptiveACI attributes to collections of entries within the ACSA.</para>
+        <section
+          id="Adding an 'administrativeRole' Attribute">
+          <title>Adding an 'administrativeRole' Attribute</title>
+          <para>An entry becomes an AP when it has an administrativeRole attribute added to it with the appropriate
+            value(s). For an ACSA, we need to add the 'accessControlSpecificArea' value to this attribute.</para>
+          <para>Most of the time users will create partitions in the server and set the root context of the partition
+            (its suffix) to be the AP for a ACSA. For example the default server.xml for ApacheDS ships with a partition
+            with the suffix, 'dc=example,dc=com'. We can use this suffix entry as the AP and our ACSA can cover all
+            entries under and including 'dc=example,dc=com'.</para>
+          <para>The code below binds to the server as admin ('uid=admin,ou=system') and modifies the suffix entry to
+            become an ACSA. Note that we check to make sure the attribute does not already exist before attempting the
+            add operation.</para>
+          <programlisting><![CDATA[
+  ...
+  // Get a DirContext on the dc=example,dc=com entry
+  Hashtable env = new Hashtable();
+  env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
+  env.put( "java.naming.provider.url", "ldap://localhost:389/dc=example,dc=com" );
+  env.put( "java.naming.security.principal", "uid=admin,ou=system" );
+  env.put( "java.naming.security.credentials", "secret" );
+  env.put( "java.naming.security.authentication", "simple" );
+  ctx = new InitialDirContext( env );
+
+  // Lookup the administrativeRole specifically since it is operational
+  Attributes ap = ctx.getAttributes( "", new String[] { "administrativeRole" } );
+  Attribute administrativeRole = ap.get( "administrativeRole" );
+
+  // If it does not exist or has no ACSA value then add the attribute
+  if ( administrativeRole == null || ! administrativeRole.contains( "accessControlSpecificArea" ) )
+  {
+    Attributes changes = new BasicAttributes( "administrativeRole", "accessControlSpecificArea", true );
+    ctx.modifyAttributes( "", DirContext.ADD_ATTRIBUTE, changes );
+  }
+  ...
+          ]]></programlisting>
+          <para>This simple modification of adding the value 'accessControlSpecificArea' to the administrativeRole makes
+            the suffix entry 'dc=example,dc=com' an AP for an access control specific area. Now you can add subentries
+            to your heart's content which subordinate to the AP.</para>
+        </section>
+      </section>
+      <section
+        id="Creating an Access Control Inner Administrative Area">
+        <title>Creating an Access Control Inner Administrative Area</title>
+        <para>Creating an inner area involves the same process. In fact the same code can be used by changing the value
+          added to the administrativeRole attribute. To create the inner area just add 'accessControlInnerArea' for the
+          administrativeRole within the AP: same steps, same code, different value for the administrativeRole.</para>
+      </section>
+      <section
+        id="Access Control Subentries">
+        <title>Access Control Subentries</title>
+        <para>After creating the access control area you can create subentries that subordinate to this AP for managing
+          access to it and anything below. Access control subentries are entries with the objectClasses: 'subentry' and
+          'accessControlSubentry'. An access control subentry must contain 3 attributes other than the obvious
+          objectClass attribute. These required attributes are listed below:</para>
+        <table
+          id="Access Control Subentries table">
+          <title>Access Control Subentries</title>
+          <tgroup
+            cols="3">
+            <thead>
+              <row>
+                <entry>Attribute</entry>
+                <entry>SINGLE-VALUED</entry>
+                <entry>Description</entry>
+              </row>
+            </thead>
+            <tbody>
+              <row>
+                <entry>cn</entry>
+                <entry>no</entry>
+                <entry>The name of the subentry used as its RDN</entry>
+              </row>
+              <row>
+                <entry>subtreeSpecification</entry>
+                <entry>yes</entry>
+                <entry>The specification for the collection of entries the ACI is to be applied to.</entry>
+              </row>
+              <row>
+                <entry>prescriptiveACI</entry>
+                <entry>no</entry>
+                <entry>The attribute holding the ACIItem</entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </table>
+      </section>
+    </section>
+    <section
+      id="AllowSelfPasswordModify">
+      <title>AllowSelfPasswordModify</title>
+      <programlisting><![CDATA[
+{
+  identificationTag "allowSelfAccessAndModification",
+  precedence 14,
+  authenticationLevel none,
+  itemOrUserFirst userFirst: 
+  {
+    userClasses { thisEntry },
+    userPermissions 
+    { 
+      { protectedItems {entry}, grantsAndDenials { grantModify, grantBrowse, grantRead } },
+      { protectedItems {allAttributeValues {userPassword}}, grantsAndDenials { grantAdd, grantRemove } }
+    } 
+  } 
+}
+      ]]></programlisting>
+      <section
+        id="Commentary">
+        <title>Commentary</title>
+        <para>
+          Note that two different user permissions are used to accurately specify self access and self modification
+          of
+          the
+          <emphasis
+            role="bold">userPassword</emphasis>
+          attribute within the entry. So with the first userPermission of this ACI a user would be
+          able to read all
+          attributes and values within his/her entry. They also have the ability to modify the entry
+          but this is moot
+          since they cannot add, remove or replace any attributes within their entry. The second user
+          permission
+          completes the picture by granting add and remove permissions to all values of userPassword. This
+          means the user
+          can replace the password.
+        </para>
+        <info>
+          <title>"grantAdd + grantRemove = grantReplace"</title>
+          <para>
+            Modify operations either add, remove or replace attributes and their values in LDAP. X.500 seems to have
+            overlooked the replace capability. Hence there is no such thing as a
+            <emphasis
+              role="bold">grantReplace</emphasis>
+            permission. However grantAdd and grantDelete on an attribute and its values are both required for a replace
+            operation to take place.
+          </para>
+        </info>
+      </section>
+    </section>
+    <section
+      id="EnableSearchForAllUsers">
+      <title>EnableSearchForAllUsers</title>
+      <section
+        id="Enable Authenticated Users to Browse and Read Entries in a Subtree">
+        <title>Enable Authenticated Users to Browse and Read Entries in a Subtree</title>
+        <warning>
+          <title>The first time is always the hardest!</title>
+          <para>We presume this is your first encounter and so many bases will be covered this time around. Every other
+            trail will build on this information. So expect a little less to read as you gain momentum.</para>
+        </warning>
+        <para>Since the entire directory is locked down for all but the superuser, you're going to want to grant read
+          and browse access to users for certain regions of the DIT. This will probably be the first thing you'll want
+          to do after turning on access controls.</para>
+        <section
+          id="Check for insufficientAccessRights for Normal Users">
+          <title>Check for insufficientAccessRights for Normal Users</title>
+          <para>
+            Just to make sure everything is locked down login as admin and create a new non-superuser. For more
+            information on how to do this see
+            <xref
+              linkend="Authentication" />
+            . After creating the normal user make sure you cannot bind
+            to dc=example,dc=com with access controls enabled.
+            You should get an error trying to bind with a result code
+            of 50 (insufficientAccessRights). If using JNDI to
+            connect to the server you should get a
+            NoPermissionException. After we apply the following ACI you can check
+            again.
+          </para>
+        </section>
+        <section
+          id="Partition and Access Control Area Setup">
+          <title>Partition and Access Control Area Setup</title>
+          <para>For this example we presume you have setup a partition at the namingContext dc=example,dc=com and have
+            turned on access controls. Now you want to grant browse and read access to entries and their attributes.
+          </para>
+          <para>
+            Before you can add a subentry with the prescriptiveACI you'll need to create an administrative area. For
+            now
+            we'll make the root of the partition the adminstrative point (AP). Every entry including this entry and
+            those underneath it will be part of the autonous administrative area for managing access controls. To do
+            this we must add the administrativeRole operational attribute to the AP entry. See
+            <xref
+              linkend="ACArea" />
+            for code and
+            information about creating access control administrative areas.
+          </para>
+        </section>
+        <section
+          id="Adding the Subentry">
+          <title>Adding the Subentry</title>
+          <para>
+            The subentry can be added using an LDIF or via code. We'll show the code but the LDIF can be accessed here
+            <link
+              xlink:href="data/enableSearchForAllUsers.ldif">
+              enableSearchForAllUsers.ldif</link>
+            :
+          </para>
+          <programlisting><![CDATA[
+// Get a DirContext on the dc=example,dc=com entry
+  Hashtable env = new Hashtable();
+  env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
+  env.put( "java.naming.provider.url", "ldap://localhost:" + port + "/dc=example,dc=com" );
+  env.put( "java.naming.security.principal", "uid=admin,ou=system" );
+  env.put( "java.naming.security.credentials", "secret" );
+  env.put( "java.naming.security.authentication", "simple" );
+  ctx = new InitialDirContext( env );
+
+  // now add the A/C subentry below dc=example,dc=com
+  Attributes subentry = new BasicAttributes( "cn", "enableSearchForAllUsers", true );
+  Attribute objectClass = new BasicAttribute( "objectClass" );
+  subentry.put( objectClass );
+  objectClass.add( "top" );
+  objectClass.add( "subentry" );
+  objectClass.add( "accessControlSubentry" );
+  subentry.put( "subtreeSpecification", "{}" );
+  subentry.put( "prescriptiveACI",
+                "{ \n" +
+                "  identificationTag \"enableSearchForAllUsers\",\n" +
+                "  precedence 14,\n" +
+                "  authenticationLevel simple,\n" +
+                "  itemOrUserFirst userFirst: \n" +
+                "  { \n" +
+                "    userClasses { allUsers }, \n" +
+                "    userPermissions \n" +
+                "    { \n" +
+                "      {\n" +
+                "        protectedItems {entry, allUserAttributeTypesAndValues}, \n" +
+                "        grantsAndDenials { grantRead, grantReturnDN, grantBrowse } \n" +
+                "      }\n" +
+                "    } \n" +
+                "  } \n" +
+                "}" );
+  ctx.createSubcontext( "cn=enableSearchForAllUsers", subentry );
+          ]]></programlisting>
+          <para>Before we cover the anatomy of this ACIItem, you might want to add the subentry and test access with a
+            normal non-super user to make sure access is now granted.</para>
+        </section>
+        <section
+          id="ACIItem Description">
+          <title>ACIItem Description</title>
+          <para>Here's the ACIItem you just added above without all the Java clutter:</para>
+          <programlisting><![CDATA[
+{ 
+  identificationTag "enableSearchForAllUsers",
+  precedence 14,
+  authenticationLevel simple,
+  itemOrUserFirst userFirst: 
+  { 
+    userClasses { allUsers }, 
+    userPermissions 
+    { 
+       {
+         protectedItems {entry, allUserAttributeTypesAndValues}, 
+         grantsAndDenials { grantRead, grantReturnDN, grantBrowse } 
+       }
+    } 
+  } 
+}
+        ]]></programlisting>
+          <para>There are several parameters to this simple ACIItem. Here's a breif exaplanation of each field and it's
+            meaning or significance.</para>
+          <table
+            id="ACIItem fields table">
+            <title>ACIItem fields</title>
+            <tgroup
+              cols="2">
+              <thead>
+                <row>
+                  <entry>Fields</entry>
+                  <entry>Description</entry>
+                </row>
+              </thead>
+              <tbody>
+                <row>
+                  <entry>identificationTag</entry>
+                  <entry>Identifies the ACIItem within an entry.</entry>
+                </row>
+                <row>
+                  <entry>precedence</entry>
+                  <entry>Determine which ACI to apply with conflicting ACIItems.</entry>
+                </row>
+                <row>
+                  <entry>authenticationLevel</entry>
+                  <entry>User's level of trust with values of none, simple, strong</entry>
+                </row>
+                <row>
+                  <entry>itemOrUserFirst</entry>
+                  <entry>Determines order of item permissions or user permissions.</entry>
+                </row>
+                <row>
+                  <entry>userClasses</entry>
+                  <entry>The set of users the permissions apply to.</entry>
+                </row>
+                <row>
+                  <entry>userPermissions</entry>
+                  <entry>Permissions on protected items</entry>
+                </row>
+              </tbody>
+            </tgroup>
+          </table>
+          <section
+            id="identificationTag">
+            <title>identificationTag</title>
+            <para>The identificationTag is just that a tag. It's often used with a subtring search filter to lookup a
+              specific ACIItem within an entry. One or more ACIItems may be present within a subentry, zero or more in
+              entries, so this serves as a means to address the ACIItem within entries.</para>
+          </section>
+          <section
+            id="precedence">
+            <title>precedence</title>
+            <para>Precendence is used to determine the ACI to apply when two or more ACIItem's applied to an entry
+              conflict. The ACIItem with the highest precedence is applied over other conflicting ACIItems.</para>
+            <warning>
+              <title>Denials Overpower Grants</title>
+              <para>When two or more conflicting ACIItems are encountered with the same precedence the ACIItems with
+                denials overpower ACIItems with grants.</para>
+            </warning>
+            <para>Right now the use of this field may not mean too much to you. We're dealing with a very simple
+              situation with a single access control area. Later as you add more subentries their subtreeSpecifications
+              may define collections that intersect. When this happens two or more conflicting ACIItems may apply to the
+              same entry. Precendence is then applied to determine which permissions apply.</para>
+            <para>Another complex situation requiring precedence is the use of inner areas. These nested inner
+              administrative areas overlap and so do their effects. The authority within an AA may deny some operation
+              to all entries but grant access to subentries of inner areas so minor authorities can control access to
+              inner areas. Their grants to users may need to have a higher precedence over denials in outer areas. Such
+              situations will arise and precedence will need to be used. In this example we just assign an arbitrary
+              value to the precedence.</para>
+          </section>
+          <section
+            id="authenticationLevel">
+            <title>authenticationLevel</title>
+            <para>The authenticationLevel is the minimum authentication requirement for requestor for the ACI to by
+              applied: According to X.501:</para>
+            <info>
+              <title>18.4.2.3 Authentication Level</title>
+              <para>... Strong authentication of the requestor is considered to exceed a requirement for simple or no
+                authentication, and simple authentication exceeds a requirement for no authentication ...</para>
+            </info>
+            <para>The authenticationLevel can have three values: none, simple and strong. It's used to be able to
+              associate permissions with the level of trust in users. For none, the identity of the user is anonymous or
+              does not matter. The user can be anyone. The simple authenticationLevel means the user has authenticated
+              but is using a simple bind with clear text passwords. The strong authenticationLevel represents users that
+              bind to the directory using strong authentication mechanisms via SASL.</para>
+            <para>SASL can allow annonynous binds as well so there is a distinction here. Using SASL alone does not mean
+              the authenticationLevel is strong. As we add SASL mechanisms to the server, we'll qualify each one with
+              none, simple or strong. This will be reflected in the authenticationLevel property of the principal making
+              requests.</para>
+          </section>
+          <section
+            id="itemOrUserFirst">
+            <title>itemOrUserFirst</title>
+            <para>This field describes the order of information within the ACI whether protected items are described
+              first or user classes and permissions are described first. For simplicity we will only describe the
+              userFirst configuration in this tutorial.</para>
+          </section>
+          <section
+            id="userClasses">
+            <title>userClasses</title>
+            <para>UserClasses is used to list the sets of users to which this permission applies. Several mechanisms can
+              be used here to define userClasses. They can be defined by name per user, by group membership, or by the
+              superset of all users possible and many more. In our example we have applied the ACI to all users that
+              have authenticated by simple or strong means.</para>
+            <para>
+              For more information see
+              <xref
+                linkend="UserClasses" />
+              .
+            </para>
+          </section>
+          <section
+            id="userPermissions">
+            <title>userPermissions</title>
+            <para>These are the permissions granted or denied to those users included by the userClasses field. The
+              grants or denials however are qualified by the protected items operated upon. In our example we grant
+              read, return DN and browse to all entries, their attributes and all possible values they may have.</para>
+            <para>
+              For more information see
+              <xref
+                linkend="UserPermissions" />
+              .
+            </para>
+          </section>
+        </section>
+      </section>
+    </section>
+    <section
+      id="UserClasses">
+      <title>UserClasses</title>
+      <section
+        id="What are User Classes?">
+        <title>What are User Classes?</title>
+        <para>
+          A large part of managing access control information involves the specification of
+          <emphasis
+            role="bold">who</emphasis>
+          can perform
+          <emphasis
+            role="bold">which</emphasis>
+          operation on
+          <emphasis
+            role="bold">what</emphasis>
+          protected resource (entries, attributes, values etc). At evaluation time a requestor of an
+          operation is known.
+          The identity of the requestor is checked to see if it falls into the set of users
+          authorized to perform the
+          operation. User classes are hence definitions of a set of zero or more users
+          permissions apply to. Several
+          constructs exist for specifying a user class.
+        </para>
+      </section>
+      <section
+        id="Simple User Classes">
+        <title>Simple User Classes</title>
+        <para>There are 3 really simple constructs for specifying the user. These constructs are listed in the table
+          below:</para>
+        <table
+          id="Simple User Classes table">
+          <title>Simple User Classes</title>
+          <tgroup
+            cols="3">
+            <thead>
+              <row>
+                <entry>User Class Construct</entry>
+                <entry>Meaning</entry>
+                <entry>Example</entry>
+              </row>
+            </thead>
+            <tbody>
+              <row>
+                <entry>allUsers</entry>
+                <entry>Any user with possible requirements for AuthenticationLevel</entry>
+                <entry>
+                  <emphasis
+                    role="bold">allUsers</emphasis>
+                </entry>
+              </row>
+              <row>
+                <entry>thisEntry</entry>
+                <entry>The user with the same DN as the entry being accessed</entry>
+                <entry>
+                  <emphasis
+                    role="bold">thisEntry</emphasis>
+                </entry>
+              </row>
+              <row>
+                <entry>name</entry>
+                <entry>The user with the specified DN</entry>
+                <entry>
+                  <emphasis
+                    role="bold">name</emphasis>
+                  { "uid=admin,ou=system" }
+                </entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </table>
+        <para>These are pretty intuitive. Two other user classes may be a bit less easy to understand or may require
+          some explanation. For these we discuss them in the sections below.</para>
+      </section>
+      <section
+        id="User Class: userGroup">
+        <title>User Class: userGroup</title>
+        <para>
+          The
+          <emphasis
+            role="bold">userGroup</emphasis>
+          user class construct is also pretty intuitive. It does however require some background information about how
+          group membership is determined for this purpose.
+        </para>
+        <para>
+          ApacheDS associates users within a group using the
+          <emphasis
+            role="bold">groupOfNames</emphasis>
+          and
+          <emphasis
+            role="bold">groupOfUniqueNames</emphasis>
+          objectClasses. To
+          define groups an entry of either of these objectClasses is added anywhere in the server's
+          DIT.
+          <emphasis
+            role="bold">member</emphasis>
+          or
+          <emphasis
+            role="bold">uniqueMember</emphasis>
+          attributes whose values are the DN of user entries are present within the entry to represent
+          membership within
+          the group.
+        </para>
+        <warning>
+          <para>Although such group entries can be added anywhere within the DIT to be recognized by the Authorization
+            subsystem, a recommended convention exists. Use the 'ou=groups' container under a namingContext/partition
+            within the server to localize groups. Most of the time group information can be stored under
+            'ou=groups,ou=system'.</para>
+        </warning>
+        <para>
+          Just like the
+          <emphasis
+            role="bold">name</emphasis>
+          construct, the
+          <emphasis
+            role="bold">userGroup</emphasis>
+          construct takes a single parameter: the DN of the group entry.
+          During ACI evaluation ApacheDS checks to see if
+          the requestor's DN is contained within the group. Below is a
+          section from X.501 specification which explains
+          just how this is done:
+        </para>
+        <para>
+          <emphasis
+            role="bold">Section 18.4.2.5 Determining group membership (b)</emphasis>
+        </para>
+        <para>
+          In order to determine whether the requestor is a member of a userGroup user class, the following criteria
+          apply:
+          <itemizedlist>
+            <listitem>
+              <para>The entry named by the userGroup specification shall be an instance of the object class groupOfNames
+                or groupOfUniqueNames.</para>
+            </listitem>
+            <listitem>
+              <para>The name of the requestor shall be a value of the member or uniqueMember attribute of that entry.
+              </para>
+            </listitem>
+          </itemizedlist>
+        </para>
+      </section>
+      <section
+        id="User Class: subtree">
+        <title>User Class: subtree</title>
+        <para>Here the user class specification construct is a subtree specification without a refinement filter. Such a
+          specification is simple yet very powerful. The subtree defines a collection of entries. During ACI evaluation,
+          ApacheDS will check to see if the requestor's DN is included by this collection.</para>
+        <para>
+          For more information on how to define a subtreeSpecification please see
+          <xref
+            linkend="Subentries" />
+          and
+          <xref
+            linkend="The Administrative Model" />
+          .
+        </para>
+        <warning>
+          <para>For this purpose a subtree is not refined. Meaning it does not evaluate refinement filters. This is to
+            restrict the information needed to make a determination to just the DN of the requestor and not the entry of
+            the requestor.</para>
+        </warning>
+      </section>
+    </section>
+    <section
+      id="Combining Multiple UserClass Specification Mechanisms">
+      <title>Combining Multiple UserClass Specification Mechanisms</title>
+      <para>The same userClass mechanism can be specified more than once if it makes sense. There is no reason to
+        specify allUsers more than once. More than one type of user class mechanism can be used as well. Again some
+        combinations just will not make sense like having a name based userClass then allUsers. The following ACIItem
+        grants delete abilities to a set of users using more than one machanism. It allows jbean, jdoe, all users in the
+        Administrators group to delete entries. It also allows requestors to delete their own user entry.</para>
+      <programlisting><![CDATA[
+{ identificationTag "deleteAci"
+  precedence 255,
+  authenticationLevel simple,
+  itemOrUserFirst userFirst: 
+    {
+      userClasses 
+        { 
+           thisEntry, 
+           name { "uid=jbean,ou=users,ou=system" }, 
+           name { "uid=jdoe,ou=users,ou=system" }, 
+           userGroup { "cn=Administrators,ou=groups,ou=system" } 
+        },
+      userPermissions { { protectedItems {entry}, grantsAndDenials { grantRemove } } } 
+    } 
+}
+    ]]></programlisting>
+    </section>
+  </section>
+</chapter>
\ No newline at end of file

Propchange: directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-authentication-and-authorization.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-authentication-and-authorization.xml
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-community.xml
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-community.xml?rev=985486&r1=985485&r2=985486&view=diff
==============================================================================
--- directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-community.xml (original)
+++ directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/chapter-community.xml Sat Aug 14 13:11:37 2010
@@ -16,20 +16,6 @@
   xmlns:ns3="http://www.w3.org/1999/xhtml"
   xml:lang="en">
   <title>Community</title>
-  <itemizedlist>
-    <listitem>
-      <xref
-        linkend="Reporting Bugs" />
-    </listitem>
-    <listitem>
-      <xref
-        linkend="Building trunks" />
-    </listitem>
-    <listitem>
-      <xref
-        linkend="Contributing" />
-    </listitem>
-  </itemizedlist>
   <section
     id="Reporting Bugs">
     <title>Reporting Bugs</title>

Added: directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/data/sasl-gssapi-example.ldif
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/data/sasl-gssapi-example.ldif?rev=985486&view=auto
==============================================================================
--- directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/data/sasl-gssapi-example.ldif (added)
+++ directory/sandbox/felixk/apacheds-docs/src/advanced-user-guide/data/sasl-gssapi-example.ldif Sat Aug 14 13:11:37 2010
@@ -0,0 +1,57 @@
+#
+#   Copyright 2007 The Apache Software Foundation
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+#   EXAMPLE.COM is reserved for testing per RFC 2606.
+
+dn: ou=users,dc=example,dc=com
+objectclass: top
+objectclass: organizationalunit
+ou: users
+
+dn: uid=hnelson,ou=users,dc=example,dc=com
+objectclass: top
+objectclass: person
+objectclass: inetOrgPerson
+objectclass: krb5Principal
+objectclass: krb5KDCEntry
+cn: Horatio Nelson
+sn: Nelson
+uid: hnelson
+userpassword: s3crEt
+krb5PrincipalName: hnelson@EXAMPLE.COM
+
+dn: uid=krbtgt,ou=users,dc=example,dc=com
+objectclass: top
+objectclass: person
+objectclass: inetOrgPerson
+objectclass: krb5Principal
+objectclass: krb5KDCEntry
+cn: KDC Service
+sn: Service
+uid: krbtgt
+userpassword: randomKey
+krb5PrincipalName: krbtgt/EXAMPLE.COM@EXAMPLE.COM
+
+dn: uid=hostldap,ou=users,dc=example,dc=com
+objectclass: top
+objectclass: person
+objectclass: inetOrgPerson
+objectclass: krb5Principal
+objectclass: krb5KDCEntry
+cn: LDAP Service
+sn: Service
+uid: hostldap
+userpassword: randomKey
+krb5PrincipalName: ldap/ldap.example.com@EXAMPLE.COM

Modified: directory/sandbox/felixk/apacheds-docs/src/docbkx-stylesheet/fo/docbook.xsl
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/apacheds-docs/src/docbkx-stylesheet/fo/docbook.xsl?rev=985486&r1=985485&r2=985486&view=diff
==============================================================================
--- directory/sandbox/felixk/apacheds-docs/src/docbkx-stylesheet/fo/docbook.xsl (original)
+++ directory/sandbox/felixk/apacheds-docs/src/docbkx-stylesheet/fo/docbook.xsl Sat Aug 14 13:11:37 2010
@@ -20,6 +20,7 @@ under the License.
 
 <xsl:stylesheet
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  xmlns:fo="http://www.w3.org/1999/XSL/Format"
   version="1.0">
 
   <!-- imports the original docbook stylesheet -->
@@ -40,4 +41,8 @@ under the License.
 
   <!-- Important links: - http://www.sagehill.net/docbookxsl/ - http://docbkx-tools.sourceforge.net/ -->
 
+  <xsl:template match="processing-instruction('linebreak')">
+    <fo:block/>
+  </xsl:template>
+  
 </xsl:stylesheet>
\ No newline at end of file

Modified: directory/sandbox/felixk/apacheds-docs/src/docbkx-stylesheet/html/docbook.xsl
URL: http://svn.apache.org/viewvc/directory/sandbox/felixk/apacheds-docs/src/docbkx-stylesheet/html/docbook.xsl?rev=985486&r1=985485&r2=985486&view=diff
==============================================================================
--- directory/sandbox/felixk/apacheds-docs/src/docbkx-stylesheet/html/docbook.xsl (original)
+++ directory/sandbox/felixk/apacheds-docs/src/docbkx-stylesheet/html/docbook.xsl Sat Aug 14 13:11:37 2010
@@ -56,6 +56,10 @@ under the License.
 
   <!-- Important links: - http://www.sagehill.net/docbookxsl/ - http://docbkx-tools.sourceforge.net/ -->
   
+  <xsl:template match="processing-instruction('linebreak')">
+    <br/>
+  </xsl:template>
+
   <!--
     TODO
     - template match="warning", add image