<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.auth.adapter.ldap">

    <title>LDAP Authentication</title>

    <sect2 id="zend.auth.adapter.ldap.introduction">

        <title>Introduction</title>

        <para>
            <classname>Zend_Auth_Adapter_Ldap</classname> supports web application authentication with LDAP services. Its
            features include username and domain name canonicalization, multi-domain authentication, and failover
            capabilities. It has been tested to work with
            <ulink url="http://www.microsoft.com/windowsserver2003/technologies/directory/activedirectory/">Microsoft
            Active Directory</ulink> and <ulink url="http://www.openldap.org/">OpenLDAP</ulink>, but it should also
            work with other LDAP service providers.
        </para>

        <para>
            This documentation includes a guide on using <classname>Zend_Auth_Adapter_Ldap</classname>, an exploration of its
            API, an outline of the various available options, diagnostic information for troubleshooting authentication
            problems, and example options for both Active Directory and OpenLDAP servers.
        </para>

    </sect2>

    <sect2 id="zend.auth.adapter.ldap.usage">

        <title>Usage</title>

        <para>
            To incorporate <classname>Zend_Auth_Adapter_Ldap</classname> authentication into your application quickly, even if
            you're not using <classname>Zend_Controller</classname>, the meat of your code should look something like the
            following:
            <programlisting role="php"><![CDATA[
$username = $this->_request->getParam('username');
$password = $this->_request->getParam('password');

$auth = Zend_Auth::getInstance();

$config = new Zend_Config_Ini('../application/config/config.ini',
                              'production');
$log_path = $config->ldap->log_path;
$options = $config->ldap->toArray();
unset($options['log_path']);

$adapter = new Zend_Auth_Adapter_Ldap($options, $username,
                                      $password);

$result = $auth->authenticate($adapter);

if ($log_path) {
    $messages = $result->getMessages();

    $logger = new Zend_Log();
    $logger->addWriter(new Zend_Log_Writer_Stream($log_path));
    $filter = new Zend_Log_Filter_Priority(Zend_Log::DEBUG);
    $logger->addFilter($filter);

    foreach ($messages as $i => $message) {
        if ($i-- > 1) { // $messages[2] and up are log messages
            $message = str_replace("\n", "\n  ", $message);
            $logger->log("Ldap: $i: $message", Zend_Log::DEBUG);
        }
    }
}
]]></programlisting>
            Of course, the logging code is optional, but it is highly recommended that you use a logger.
            <classname>Zend_Auth_Adapter_Ldap</classname> will record just about every bit of information anyone could want in
            <code>$messages</code> (more below), which is a nice feature in itself for something that has a history of
            being notoriously difficult to debug.
        </para>

        <para>
            The <classname>Zend_Config_Ini</classname> code is used above to load the adapter options. It is also optional. A
            regular array would work equally well. The following is an example
            <code>application/config/config.ini</code> file that has options for two separate servers. With multiple
            sets of server options the adapter will try each, in order, until the credentials are successfully
            authenticated. The names of the servers (e.g., <code>server1</code> and <code>server2</code>) are largely
            arbitrary. For details regarding the options array, see the <emphasis>Server Options</emphasis> section
            below. Note that <classname>Zend_Config_Ini</classname> requires that any values with "equals" characters
            (<code>=</code>) will need to be quoted (like the DNs shown below).
            <programlisting role="ini"><![CDATA[
[production]

ldap.log_path = /tmp/ldap.log

; Typical options for OpenLDAP
ldap.server1.host = s0.foo.net
ldap.server1.accountDomainName = foo.net
ldap.server1.accountDomainNameShort = FOO
ldap.server1.accountCanonicalForm = 3
ldap.server1.username = "CN=user1,DC=foo,DC=net"
ldap.server1.password = pass1
ldap.server1.baseDn = "OU=Sales,DC=foo,DC=net"
ldap.server1.bindRequiresDn = true

; Typical options for Active Directory
ldap.server2.host = dc1.w.net
ldap.server2.useStartTls = true
ldap.server2.accountDomainName = w.net
ldap.server2.accountDomainNameShort = W
ldap.server2.accountCanonicalForm = 3
ldap.server2.baseDn = "CN=Users,DC=w,DC=net"
]]></programlisting>
            The above configuration will instruct <classname>Zend_Auth_Adapter_Ldap</classname> to attempt to authenticate users
            with the OpenLDAP server <code>s0.foo.net</code> first. If the authentication fails for any reason, the AD
            server <code>dc1.w.net</code> will be tried.
        </para>

        <para>
            With servers in different domains, this configuration illustrates multi-domain authentication. You can also
            have multiple servers in the same domain to provide redundancy.
        </para>

        <para>
            Note that in this case, even though OpenLDAP has no need for the short NetBIOS style domain name used by
            Windows, we provide it here for name canonicalization purposes (described in the
            <emphasis>Username Canonicalization</emphasis> section below).
        </para>

    </sect2>

    <sect2 id="zend.auth.adapter.ldap.api">

        <title>The API</title>

        <para>
            The <classname>Zend_Auth_Adapter_Ldap</classname> constructor accepts three parameters.
        </para>

        <para>
            The <code>$options</code> parameter is required and must be an array containing one or more sets of
            options. Note that it is <emphasis>an array of arrays</emphasis> of
            <link linkend="zend.ldap"><classname>Zend_Ldap</classname></link> options. Even if you will be using only one LDAP server, the
            options must still be within another array.
        </para>

        <para>
            Below is <ulink url="http://php.net/print_r"><code>print_r()</code></ulink> output of an example options
            parameter containing two sets of server options for LDAP servers <code>s0.foo.net</code> and
            <code>dc1.w.net</code> (the same options as the above INI representation):
            <programlisting role="output"><![CDATA[
Array
(
    [server2] => Array
        (
            [host] => dc1.w.net
            [useStartTls] => 1
            [accountDomainName] => w.net
            [accountDomainNameShort] => W
            [accountCanonicalForm] => 3
            [baseDn] => CN=Users,DC=w,DC=net
        )

    [server1] => Array
        (
            [host] => s0.foo.net
            [accountDomainName] => foo.net
            [accountDomainNameShort] => FOO
            [accountCanonicalForm] => 3
            [username] => CN=user1,DC=foo,DC=net
            [password] => pass1
            [baseDn] => OU=Sales,DC=foo,DC=net
            [bindRequiresDn] => 1
        )

)
]]></programlisting>
            The information provided in each set of options above is different mainly because AD does not require a
            username be in DN form when binding (see the <code>bindRequiresDn</code> option in the
            <emphasis>Server Options</emphasis> section below), which means we can omit a number of options
            associated with retrieving the DN for a username being authenticated.
        </para>

        <note>
            <title>What is a Distinguished Name?</title>
            <para>
                A DN or "distinguished name" is a string that represents the path to an object within the LDAP
                directory. Each comma-separated component is an attribute and value representing a node. The components
                are evaluated in reverse. For example, the user account
                <emphasis>CN=Bob Carter,CN=Users,DC=w,DC=net</emphasis> is located directly within the
                <emphasis>CN=Users,DC=w,DC=net container</emphasis>. This structure is best explored with an LDAP
                browser like the ADSI Edit MMC snap-in for Active Directory or phpLDAPadmin.
            </para>
        </note>

        <para>
            The names of servers (e.g. '<code>server1</code>' and '<code>server2</code>' shown above) are largely
            arbitrary, but for the sake of using <classname>Zend_Config</classname>, the identifiers should be present (as
            opposed to being numeric indexes) and should not contain any special characters used by the associated file
            formats (e.g. the '<code>.</code>' INI property separator, '<code>&amp;</code>' for XML entity references,
            etc).
        </para>

        <para>
            With multiple sets of server options, the adapter can authenticate users in multiple domains and provide
            failover so that if one server is not available, another will be queried.
        </para>

        <note>
            <title>The Gory Details: What Happens in the Authenticate Method?</title>
            <para>
                When the <code>authenticate()</code> method is called, the adapter iterates over each set of server
                options, sets them on the internal <classname>Zend_Ldap</classname> instance, and calls the
                <classname>Zend_Ldap::bind()</classname> method with the username and password being authenticated. The
                <classname>Zend_Ldap</classname> class checks to see if the username is qualified with a domain (e.g., has a
                domain component like <emphasis>alice@foo.net</emphasis> or <emphasis>FOO\alice</emphasis>). If a
                domain is present, but does not match either of the server's domain names
                (<emphasis>foo.net</emphasis> or <emphasis>FOO</emphasis>), a special exception is thrown and caught by
                <classname>Zend_Auth_Adapter_Ldap</classname> that causes that server to be ignored and the next set of server
                options is selected. If a domain <emphasis>does</emphasis> match, or if the user did not supply a
                qualified username, <classname>Zend_Ldap</classname> proceeds to try to bind with the supplied credentials. If
                the bind is not successful, <classname>Zend_Ldap</classname> throws a <classname>Zend_Ldap_Exception</classname> which is
                caught by <classname>Zend_Auth_Adapter_Ldap</classname> and the next set of server options is tried. If the bind
                is successful, the iteration stops, and the adapter's <code>authenticate()</code> method returns a
                successful result. If all server options have been tried without success, the authentication fails, and
                <code>authenticate()</code> returns a failure result with error messages from the last iteration.
            </para>
        </note>

        <para>
            The username and password parameters of the <classname>Zend_Auth_Adapter_Ldap</classname> constructor represent the
            credentials being authenticated (i.e., the credentials supplied by the user through your HTML login form).
            Alternatively, they may also be set with the <code>setUsername()</code> and <code>setPassword()</code>
            methods.
        </para>

    </sect2>

    <sect2 id="zend.auth.adapter.ldap.server-options">

        <title>Server Options</title>

        <para>
            Each set of server options <emphasis>in the context of <classname>Zend_Auth_Adapter_Ldap</classname></emphasis> consists of the
            following options, which are passed, largely unmodified, to <classname>Zend_Ldap::setOptions()</classname>:

            <table id="zend.auth.adapter.ldap.server-options.table">
              <title>Server Options</title>
              <tgroup cols="2">
                <thead>
                  <row>
                    <entry>Name</entry>
                    <entry>Description</entry>
                  </row>
                </thead>
                <tbody>
                  <row>
                    <entry><emphasis role="strong">host</emphasis></entry>
                    <entry>
                        The hostname of LDAP server that these options represent. This option is required.
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">port</emphasis></entry>
                    <entry>
                        The port on which the LDAP server is listening. If <emphasis role="strong">useSsl</emphasis> is
                        <code>true</code>, the default <emphasis role="strong">port</emphasis> value is 636. If
                        <emphasis role="strong">useSsl</emphasis> is <code>false</code>, the default
                        <emphasis role="strong">port</emphasis> value is 389.
                    </entry>
                  </row>
                  <row>
                    <entry>useStartTls</entry>
                    <entry>
                        Whether or not the LDAP client should use TLS (aka SSLv2) encrypted transport. A value of
                        <code>true</code> is strongly favored in production environments to prevent passwords from
                        be transmitted in clear text. The default value is <code>false</code>, as servers
                        frequently require that a certificate be installed separately after installation.
                        The <code>useSsl</code> and <code>useStartTls</code> options are mutually exclusive.
                        The <code>useStartTls</code> option should be favored over <code>useSsl</code> but
                        not all servers support this newer mechanism.
                    </entry>
                  </row>
                  <row>
                    <entry>useSsl</entry>
                    <entry>
                        Whether or not the LDAP client should use SSL encrypted transport. The <code>useSsl</code>
                        and <code>useStartTls</code> options are mutually exclusive, but <code>useStartTls</code>
                        should be favored if the server and LDAP client library support it.
                        This value also changes the default <emphasis role="strong">port</emphasis> value (see
                        <emphasis role="strong">port</emphasis> description above).
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">username</emphasis></entry>
                    <entry>
                        The DN of the account used to perform account DN lookups. LDAP servers that require the
                        username to be in DN form when performing the "bind" require this option. Meaning, if
                        <emphasis role="strong">bindRequiresDn</emphasis> is <code>true</code>, this option is
                        required. This account does not need to be a privileged account; an account with read-only
                        access to objects under the <emphasis role="strong">baseDn</emphasis> is all that is necessary
                        (and preferred based on the <emphasis>Principle of Least Privilege</emphasis>).
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">password</emphasis></entry>
                    <entry>
                        The password of the account used to perform account DN lookups. If this option is not supplied,
                        the LDAP client will attempt an "anonymous bind" when performing account DN lookups.
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">bindRequiresDn</emphasis></entry>
                    <entry>
                        Some LDAP servers require that the username used to bind be in DN form like
                        <emphasis>CN=Alice Baker,OU=Sales,DC=foo,DC=net</emphasis> (basically all servers
                        <emphasis>except</emphasis> AD). If this option is <code>true</code>, this instructs
                        <classname>Zend_Ldap</classname> to automatically retrieve the DN corresponding to the username being
                        authenticated, if it is not already in DN form, and then re-bind with the proper DN. The
                        default value is <code>false</code>. Currently only Microsoft Active Directory Server (ADS) is
                        known <emphasis>not</emphasis> to require usernames to be in DN form when binding, and
                        therefore this option may be <code>false</code> with AD (and it should be, as retrieving the DN
                        requires an extra round trip to the server). Otherwise, this option must be set to
                        <code>true</code> (e.g. for OpenLDAP). This option also controls the default
                        <emphasis role="strong">acountFilterFormat</emphasis> used when searching for accounts. See the
                        <emphasis role="strong">accountFilterFormat</emphasis> option.
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">baseDn</emphasis></entry>
                    <entry>
                        The DN under which all accounts being authenticated are located. This option is required. If
                        you are uncertain about the correct <emphasis role="strong">baseDn</emphasis> value, it should
                        be sufficient to derive it from the user's DNS domain using <emphasis>DC=</emphasis>
                        components. For example, if the user's principal name is <emphasis>alice@foo.net</emphasis>, a
                        <emphasis role="strong">baseDn</emphasis> of <emphasis>DC=foo,DC=net</emphasis> should work. A
                        more precise location (e.g., <emphasis>OU=Sales,DC=foo,DC=net</emphasis>) will be more
                        efficient, however.
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">accountCanonicalForm</emphasis></entry>
                    <entry>
                        A value of 2, 3 or 4 indicating the form to which account names should be canonicalized after
                        successful authentication. Values are as follows: 2 for traditional username style names (e.g.,
                        <emphasis>alice</emphasis>), 3 for backslash-style names (e.g., <emphasis>FOO\alice</emphasis>)
                        or 4 for principal style usernames (e.g., <emphasis>alice@foo.net</emphasis>). The default
                        value is 4 (e.g., <emphasis>alice@foo.net</emphasis>). For example, with a value of 3, the
                        identity returned by <classname>Zend_Auth_Result::getIdentity()</classname> (and
                        <classname>Zend_Auth::getIdentity()</classname>, if <classname>Zend_Auth</classname> was used) will always be
                        <emphasis>FOO\alice</emphasis>, regardless of what form Alice supplied, whether it be
                        <emphasis>alice</emphasis>, <emphasis>alice@foo.net</emphasis>, <emphasis>FOO\alice</emphasis>,
                        <emphasis>FoO\aLicE</emphasis>, <emphasis>foo.net\alice</emphasis>, etc. See the
                        <emphasis>Account Name Canonicalization</emphasis> section in the <classname>Zend_Ldap</classname>
                        documentation for details. Note that when using multiple sets of server options it is
                        recommended, but not required, that the same
                        <emphasis role="strong">accountCanonicalForm</emphasis> be used with all server options so that
                        the resulting usernames are always canonicalized to the same form (e.g., if you canonicalize to
                        <emphasis>EXAMPLE\username</emphasis> with an AD server but to
                        <emphasis>username@example.com</emphasis> with an OpenLDAP server, that may be awkward for the
                        application's high-level logic).
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">accountDomainName</emphasis></entry>
                    <entry>
                        The FQDN domain name for which the target LDAP server is an authority (e.g.,
                        <code>example.com</code>). This option is used to canonicalize names so that the username
                        supplied by the user can be converted as necessary for binding. It is also used to determine if
                        the server is an authority for the supplied username (e.g., if
                        <emphasis role="strong">accountDomainName</emphasis> is <emphasis>foo.net</emphasis> and the
                        user supplies <emphasis>bob@bar.net</emphasis>, the server will not be queried, and a failure
                        will result). This option is not required, but if it is not supplied, usernames in principal
                        name form (e.g., <emphasis>alice@foo.net</emphasis>) are not supported. It is strongly
                        recommended that you supply this option, as there are many use-cases that require generating
                        the principal name form.
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">accountDomainNameShort</emphasis></entry>
                    <entry>
                        The 'short' domain for which the target LDAP server is an authority (e.g.,
                        <emphasis>FOO</emphasis>). Note that there is a 1:1 mapping between the
                        <emphasis role="strong">accountDomainName</emphasis> and
                        <emphasis role="strong">accountDomainNameShort</emphasis>. This option should be used to
                        specify the NetBIOS domain name for Windows networks, but may also be used by non-AD servers
                        (e.g., for consistency when multiple sets of server options with the backslash style
                        <emphasis role="strong">accountCanonicalForm</emphasis>). This option is not required but if it
                        is not supplied, usernames in backslash form (e.g., <emphasis>FOO\alice</emphasis>) are not
                        supported.
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">accountFilterFormat</emphasis></entry>
                    <entry>
                        The LDAP search filter used to search for accounts. This string is a
                        <ulink url="http://php.net/printf"><code>printf()</code></ulink>-style expression that must
                        contain one '<code>%s</code>' to accomodate the username. The default value is
                        '<code>(&amp;(objectClass=user)(sAMAccountName=%s))</code>', unless
                        <emphasis role="strong">bindRequiresDn</emphasis> is set to <code>true</code>, in which case
                        the default is '<code>(&amp;(objectClass=posixAccount)(uid=%s))</code>'. For example, if for
                        some reason you wanted to use <code>bindRequiresDn = true</code> with AD you would need to set
                        <code>accountFilterFormat = '(&amp;(objectClass=user)(sAMAccountName=%s))</code>'.
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">optReferrals</emphasis></entry>
                    <entry>
                        If set to <code>true</code>, this option indicates to the LDAP client that referrals should
                        be followed. The default value is <code>false</code>.
                    </entry>
                  </row>
                </tbody>
              </tgroup>
            </table>
        </para>

        <note>
            <para>
                If you enable <code>useStartTls = true</code> or <code>useSsl = true</code> you may find that
                the LDAP client generates an error
                claiming that it cannot validate the server's certificate. Assuming the PHP LDAP extension is
                ultimately linked to the OpenLDAP client libraries, to resolve this issue you can set
                "<code>TLS_REQCERT never</code>" in the OpenLDAP client <code>ldap.conf</code> (and restart the web
                server) to indicate to the OpenLDAP client library that you trust the server. Alternatively, if you are
                concerned that the server could be spoofed, you can export the LDAP server's root certificate and put
                it on the web server so that the OpenLDAP client can validate the server's identity.
            </para>
        </note>

    </sect2>

    <sect2 id="zend.auth.adapter.ldap.debugging">

        <title>Collecting Debugging Messages</title>

        <para>
            <classname>Zend_Auth_Adapter_Ldap</classname> collects debugging information within its <code>authenticate()</code>
            method. This information is stored in the <classname>Zend_Auth_Result</classname> object as messages. The array
            returned by <classname>Zend_Auth_Result::getMessages()</classname> is described as follows:

            <table id="zend.auth.adapter.ldap.debugging.table">
              <title>Debugging Messages</title>
              <tgroup cols="2">
                <thead>
                  <row>
                    <entry>Messages Array Index</entry>
                    <entry>Description</entry>
                  </row>
                </thead>
                <tbody>
                  <row>
                    <entry>Index 0</entry>
                    <entry>
                        A generic, user-friendly message that is suitable for displaying to users (e.g., "Invalid
                        credentials"). If the authentication is successful, this string is empty.
                    </entry>
                  </row>
                  <row>
                    <entry>Index 1</entry>
                    <entry>
                        A more detailed error message that is not suitable to be displayed to users but should be
                        logged for the benefit of server operators. If the authentication is successful, this string is
                        empty.
                    </entry>
                  </row>
                  <row>
                    <entry>Indexes 2 and higher</entry>
                    <entry>
                        All log messages in order starting at index 2.
                    </entry>
                  </row>
                </tbody>
              </tgroup>
            </table>

            In practice, index 0 should be displayed to the user (e.g., using the FlashMessenger helper), index 1 should
            be logged and, if debugging information is being collected, indexes 2 and higher could be logged as well
            (although the final message always includes the string from index 1).
        </para>

    </sect2>

    <sect2 id="zend.auth.adapter.ldap.options-common-server-specific">

        <title>Common Options for Specific Servers</title>

        <sect3 id="zend.auth.adapter.ldap.options-common-server-specific.active-directory">

            <title>Options for Active Directory</title>

            <para>
                For ADS, the following options are noteworthy:

                <table id="zend.auth.adapter.ldap.options-common-server-specific.active-directory.table">
                  <title>Options for Active Directory</title>
                  <tgroup cols="2">
                    <thead>
                      <row>
                        <entry>Name</entry>
                        <entry>Additional Notes</entry>
                      </row>
                    </thead>
                    <tbody>
                      <row>
                        <entry><emphasis role="strong">host</emphasis></entry>
                        <entry>
                            As with all servers, this option is required.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">useStartTls</emphasis></entry>
                        <entry>
                            For the sake of security, this should be <code>true</code> if the server has the necessary
                            certificate installed.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">useSsl</emphasis></entry>
                        <entry>
                            Possibly used as an alternative to <code>useStartTls</code> (see above).
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">baseDn</emphasis></entry>
                        <entry>
                            As with all servers, this option is required. By default AD places all user accounts under
                            the <emphasis>Users</emphasis> container (e.g.,
                            <emphasis>CN=Users,DC=foo,DC=net</emphasis>), but the default is not common in larger
                            organizations. Ask your AD administrator what the best DN for accounts for your application
                            would be.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">accountCanonicalForm</emphasis></entry>
                        <entry>
                            You almost certainly want this to be 3 for backslash style names (e.g.,
                            <emphasis>FOO\alice</emphasis>), which are most familiar to Windows users. You should
                            <emphasis>not</emphasis> use the unqualified form 2 (e.g., <emphasis>alice</emphasis>), as
                            this may grant access to your application to users with the same username in other trusted
                            domains (e.g., <emphasis>BAR\alice</emphasis> and <emphasis>FOO\alice</emphasis> will be
                            treated as the same user). (See also note below.)
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">accountDomainName</emphasis></entry>
                        <entry>
                            This is required with AD unless <emphasis role="strong">accountCanonicalForm</emphasis> 2
                            is used, which, again, is discouraged.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">accountDomainNameShort</emphasis></entry>
                        <entry>
                            The NetBIOS name of the domain that users are in and for which the AD server is an authority.
                            This is required if the backslash style
                            <emphasis role="strong">accountCanonicalForm</emphasis> is used.
                        </entry>
                      </row>
                    </tbody>
                  </tgroup>
                </table>
            </para>

            <note>
                <para>
                    Technically there should be no danger of accidental cross-domain authentication with the current
                    <classname>Zend_Auth_Adapter_Ldap</classname> implementation, since server domains are explicitly checked,
                    but this may not be true of a future implementation that discovers the domain at runtime, or if an
                    alternative adapter is used (e.g., Kerberos). In general, account name ambiguity is known to be the
                    source of security issues, so always try to use qualified account names.
                </para>
            </note>

        </sect3>

        <sect3 id="zend.auth.adapter.ldap.options-common-server-specific.openldap">

            <title>Options for OpenLDAP</title>

            <para>
                For OpenLDAP or a generic LDAP server using a typical posixAccount style schema, the following options
                are noteworthy:

                <table id="zend.auth.adapter.ldap.options-common-server-specific.openldap.table">
                  <title>Options for OpenLDAP</title>
                  <tgroup cols="2">
                    <thead>
                      <row>
                        <entry>Name</entry>
                        <entry>Additional Notes</entry>
                      </row>
                    </thead>
                    <tbody>
                      <row>
                        <entry><emphasis role="strong">host</emphasis></entry>
                        <entry>
                            As with all servers, this option is required.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">useStartTls</emphasis></entry>
                        <entry>
                            For the sake of security, this should be <code>true</code> if the server has the necessary
                            certificate installed.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">useSsl</emphasis></entry>
                        <entry>
                            Possibly used as an alternative to <code>useStartTls</code> (see above).
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">username</emphasis></entry>
                        <entry>
                            Required and must be a DN, as OpenLDAP requires that usernames be in DN form when
                            performing a bind. Try to use an unprivileged account.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">password</emphasis></entry>
                        <entry>
                            The password corresponding to the username above, but this may be omitted if the LDAP
                            server permits an anonymous binding to query user accounts.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">bindRequiresDn</emphasis></entry>
                        <entry>
                            Required and must be <code>true</code>, as OpenLDAP requires that usernames be in DN form
                            when performing a bind.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">baseDn</emphasis></entry>
                        <entry>
                            As with all servers, this option is required and indicates the DN under which all accounts
                            being authenticated are located.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">accountCanonicalForm</emphasis></entry>
                        <entry>
                            Optional, but the default value is 4 (principal style names like
                            <emphasis>alice@foo.net</emphasis>), which may not be ideal if your users are used to
                            backslash style names (e.g., <emphasis>FOO\alice</emphasis>). For backslash style names use
                            value 3.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">accountDomainName</emphasis></entry>
                        <entry>
                            Required unless you're using <emphasis role="strong">accountCanonicalForm</emphasis> 2,
                            which is not recommended.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">accountDomainNameShort</emphasis></entry>
                        <entry>
                            If AD is not also being used, this value is not required. Otherwise, if
                            <emphasis role="strong">accountCanonicalForm</emphasis> 3 is used, this option is required
                            and should be a short name that corresponds adequately to the
                            <emphasis role="strong">accountDomainName</emphasis> (e.g., if your
                            <emphasis role="strong">accountDomainName</emphasis> is
                            <emphasis role="strong">foo.net</emphasis>, a good
                            <emphasis role="strong">accountDomainNameShort</emphasis> value might be
                            <emphasis>FOO</emphasis>).
                        </entry>
                      </row>
                    </tbody>
                  </tgroup>
                </table>

            </para>

        </sect3>

    </sect2>

</sect1>
<!--
vim:se ts=4 sw=4 et:
-->
