|
@@ -2,31 +2,55 @@
|
|
|
<!-- Reviewed: no -->
|
|
<!-- Reviewed: no -->
|
|
|
<sect1 id="zend.ldap.introduction">
|
|
<sect1 id="zend.ldap.introduction">
|
|
|
<title>Introduction</title>
|
|
<title>Introduction</title>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- <code>Zend_Ldap</code> is a class for performing LDAP operations including but not limited to binding,
|
|
|
|
|
- searching and modifying entries in an LDAP directory.
|
|
|
|
|
|
|
+ <classname>Zend_Ldap</classname> is a class for performing <acronym>LDAP</acronym>
|
|
|
|
|
+ operations including but not limited to binding, searching and modifying entries
|
|
|
|
|
+ in an <acronym>LDAP</acronym> directory.
|
|
|
</para>
|
|
</para>
|
|
|
|
|
+
|
|
|
<sect2 id="zend.ldap.introduction.theory-of-operations">
|
|
<sect2 id="zend.ldap.introduction.theory-of-operations">
|
|
|
<title>Theory of operation</title>
|
|
<title>Theory of operation</title>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- This component currently consists of the main <code>Zend_Ldap</code> class, that conceptually represents a binding to a
|
|
|
|
|
- single LDAP server and allows for executing operations against a LDAP server such as OpenLDAP or ActiveDirectory (AD) servers. The parameters for binding may be provided explicitly or in the form of an options array. <code>Zend_Ldap_Node</code> provides an object-oriented interface for single LDAP nodes and can be used to form a basis for an active-record-like interface for a LDAP-based domain model.
|
|
|
|
|
|
|
+ This component currently consists of the main <classname>Zend_Ldap</classname> class,
|
|
|
|
|
+ that conceptually represents a binding to a single <acronym>LDAP</acronym> server
|
|
|
|
|
+ and allows for executing operations against a <acronym>LDAP</acronym> server such
|
|
|
|
|
+ as OpenLDAP or ActiveDirectory (AD) servers. The parameters for binding may be
|
|
|
|
|
+ provided explicitly or in the form of an options array.
|
|
|
|
|
+ <classname>Zend_Ldap_Node</classname> provides an object-oriented interface
|
|
|
|
|
+ for single <acronym>LDAP</acronym> nodes and can be used to form a basis for an
|
|
|
|
|
+ active-record-like interface for a <acronym>LDAP</acronym>-based domain model.
|
|
|
</para>
|
|
</para>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- The component provides several helper classes to perform operations on LDAP entries (<code>Zend_Ldap_Attribute</code>) such as setting and retrieving attributes (date values, passwords, boolean values, ...), to create and modifiy LDAP filter strings (<code>Zend_Ldap_Filter</code>) and to manipulate LDAP distinguished names (DN) (<code>Zend_Ldap_Dn</code>).
|
|
|
|
|
|
|
+ The component provides several helper classes to perform operations on
|
|
|
|
|
+ <acronym>LDAP</acronym> entries (<classname>Zend_Ldap_Attribute</classname>) such as
|
|
|
|
|
+ setting and retrieving attributes (date values, passwords, boolean values, ...), to
|
|
|
|
|
+ create and modifiy <acronym>LDAP</acronym> filter strings
|
|
|
|
|
+ (<classname>Zend_Ldap_Filter</classname>) and to manipulate <acronym>LDAP</acronym>
|
|
|
|
|
+ distinguished names (DN) (<classname>Zend_Ldap_Dn</classname>).
|
|
|
</para>
|
|
</para>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- Additionally the component abstracts LDAP schema browsing for OpenLDAP and ActiveDirectoy servers <code>Zend_Ldap_Node_Schema</code> and server information retrieval for OpenLDAP-, ActiveDirectory- and Novell eDirectory servers (<code>Zend_Ldap_Node_RootDse</code>).
|
|
|
|
|
|
|
+ Additionally the component abstracts <acronym>LDAP</acronym> schema browsing
|
|
|
|
|
+ for OpenLDAP and ActiveDirectoy servers <classname>Zend_Ldap_Node_Schema</classname>
|
|
|
|
|
+ and server information retrieval for OpenLDAP-, ActiveDirectory- and Novell
|
|
|
|
|
+ eDirectory servers (<classname>Zend_Ldap_Node_RootDse</classname>).
|
|
|
</para>
|
|
</para>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- Using the <code>Zend_Ldap</code> class depends on the type of LDAP server and is best summarized with some
|
|
|
|
|
- simple examples.
|
|
|
|
|
|
|
+ Using the <classname>Zend_Ldap</classname> class depends on the type of
|
|
|
|
|
+ <acronym>LDAP</acronym> server and is best summarized with some simple examples.
|
|
|
</para>
|
|
</para>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- If you are using OpenLDAP, a simple example looks like the following (note that the
|
|
|
|
|
- <code>bindRequiresDn</code> option is important if you are <emphasis>not</emphasis> using AD):
|
|
|
|
|
-<example>
|
|
|
|
|
- <programlisting role="php"><![CDATA[
|
|
|
|
|
|
|
+ If you are using OpenLDAP, a simple example looks like the following
|
|
|
|
|
+ (note that the <emphasis>bindRequiresDn</emphasis> option is important if you are
|
|
|
|
|
+ <emphasis>not</emphasis> using AD):
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$options = array(
|
|
$options = array(
|
|
|
'host' => 's0.foo.net',
|
|
'host' => 's0.foo.net',
|
|
|
'username' => 'CN=user1,DC=foo,DC=net',
|
|
'username' => 'CN=user1,DC=foo,DC=net',
|
|
@@ -40,12 +64,12 @@ $acctname = $ldap->getCanonicalAccountName('abaker',
|
|
|
Zend_Ldap::ACCTNAME_FORM_DN);
|
|
Zend_Ldap::ACCTNAME_FORM_DN);
|
|
|
echo "$acctname\n";
|
|
echo "$acctname\n";
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
-</example>
|
|
|
|
|
- </para>
|
|
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
If you are using Microsoft AD a simple example is:
|
|
If you are using Microsoft AD a simple example is:
|
|
|
-<example>
|
|
|
|
|
- <programlisting role="php"><![CDATA[
|
|
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$options = array(
|
|
$options = array(
|
|
|
'host' => 'dc1.w.net',
|
|
'host' => 'dc1.w.net',
|
|
|
'useStartTls' => true,
|
|
'useStartTls' => true,
|
|
@@ -60,30 +84,38 @@ $acctname = $ldap->getCanonicalAccountName('bcarter',
|
|
|
Zend_Ldap::ACCTNAME_FORM_DN);
|
|
Zend_Ldap::ACCTNAME_FORM_DN);
|
|
|
echo "$acctname\n";
|
|
echo "$acctname\n";
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
-</example>
|
|
|
|
|
- Note that we use the <code>getCanonicalAccountName()</code> method to retrieve the account DN here only
|
|
|
|
|
- because that is what exercises the most of what little code is currently present in this class.
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Note that we use the <methodname>getCanonicalAccountName()</methodname> method
|
|
|
|
|
+ to retrieve the account DN here only because that is what exercises the
|
|
|
|
|
+ most of what little code is currently present in this class.
|
|
|
</para>
|
|
</para>
|
|
|
|
|
+
|
|
|
<sect3 id="zend.ldap.introduction.theory-of-operations.automatic-username-canonicalization">
|
|
<sect3 id="zend.ldap.introduction.theory-of-operations.automatic-username-canonicalization">
|
|
|
<title>Automatic Username Canonicalization When Binding</title>
|
|
<title>Automatic Username Canonicalization When Binding</title>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- If <code>bind()</code> is called with a non-DN username but <code>bindRequiresDN</code> is
|
|
|
|
|
- <code>true</code> and no username in DN form was supplied as an option, the bind will fail. However, if
|
|
|
|
|
- a username in DN form is supplied in the options array, <code>Zend_Ldap</code> will first bind with
|
|
|
|
|
- that username, retrieve the account DN for the username supplied to <code>bind()</code> and then re-
|
|
|
|
|
- bind with that DN.
|
|
|
|
|
|
|
+ If <methodname>bind()</methodname> is called with a non-DN username but
|
|
|
|
|
+ <emphasis>bindRequiresDN</emphasis> is <constant>TRUE</constant> and no username in
|
|
|
|
|
+ DN form was supplied as an option, the bind will fail. However, if a username in DN
|
|
|
|
|
+ form is supplied in the options array, <classname>Zend_Ldap</classname> will
|
|
|
|
|
+ first bind with that username, retrieve the account DN for the username
|
|
|
|
|
+ supplied to <methodname>bind()</methodname> and then re-bind with that DN.
|
|
|
</para>
|
|
</para>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- This behavior is critical to <link linkend="zend.auth.adapter.ldap">
|
|
|
|
|
- <code>Zend_Auth_Adapter_Ldap</code>
|
|
|
|
|
- </link>, which passes the username supplied by
|
|
|
|
|
- the user directly to <code>bind()</code>.
|
|
|
|
|
|
|
+ This behavior is critical to <link
|
|
|
|
|
+ linkend="zend.auth.adapter.ldap"><classname>Zend_Auth_Adapter_Ldap</classname></link>,
|
|
|
|
|
+ which passes the username supplied by the user directly to
|
|
|
|
|
+ <methodname>bind()</methodname>.
|
|
|
</para>
|
|
</para>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- The following example illustrates how the non-DN username '<code>abaker</code>' can be used with
|
|
|
|
|
- <code>bind()</code>:
|
|
|
|
|
-<example>
|
|
|
|
|
- <programlisting role="php"><![CDATA[
|
|
|
|
|
|
|
+ The following example illustrates how the non-DN username
|
|
|
|
|
+ '<emphasis>abaker</emphasis>' can be used with <methodname>bind()</methodname>:
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$options = array(
|
|
$options = array(
|
|
|
'host' => 's0.foo.net',
|
|
'host' => 's0.foo.net',
|
|
|
'username' => 'CN=user1,DC=foo,DC=net',
|
|
'username' => 'CN=user1,DC=foo,DC=net',
|
|
@@ -98,96 +130,116 @@ $acctname = $ldap->getCanonicalAccountName('abaker',
|
|
|
Zend_Ldap::ACCTNAME_FORM_DN);
|
|
Zend_Ldap::ACCTNAME_FORM_DN);
|
|
|
echo "$acctname\n";
|
|
echo "$acctname\n";
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
-</example>
|
|
|
|
|
- The <code>bind()</code> call in this example sees that the username '<code>abaker</code>' is not in DN
|
|
|
|
|
- form, finds <code>bindRequiresDn</code> is <code>true</code>, uses
|
|
|
|
|
- '<code>CN=user1,DC=foo,DC=net</code>' and '<code>pass1</code>' to bind, retrieves the DN for
|
|
|
|
|
- '<code>abaker</code>', unbinds and then rebinds with the newly discovered
|
|
|
|
|
- '<code>CN=Alice Baker,OU=Sales,DC=foo,DC=net</code>'.
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ The <methodname>bind()</methodname> call in this example sees that
|
|
|
|
|
+ the username '<emphasis>abaker</emphasis>' is not in DN form, finds
|
|
|
|
|
+ <emphasis>bindRequiresDn</emphasis> is <constant>TRUE</constant>, uses
|
|
|
|
|
+ '<command>CN=user1,DC=foo,DC=net</command>' and '<emphasis>pass1</emphasis>' to
|
|
|
|
|
+ bind, retrieves the DN for '<emphasis>abaker</emphasis>', unbinds and then rebinds
|
|
|
|
|
+ with the newly discovered
|
|
|
|
|
+ '<command>CN=Alice Baker,OU=Sales,DC=foo,DC=net</command>'.
|
|
|
</para>
|
|
</para>
|
|
|
</sect3>
|
|
</sect3>
|
|
|
|
|
+
|
|
|
<sect3 id="zend.ldap.introduction.theory-of-operations.account-name-canonicalization">
|
|
<sect3 id="zend.ldap.introduction.theory-of-operations.account-name-canonicalization">
|
|
|
<title>Account Name Canonicalization</title>
|
|
<title>Account Name Canonicalization</title>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- The <code>accountDomainName</code> and <code>accountDomainNameShort</code> options are used for two
|
|
|
|
|
- purposes: (1) they facilitate multi-domain authentication and failover capability, and (2) they are
|
|
|
|
|
- also used to canonicalize usernames. Specifically, names are canonicalized to the form specified by the
|
|
|
|
|
- <code>accountCanonicalForm</code> option. This option may one of the following values:
|
|
|
|
|
-
|
|
|
|
|
- <table id="zend.ldap.using.theory-of-operation.account-name-canonicalization.table">
|
|
|
|
|
- <title>Options for <code>accountCanonicalForm</code>
|
|
|
|
|
- </title>
|
|
|
|
|
- <tgroup cols="3">
|
|
|
|
|
- <thead>
|
|
|
|
|
- <row>
|
|
|
|
|
- <entry>Name</entry>
|
|
|
|
|
- <entry>Value</entry>
|
|
|
|
|
- <entry>Example</entry>
|
|
|
|
|
- </row>
|
|
|
|
|
- </thead>
|
|
|
|
|
- <tbody>
|
|
|
|
|
- <row>
|
|
|
|
|
- <entry>
|
|
|
|
|
- <code>ACCTNAME_FORM_DN</code>
|
|
|
|
|
- </entry>
|
|
|
|
|
- <entry>1</entry>
|
|
|
|
|
- <entry>CN=Alice Baker,CN=Users,DC=example,DC=com</entry>
|
|
|
|
|
- </row>
|
|
|
|
|
- <row>
|
|
|
|
|
- <entry>
|
|
|
|
|
- <code>ACCTNAME_FORM_USERNAME</code>
|
|
|
|
|
- </entry>
|
|
|
|
|
- <entry>2</entry>
|
|
|
|
|
- <entry>abaker</entry>
|
|
|
|
|
- </row>
|
|
|
|
|
- <row>
|
|
|
|
|
- <entry>
|
|
|
|
|
- <code>ACCTNAME_FORM_BACKSLASH</code>
|
|
|
|
|
- </entry>
|
|
|
|
|
- <entry>3</entry>
|
|
|
|
|
- <entry>EXAMPLE\abaker</entry>
|
|
|
|
|
- </row>
|
|
|
|
|
- <row>
|
|
|
|
|
- <entry>
|
|
|
|
|
- <code>ACCTNAME_FORM_PRINCIPAL</code>
|
|
|
|
|
- </entry>
|
|
|
|
|
- <entry>4</entry>
|
|
|
|
|
- <entry>abaker@example.com</entry>
|
|
|
|
|
- </row>
|
|
|
|
|
- </tbody>
|
|
|
|
|
- </tgroup>
|
|
|
|
|
- </table>
|
|
|
|
|
|
|
+ The <emphasis>accountDomainName</emphasis> and
|
|
|
|
|
+ <emphasis>accountDomainNameShort</emphasis>
|
|
|
|
|
+ options are used for two purposes: (1) they facilitate multi-domain
|
|
|
|
|
+ authentication and failover capability, and (2) they are also used to
|
|
|
|
|
+ canonicalize usernames. Specifically, names are canonicalized to the
|
|
|
|
|
+ form specified by the <emphasis>accountCanonicalForm</emphasis> option.
|
|
|
|
|
+ This option may one of the following values:
|
|
|
</para>
|
|
</para>
|
|
|
|
|
+
|
|
|
|
|
+ <table id="zend.ldap.using.theory-of-operation.account-name-canonicalization.table">
|
|
|
|
|
+ <title>Options for accountCanonicalForm</title>
|
|
|
|
|
+ <tgroup cols="3">
|
|
|
|
|
+ <thead>
|
|
|
|
|
+ <row>
|
|
|
|
|
+ <entry>Name</entry>
|
|
|
|
|
+ <entry>Value</entry>
|
|
|
|
|
+ <entry>Example</entry>
|
|
|
|
|
+ </row>
|
|
|
|
|
+ </thead>
|
|
|
|
|
+ <tbody>
|
|
|
|
|
+ <row>
|
|
|
|
|
+ <entry>
|
|
|
|
|
+ <constant>ACCTNAME_FORM_DN</constant>
|
|
|
|
|
+ </entry>
|
|
|
|
|
+ <entry>1</entry>
|
|
|
|
|
+ <entry>CN=Alice Baker,CN=Users,DC=example,DC=com</entry>
|
|
|
|
|
+ </row>
|
|
|
|
|
+ <row>
|
|
|
|
|
+ <entry>
|
|
|
|
|
+ <constant>ACCTNAME_FORM_USERNAME</constant>
|
|
|
|
|
+ </entry>
|
|
|
|
|
+ <entry>2</entry>
|
|
|
|
|
+ <entry>abaker</entry>
|
|
|
|
|
+ </row>
|
|
|
|
|
+ <row>
|
|
|
|
|
+ <entry>
|
|
|
|
|
+ <constant>ACCTNAME_FORM_BACKSLASH</constant>
|
|
|
|
|
+ </entry>
|
|
|
|
|
+ <entry>3</entry>
|
|
|
|
|
+ <entry>EXAMPLE\abaker</entry>
|
|
|
|
|
+ </row>
|
|
|
|
|
+ <row>
|
|
|
|
|
+ <entry>
|
|
|
|
|
+ <constant>ACCTNAME_FORM_PRINCIPAL</constant>
|
|
|
|
|
+ </entry>
|
|
|
|
|
+ <entry>4</entry>
|
|
|
|
|
+ <entry><filename>abaker@example.com</filename></entry>
|
|
|
|
|
+ </row>
|
|
|
|
|
+ </tbody>
|
|
|
|
|
+ </tgroup>
|
|
|
|
|
+ </table>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- The default canonicalization depends on what account domain name options were supplied. If
|
|
|
|
|
- <code>accountDomainNameShort</code> was supplied, the default <code>accountCanonicalForm</code> value
|
|
|
|
|
- is <code>ACCTNAME_FORM_BACKSLASH</code>. Otherwise, if <code>accountDomainName</code> was supplied, the
|
|
|
|
|
- default is <code>ACCTNAME_FORM_PRINCIPAL</code>.
|
|
|
|
|
|
|
+ The default canonicalization depends on what account domain name options
|
|
|
|
|
+ were supplied. If <emphasis>accountDomainNameShort</emphasis> was supplied, the
|
|
|
|
|
+ default <emphasis>accountCanonicalForm</emphasis> value is
|
|
|
|
|
+ <constant>ACCTNAME_FORM_BACKSLASH</constant>. Otherwise, if
|
|
|
|
|
+ <emphasis>accountDomainName</emphasis> was supplied, the
|
|
|
|
|
+ default is <constant>ACCTNAME_FORM_PRINCIPAL</constant>.
|
|
|
</para>
|
|
</para>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- Account name canonicalization ensures that the string used to identify an account is consistent
|
|
|
|
|
- regardless of what was supplied to <code>bind()</code>. For example, if the user supplies an account
|
|
|
|
|
- name of <emphasis>abaker@example.com</emphasis> or just <emphasis>abaker</emphasis> and the
|
|
|
|
|
- <code>accountCanonicalForm</code> is set to 3, the resulting canonicalized name would be
|
|
|
|
|
|
|
+ Account name canonicalization ensures that the string used to identify
|
|
|
|
|
+ an account is consistent regardless of what was supplied to
|
|
|
|
|
+ <methodname>bind()</methodname>. For example, if the user supplies an account
|
|
|
|
|
+ name of <filename>abaker@example.com</filename> or just
|
|
|
|
|
+ <emphasis>abaker</emphasis> and the <emphasis>accountCanonicalForm</emphasis>
|
|
|
|
|
+ is set to 3, the resulting canonicalized name would be
|
|
|
<emphasis>EXAMPLE\abaker</emphasis>.
|
|
<emphasis>EXAMPLE\abaker</emphasis>.
|
|
|
</para>
|
|
</para>
|
|
|
</sect3>
|
|
</sect3>
|
|
|
|
|
+
|
|
|
<sect3 id="zend.ldap.introduction.theory-of-operations.multi-domain-failover">
|
|
<sect3 id="zend.ldap.introduction.theory-of-operations.multi-domain-failover">
|
|
|
<title>Multi-domain Authentication and Failover</title>
|
|
<title>Multi-domain Authentication and Failover</title>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- The <code>Zend_Ldap</code> component by itself makes no attempt to authenticate with multiple servers.
|
|
|
|
|
- However, <code>Zend_Ldap</code> is specifically designed to handle this scenario gracefully. The
|
|
|
|
|
- required technique is to simply iterate over an array of arrays of server options and attempt to bind
|
|
|
|
|
- with each server. As described above <code>bind()</code> will automatically canonicalize each name, so
|
|
|
|
|
- it does not matter if the user passes <code>abaker@foo.net</code> or <code>W\bcarter</code> or
|
|
|
|
|
- <code>cdavis</code> - the <code>bind()</code> method will only succeed if the credentials were
|
|
|
|
|
|
|
+ The <classname>Zend_Ldap</classname> component by itself makes no attempt
|
|
|
|
|
+ to authenticate with multiple servers. However, <classname>Zend_Ldap</classname>
|
|
|
|
|
+ is specifically designed to handle this scenario gracefully. The
|
|
|
|
|
+ required technique is to simply iterate over an array of arrays of serve
|
|
|
|
|
+ options and attempt to bind with each server. As described above
|
|
|
|
|
+ <methodname>bind()</methodname> will automatically canonicalize each name, so
|
|
|
|
|
+ it does not matter if the user passes <filename>abaker@foo.net</filename> or
|
|
|
|
|
+ <emphasis>W\bcarter</emphasis> or <emphasis>cdavis</emphasis> - the
|
|
|
|
|
+ <methodname>bind()</methodname> method will only succeed if the credentials were
|
|
|
successfully used in the bind.
|
|
successfully used in the bind.
|
|
|
</para>
|
|
</para>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- Consider the following example that illustrates the technique required to implement multi-domain
|
|
|
|
|
- authentication and failover:
|
|
|
|
|
-<example>
|
|
|
|
|
- <programlisting role="php"><![CDATA[
|
|
|
|
|
|
|
+ Consider the following example that illustrates the technique required to
|
|
|
|
|
+ implement multi-domain authentication and failover:
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$acctname = 'W\\user2';
|
|
$acctname = 'W\\user2';
|
|
|
$password = 'pass2';
|
|
$password = 'pass2';
|
|
|
|
|
|
|
@@ -234,33 +286,41 @@ foreach ($multiOptions as $name => $options) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
-</example>
|
|
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
If the bind fails for any reason, the next set of server options is tried.
|
|
If the bind fails for any reason, the next set of server options is tried.
|
|
|
</para>
|
|
</para>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- The <code>getCanonicalAccountName</code> call gets the canonical account name that the application
|
|
|
|
|
- would presumably use to associate data with such as preferences. The
|
|
|
|
|
- <code>accountCanonicalForm = 4</code> in all server options ensures that the canonical form is
|
|
|
|
|
- consistent regardless of which server was ultimately used.
|
|
|
|
|
|
|
+ The <methodname>getCanonicalAccountName()</methodname> call gets the canonical
|
|
|
|
|
+ account name that the application would presumably use to associate data with such
|
|
|
|
|
+ as preferences. The <emphasis>accountCanonicalForm = 4</emphasis> in all server
|
|
|
|
|
+ options ensures that the canonical form is consistent regardless of which
|
|
|
|
|
+ server was ultimately used.
|
|
|
</para>
|
|
</para>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- The special <code>LDAP_X_DOMAIN_MISMATCH</code> exception occurs when an account name with a domain
|
|
|
|
|
- component was supplied (e.g., <code>abaker@foo.net</code> or <code>FOO\abaker</code> and not just
|
|
|
|
|
- <code>abaker</code>) but the domain component did not match either domain in the currently selected
|
|
|
|
|
- server options. This exception indicates that the server is not an authority for the account. In this
|
|
|
|
|
- case, the bind will not be performed, thereby eliminating unnecessary communication with the server.
|
|
|
|
|
- Note that the <code>continue</code> instruction has no effect in this example, but in practice for
|
|
|
|
|
- error handling and debugging purposes, you will probably want to check for
|
|
|
|
|
- <code>LDAP_X_DOMAIN_MISMATCH</code> as well as <code>LDAP_NO_SUCH_OBJECT</code> and
|
|
|
|
|
- <code>LDAP_INVALID_CREDENTIALS</code>.
|
|
|
|
|
|
|
+ The special <constant>LDAP_X_DOMAIN_MISMATCH</constant> exception occurs when an
|
|
|
|
|
+ account name with a domain component was supplied (e.g.,
|
|
|
|
|
+ <filename>abaker@foo.net</filename> or <emphasis>FOO\abaker</emphasis> and not just
|
|
|
|
|
+ <emphasis>abaker</emphasis>) but the domain component did not match either domain
|
|
|
|
|
+ in the currently selected server options. This exception indicates
|
|
|
|
|
+ that the server is not an authority for the account. In this
|
|
|
|
|
+ case, the bind will not be performed, thereby eliminating unnecessary
|
|
|
|
|
+ communication with the server. Note that the <emphasis>continue</emphasis>
|
|
|
|
|
+ instruction has no effect in this example, but in practice for error handling and
|
|
|
|
|
+ debugging purposes, you will probably want to check for
|
|
|
|
|
+ <constant>LDAP_X_DOMAIN_MISMATCH</constant> as well as
|
|
|
|
|
+ <constant>LDAP_NO_SUCH_OBJECT</constant> and
|
|
|
|
|
+ <constant>LDAP_INVALID_CREDENTIALS</constant>.
|
|
|
</para>
|
|
</para>
|
|
|
|
|
+
|
|
|
<para>
|
|
<para>
|
|
|
- The above code is very similar to code used within
|
|
|
|
|
- <link linkend="zend.auth.adapter.ldap">
|
|
|
|
|
- <code>Zend_Auth_Adapter_Ldap</code>
|
|
|
|
|
- </link>. In fact, we
|
|
|
|
|
- recommend that you simply use that authentication adapter for multi-domain + failover LDAP based
|
|
|
|
|
- authentication (or copy the code).
|
|
|
|
|
|
|
+ The above code is very similar to code used within <link
|
|
|
|
|
+ linkend="zend.auth.adapter.ldap"><classname>Zend_Auth_Adapter_Ldap</classname></link>.
|
|
|
|
|
+ In fact, we recommend that you simply use that authentication adapter for
|
|
|
|
|
+ multi-domain + failover <acronym>LDAP</acronym> based authentication
|
|
|
|
|
+ (or copy the code).
|
|
|
</para>
|
|
</para>
|
|
|
</sect3>
|
|
</sect3>
|
|
|
</sect2>
|
|
</sect2>
|