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 & 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/<fqdn>@<realm>. The 'ldap' name component and the @<realm> 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