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

    <title>LDAP Authentifizierung</title>

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

        <title>Einführung</title>

        <para>
            <classname>Zend_Auth_Adapter_Ldap</classname> unterstützt Webanwendungen bei der
            Authentifizierung mit LDAP Services. Die Features beinhalten Kanonisierung von
            Benutzernamen und Domainnamen, Mehrfach-Domain Authentifizierung, und Fehlerbehandlungs
            Features. Es wurde getestet mit
            <ulink url="http://www.microsoft.com/windowsserver2003/technologies/directory/activedirectory/">Microsoft
            Active Directory</ulink> und <ulink url="http://www.openldap.org/">OpenLDAP</ulink>,
            sollte auch auch mit anderen LDAP Service Provider zusammenarbeiten.
        </para>

        <para>
            Diese Dokumentation enthält eine Anleitung der Verwendung von
            <classname>Zend_Auth_Adapter_Ldap</classname>, eine Beschreibung der API, eine Ausgabe der
            verschiedenen Optionen, Diagnostische Informationen für die Fehlerbehandlung bei
            Authentifizierungs Problemen, und Beispiel Optionen für beide, Active Directory und
            OpenLDAP Server.
        </para>

    </sect2>

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

        <title>Verwendung</title>

        <para>
            Um <classname>Zend_Auth_Adapter_Ldap</classname> Authentifizierung in eigene Anwendungen schnell
            einzubauen, selbst wenn <classname>Zend_Controller</classname> nicht verwendet wird, sollte das
            Fleisch des eigenen Codes in etwa wie folgt aussehen:
            <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] und höher sind Log Nachrichten
            $message = str_replace("\n", "\n  ", $message);
            $logger->log("Ldap: $i: $message", Zend_Log::DEBUG);
        }
    }
}
]]>
            </programlisting>
            Natürlich ist der Logging Code optional, aber es wird dringend empfohlen einen Logger
            zu verwenden. <classname>Zend_Auth_Adapter_Ldap</classname> zeichnet fast jedes Bisschen an
            Information in <code>$messages</code> auf das irgendwer benötigen können (mehr anbei),
            was allerdings selbst ein nettes Feature für jemanden als History ist, kann überaus
            schwierig zu debuggen sein.
        </para>

        <para>
            Der <classname>Zend_Config_Ini</classname> wird oben verwendet um die Optionen des Adapters zu
            laden. Er ist also auch optional. Ein reguläres Array würde genauso gut arbeiten. Das
            folgende ist eine Beispiel <code>application/config/config.ini</code> Datei die
            Optionen für zwei separate Server hat. Mit mehreren Sets von Server Optionen versucht
            der Adapter jede in Reihenfolge bis die Zugangsdaten erfolgreich authentifiziert
            wurden. Die Namen der Server (z.B., <code>server1</code> und <code>server2</code>) sind
            sehr verallgemeinert. Für Details betreffend dem Array für Optionen, siehe das Kapitel
            über <emphasis>Server Optionen</emphasis> weiter unten. Es ist zu beachten das
            <classname>Zend_Config_Ini</classname> jeden Wert der mit Gleichheitszeichen (<code>=</code>)
            geschrieben wird auch unter Anführungszeichen gesetzt wird (wie unten bei DNs gezeigt).
            <programlisting role="ini"><![CDATA[
[production]

ldap.log_path = /tmp/ldap.log

; Typische Optionen für 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

; Typische Optionen für 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>
            Die obige Konfiguration instruiert <classname>Zend_Auth_Adapter_Ldap</classname> das es versuchen
            soll Benutzer zuerst mit dem OpenLDAP Server <code>s0.foo.net</code> authentifizieren
            soll. Wenn die Authentifizierung auf irgendeinem Grund fehlschlägt, wird der AD Server
            <code>dc1.w.net</code> versucht.
        </para>

        <para>
            Mit Servern in verschiedenen Domains, zeigt diese Konfiguration Multi-Domain
            Authentifizierung. Es können auch mehrere Server in der gleichen Domain sein um
            Redundanz anzubieten.
        </para>

        <para>
            In diesem Fall ist zu beachten das, selbst wenn OpenLDAP keine Notwendigkeit für kurze
            NetBIOS Stil Domainnamen hat die von Windows verwendet werden bieten wir Sie hier an
            wegen der Kanonifizierung der Namen (beschrieben im
            <emphasis>Kanonifizierung von Benutzernamen</emphasis> Kapitel anbei).
        </para>

    </sect2>

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

        <title>Die API</title>

        <para>
            Der <classname>Zend_Auth_Adapter_Ldap</classname> Konstruktor akzeptiert drei Parameter.
        </para>

        <para>
            Der <code>$options</code> Parameter wird benötigt und muß ein Array sein das ein oder
            mehrere Sets von Optionen enthält. Es ist zu beachten das es sich um
            <emphasis>Array von Arrays</emphasis> von <link linkend="zend.ldap"><classname>Zend_Ldap</classname></link>
            Optionen handelt. Selbst wenn nur ein einzelner LDAP Server verwendet wird, müssen die
            Optionen trotzdem in einem anderen Array sein.
        </para>

        <para>
            Anbei ist eine <ulink url="http://php.net/print_r"><code>print_r()</code></ulink>
            Ausgabe von beispielhaften Optionsparameters die twei Sets von Serveroptionen für LDAP
            Server enthalten, <code>s0.foo.net</code> und <code>dc1.w.net</code> (die gleichen
            Optionen wie in der oberen INI Repräsentation):
            <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>
            Die oben angebotene Information in jedem Set von Optionen ist hauptsächlich deswegen
            unterschiedlich weil AD keinen Benutzernamen wärend des Bindesn in der DN Form benötigt
            (siehe die <code>bindRequiresDn</code> Option des <emphasis>Server Optionen</emphasis>
            Kapitels weiter unten), was bedeutet das die Anzahl der, mit dem Empfangen der DN, für
            einen Benutzernamen der Authentifiziert werden soll, assoziierten Optionen,
            unterdrückt werden kann.
        </para>

        <note>
            <title>Was ist ein ausgezeichneter Name?</title>
            <para>
                Ein DN oder "distinguished name" ist ein String der den Pfad zu einem Objekt im
                LDAP Verzeichnis repräsentiert. Jede komma-seperierte Komponente ist ein Attribut
                und Wert der einen Node repräsentiert. Die Komponenten werden rückwirkend
                evaluiert. Zum Beispiel ist der Benutzeraccount
                <emphasis>CN=Bob Carter,CN=Users,DC=w,DC=net</emphasis> direkt in
                <emphasis>CN=Users,DC=w,DC=net container</emphasis> enthalten. Diese Struktur wird
                am besten mit einem LDAP Browser wie das ADSI Edit MMC snap-in für Active Directory
                oder phpLDAPadmin erkundet.
            </para>
        </note>

        <para>
            Die Namen von Servern (z.B. '<code>server1</code>' und '<code>server2</code>' wie unten
            gezeigt) sind großteils beliebig, aber aus Gründen der Verwendung von
            <classname>Zend_Config</classname> sollten die Identifikatoren (im Gegensatz dazu das Sie
            nummerische Indezes sind) vorhanden sein, und sollten keine spezielle Zeichen enthalten
            die vom assoziierten Dateiformat verwendet werden (z.B. der '<code>.</code>' INI
            Eigenschafts Separator, '<code>&amp;</code>' für XML Entity Referenzen, usw.).
        </para>

        <para>
            Mit mehreren Sets von Serveroptionen, kann der Adapter Benutzer in mehreren Domains
            authentifizieren und bietet ein Failover damit, wenn ein Server nicht erreichbar ist,
            ein anderer abgefragt wird.
        </para>

        <note>
            <title>Die glorreichen Details: Was passiert bei der Authentifizierungs Methode?</title>
            <para>
                Wenn die <code>authenticate()</code> Methode aufgerufen wird, iteriert der Adapter
                über jedes Set von Serveroptione, setzt diese auf der internen
                <classname>Zend_Ldap</classname> Instanz und ruft die <classname>Zend_Ldap::bind()</classname> Methode,
                mit dem Benutzernamen und Passwort das authentifiziert werden soll, auf. Die
                <classname>Zend_Ldap</classname> Klasse prüft um zu sehen ob der Benutzer mit einer Domain
                qualifiziert ist (hat z.B. eine Domainkomponente wie
                <emphasis>alice@foo.net</emphasis> oder <emphasis>FOO\alice</emphasis>). Wenn eine
                Domain vorhanden ist, aber mit keiner der Domainnamen der Server
                (<emphasis>foo.net</emphasis> oder <emphasis>FOO</emphasis>) übereinstimmt, wird
                eine spezielle Ausnahme geworfen und durch <classname>Zend_Auth_Adapter_Ldap</classname>
                gefangen, was bewirkt das der Server ignoriert wird und der nächste, in den
                Serveroptionen gesetzte Server, ausgewählt wird. Wenn eine Domain
                <emphasis>doch</emphasis> passt, oder der Benutzer keinen qualifizierten
                Benutzernamen angegeben hat, fährt <classname>Zend_Ldap</classname> weiter fort und versucht
                mit den angegebenen Zugangsdaten zu binden. Wenn das Binden nicht erfolgreich war
                wirft <classname>Zend_Ldap</classname> eine <classname>Zend_Ldap_Exception</classname> welche durch
                <classname>Zend_Auth_Adapter_Ldap</classname> gefangen wird, und das nächste Ser von
                Serveroptionen wird versucht. Wenn das Binden erfolgreich war, wird die Iteration
                gestoppt, und die <code>authenticate()</code> Methode des Adapters gibt ein
                erfolgreiches Ergebnis zurück. Wenn alle Serveroptionen ohne erfolg durchprobiert
                wurden, schlägt die Authentifizierung fehl, und <code>authenticate()</code> gibt
                ein Fehlerergebnis zurück mit der Fehlermeldung der letzten Iteration.
            </para>
        </note>

        <para>
            Die username und password Parameter des <classname>Zend_Auth_Adapter_Ldap</classname>
            Konstruktors repräsentieren die Zugangsdaten die authentifiziert werden sollen (z.B.
            die Zugangsdaten die durch den Benutzer über eine HTML Login Form angegeben werden).
            Alternativ können Sie auch mit den <code>setUsername()</code> und
            <code>setPassword()</code> Methoden gesetzt werden.
        </para>

    </sect2>

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

        <title>Server Optionen</title>

        <para>
            Jedes Set von Serveroptionen <emphasis>im Kontext von <classname>Zend_Auth_Adapter_Ldap</classname></emphasis>
            besteht aus den folgenden Optionen welche, großteils ungeändert, an
            <classname>Zend_Ldap::setOptions()</classname> übergeben werden:

            <table id="zend.auth.adapter.ldap.server-options.table">
              <title>Server Optionen</title>
              <tgroup cols="2">
                <thead>
                  <row>
                    <entry>Name</entry>
                    <entry>Beschreibung</entry>
                  </row>
                </thead>
                <tbody>
                  <row>
                    <entry><emphasis role="strong">host</emphasis></entry>
                    <entry>
                        Der Hostname des LDAP Servers der diese Optionen repräsentiert. Diese
                        Option wird benötigt.
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">port</emphasis></entry>
                    <entry>
                        Der Port auf den der LDAP Server schaut. Wenn
                        <emphasis role="strong">useSsl</emphasis> <code>true</code> ist, ist der
                        Standardwert von <emphasis role="strong">port</emphasis> 636. Wenn
                        <emphasis role="strong">useSsl</emphasis> <code>false</code> ist, ist der
                        Standardwert von <emphasis role="strong">port</emphasis> 389.
                    </entry>
                  </row>
                  <row>
                    <entry>useStartTls</entry>
                    <entry>
                        Ob der LDAP Client einen TSL (aka SSLv2) verschlüsselten Transport verwenden soll
                        oder nicht. Der Wert <code>true</code> wird in einer Produktionsumgebung strengstens
                        empfohlen um zu verhindern das Passwörter im Klartext übertragen werden. Der
                        Standardwert ist <code>false</code>, da Server typischerweise nach deren Installation
                        erwarten das ein Zertifikat installiert wird. Die <code>useSsl</code> und
                        <code>useStartTls</code> Optionen schließen sich gegenseitig aus. Die
                        <code>useStartTls</code> Option sollte über <code>useSsl</code> favorisiert werden,
                        aber nicht alle Server unterstützen diesen neueren Mechanismus.
                    </entry>
                  </row>
                  <row>
                    <entry>useSsl</entry>
                    <entry>
                        Ob der LDAP Client einen SSL verschlüsselten Transport verwenden soll. Die
                        <code>useSsl</code> und <code>useStartTls</code> Optionen schließen sich gegenseitig
                        aus, aber <code>useStartTls</code> sollte favorisiert werden wenn der Server und die
                        LDAP Bibliothek des Clients diese unterstützen. Dieser Wert ändert auch den
                        Standardwert von <emphasis role="strong">port</emphasis> (siehe die
                        <emphasis role="strong">port</emphasis> Beschreibung weiter oben).
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">username</emphasis></entry>
                    <entry>
                        Der DN des Accounts der verwendet wird um DN Account Loopups durchzuführen.
                        LDAP Server die den Benutzernamen in in DN Form benötigenwenn "bind"
                        durchgeführt wird, benötigen diese Option. Wenn
                        <emphasis role="strong">bindRequiresDn</emphasis> <code>true</code> ist,
                        wird diese Option benötigt. Dieser Account muß kein privilegierter Account
                        sein - ein Account mit nur-lese Zugriff zu Objekten unter
                        <emphasis role="strong">baseDn</emphasis> ist alles was notwendig ist
                        (und bevorzugt unter dem <emphasis>Prinzip des geringsten
                        Privilegs</emphasis>).
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">password</emphasis></entry>
                    <entry>
                        Das Passwort des Accounts der verwendet wird um DN Lookups durchzuführen.
                        Wenn diese Option nicht unterstützt wird, versucht der LDAP Client einen
                        "anonymen bind" wenn DN Lookups durchgeführt werden.
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">bindRequiresDn</emphasis></entry>
                    <entry>
                        Einige LDAP Server benötigen den zum Binden verwendeten Benutzernamen in
                        der DN Form wie <emphasis>CN=Alice Baker,OU=Sales,DC=foo,DC=net</emphasis>
                        (grundsätzlich alle Server <emphasis>außer</emphasis> AD). Wenn diese
                        Option <code>true</code> ist, instuiert dies <classname>Zend_Ldap</classname> das der
                        DN automatisch empfangen wird, abhängig vom Benutzernamen der
                        authentifiziert wird, wenn er nicht bereits in DN Form ist, und diesen dann
                        wieder mit der richtigen DN zu binden. Der Standardwert ist
                        <code>false</code>. Aktuell ist nur von Microsoft Active Directory Server
                        (ADS) bekannt das es den Benutzernamen <emphasis>nicht</emphasis> in der DN
                        Form benötigt wenn gebunden wird, und deswegen kann diese Option mit AD
                        auch <code>false</code> sein (und sollte das auch, da das Empfangen des DN
                        eine extra Anfrage zum Server benötigt). Andernfalls muß diese Option auf
                        <code>true</code> gesetzt werden (z.B. für OpenLDAP). Diese Option
                        kontrolliert das Standard
                        <emphasis role="strong">acountFilterFormat</emphasis> das verwendet wird
                        wenn nach Accounts gesucht wird. Siehe auch die
                        <emphasis role="strong">accountFilterFormat</emphasis> Option.
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">baseDn</emphasis></entry>
                    <entry>
                        Der Ort vom DN unter dem alle Accounts die authentifiziert werden. Diese
                        Option wird benötigt. Wenn man sich unsicher über den richtigen
                        <emphasis role="strong">baseDn</emphasis> ist, sollte es genug sein Ihn von
                        der DNS Domain des Benutzers der die <emphasis>DC=</emphasis> Komponenten
                        verwedet abzuleiten. Wenn der Hauptname eines Benutzers
                        <emphasis>alice@foo.net</emphasis> ist, sollte ein
                        <emphasis role="strong">baseDn</emphasis> von
                        <emphasis>DC=foo,DC=net</emphasis> funktionieren. Eine präzisere Ortsangabe
                        (z.B. <emphasis>OU=Sales,DC=foo,DC=net</emphasis>) ist trotzdem
                        effizienter.
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">accountCanonicalForm</emphasis></entry>
                    <entry>
                        Ein Wert von 2, 3 oder 4 zeigt die Form zu der Account Namen authorisiert
                        werden sollten nachdem die Authentifizierung erfolgreich war. Die Werte
                        sind wie folgt: 2 für traditionelle Benutzernamen-Stil Namen
                        (z.B., <emphasis>alice</emphasis>), 3 für Schrägstrich-Stil Namen (z.B.,
                        <emphasis>FOO\alice</emphasis>) oder 4 für Authentifiziert-Sil Namen (z.B.,
                        <emphasis>alice@foo.net</emphasis>). Der Standardwert ist 4 (z.B.,
                        <emphasis>alice@foo.net</emphasis>). Mit einem Wert von 3, z.B., wird die
                        Identität die von <classname>Zend_Auth_Result::getIdentity()</classname>
                        zurückgegeben wird (und <classname>Zend_Auth::getIdentity()</classname>, wenn
                        <classname>Zend_Auth</classname> verwendet wird), immer
                        <emphasis>FOO\alice</emphasis> sein, unabhängig von der Form in der Alice
                        angegeben wurde, egal ob es <emphasis>alice</emphasis>,
                        <emphasis>alice@foo.net</emphasis>, <emphasis>FOO\alice</emphasis>,
                        <emphasis>FoO\aLicE</emphasis>, <emphasis>foo.net\alice</emphasis>, etc.
                        Siehe das Kapitel <emphasis>Kanonisierung von Account Namen</emphasis>
                        in der <classname>Zend_Ldap</classname> Dokumentation für Details. Bei der
                        Verwendung von mehreren Sets von Serveroptionen ist es empfehlenswert,
                        aber nicht notwendig, das die selbe
                        <emphasis role="strong">accountCanonicalForm</emphasis> in allen
                        Serveroptionen verwendet wird, sodas die sich ergebenden Benutzernamen
                        immer auf die selbe Art und Weise kanonisiert werden (z.b. wenn man auf
                        <emphasis>EXAMPLE\username</emphasis> mit einem AD Server kanonisiert, aber
                        zu <emphasis>username@example.com</emphasis> mit einem OpenLDAP Server,
                        kann das quirks für die High-Level Logik einer Anwendung sein).
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">accountDomainName</emphasis></entry>
                    <entry>
                        Der FDQN Domainname für welchen der Ziel LDAP Server eine Authorität ist
                        (z.B., <code>example.com</code>). Diese Option wird verwendet um Namen zu
                        kanonisieren sodas der Benutzername der vom Benutzer angeboten wird, wie es
                        für das Binden notwendig ist, konvertiert werden kann. Ere wird auch
                        verwendet um festzustellen ob der Server eine Authorität für den
                        angegebenen Benutzernamen ist (z.B., wenn
                        <emphasis role="strong">accountDomainName</emphasis>
                        <emphasis>foo.net</emphasis> ist und der angegebene Benutzer
                        <emphasis>bob@bar.net</emphasis>, wird der Server nicht abgefragt, und das
                        Ergebnis wird ein Fehler sein). Diese Option wird nicht benötigt, aber wenn
                        Sie nicht angegeben wird, dann werden Benutzernamen in prinzipieller
                        Namensform (z.B., <emphasis>alice@foo.net</emphasis>) nicht unterstützt. Es
                        wird stark empfohlen das diese Option angegeben wird, da es viele
                        Anwendungsfälle gibt die die Erstellung von prinzipieller Namensform
                        benötigen.
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">accountDomainNameShort</emphasis></entry>
                    <entry>
                        Die 'short' Domain für die der Ziel LDAP Server eine Authorität ist (z.B.,
                        <emphasis>FOO</emphasis>). Es ist z ubeachten das es ein 1:1 Mapping
                        zwischen <emphasis role="strong">accountDomainName</emphasis> und
                        <emphasis role="strong">accountDomainNameShort</emphasis> existiert. Diese
                        Option sollte verwendet werden um den NetBIOS Domainnamen für Windows
                        Netzwerke zu spezifizieren, kann aber auch von nicht-AD Servern verwendet
                        werden (z.B., für Konsistenz bei mehreren Sets von Serveroptionen bei dem
                        Schrägstrich Stil <emphasis role="strong">accountCanonicalForm</emphasis>).
                        Diese Option wird nicht benötigt, aber wenn Sie nicht angegeben wird,
                        werden Benutzernamen im Schrägstrich Stil (z.B.
                        <emphasis>FOO\alice</emphasis>) nicht unterstützt.
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">accountFilterFormat</emphasis></entry>
                    <entry>
                        Der LDAP Suchfilter der für die Suche nach Accounts verwendet wird. Dieser
                        String ist ein
                        <ulink url="http://php.net/printf"><code>printf()</code></ulink>-Stil
                        Ausdruck der ein '<code>%s</code>' enthalten muß um den Benutzernamen
                        unterzubringen. Der Standardwert ist
                        '<code>(&amp;(objectClass=user)(sAMAccountName=%s))</code>', ausgenommen
                        <emphasis role="strong">bindRequiresDn</emphasis> wird auf
                        <code>true</code> gesetzt. In diesem Fall ist der Standardwert
                        '<code>(&amp;(objectClass=posixAccount)(uid=%s))</code>'. Wenn, zum
                        Beispiel, aus irgendeinem Grund <code>bindRequiresDn = true</code> mti AD
                        verwendet werden soll, muß
                        <code>accountFilterFormat = '(&amp;(objectClass=user)(sAMAccountName=%s))</code>'
                        gesetzt werden.
                    </entry>
                  </row>
                  <row>
                    <entry><emphasis role="strong">optReferrals</emphasis></entry>
                    <entry>
                        Wenn sie auf <code>true</code> gesetzt wird, zeigt diese Option dem LDAP Client an,
                        das Referenzen gefolgt werden soll. Der Standardwert ist <code>false</code>.
                    </entry>
                  </row>
                </tbody>
              </tgroup>
            </table>
        </para>

        <note>
            <para>
                Wenn <code>useStartTls = true</code> oder <code>useSsl = true</code> aktiviert ist,
                erzeugt der LDAP Client einen Fehler
                der aussagt das er das Zertifikat des Servers nicht überprüfen kann. Angenommen die
                PHP LDAP Erweiterung ist ultimativ verlinkt mit der OpenLDAP Client Bibliothek, muß
                man um dieses Problem zu lösen "<code>TLS_REQCERT niemals</code>" im OpenLDAP
                Client <code>ldap.conf</code> setzen (und den Web Server restarten) um der OpenLDAP
                Client Bibliothek anzuzeigen das man dem Server vertraut. Alternativ, wenn man
                annimmt das der Server gehackt werden könnte kann das Basiszertifikat des LDAP
                Servers exportiert und auf den Webserver gegeben werdensodas der OpenLDAP Client
                die Identität des Servers prüfen kann.
            </para>
        </note>

    </sect2>

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

        <title>Debug Nachrichten sammeln</title>

        <para>
            <classname>Zend_Auth_Adapter_Ldap</classname> sammelt Debug Informationen in seiner
            <code>authenticate()</code> Methode. Diese Information wird im
            <classname>Zend_Auth_Result</classname> Objekt als Nachrichten gespeichert. Das von
            <classname>Zend_Auth_Result::getMessages()</classname> zurückgegebene Array kann wie folgt
            beschrieben werden:

            <table id="zend.auth.adapter.ldap.debugging.table">
              <title>Debug Nachrichten</title>
              <tgroup cols="2">
                <thead>
                  <row>
                    <entry>Array Index der Nachricht</entry>
                    <entry>Beschreibung</entry>
                  </row>
                </thead>
                <tbody>
                  <row>
                    <entry>Index 0</entry>
                    <entry>
                        Eine generelle, Benutzerfreundliche Meldung die für die Anzeige für
                        Benutzer passt (z.B. "Ungültige Anmeldedaten"). Wenn die Authentifizierung
                        erfolgreich ist, dann ist dieser String leer.
                    </entry>
                  </row>
                  <row>
                    <entry>Index 1</entry>
                    <entry>
                        Eine detailiertere Fehlermeldung die nicht für die Anzeige für Benutzer
                        hergenommen werden kann, die aber mitgeloggt werden sollte zum Vorteil des
                        Server Operators. Wenn die Authentifizierung erfolgreich war, ist dieser
                        String leer.
                    </entry>
                  </row>
                  <row>
                    <entry>Indezes 2 und höher</entry>
                    <entry>
                        Alle Logmeldungen in Reihenfolge starten bei Index 2.
                    </entry>
                  </row>
                </tbody>
              </tgroup>
            </table>

            Aus der Praxis heraus sollte der Index 0 dem Benutzer angezeigt werden (z.B. bei
            Verwendung des FlashMessenger Helfers), Index 1 sollte geloggt werden und, wenn die
            Debugging Information gesammelt wird, sollten die Indezes 2 und höher auch geloggt
            werden (auch wenn die letzte Nachricht immer den String vom Index 1 enthält).
        </para>

    </sect2>

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

        <title>Übliche Optionen für spezielle Server</title>

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

            <title>Optionen für Active Directory</title>

            <para>
                Für ADS sind die folgenden Optionen beachtenswert:

                <table id="zend.auth.adapter.ldap.options-common-server-specific.active-directory.table">
                  <title>Optionen für Active Directory</title>
                  <tgroup cols="2">
                    <thead>
                      <row>
                        <entry>Name</entry>
                        <entry>Zusätzliche Notizen</entry>
                      </row>
                    </thead>
                    <tbody>
                      <row>
                        <entry><emphasis role="strong">host</emphasis></entry>
                        <entry>
                            Wie bei allen Servern, wird diese Option benötigt.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">useStartTls</emphasis></entry>
                        <entry>
                            Zum Zwecke der Sicherheit, sollte das <code>true</code> sein wenn der
                            Server das notwendige Zertifikat installiert hat.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">useSsl</emphasis></entry>
                        <entry>
                            Möglicherweise als Alternative zu <code>useStartTls</code> zu verwenden (siehe davor).
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">baseDn</emphasis></entry>
                        <entry>
                            Wie bei allen Servern, wird diese Option benötigt. Standardmäßig
                            platziert AD alle Benutzer Accounts unter dem
                            <emphasis>Users</emphasis> Container (z.B.,
                            <emphasis>CN=Users,DC=foo,DC=net</emphasis>), aber der Standard ist in
                            größeren Organisationen nicht üblich. Der AD Administrator sollte nach
                            der besten DN für Accounts für die eigene Anwendung gefragt werden.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">accountCanonicalForm</emphasis></entry>
                        <entry>
                            Das wird man normalerweise für Schrägstrich-Stil Namen auf 3 stellen
                            (z.B., <emphasis>FOO\alice</emphasis>), was für Windows Benutzer am
                            bekanntesten ist. Man sollte <emphasis>nicht</emphasis> die
                            unqualifizierte Form 2 verwenden (z.B., <emphasis>alice</emphasis>),
                            da das anderen Benutzern Zugriff auf die Anwendung geben würde, wenn
                            Sie den gleichen Benutzernamen in anderen vertrauten Domains haben
                            (z.B., <emphasis>BAR\alice</emphasis> und
                            <emphasis>FOO\alice</emphasis> würden als der gleiche Benutzer
                            behandelt). (siehe auch die Notiz anbei.)
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">accountDomainName</emphasis></entry>
                        <entry>
                            Das wird mit AD benötigt, ausser
                            <emphasis role="strong">accountCanonicalForm</emphasis> 2 wird
                            verwendet, was wiederum nicht eingesetzt werden sollte.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">accountDomainNameShort</emphasis></entry>
                        <entry>
                            Der NetBIOS Name der Domain in der die Benutzer sind und für den der AD
                            Server die Authorität ist. Das wird benötigt wenn der Schrägstrich-Stil
                            <emphasis role="strong">accountCanonicalForm</emphasis> verwendet wird.
                        </entry>
                      </row>
                    </tbody>
                  </tgroup>
                </table>
            </para>

            <note>
                <para>
                    Technisch sollte es keine Probleme mit irrtümlichen Domain-übergreifenden
                    Authentifizierungen mit der aktuellen <classname>Zend_Auth_Adapter_Ldap</classname>
                    Implementation geben, da Serverdomains explizit geprüft werden, aber das muss
                    für zukünftige Implementationen, die die Domain wärend der Laufzeit ermitteln,
                    nicht wahr sein, oder auch wenn ein alternativer Adapter verwendet wird (z.B.,
                    Kerberos). Generell ist bekannt das die Mehrdeutigkeit von Accountnamen ein
                    Sicherheitsproblem ist. Man sollte deswegen immer versuchen qualifizierte
                    Accountnamen zu verwenden.
                </para>
            </note>

        </sect3>

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

            <title>Optionen für OpenLDAP</title>

            <para>
                Für OpenLDAP oder einen generellen LDAP Server der ein typisches posixAccount
                Stil Schema verwendet sind die folgenden Optionen beachtenswert:

                <table id="zend.auth.adapter.ldap.options-common-server-specific.openldap.table">
                  <title>Optionen für OpenLDAP</title>
                  <tgroup cols="2">
                    <thead>
                      <row>
                        <entry>Name</entry>
                        <entry>Zusätzliche Notizen</entry>
                      </row>
                    </thead>
                    <tbody>
                      <row>
                        <entry><emphasis role="strong">host</emphasis></entry>
                        <entry>
                            Wie bei allen Servern, wird diese Option benötigt.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">useStartTls</emphasis></entry>
                        <entry>
                            Zum Zwecke der Sicherheit, sollte das <code>true</code> sein wenn der
                            Server das notwendige Zertifikat installiert hat.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">useSsl</emphasis></entry>
                        <entry>
                            Möglicherweise als Alternative zu <code>useStartTls</code> zu verwenden (siehe davor).
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">username</emphasis></entry>
                        <entry>
                            Benötigt und muß ein DN sein, da OpenLDAP den Benutzernamen in DN Form
                            benötigt wenn ein Binden durchgeführt wird. Es sollte versucht werden
                            einen nicht privelegierten Account zu verwenden.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">password</emphasis></entry>
                        <entry>
                            Das Passwort das zum Benutzernamen von oben gehört. Es kann aber
                            unterdrückt werden wenn der LDAP Server anonymes Binden bei Abfragen zu
                            Benutzer Accounts erlaubt.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">bindRequiresDn</emphasis></entry>
                        <entry>
                            Benötigt und muß <code>true</code> sein, da OpenLDAP den Benutzernamen
                            in DN Form benötigt wenn ein Binden durchgeführt wird.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">baseDn</emphasis></entry>
                        <entry>
                            Wie bei allen Servern, wird diese Option benötigt und zeigt den DN in
                            dem alle Accounts die authentifiziert werden enthalten sind.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">accountCanonicalForm</emphasis></entry>
                        <entry>
                            Optional, aber der Standardwert ist 4 (prinzipielle-Stil Namen wie
                            <emphasis>alice@foo.net</emphasis>) und könnte für die Benutzer nicht
                            ideal sein wenn diese Schrägstrich-Stil Namen verwendetn (z.B.,
                            <emphasis>FOO\alice</emphasis>). Für Schrägstrich-Stil Namen sollte der
                            Wert 3 verwendet werden.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">accountDomainName</emphasis></entry>
                        <entry>
                            Benötigt es sei denn man verwendet
                            <emphasis role="strong">accountCanonicalForm</emphasis> 2, was nicht
                            zu empfehlen ist.
                        </entry>
                      </row>
                      <row>
                        <entry><emphasis role="strong">accountDomainNameShort</emphasis></entry>
                        <entry>
                            Wenn AD auch nicht verwendet wird, wird dieser Wert nicht benötigt.
                            Andernfalls, wenn
                            <emphasis role="strong">accountCanonicalForm</emphasis> 3 verwendet
                            wird, wird diese Option benötigt und sollte ein Kurzname sein der
                            adäquat zu <emphasis role="strong">accountDomainName</emphasis>
                            korrespondiert (z.B., wenn
                            <emphasis role="strong">accountDomainName</emphasis>
                            <emphasis role="strong">foo.net</emphasis> ist, wäre ein guter
                            <emphasis role="strong">accountDomainNameShort</emphasis> Wert
                            <emphasis>FOO</emphasis>).
                        </entry>
                      </row>
                    </tbody>
                  </tgroup>
                </table>

            </para>

        </sect3>

    </sect2>

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