initial import of docbook contribution from Sun
git-svn-id: svn://10.0.0.236/trunk@228382 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
24
mozilla/directory/docs/Readme.txt
Normal file
24
mozilla/directory/docs/Readme.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
The split here is Directory SDK for C versus Directory SDK for Java.
|
||||
|
||||
The content is the very latest I have... but I have been tardy in reading
|
||||
the developer Wiki, so perhaps some of what I've done is out of sync. I mean
|
||||
Anton has reviewed the C SDK content and I've updated that to account for
|
||||
his review comments. Also, I added what was necessary to cover the new
|
||||
sample code I wrote (and I think Anton checked in). But it might not do
|
||||
blindly to overwrite anything on the Wiki with what I have here. And it
|
||||
might require a little post-update Wiki gardening to remove weeds.
|
||||
|
||||
The Directory SDK for C guide includes reference material. The Directory SDK
|
||||
for Java guide does not, since there should be Javadoc somewhere. If this
|
||||
assumption is wrong, let me know. I had a script to do that in my home dir
|
||||
at work.
|
||||
|
||||
This version has the proper license as per
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=369156
|
||||
|
||||
The top files for each book are named 00-Programmers-Guide.book, so all
|
||||
the other files are then pulled in through SYSTEM entities. In other words
|
||||
run validation on the .books.
|
||||
|
||||
Hope it helps,
|
||||
mark.craig@gmail.com, June 19, 2007
|
||||
114
mozilla/directory/docs/ldapcsdk/00-Programmers-Guide.book
Normal file
114
mozilla/directory/docs/ldapcsdk/00-Programmers-Guide.book
Normal file
@@ -0,0 +1,114 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<!DOCTYPE BOOK PUBLIC "-//OASIS//DTD DocBook V4.3//EN" [
|
||||
<!ENTITY BookTitle "Programmer's Guide">
|
||||
<!ENTITY DirectorySDKForC "Directory SDK for C">
|
||||
<!ENTITY DirectorySDKForJava "Directory SDK for Java">
|
||||
<!ENTITY abstract SYSTEM "abstract.sgm">
|
||||
<!ENTITY best-practices SYSTEM "best-practices.sgm">
|
||||
<!ENTITY choose-api SYSTEM "choose-api.sgm">
|
||||
<!ENTITY cnDirectoryServer "Directory Server">
|
||||
<!ENTITY csdk-api SYSTEM "csdk-api.sgm">
|
||||
<!ENTITY csdk-client SYSTEM "csdk-client.sgm">
|
||||
<!ENTITY csdk-compare SYSTEM "csdk-compare.sgm">
|
||||
<!ENTITY csdk-controls SYSTEM "csdk-controls.sgm">
|
||||
<!ENTITY csdk-datatypes SYSTEM "csdk-datatypes.sgm">
|
||||
<!ENTITY csdk-extendop SYSTEM "csdk-extendop.sgm">
|
||||
<!ENTITY csdk-filter-conf SYSTEM "csdk-filter-conf.sgm">
|
||||
<!ENTITY csdk-functions SYSTEM "csdk-functions.sgm">
|
||||
<!ENTITY csdk-ldap-urls SYSTEM "csdk-ldap-urls.sgm">
|
||||
<!ENTITY csdk-multithread SYSTEM "csdk-multithread.sgm">
|
||||
<!ENTITY csdk-quickstart SYSTEM "csdk-quickstart.sgm">
|
||||
<!ENTITY csdk-resultcodes SYSTEM "csdk-resultcodes.sgm">
|
||||
<!ENTITY csdk-sasl SYSTEM "csdk-sasl.sgm">
|
||||
<!ENTITY csdk-search SYSTEM "csdk-search.sgm">
|
||||
<!ENTITY csdk-server-info SYSTEM "csdk-server-info.sgm">
|
||||
<!ENTITY csdk-ssl SYSTEM "csdk-ssl.sgm">
|
||||
<!ENTITY csdk-understanding SYSTEM "csdk-understanding.sgm">
|
||||
<!ENTITY csdk-whatsnew SYSTEM "csdk-whatsnew.sgm">
|
||||
<!ENTITY csdk-write SYSTEM "csdk-write.sgm">
|
||||
<!ENTITY hierovrw SYSTEM "figures/hierovrw.eps" NDATA eps>
|
||||
<!ENTITY legal SYSTEM "legal.sgm">
|
||||
<!ENTITY license SYSTEM "license.txt">
|
||||
<!ENTITY preface SYSTEM "preface.sgm">
|
||||
<!ENTITY understanding-ldap SYSTEM "understanding-ldap.sgm">
|
||||
<!NOTATION graphic SYSTEM "graphic">
|
||||
]>
|
||||
<book lang="en">
|
||||
<title>LDAP C SDK Programmer's Guide</title>
|
||||
<bookinfo>
|
||||
<authorgroup><author><firstname>Mark</firstname><surname>Craig</surname>
|
||||
</author></authorgroup>
|
||||
<pubdate>June 2007</pubdate>
|
||||
<publisher>
|
||||
<publishername>Sun Microsystems, Inc.</publishername>
|
||||
<address>
|
||||
<street>4150 Network Circle</street>
|
||||
<city>Santa Clara</city><state>CA</state><postcode>95054</postcode>
|
||||
<country>U.S.A.</country>
|
||||
</address></publisher>
|
||||
<copyright><year>2000-2007</year><holder>Sun Microsystems, Inc. All Rights Reserved.</holder></copyright>
|
||||
<legalnotice><para><emphasis role="strong">License</emphasis> -
|
||||
<emphasis>The contents of this document are subject to the terms of
|
||||
the Creative Commons Attribution-ShareAlike 2.5 license or any later version (the
|
||||
"License"). You may not use this document except in compliance with
|
||||
the License.</emphasis></para>
|
||||
<para><emphasis>See the License for the specific language governing
|
||||
permissions and limitations under the License. The full text of the
|
||||
License is provided at the end of this
|
||||
document.</emphasis></para>&legal;
|
||||
</legalnotice>
|
||||
<abstract>&abstract;
|
||||
</abstract>
|
||||
</bookinfo>&preface;
|
||||
&understanding-ldap;
|
||||
&choose-api;
|
||||
&best-practices;
|
||||
&csdk-understanding;
|
||||
&csdk-quickstart;
|
||||
&csdk-whatsnew;
|
||||
&csdk-client;
|
||||
&csdk-api;
|
||||
&csdk-search;
|
||||
&csdk-filter-conf;
|
||||
&csdk-write;
|
||||
&csdk-compare;
|
||||
&csdk-ldap-urls;
|
||||
&csdk-server-info;
|
||||
&csdk-ssl;
|
||||
&csdk-controls;
|
||||
&csdk-sasl;
|
||||
&csdk-extendop;
|
||||
&csdk-multithread;
|
||||
&csdk-datatypes;
|
||||
&csdk-functions;
|
||||
&csdk-resultcodes;
|
||||
<appendix id="share-alike">
|
||||
<title>Creative Commons Attribution-ShareAlike 2.5</title>
|
||||
<para>The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license (the
|
||||
"License"). You may not use this document except in compliance with
|
||||
the License.</para>
|
||||
<para>See the License for the specific language governing permissions
|
||||
and limitations under the License. The full text of the License is as
|
||||
follows.</para>
|
||||
<programlisting>&license;</programlisting>
|
||||
</appendix>
|
||||
<index><title>Index</title>
|
||||
<indexentry><primaryie></primaryie></indexentry></index>
|
||||
</book>
|
||||
20
mozilla/directory/docs/ldapcsdk/abstract.sgm
Normal file
20
mozilla/directory/docs/ldapcsdk/abstract.sgm
Normal file
@@ -0,0 +1,20 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<para>This <citetitle>&BookTitle;</citetitle> shows you how to
|
||||
create LDAP client applications in the C language to connect to LDAP servers.
|
||||
This guide also shows you how to perform standard LDAP operations.</para>
|
||||
378
mozilla/directory/docs/ldapcsdk/best-practices.sgm
Normal file
378
mozilla/directory/docs/ldapcsdk/best-practices.sgm
Normal file
@@ -0,0 +1,378 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="best-practices-overview"><title>Best Practices for
|
||||
Writing Client Applications</title>
|
||||
<highlights>
|
||||
<itemizedlist>
|
||||
<para>This chapter includes best practices for developing client applications
|
||||
and cover the following topics:</para>
|
||||
<listitem><para><olink targetptr="best-ldapv3">Creating Your Application</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-troubleshooting">Troubleshooting Problems</olink></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="best-ldapv3"><title>Creating Your Application</title>
|
||||
<itemizedlist>
|
||||
<para>This section identifies practices to observe when creating directory
|
||||
client applications.</para>
|
||||
<listitem><para><olink targetptr="specify-ldapv3">Specify LDAP v3</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-authenticating">Authenticate Correctly</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-connect">Limit Connection Overhead</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-inactivity-timeouts">Handle Potential
|
||||
Inactivity Timeouts</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="best-entries">Retrieve Entries Intelligently</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-filters">Write Simple, Conforming LDAP
|
||||
Filters</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="best-mods">Performing Specific Modifications</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-rc">Trust Result Codes</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-groups">Limit Dealings With Groups
|
||||
and Roles</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="best-dse">Read the DSE</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-resources">Use Resource-Intensive Features Sparingly</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="best-dit">Avoid Hard Coding Certain Information
|
||||
</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="best-schema">Define Schemas Only When Necessary
|
||||
</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="best-refer">Handle Referrals</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-not-rdbm">Treat a Directory as a Directory
|
||||
</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
<sect2 id="specify-ldapv3"><title>Specify LDAP v3</title>
|
||||
<itemizedlist>
|
||||
<para>Many client libraries default to LDAP v2, but you can elect to use LDAP
|
||||
v3. To benefit from LDAP v3 features, you can set up the connection, and then
|
||||
authenticate explicitly using LDAP v3.</para>
|
||||
<listitem><para>With JNDI, you could use LDAP v3 as shown here.</para>
|
||||
<programlisting role="fragment">import java.util.Hashtable;
|
||||
import javax.naming.ldap.InitialLdapContext;
|
||||
|
||||
Hashtable env = new Hashtable();
|
||||
env.put("java.naming.ldap.version", "<emphasis>3</emphasis>");
|
||||
InitialLdapContext ctx = new InitialLdapContext(env, null);</programlisting>
|
||||
</listitem>
|
||||
<listitem><para>With &DirectorySDKForC;, you could use LDAP v3 as shown
|
||||
here.</para>
|
||||
<programlisting role="fragment">#include "ldap.h"
|
||||
|
||||
int version = <emphasis>LDAP_VERSION3</emphasis>;
|
||||
ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version );</programlisting>
|
||||
<para>&DirectorySDKForC; uses LDAP v3 by default.</para></listitem>
|
||||
<listitem><para>With &DirectorySDKForJava;, you could use LDAP v3 as shown
|
||||
here.</para>
|
||||
<programlisting role="fragment">import netscape.ldap.LDAPConnection;
|
||||
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.setOption(LDAPv3.PROTOCOL_VERSION, new Integer(<emphasis>3</emphasis>));
|
||||
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<sect2 id="best-authenticating"><title>Authenticate Correctly</title>
|
||||
<para>Your SDK uses terminology that is slightly different from LDAP v3. In
|
||||
LDAP v3, you connect, then you bind and perform LDAP operations, then you
|
||||
unbind and disconnect. The bind is the authentication operation in LDAP. Your
|
||||
application can hold onto a connection but change the authentication credentials
|
||||
by using the bind operation again.</para>
|
||||
<para>Some directories do not allow anonymous access, even for reads. When
|
||||
you build your application, keep the option that allows users to authenticate
|
||||
to the directory. Furthermore, the information sent across the network can
|
||||
be sensitive. You can protect sensitive data by allowing the application to
|
||||
secure the connection by using Secure Sockets Layer (SSL) or Start Transport
|
||||
Layer Security (TLS).</para>
|
||||
<para>If your application needs to authenticate, obtain a regular account
|
||||
to authenticate with the directory, rather than using the directory superuser
|
||||
account such as <literal>cn=Directory Manager</literal>. When you authenticate
|
||||
as directory superuser, you often bypass normal access control mechanisms.
|
||||
Bypassing normal access control renders auditing directory access more difficult.
|
||||
</para>
|
||||
<para>When authenticating, have your application use SSL or SASL DIGEST MD5
|
||||
to avoid sending passwords over the network in clear text. Furthermore, when
|
||||
using password-based authentication, have your application check password
|
||||
policy controls, especially to determine when a password must be renewed.</para>
|
||||
</sect2>
|
||||
<sect2 id="best-connect"><title>Limit Connection Overhead</title>
|
||||
<para>A new connection requires system resources. The LDAP model allows you
|
||||
to reuse connections by binding again with a different identity on the same
|
||||
connection. Thus, you can avoid the costs of new connections, particularly
|
||||
negotiated connections such as connections that use SSL, by reusing connections.
|
||||
Your application can use a pool of connections, rebinding when necessary.
|
||||
Your application can alternatively use the proxy authorization control to
|
||||
remain authenticated as the application but perform operations on behalf of
|
||||
a particular user.</para>
|
||||
<para>When establishing a connection, your application can provide alternate
|
||||
server host names and port numbers to facilitate failover that is transparent
|
||||
to the application. You can also set time limits for LDAP operations to avoid
|
||||
getting blocked.</para>
|
||||
<para>When finished with a connection, your application should perform an
|
||||
unbind.</para></sect2>
|
||||
<sect2 id="best-inactivity-timeouts"><title>Handle Potential Inactivity Timeouts</title>
|
||||
<para>Most network equipment can use timeouts to drop stale connections, ensuring
|
||||
the equipment keeps a maximum number of connections that are available.</para>
|
||||
<para>If your application pools connections or opens connections for persistent
|
||||
search, than guard against timeouts that drop those connections. Use the connections
|
||||
occasionally to reset inactivity timers present in the network.</para>
|
||||
<para>Alternatively, if you have control over the connection, consider disabling
|
||||
inactivity time outs for your applications that need to keep persistent connections
|
||||
open. Load balancers and proxy software often use inactivity timeouts.</para>
|
||||
</sect2>
|
||||
<sect2 id="best-entries"><title>Retrieve Entries Intelligently</title>
|
||||
<para>&cnDirectoryServer; typically responds quickly to requests for entries.
|
||||
Yet, &cnDirectoryServer; can respond most quickly when your application asks
|
||||
it to do only necessary work. If you need to read only a few attributes in
|
||||
an entry, request each attribute explicitly. Avoid reading the entire entry,
|
||||
then parsing the entire entry to obtain the required data.</para>
|
||||
<para>Furthermore, when you do request attributes in an entry, retrieve all
|
||||
the required attributes at once. Each new request involves a new operation
|
||||
on the server.</para>
|
||||
<para>If any of the attributes that you require are operational attributes,
|
||||
you must request those attributes specifically. Such attributes are identifiable
|
||||
in directory schema by their <literal>USAGE</literal>, which is <literal>directoryOperation
|
||||
</literal> or <literal>dsaOperation</literal>.</para>
|
||||
<para>When retrieving entries and attributes, recognize that you might not
|
||||
have access to all the attributes that exist.</para></sect2>
|
||||
<sect2 id="best-filters"><title>Write Simple, Conforming LDAP Filters</title>
|
||||
<indexterm>
|
||||
<primary>LDAP filters</primary>
|
||||
<secondary>writing</secondary>
|
||||
</indexterm>
|
||||
<para>The best filters use attributes that are indexed according to the way
|
||||
the attributes are indexed. For example, if <literal>employeeNumber</literal> is
|
||||
indexed for equality, your filter should be an equality filter such as <literal>(employeeNumber=123456)
|
||||
</literal>. Do not use a substring filter instead.</para>
|
||||
<para>Avoid deeply nested complex filters when you can. When you must use
|
||||
complex filters, place the most specific filters first to narrow the list
|
||||
of candidate entries the directory must check. For best results, use <literal>not
|
||||
</literal>, <literal>!</literal>, only with <literal>and</literal>, <literal>&
|
||||
</literal>, for example <literal>(&(cn=Barbara)(!(sn=Jensen)))</literal>.
|
||||
When you use <literal>not</literal> with <literal>or</literal> in a filter,
|
||||
the directory must construct a candidate list of everything except what your
|
||||
filter specifies.</para></sect2>
|
||||
<sect2 id="best-mods"><title>Performing Specific Modifications</title>
|
||||
<para>Modifications are atomic on the entry to which the modifications apply.
|
||||
When modifying multivalued attributes, delete and replace specific values.
|
||||
Do not replace an entire list of multiple values to change only a few values.
|
||||
Replacing specific values is particularly good practice when the changes must
|
||||
be replicated across a set of servers.</para>
|
||||
<para>Moreover, when you have large values to store in an attribute, store
|
||||
a reference to the data instead of storing the data object.</para></sect2>
|
||||
<sect2 id="best-rc"><title>Trust Result Codes</title>
|
||||
<indexterm>
|
||||
<primary>result codes</primary>
|
||||
<secondary>trust</secondary>
|
||||
</indexterm>
|
||||
<para>&cnDirectoryServer; trades tight consistency across replica servers
|
||||
for very high performance, availability, and scalability. By allowing <firstterm>
|
||||
loose consistency</firstterm> of data across sets of replica servers, &cnDirectoryServer; instances
|
||||
can respond very quickly to your application. Yet, data replication is not
|
||||
instantaneous. A short but detectable delay can ensue after a server returns
|
||||
success for a write operation, but before the effects are seen on other replicas.
|
||||
</para>
|
||||
<para>Therefore, when your application receives a result code from &cnDirectoryServer; to
|
||||
indicate that an operation was successful, your application should trust the
|
||||
result code. When application requests are balanced across replicas, reading
|
||||
from another replica might result in errors due to a slight delay in replication.
|
||||
</para></sect2>
|
||||
<sect2 id="best-groups"><title>Limit Dealings With Groups and Roles</title>
|
||||
<indexterm>
|
||||
<primary>groups</primary>
|
||||
<secondary>working with</secondary>
|
||||
</indexterm>
|
||||
<para>When you want to know whether an account belongs to a group or a role,
|
||||
read only the necessary attribute values. Do not read the entire list of group
|
||||
members.</para>
|
||||
<orderedlist>
|
||||
<para>For <literal>dynamic groups</literal>, do the following:</para>
|
||||
<listitem><para>Read the URL from the group definition.</para></listitem>
|
||||
<listitem><para>Examine the host, DN, and scope of the URL.</para></listitem>
|
||||
<listitem><para>Apply the filter part of the URL to the entry for the account.</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para><indexterm>
|
||||
<primary>roles</primary>
|
||||
<secondary>working with</secondary>
|
||||
</indexterm>For <literal>roles</literal>, compare the DN of the role to the <literal>
|
||||
nsRole</literal> attribute of the entry for the account, such as <literal>(nsrole=cn=management,ou=people,dc=example,dc=com)
|
||||
</literal>. You can then retrieve all the values of the <literal>nsRole</literal> attribute
|
||||
for the account.</para></sect2>
|
||||
<sect2 id="best-dse"><title>Read the DSE</title>
|
||||
<indexterm>
|
||||
<primary>DSE, root</primary>
|
||||
<secondary>reading</secondary>
|
||||
</indexterm>
|
||||
<para>The root DSE is the entry that is retrieved by <command>ldapsearch -b
|
||||
"" -s base "(objectclass=*)"</command>. The root DSE describes server capabilities.
|
||||
The root DSE contains information about supported LDAP protocol versions,
|
||||
naming contexts (suffixes), LDAP v3 controls, LDAP v3 extensions, and authentication
|
||||
mechanisms. The root DSE can contain information about the server version.</para>
|
||||
<para>Some directory administrators protect access to the root DSE. Yet, applications
|
||||
might read the root DSE to confirm that the server in fact supports functionality
|
||||
required by applications.</para></sect2>
|
||||
<sect2 id="best-resources"><title>Use Resource-Intensive Features Sparingly</title>
|
||||
<para>Directories offer powerful features that can nevertheless place a heavy
|
||||
load on the server. Two such features are persistent search, and server-side
|
||||
sorting.</para>
|
||||
<para>Persistent search lets you start a search that does not stop when complete,
|
||||
but instead allows you to receive updates when entries are modified. To provide
|
||||
this feature, the server must handle your search when anything happens to
|
||||
an entry in its scope.</para>
|
||||
<para>Server-side sorting requires that the server sort the entries that are
|
||||
returned during a search. Instead of returning entries as quickly as possible,
|
||||
the server must therefore get the list to return, and sort the list.</para>
|
||||
</sect2>
|
||||
<sect2 id="best-dit"><title>Avoid Hard Coding Certain Information</title>
|
||||
<para>The container entry for a subtree might be not be identical on different
|
||||
directories. Rather than hard code the container entry throughout your application,
|
||||
locate the container entry. Then navigate beneath the container entry in the
|
||||
tree.</para>
|
||||
<para>Object classes and attribute types for the same information can also
|
||||
differ from directory to directory. Use configuration files, properties files,
|
||||
or other easily modifiable variables rather than hard coding object class
|
||||
and attribute type identifiers into your application.</para>
|
||||
<para>Be aware as well that object class and attribute type identifiers are <emphasis>
|
||||
not case-sensitive</emphasis> in LDAP. Your application should therefore recognize
|
||||
that <literal>inetOrgPerson</literal> and <literal>inetorgperson</literal> are
|
||||
equivalent, as are <literal>isMemberOf</literal> and <literal>ismemberof</literal>.
|
||||
</para></sect2>
|
||||
<sect2 id="best-schema"><title>Define Schemas Only When Necessary</title>
|
||||
<indexterm>
|
||||
<primary>schema</primary>
|
||||
<secondary>defining</secondary>
|
||||
</indexterm>
|
||||
<para>Schemas define the object classes and attribute types that are recognized
|
||||
by the directory. If your application can use a standard schema, use the standard
|
||||
schema. &cnDirectoryServer; contains schemas that define numerous standard
|
||||
object classes, and attribute types.</para>
|
||||
<itemizedlist>
|
||||
<para>When you must define your own schema objects, follow these guidelines:</para>
|
||||
<listitem><para>Extend existing object classes by using <literal>AUXILIARY</literal> classes.
|
||||
</para></listitem>
|
||||
<listitem><para>Create new attributes rather than redefining existing attributes.
|
||||
</para><para>Other applications might depend on existing attributes to keep
|
||||
their existing semantics.</para></listitem>
|
||||
<listitem><para>Obtain new object identifiers for the schema elements you
|
||||
define, rather than reusing existing object identifiers.</para></listitem>
|
||||
<listitem><para>Obtain new names for the schema elements you define, rather
|
||||
than reusing existing names.</para></listitem>
|
||||
<listitem><para>Update &cnDirectoryServer; schema over LDAP if you can.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<sect2 id="best-refer"><title>Handle Referrals</title>
|
||||
<indexterm>
|
||||
<primary>referrals</primary>
|
||||
<secondary>following</secondary>
|
||||
</indexterm>
|
||||
<para>LDAP v3 allows directories that are unable to handle your request to
|
||||
refer your application to other directories. Your application should follow
|
||||
those referrals.</para>
|
||||
<para>When following referrals, realize that authentication procedures might
|
||||
not be exactly the same on different directories. Also, directories that refer
|
||||
to each other could potentially cause a referral loop. With &DirectorySDKForC; and &DirectorySDKForJava;,
|
||||
you can limit referral hops to prevent your application from being referred
|
||||
endlessly from one directory to another directory. The JNDI interface enables
|
||||
you to follow referrals automatically.</para></sect2>
|
||||
<sect2 id="best-not-rdbm"><title>Treat a Directory as a Directory</title>
|
||||
<para>A directory is typically a repository for identity data, and for information
|
||||
that you expect to keep for awhile and read often. You might typically find
|
||||
relational databases better adapted to hold transient data such as session
|
||||
keys and presence information, or voluminous accumulated data such as application
|
||||
logs.</para></sect2>
|
||||
</sect1>
|
||||
<sect1 id="best-troubleshooting"><title>Troubleshooting Problems</title>
|
||||
<para>This section covers basic troubleshooting approaches and techniques
|
||||
to use when developing directory client applications. You can check result
|
||||
codes, check server log files, and inspect network packets.</para>
|
||||
<sect2 id="trouble-rc"><title>Check Result Codes</title>
|
||||
<indexterm>
|
||||
<primary>troubleshooting</primary>
|
||||
<secondary>result codes</secondary>
|
||||
</indexterm>
|
||||
<para>When an LDAP request from your application fails on the server, the
|
||||
server sends back a result code, and possibly an explanatory message. Your
|
||||
application should check the result codes, and for explanatory messages. Common
|
||||
failure result codes include the following, which are expressed as decimal
|
||||
values. Others result codes are defined as well.</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><errorcode>1</errorcode></term>
|
||||
<listitem><para>LDAP operations error. The server encountered an error while
|
||||
processing your request.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><errorcode>32</errorcode></term>
|
||||
<listitem><para>No such object. The entry is not present on the server. Also,
|
||||
no referral is defined for the entry.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><errorcode>49</errorcode></term>
|
||||
<listitem><para>Invalid credentials. Your application failed to authenticate
|
||||
properly.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><errorcode>53</errorcode></term>
|
||||
<listitem><para>LDAP unwilling to perform. The directory does not support
|
||||
the request. Alternatively, the directory is not currently in a state in which
|
||||
to complete your request. For example, the directory might be in read-only
|
||||
mode when your application requests a modification.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><errorcode>65</errorcode></term>
|
||||
<listitem><para>Object class violation. Your write request would cause an
|
||||
entry to no longer conform to the schema defined for the directory.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><errorcode>68</errorcode></term>
|
||||
<listitem><para>Already exists. Your application is requesting to add an entry
|
||||
that has the same DN as an entry already present in the directory.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para><ulink url="http://ietf.org/rfc/rfc4511.txt" type="text_url">RFC 4511</ulink> defines
|
||||
LDAP error codes, as does <olink targetptr="bdaxx">Chapter 22, Directory
|
||||
SDK for C Result Codes</olink>.</para></sect2>
|
||||
<sect2 id="trouble-logs"><title>Check Server Log Files</title>
|
||||
<indexterm>
|
||||
<primary>troubleshooting</primary>
|
||||
<secondary>log files</secondary>
|
||||
</indexterm>
|
||||
<para>&cnDirectoryServer; logs messages related to server operation in its <filename>
|
||||
logs/errors</filename> file. If you have access to this file, you might find
|
||||
useful troubleshooting information there.</para>
|
||||
<para>When debugging your application against &cnDirectoryServer;, you can
|
||||
adjust the log level, as well. See the server documentation for instructions.</para>
|
||||
</sect2>
|
||||
<sect2 id="trouble-network-tools"><title>Inspect Network Packets</title>
|
||||
<indexterm>
|
||||
<primary>troubleshooting</primary>
|
||||
<secondary>decoding packets</secondary>
|
||||
</indexterm>
|
||||
<para>Although LDAP is not a textual protocol, tools such as <citerefentry>
|
||||
<refentrytitle>snoop</refentrytitle><manvolnum>1M</manvolnum></citerefentry>, <command>
|
||||
ethereal</command>, and <command>tcpdump</command> can decode the packets,
|
||||
sometimes providing you with important debugging information.</para></sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
98
mozilla/directory/docs/ldapcsdk/choose-api.sgm
Normal file
98
mozilla/directory/docs/ldapcsdk/choose-api.sgm
Normal file
@@ -0,0 +1,98 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="best-practices-choose"><title>Choosing a Client
|
||||
SDK</title>
|
||||
<highlights>
|
||||
<para>This chapter discusses software development kits to help you select
|
||||
the appropriate directory SDK for your particular situation.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="choose-jndi">Java Naming and Directory Interface
|
||||
</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="choose-ljdk">Directory SDK for Java</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="choose-cdsk">Directory SDK for C</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="choose-solaris-libldap">Operating System libldap Library</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="choose-other">Support for Other Programming
|
||||
Languages</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="choose-jndi"><title>Java Naming and Directory Interface</title>
|
||||
<indexterm>
|
||||
<primary>Java Naming and Directory Interface</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>JNDI</primary>
|
||||
<see>Java Naming and Directory Interface</see></indexterm>
|
||||
<para>Java Naming and Directory Interface (JNDI) technology supports directory
|
||||
access through LDAP and DSML v2 from <trademark>Java</trademark> applications,
|
||||
and is part of the Java platform. With JNDI, you can build powerful, portable,
|
||||
directory-enabled applications that do not depend on classes outside the Java
|
||||
platform.</para>
|
||||
<para>JNDI provides an abstract model that lets you access not only directories,
|
||||
but also naming services in general, including DNS, RMI, COS, and file systems.</para>
|
||||
<para>For information about JNDI, see <ulink
|
||||
url="http://java.sun.com/products/jndi/" type="url"></ulink>. The <citetitle>JNDI
|
||||
Tutorial</citetitle> contains descriptions and examples of how to use JNDI.
|
||||
The tutorial is at <ulink url="http://java.sun.com/products/jndi/tutorial/"
|
||||
type="url"></ulink>.</para></sect1>
|
||||
<sect1 id="choose-cdsk"><title>&DirectorySDKForC;</title>
|
||||
<para>&DirectorySDKForC; lets you access LDAP directories from C and C++
|
||||
applications. &DirectorySDKForC; applications depend on &DirectorySDKForC; libraries,
|
||||
which are available on a wide range of platforms.</para>
|
||||
<para>&DirectorySDKForC; was the subject of Internet-Draft work but never
|
||||
became a standard API. &DirectorySDKForC; closely follows LDAP v3, providing
|
||||
support for core LDAP operations and for LDAP v3 extensions and widely used
|
||||
controls. &DirectorySDKForC; offers a rich API to the C and C++ developer
|
||||
familiar with the LDAP model. &cnDirectoryServer; relies on &DirectorySDKForC;.
|
||||
</para>
|
||||
<para>This document demonstrates how to use &DirectorySDKForC;. &DirectorySDKForC; code
|
||||
is published in open source form as part of the Mozilla Directory SDK project.</para>
|
||||
</sect1>
|
||||
<sect1 id="choose-ljdk"><title>&DirectorySDKForJava;</title>
|
||||
<para>&DirectorySDKForJava; lets you access LDAP directories from Java
|
||||
applications, but it is not part of the Java platform.</para>
|
||||
<para>Although not a standard API, &DirectorySDKForJava; closely follows
|
||||
LDAP v3 idioms. &DirectorySDKForJava; provides a rich set of interfaces
|
||||
to the Java developer familiar with the LDAP model.</para>
|
||||
<para>This document demonstrates how to use &DirectorySDKForJava;. &DirectorySDKForJava; code
|
||||
is published in open source form as part of the Mozilla Directory SDK project.</para>
|
||||
</sect1>
|
||||
<sect1 id="choose-solaris-libldap"><title>Operating System <filename>libldap</filename> Library
|
||||
</title>
|
||||
<indexterm>
|
||||
<primary>libraries</primary>
|
||||
<secondary><filename>libldap</filename></secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary><filename>libldap</filename></primary>
|
||||
</indexterm>
|
||||
<para>The native LDAP library on <trademark>Solaris</trademark> systems provides
|
||||
essentially the same API as &DirectorySDKForC;. Many &DirectorySDKForC; need
|
||||
only be recompiled to work with <filename>libldap</filename>.</para>
|
||||
<para>The LDAP library is sometimes not compatible with <filename>libldap</filename> on
|
||||
many GNU/Linux distributions. Many GNU/Linux distributions provide OpenLDAP
|
||||
support by default.</para></sect1>
|
||||
<sect1 id="choose-other"><title>Support for Other Programming Languages</title>
|
||||
<para>Support for directory access is available in a number of contexts where
|
||||
you do not choose to use the C or Java languages.</para>
|
||||
<para>For example, Perl has the PerLDAP module and the Net::LDAP collection
|
||||
of modules. Python has the <literal>python-ldap</literal> package. PHP can
|
||||
be compiled with LDAP support. Ruby has the Ruby/LDAP extension module. In
|
||||
many cases, you can choose the language that fits the task and find that LDAP
|
||||
support is available.</para></sect1>
|
||||
</chapter>
|
||||
1465
mozilla/directory/docs/ldapcsdk/csdk-api.sgm
Normal file
1465
mozilla/directory/docs/ldapcsdk/csdk-api.sgm
Normal file
File diff suppressed because it is too large
Load Diff
768
mozilla/directory/docs/ldapcsdk/csdk-client.sgm
Normal file
768
mozilla/directory/docs/ldapcsdk/csdk-client.sgm
Normal file
@@ -0,0 +1,768 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="csdk-client"><title>Writing an LDAP Client With &DirectorySDKForC;</title>
|
||||
<highlights>
|
||||
<para>With &DirectorySDKForC;, you can write a new application. You can
|
||||
also enable an existing application to interact with a Lightweight Directory
|
||||
Access Protocol (LDAP) server. This chapter explains how to connect to an
|
||||
LDAP server, authenticate, request operations, and disconnect from the server.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="bdacb">Designing an LDAP Client With Directory
|
||||
SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdacc">Initializing an LDAP Session With
|
||||
Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdacj">Binding and Authenticating to an
|
||||
LDAP Server With Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdacs">Performing LDAP Operations With Directory
|
||||
SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdact">Closing the Connection to an LDAP
|
||||
Server With Directory SDK for C</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="bdacb"><title>Designing an LDAP Client With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>designing LDAP client</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>designing with C SDK</secondary>
|
||||
</indexterm>
|
||||
<para>The following procedure outlines a typical process for communicating
|
||||
with an LDAP server.</para>
|
||||
<task><title>To Communicate With an LDAP Server</title>
|
||||
<procedure>
|
||||
<step><para>Initialize an LDAP session.</para><para>See <olink targetptr="bdacc">
|
||||
Initializing an LDAP Session With Directory SDK for C</olink> for details.</para>
|
||||
</step>
|
||||
<step><para>Bind to the LDAP server, if necessary.</para><para>See <olink targetptr="bdacj">Binding and Authenticating to an LDAP Server With Directory
|
||||
SDK for C</olink> for details.</para></step>
|
||||
<step><para>Perform LDAP operations, such as searching the directory or modifying
|
||||
entries in the directory.</para><para>See <olink targetptr="bdacs">Performing
|
||||
LDAP Operations With Directory SDK for C</olink> for details.</para></step>
|
||||
<step><para>Close the connection to the LDAP server when finished.</para><para>See <olink targetptr="bdact">Closing the Connection to an LDAP Server With Directory
|
||||
SDK for C</olink> for details.</para></step>
|
||||
</procedure>
|
||||
<example id="csdk-search-example">
|
||||
<title>Performing an LDAP Search</title>
|
||||
<indexterm>
|
||||
<primary>example programs</primary>
|
||||
<secondary>LDAP search</secondary>
|
||||
</indexterm>
|
||||
<para>This sample source code shows a client that requests an LDAP search
|
||||
operation from a server. The LDAP server runs on the local system on port <literal>
|
||||
389</literal>. The client searches the directory for entries with the last
|
||||
name <literal>Jensen</literal> (<literal>sn=Jensen</literal>), and prints
|
||||
the distinguished name (DN) of any matching entry.</para>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include "ldap.h"
|
||||
|
||||
/* Specify the search criteria here. */
|
||||
#define HOSTNAME "localhost"
|
||||
#define PORTNUMBER 389
|
||||
#define BASEDN "dc=example,dc=com"
|
||||
#define SCOPE LDAP_SCOPE_SUBTREE
|
||||
#define FILTER "(sn=Jensen)"
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
LDAP *ld;
|
||||
LDAPMessage *result, *e;
|
||||
char *dn;
|
||||
int version, rc;
|
||||
/* Print out an informational message. */
|
||||
printf( "Connecting to host %s at port %d...\n\n", HOSTNAME,
|
||||
PORTNUMBER );
|
||||
|
||||
/* STEP 1: Get a handle to an LDAP connection and
|
||||
set any session preferences. Use prldap_init() for IPv6. */
|
||||
if ( (ld = ldap_init( HOSTNAME, PORTNUMBER )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Use the LDAP_OPT_PROTOCOL_VERSION session preference to specify
|
||||
that the client is an LDAPv3 client. */
|
||||
version = LDAP_VERSION3;
|
||||
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
|
||||
|
||||
/* STEP 2: Bind to the server.
|
||||
In this example, the client binds anonymously to the server
|
||||
(no DN or credentials are specified). */
|
||||
rc = ldap_simple_bind_s( ld, NULL, NULL );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf(stderr, "ldap_simple_bind_s: %s\n", ldap_err2string(rc));
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Print out an informational message. */
|
||||
printf( "Searching the directory for entries\n"
|
||||
" starting from the base DN %s\n"
|
||||
" within the scope %d\n"
|
||||
" matching the search filter %s...\n\n",
|
||||
BASEDN, SCOPE, FILTER );
|
||||
|
||||
/* STEP 3: Perform the LDAP operations.
|
||||
In this example, a simple search operation is performed.
|
||||
The client iterates through each of the entries returned and
|
||||
prints out the DN of each entry. */
|
||||
rc = ldap_search_ext_s( ld, BASEDN, SCOPE, FILTER, NULL, 0,
|
||||
NULL, NULL, NULL, 0, &result );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf(stderr, "ldap_search_ext_s: %s\n", ldap_err2string(rc));
|
||||
return( 1 );
|
||||
}
|
||||
for ( e = ldap_first_entry( ld, result ); e != NULL;
|
||||
e = ldap_next_entry( ld, e ) ) {
|
||||
if ( (dn = ldap_get_dn( ld, e )) != NULL ) {
|
||||
printf( "dn: %s\n", dn );
|
||||
ldap_memfree( dn );
|
||||
}
|
||||
}
|
||||
ldap_msgfree( result );
|
||||
|
||||
/* STEP 4: Disconnect from the server. */
|
||||
ldap_unbind( ld );
|
||||
return( 0 );
|
||||
}
|
||||
...</programlisting>
|
||||
</example>
|
||||
</task>
|
||||
</sect1>
|
||||
<sect1 id="bdacc"><title>Initializing an LDAP Session With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>initializing an LDAP session</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP session</primary>
|
||||
<secondary>initializing</secondary>
|
||||
</indexterm>
|
||||
<para>Before connecting to an LDAP server, you must initialize a session.
|
||||
As part of this process, you create an <structname>LDAP</structname> structure
|
||||
that contains information about the LDAP server and session. You then pass
|
||||
this <structname>LDAP</structname> structure, usually as a pointer, to all
|
||||
subsequent functions in order to identify the LDAP server with which you are
|
||||
working. Sample code for initializing an LDAP session is provided in <olink targetptr="bdacf">Example Session Initialization</olink>.</para>
|
||||
<note><para>If you plan to connect to the LDAP server over the Secure Sockets
|
||||
Layer (SSL) protocol, the procedure for initializing an LDAP session is different.
|
||||
For details, see <olink targetptr="csdk-ssl">Chapter 15, SSL Connections
|
||||
With Directory SDK for C</olink>.</para></note>
|
||||
<sect2 id="bdacd"><title>Specifying a Single LDAP Server</title>
|
||||
<para>To initialize an LDAP session, call <function>ldap_init</function>,
|
||||
or <function>prldap_init</function> for IPv6 support, with the host name and
|
||||
port number of the LDAP server. If the server is using the default port <literal>
|
||||
389</literal> for the LDAP server, pass <literal>LDAP_PORT</literal> as the
|
||||
value for the <parameter>defport</parameter> parameter as shown here.</para>
|
||||
<example id="csdk-init-example"><title>Passing an LDAP Server With the Default
|
||||
LDAP Port</title>
|
||||
<programlisting>...
|
||||
LDAP *ld
|
||||
...
|
||||
ld = ldap_init( "directory.example.com", LDAP_PORT );</programlisting>
|
||||
</example>
|
||||
<para>If successful, <function>ldap_init</function>, or <function>prldap_init</function>,
|
||||
returns a connection handle to the LDAP server. A <firstterm>connection handle</firstterm> is
|
||||
a pointer to the <structname>LDAP</structname> structure that contains information
|
||||
about the connection. You must pass this pointer to the API for connecting,
|
||||
authenticating, and performing LDAP operations on a server. For example, when
|
||||
you search the directory, you pass the connection handle as a parameter to
|
||||
provide a context for the connection.</para>
|
||||
<note><para>The initialization function does not open a connection to the
|
||||
LDAP server. The actual opening of a connection occurs when the first operation
|
||||
is attempted.</para></note>
|
||||
</sect2>
|
||||
<sect2 id="bdace"><title>Specifying a List of LDAP Servers</title>
|
||||
<para>When initializing the LDAP session, you can also specify a list of LDAP
|
||||
servers for which you want to attempt connections. If the first LDAP server
|
||||
in the list does not respond, the client attempts to connect to the next server
|
||||
in the list. To specify a list of LDAP servers, pass a space-delimited list
|
||||
of the host names as the first argument to the <function>ldap_init</function> or <function>
|
||||
prldap_init</function> function. In the following example, the LDAP client
|
||||
attempts to connect to the LDAP server on <literal>ld1.example.com</literal>,
|
||||
port <literal>389</literal>. If that server does not respond, the client attempts
|
||||
to connect to the LDAP server on <literal>ld2.example2.com</literal>, port <literal>
|
||||
389</literal>. If that server does not respond, the client uses the server
|
||||
on <literal>ld3.example.com</literal>, port <literal>389</literal>.</para>
|
||||
<example id="csdk-init-mult-example"><title>Passing Multiple LDAP Servers
|
||||
With the Default LDAP Port</title>
|
||||
<programlisting>...
|
||||
LDAP *ld
|
||||
...
|
||||
ld = ldap_init( "ld1.example.com ld2.example2.com
|
||||
ld3.example.com", LDAP_PORT );</programlisting>
|
||||
</example>
|
||||
<para>If any servers do not use the default LDAP port, use the <replaceable>host</replaceable><literal>
|
||||
:</literal><replaceable>port</replaceable> format to specify the server name
|
||||
and port number. In the following example, that means <literal>ld1.example.com</literal>,
|
||||
port <literal>389</literal>. If that server does not respond, the client attempts
|
||||
to connect to the LDAP server on <literal>ld2.example.com</literal>, port <literal>
|
||||
1389</literal>.</para>
|
||||
<example id="csdk-init-mult2-example"><title>Passing Non-Default LDAP Ports</title>
|
||||
<programlisting>...
|
||||
LDAP *ld
|
||||
...
|
||||
ld = ldap_init( "ld1.example.com ld2.example.com:1389",
|
||||
LDAP_PORT );</programlisting>
|
||||
</example>
|
||||
</sect2>
|
||||
<sect2 id="bdacf"><title>Example Session Initialization</title>
|
||||
<indexterm>
|
||||
<primary>example programs</primary>
|
||||
<secondary>initializing an LDAP session</secondary>
|
||||
</indexterm>
|
||||
<para>The following example initializes a session with an LDAP server, specifying
|
||||
a list of LDAP servers to try: <literal>ldap.example.com:389</literal> and <literal>
|
||||
directory.example.com:1389</literal>. The example also sets a session preference
|
||||
that identifies the client as an LDAP v3 client. This session initialization
|
||||
code uses the <function>prldap_init</function> function, which works on IPv6
|
||||
networks. Notice that <function>prldap_init</function> does not connect to
|
||||
the LDAP server right away.</para>
|
||||
<para>After you initialize a session with an LDAP server, you can set session
|
||||
preferences. For information, see<olink targetptr="bdacg">Setting Session
|
||||
Preferences With Directory SDK for C</olink>. </para>
|
||||
<example id="csdk-init2-example"><title>Initializing an LDAP Session</title>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include "ldappr.h"
|
||||
#include "ldap.h"
|
||||
...
|
||||
LDAP *ld;
|
||||
int ldap_default_port, version;
|
||||
|
||||
/* Specify list of LDAP servers that you want to try connecting to. */
|
||||
char *ldap_host = "ldap.example.com directory.example.com:1389";
|
||||
|
||||
/* If the LDAP server is running on the standard LDAP port (port 389),
|
||||
* you can use LDAP_PORT to identify the port number. */
|
||||
ldap_default_port = LDAP_PORT;
|
||||
...
|
||||
/* Initialize the session with the LDAP servers. */
|
||||
if ( ( ld = prldap_init( ldap_host, ldap_default_port, NULL ) ) == NULL ) {
|
||||
perror( "prldap_init" );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Specify the LDAP version supported by the client. */
|
||||
version = LDAP_VERSION3;
|
||||
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
|
||||
|
||||
...
|
||||
/* Subsequent calls pass ld as argument to identify the LDAP server. */
|
||||
|
||||
...</programlisting>
|
||||
</example>
|
||||
</sect2>
|
||||
<sect2 id="bdacg"><title>Setting Session Preferences With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>setting LDAP session preferences</secondary>
|
||||
</indexterm>
|
||||
<para>With &DirectorySDKForC;, you can set preferences for your client
|
||||
that you want applied to all LDAP sessions. To get or set the value of a preference,
|
||||
call the <function>ldap_get_option</function> or <function>ldap_set_option</function> functions
|
||||
respectively.</para>
|
||||
<itemizedlist>
|
||||
<para>Both functions pass two parameters in addition to the <parameter>ld</parameter> parameter,
|
||||
which represents the connection to the server:</para>
|
||||
<listitem><para>The <parameter>option</parameter> parameter identifies the
|
||||
option that you want to get or set.</para></listitem>
|
||||
<listitem><para>The <parameter>value</parameter> parameter is either a pointer
|
||||
to a place to put the value to get, or a pointer to the value to set.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>You can set a preference for all connections by passing <literal>NULL</literal> as
|
||||
the first argument, not an <structname>LDAP</structname> structure that specifies
|
||||
the connection.</para>
|
||||
<sect3 id="bdach"><title>Reconnecting Automatically</title>
|
||||
<para>If communication with the LDAP server is interrupted, the server returns <errorcode>
|
||||
LDAP_SERVER_DOWN</errorcode>. If you want your client to continue to attempt
|
||||
communication with the server, you can set the <literal>LDAP_OPT_RECONNECT</literal> preference
|
||||
for the session. Once set, if your connection is lost, the client attempts
|
||||
another bind with the same authentication to reestablish the connection.</para>
|
||||
<para>The following example shows that to set the reconnect preference, call
|
||||
the <function>ldap_set_option</function> function and pass <literal>LDAP_OPT_RECONNECT
|
||||
</literal> as the value of the <parameter>option</parameter> parameter. To
|
||||
resume LDAP I/O operations automatically, set the <parameter>optdata</parameter> parameter
|
||||
to <literal>LDAP_OPT_ON</literal>. This setting specifies the same connection
|
||||
handle that can be used to reconnect to the server. </para>
|
||||
<example><title>Passing Restart Preferences</title>
|
||||
<programlisting>ldap_set_option( ld, LDAP_OPT_RECONNECT, LDAP_OPT_ON );</programlisting>
|
||||
</example>
|
||||
<para>To avoid resuming I/O operations, you would set the <parameter>optdata</parameter> parameter
|
||||
to <literal>LDAP_OPT_OFF</literal>. This setting specifies that you want to
|
||||
create a new connection handle to connect to the server. By default, the <parameter>
|
||||
optdata</parameter> parameter is set to <literal>LDAP_OPT_OFF</literal>. Both <literal>
|
||||
LDAP_OPT_OFF</literal> and <literal>LDAP_OPT_ON</literal> are cast to <literal>(void
|
||||
*)</literal>.</para></sect3>
|
||||
<sect3 id="bdaci"><title>Specifying the LDAP Version of Your Client</title>
|
||||
<para>If you plan to call functions that use LDAP v3 features such as controls
|
||||
or extended operations, set the protocol version to LDAP v3. By default, clients
|
||||
built with &DirectorySDKForC; identify themselves to LDAP servers as LDAP
|
||||
v3 clients, but that was not the case with previous versions.</para>
|
||||
<para>To specify the LDAP version supported by your client, call the <function>ldap_set_option
|
||||
</function> function and set the <literal>LDAP_OPT_PROTOCOL_VERSION</literal> option
|
||||
to the value <literal>3</literal>.</para>
|
||||
<example><title>Passing the LDAP Protocol Version Number</title>
|
||||
<programlisting>...
|
||||
version = LDAP_VERSION3;
|
||||
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
|
||||
...</programlisting>
|
||||
</example>
|
||||
<para>After setting this option, as part of the authentication process, your
|
||||
client sends the supported LDAP version number to the server. By setting the
|
||||
version, you allow the server to determine whether or not to enable LDAP v3
|
||||
features.</para>
|
||||
<para>LDAP v3 allows you to perform LDAP operations without first binding
|
||||
to the server. An LDAP v3 server assumes that the client is LDAP v3 compliant
|
||||
if the client issues non-bind operations before the client issues a bind.</para>
|
||||
</sect3>
|
||||
<sect3 id="setting-connection-timeout"><title>Setting Connection Timeout</title>
|
||||
<para>Clients that use &DirectorySDKForC; can control the TCP/IP level
|
||||
timeout. When the TCP/IP timeout option is not set, an attempt to connect
|
||||
to a server blocks until the connection completes or the system times out.
|
||||
By using the <literal>LDAP_X_OPT_CONNECT_TIMEOUT</literal> option, you can
|
||||
adjust how long to wait for a connection.</para>
|
||||
<para>You specify the timeout as an <literal>int</literal> number of milliseconds,
|
||||
then call the <function>ldap_set_option</function> function, passing the <literal>
|
||||
LDAP_X_OPT_CONNECT_TIMEOUT</literal> option.</para>
|
||||
<example><title>Passing Connection Timeout Preferences</title>
|
||||
<para>The following example sets the connection timeout to one second.</para>
|
||||
<programlisting>int timeout = 1000; /* 1000 milliseconds == 1 second */
|
||||
ldap_set_option( ld, LDAP_X_OPT_CONNECT_TIMEOUT, &timeout );</programlisting>
|
||||
</example>
|
||||
<itemizedlist>
|
||||
<para>The <literal>LDAP_X_OPT_CONNECT_TIMEOUT</literal> option can be set
|
||||
using the following values as well:</para>
|
||||
<listitem><para><literal>LDAP_X_IO_TIMEOUT_NO_WAIT</literal></para><para>Return
|
||||
immediately if the server cannot be reached.</para></listitem>
|
||||
<listitem><para><literal>LDAP_X_IO_TIMEOUT_NO_TIMEOUT</literal></para><para>Wait
|
||||
indefinitely for the server to connect.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>By passing <literal>NULL</literal> as the first parameter to the <function>
|
||||
ldap_set_option</function> function, you can set the default timeout for all
|
||||
connections used by your application.</para></sect3>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="bdacj"><title>Binding and Authenticating to an LDAP Server With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>binding and authenticating</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>binding</primary>
|
||||
<secondary>with C SDK</secondary>
|
||||
</indexterm>
|
||||
<para>When connecting to the LDAP server, your client might need to send a
|
||||
bind request.</para>
|
||||
<itemizedlist>
|
||||
<para>A bind request should be sent if either of the following are true.</para>
|
||||
<listitem><para>You want to authenticate to the server to add or modify entries
|
||||
in a directory that requires authentication as a user with certain access
|
||||
privileges.</para></listitem>
|
||||
<listitem><para>You are connecting to an LDAP v2 server. LDAP v2 servers typically
|
||||
require clients to bind before any operations can be performed.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<para>The bind request should contain the following information:</para>
|
||||
<listitem><para> LDAP version of the client</para></listitem>
|
||||
<listitem><para> Method of authentication to use</para></listitem>
|
||||
<listitem><para> DN that the client is attempting to authenticate as</para>
|
||||
</listitem>
|
||||
<listitem><para> Credentials to be used for authentication</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>LDAP clients can also bind anonymously to the LDAP server if, for example,
|
||||
the server is configured not to require authentication for a simple directory
|
||||
search.</para>
|
||||
<sect2 id="bdaco"><?Pub Caret1><title>Using Simple Authentication With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>methods of authentication</secondary>
|
||||
<tertiary>simple authentication</tertiary>
|
||||
</indexterm><indexterm>
|
||||
<primary>authentication</primary>
|
||||
<secondary>C SDK</secondary>
|
||||
<tertiary>simple</tertiary>
|
||||
</indexterm>
|
||||
<itemizedlist>
|
||||
<para>If you plan to use simple authentication, call one of the following
|
||||
functions:</para>
|
||||
<listitem><para><function>ldap_simple_bind_s</function> is a synchronous function
|
||||
for use if you want to wait for the bind operation to complete before the
|
||||
function returns.</para><para>See <olink targetptr="bdacp">Performing a Synchronous
|
||||
Authentication Operation</olink></para></listitem>
|
||||
<listitem><para><function>ldap_simple_bind</function> is an asynchronous function
|
||||
for use if you do not want to wait for the bind operation to complete. With
|
||||
this function, you can perform other work while periodically checking for
|
||||
the results of the bind operation.</para><para>See <olink targetptr="bdacq">Performing
|
||||
an Asynchronous Authentication Operation</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
<para>For more information about the differences between the types of functions,
|
||||
see <olink targetptr="bdacv">Synchronous and Asynchronous Functions</olink>.</para>
|
||||
<sect3 id="bdacp"><title>Performing a Synchronous Authentication Operation</title>
|
||||
<para>If you want to wait for the bind operation to complete before continuing,
|
||||
call <function>ldap_simple_bind_s</function>. This function returns <errorcode>LDAP_SUCCESS
|
||||
</errorcode> if the operation completed successfully, or an LDAP result code
|
||||
if a problem occurred. See <function>ldap_simple_bind_s</function> in <olink targetptr="bdavj">ldap_simple_bind_s</olink> for a list of result codes returned.
|
||||
</para>
|
||||
<para>If you specify a DN but no password, your client binds to the server
|
||||
anonymously. If you want a <literal>NULL</literal> password to be rejected
|
||||
as incorrect, you must write code to perform the check before you call <function>
|
||||
ldap_simple_bind_s</function>.</para>
|
||||
<para>The following example uses the synchronous <function>ldap_simple_bind_s</function> function
|
||||
to authenticate user Barbara Jensen to the LDAP server.</para>
|
||||
<example id="csdk-sync-auth-example"><title>Performing Synchronous Authentication
|
||||
</title>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include "ldap.h"
|
||||
|
||||
/* Change these as needed. */
|
||||
#define HOSTNAME "localhost"
|
||||
#define PORTNUMBER LDAP_PORT
|
||||
#define BIND_DN "uid=bjensen,ou=People,dc=example,dc=com"
|
||||
#define BIND_PW "hifalutin"
|
||||
|
||||
LDAP *ld;
|
||||
int rc;
|
||||
/* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
|
||||
if ( (ld = ldap_init( HOSTNAME, PORTNUMBER )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Print out an informational message. */
|
||||
printf( "Binding to server %s:%d\n", HOSTNAME, PORTNUMBER );
|
||||
printf( "as the DN %s ...\n", BIND_DN );
|
||||
|
||||
/* Bind to the LDAP server. */
|
||||
rc = ldap_simple_bind_s( ld, BIND_DN, BIND_PW );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf(stderr, "ldap_simple_bind_s: %s\n\n", ldap_err2string(rc));
|
||||
return( 1 );
|
||||
} else {
|
||||
printf( "Bind operation successful.\n" );
|
||||
}
|
||||
|
||||
...
|
||||
/* If you want, you can perform LDAP operations here. */
|
||||
...
|
||||
|
||||
/* Disconnect from the server when done. */
|
||||
ldap_unbind( ld );
|
||||
return( 0 );
|
||||
...</programlisting>
|
||||
</example>
|
||||
</sect3>
|
||||
<sect3 id="bdacq"><title>Performing an Asynchronous Authentication Operation</title>
|
||||
<para>If you want to perform other work in parallel while waiting for the
|
||||
bind operation to complete, call <function>ldap_simple_bind</function>. This
|
||||
function sends an LDAP bind request to the server and returns a message ID
|
||||
identifying the bind operation. To see if your client has received the results
|
||||
of the bind operation, call the <function>ldap_result</function> function
|
||||
with the message ID. If your client has received the results, <function>ldap_result
|
||||
</function> passes back the information in an <structname>LDAPMessage</structname> structure.
|
||||
To retrieve error information from <structname>LDAPMessage</structname>, you
|
||||
can pass the message ID to the <function>ldap_parse_result</function> function. <function>
|
||||
ldap_parse_result</function> gets the LDAP result code of the operation and
|
||||
any error messages sent back from the server. This function also retrieves
|
||||
any controls sent back.</para>
|
||||
<para>If you specify a DN but no password, your client binds to the server
|
||||
anonymously. If you want a <literal>NULL</literal> password to be rejected
|
||||
as incorrect, you need to write code to perform the check before you call <function>
|
||||
ldap_simple_bind</function>.</para>
|
||||
<para>The following example uses the asynchronous <function>ldap_simple_bind</function> function
|
||||
to authenticate user Barbara Jensen to the LDAP server.</para>
|
||||
<example id="csdk-async-auth-example"><title>Performing Asynchronous Authentication
|
||||
</title>
|
||||
<indexterm>
|
||||
<primary>example programs</primary>
|
||||
<secondary>asynchronous authentication</secondary>
|
||||
</indexterm>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include "ldap.h"
|
||||
|
||||
void do_other_work();
|
||||
int global_counter = 0;
|
||||
...
|
||||
|
||||
#define HOSTNAME "localhost"
|
||||
#define PORTNUMBER LDAP_PORT
|
||||
#define BIND_DN "uid=bjensen,ou=People,dc=example,dc=com"
|
||||
#define BIND_PW "hifalutin"
|
||||
|
||||
...
|
||||
LDAP *ld;
|
||||
LDAPMessage *res;
|
||||
int msgid = 0, rc = 0, parse_rc = 0, finished = 0;
|
||||
char *matched_msg = NULL, *error_msg = NULL;
|
||||
char **referrals;
|
||||
LDAPControl **serverctrls;
|
||||
struct timeval zerotime;
|
||||
|
||||
/* Specify the timeout period for ldap_result(),
|
||||
which specifies how long the function should block when waiting
|
||||
for results from the server. */
|
||||
zerotime.tv_sec = zerotime.tv_usec = 0L;
|
||||
|
||||
/* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
|
||||
if ( (ld = ldap_init( HOSTNAME, PORTNUMBER )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Print out an informational message. */
|
||||
printf( "Binding to server %s:%d\n", HOSTNAME, PORTNUMBER );
|
||||
printf( "as the DN %s ...\n", BIND_DN );
|
||||
|
||||
/* Send an LDAP bind request to the server. */
|
||||
msgid = ldap_simple_bind( ld, BIND_DN, BIND_PW );
|
||||
|
||||
/* If the returned message ID is less than zero, an error occurred. */
|
||||
if ( msgid < 0 ) {
|
||||
rc = ldap_get_lderrno( ld, NULL, NULL );
|
||||
fprintf(stderr, "ldap_simple_bind : %s\n", ldap_err2string(rc));
|
||||
ldap_unbind( ld );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Check to see if the bind operation completed. */
|
||||
while ( !finished ) {
|
||||
rc = ldap_result( ld, msgid, 0, &zerotime, &res );
|
||||
switch ( rc ) {
|
||||
/* If ldap_result() returns -1, error occurred. */
|
||||
case -1:
|
||||
rc = ldap_get_lderrno( ld, NULL, NULL );
|
||||
fprintf( stderr, "ldap_result: %s\n", ldap_err2string( rc ) );
|
||||
ldap_unbind( ld );
|
||||
return ( 1 );
|
||||
|
||||
/* If ldap_result() returns 0, the timeout (specified by the
|
||||
timeout argument) has been exceeded before the client received
|
||||
the results from the server. Continue calling ldap_result()
|
||||
to poll for results from the server. */
|
||||
case 0:
|
||||
break;
|
||||
|
||||
default:
|
||||
/* The client has received the result of the bind operation. */
|
||||
finished = 1;
|
||||
|
||||
/* Parse this result to determine if the operation was successful.
|
||||
Note that a non-zero value is passed as the last parameter,
|
||||
which indicates that the LDAPMessage structure res should be
|
||||
freed when done. (No need to call ldap_msgfree().) */
|
||||
parse_rc = ldap_parse_result( ld, res, &rc, &matched_msg,
|
||||
&error_msg, &referrals, &serverctrls, 1 );
|
||||
if ( parse_rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr, "ldap_parse_result: %s\n",
|
||||
ldap_err2string( parse_rc ) );
|
||||
ldap_unbind( ld );
|
||||
return( 1 );
|
||||
}
|
||||
/* Check the results of the operation. */
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr, "ldap_simple_bind: %s\n",
|
||||
ldap_err2string( rc ) );
|
||||
|
||||
/* If the server sent an additional error message,
|
||||
print it out. */
|
||||
if ( error_msg != NULL && *error_msg != '\0' ) {
|
||||
fprintf( stderr, "%s\n", error_msg );
|
||||
}
|
||||
|
||||
/* If an entry specified by a DN could not be found,
|
||||
the server may also return the portion of the DN
|
||||
that identifies an existing entry. */
|
||||
if ( matched_msg != NULL && *matched_msg != '\0' ) {
|
||||
fprintf( stderr,
|
||||
"Part of the DN that matches an existing entry: %s\n",
|
||||
matched_msg );
|
||||
}
|
||||
ldap_unbind( ld );
|
||||
return( 1 );
|
||||
} else {
|
||||
printf( "Bind operation successful.\n" );
|
||||
printf( "Counted to %d while waiting for bind op.\n",
|
||||
global_counter );
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Do other work here while waiting for results from the server. */
|
||||
if ( !finished ) {
|
||||
do_other_work();
|
||||
}
|
||||
}
|
||||
|
||||
...
|
||||
/* If you want, you can perform LDAP operations here. */
|
||||
...
|
||||
|
||||
/* Disconnect from the server when done. */
|
||||
ldap_unbind( ld );
|
||||
return( 0 );
|
||||
...
|
||||
/* Function that does work while waiting for results from the server. */
|
||||
void do_other_work() {
|
||||
global_counter++;
|
||||
}
|
||||
...</programlisting>
|
||||
</example>
|
||||
</sect3>
|
||||
</sect2>
|
||||
<sect2 id="bdacr"><title>Binding Anonymously With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>methods of authentication</secondary>
|
||||
<tertiary>anonymous authentication</tertiary>
|
||||
</indexterm><indexterm>
|
||||
<primary>authentication</primary>
|
||||
<secondary>C SDK</secondary>
|
||||
<tertiary>anonymous</tertiary>
|
||||
</indexterm>
|
||||
<para>In some cases, you do not need to authenticate to the LDAP server. For
|
||||
example, if users are performing a search that has no special access permissions,
|
||||
you need not authenticate before performing the search. To bind as an anonymous
|
||||
user, call <function>ldap_simple_bind</function> or <function>ldap_simple_bind_s</function>,
|
||||
and pass <literal>NULL</literal> values for the <parameter>who</parameter> and <parameter>
|
||||
passwd</parameter> parameters.</para>
|
||||
<programlisting>rc = ldap_simple_bind_s( ld, NULL, NULL );
|
||||
|
||||
</programlisting>
|
||||
<para>With LDAP v2, the client is required to send a bind request, even when
|
||||
binding anonymously. That is, bind without specifying a name or password.
|
||||
With LDAP v3, the client is no longer required to bind to the server if the
|
||||
client does not need to authenticate.</para></sect2>
|
||||
</sect1>
|
||||
<sect1 id="bdacs"><title>Performing LDAP Operations With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>LDAP operations</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP operations</primary>
|
||||
<secondary>with C SDK</secondary>
|
||||
</indexterm>
|
||||
<para>After initializing a session with a server and completing the authentication
|
||||
process, you can perform LDAP operations. The LDAP operations include searching
|
||||
the directory, adding new entries, updating existing entries, and removing
|
||||
entries. The following lists LDAP operations and the functions that you can
|
||||
call to perform the operations.</para>
|
||||
<table frame="topbot" id="csdk-fcns-ldap-ops"><title>Functions for Performing
|
||||
LDAP Operations</title>
|
||||
<tgroup cols="2"><colspec colnum="1" colwidth="50*"><colspec colnum="2"
|
||||
colwidth="50*">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>
|
||||
<para>To Perform This Operation</para></entry>
|
||||
<entry>
|
||||
<para>Call This API Function</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Search for entries</para></entry>
|
||||
<entry>
|
||||
<para><function>ldap_search_ext</function></para>
|
||||
<para><function>ldap_search_ext_s</function></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Determine an attribute’s value</para></entry>
|
||||
<entry>
|
||||
<para><function>ldap_compare_ext</function></para>
|
||||
<para><function>ldap_compare_ext_s</function></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Add entries</para></entry>
|
||||
<entry>
|
||||
<para><function>ldap_add_ext</function></para>
|
||||
<para><function>ldap_add_ext_s</function></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Modify entries</para></entry>
|
||||
<entry>
|
||||
<para><function>ldap_modify_ext</function></para>
|
||||
<para><function>ldap_modify_ext_s</function></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Delete entries</para></entry>
|
||||
<entry>
|
||||
<para><function>ldap_delete_ext</function></para>
|
||||
<para><function>ldap_delete_ext_s</function></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Change DN of entries</para></entry>
|
||||
<entry>
|
||||
<para><function>ldap_rename_ext</function></para>
|
||||
<para><function>ldap_rename_ext_s</function></para></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<para>Most LDAP operations can be performed synchronously or asynchronously.
|
||||
The functions with names that end in <literal>_s</literal> are synchronous.
|
||||
The remaining ones are asynchronous. For more information about the distinction
|
||||
between the functions, see <olink targetptr="bdaau">Synchronous and Asynchronous
|
||||
Operations</olink>.</para></sect1>
|
||||
<sect1 id="bdact"><title>Closing the Connection to an LDAP Server With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>closing an LDAP server connection</secondary>
|
||||
</indexterm>
|
||||
<para>When you have finished performing all necessary LDAP operations, you
|
||||
need to close the connection to the LDAP server. After you close the connection,
|
||||
you can no longer use the <structname>LDAP</structname> structure because
|
||||
the structure is freed from memory.</para>
|
||||
<itemizedlist>
|
||||
<para>To close a connection to an LDAP server, call one of the following functions:
|
||||
</para>
|
||||
<listitem><para><function>ldap_unbind</function></para></listitem>
|
||||
<listitem><para><function>ldap_unbind_s</function></para></listitem>
|
||||
<listitem><para><function>ldap_unbind_ext</function></para></listitem>
|
||||
</itemizedlist>
|
||||
<para>Both <function>ldap_unbind</function> and <function>ldap_unbind_s</function> are
|
||||
identical synchronous functions. These functions use different names so that
|
||||
each function has a corresponding authentication function, <function>ldap_simple_bind
|
||||
</function> and <function>ldap_simple_bind_s</function>, to close the server
|
||||
connection. </para>
|
||||
<para>The <function>ldap_unbind_ext</function> function allows you to include
|
||||
explicitly both server and client controls in your unbind request. However,
|
||||
as the server does not respond to an unbind request, you cannot receive a
|
||||
response from a server control attached to your unbind request. </para>
|
||||
<para>The following example closes the current connection with the LDAP server.</para>
|
||||
<example id="csdk-close-conn-example"><title>Closing an LDAP Server Connection</title>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include "ldap.h"
|
||||
...
|
||||
LDAP *ld;
|
||||
int rc;
|
||||
...
|
||||
/* After completing your LDAP operations with the server, close
|
||||
the connection. */
|
||||
rc = ldap_unbind( ld );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr, "ldap_unbind: %s\n", ldap_err2string( rc ) );
|
||||
}
|
||||
...</programlisting>
|
||||
</example>
|
||||
</sect1>
|
||||
</chapter>
|
||||
438
mozilla/directory/docs/ldapcsdk/csdk-compare.sgm
Normal file
438
mozilla/directory/docs/ldapcsdk/csdk-compare.sgm
Normal file
@@ -0,0 +1,438 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="csdk-compare"><title>Comparing Attribute Values
|
||||
With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>comparing attribute values</secondary>
|
||||
</indexterm><highlights>
|
||||
<para>This chapter describes how to compare the value of an attribute in an
|
||||
entry against a specified value.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="bdahc">Functions for Comparing Attribute
|
||||
Values With Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdahd">Performing Synchronous Comparison
|
||||
Operations With Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdahe">Performing Asynchronous Comparison
|
||||
Operations With Directory SDK for C</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="bdahc"><title>Functions for Comparing Attribute Values With Directory
|
||||
SDK for C</title>
|
||||
<para>&DirectorySDKForC; has functions to determine if an attribute contains
|
||||
a certain string or binary value.</para>
|
||||
<itemizedlist>
|
||||
<para>To determine if an attribute contains a certain <emphasis>string</emphasis> value,
|
||||
call either of the following functions:</para>
|
||||
<listitem><para>The synchronous <function>ldap_compare_s</function> function</para>
|
||||
</listitem>
|
||||
<listitem><para>The asynchronous <function>ldap_compare</function> function</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<para>To determine if an attribute contains a certain <emphasis>binary</emphasis> value,
|
||||
call either of the following functions:</para>
|
||||
<listitem><para>The synchronous <function>ldap_compare_ext_s</function> function</para>
|
||||
</listitem>
|
||||
<listitem><para>The asynchronous <function>ldap_compare_ext</function> function</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="bdahd"><title>Performing Synchronous Comparison Operations With
|
||||
Directory SDK for C</title>
|
||||
<indexterm>
|
||||
<primary>synchronous functions</primary>
|
||||
<secondary>comparison operation</secondary>
|
||||
</indexterm>
|
||||
<para>You can wait for the results of the compare operation to complete before
|
||||
continuing. Call the synchronous <function>ldap_compare_ext_s</function> function
|
||||
to compare values in <structname>berval</structname> structures or the synchronous <function>
|
||||
ldap_compare_s</function> function to compare string values. These functions
|
||||
send a compare request to the server and block work until the server sends
|
||||
the results of the operation back to your client.</para>
|
||||
<itemizedlist>
|
||||
<para>Both functions return one of the following values after the compare
|
||||
operation completes:</para>
|
||||
<listitem><para><errorcode>LDAP_COMPARE_TRUE</errorcode> indicates that the
|
||||
attribute contains the specified value.</para></listitem>
|
||||
<listitem><para><errorcode>LDAP_COMPARE_FALSE</errorcode> indicates that the
|
||||
attribute does not contain the specified value.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>An error code indicates that a problem has occurred during the operation.</para>
|
||||
<para>The following example calls the synchronous <function>ldap_compare_s</function> function
|
||||
to determine if an entry has the value <literal>bjensen@example.com</literal> in
|
||||
the <literal>mail</literal> attribute.</para>
|
||||
<example id="compare-sync-example"><title>Performing a Synchronous Compare
|
||||
Operation</title>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include "ldap.h"
|
||||
...
|
||||
#define COMPARE_DN "uid=bjensen,ou=People,dc=example,dc=com"
|
||||
#define COMPARE_ATTR "mail"
|
||||
#define COMPARE_VALUE "bjensen@example.com"
|
||||
...
|
||||
LDAP *ld;
|
||||
char *matched_msg = NULL, *error_msg = NULL;
|
||||
int rc;
|
||||
...
|
||||
/* Perform the compare operation. */
|
||||
rc = ldap_compare_s( ld, COMPARE_DN, COMPARE_ATTR, COMPARE_VALUE );
|
||||
switch( rc ) {
|
||||
case LDAP_COMPARE_TRUE:
|
||||
printf( "%s has the value %s in the %s attribute.\n", COMPARE_DN,
|
||||
COMPARE_VALUE, COMPARE_ATTR );
|
||||
break;
|
||||
case LDAP_COMPARE_FALSE:
|
||||
printf( "%s does not have the value %s in the %s attribute.\n",
|
||||
COMPARE_DN, COMPARE_VALUE, COMPARE_ATTR );
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "ldap_compare_s: %s\n", ldap_err2string( rc ) );
|
||||
ldap_get_lderrno( ld, &matched_msg, &error_msg );
|
||||
if ( error_msg != NULL && *error_msg != '\0' ) {
|
||||
fprintf( stderr, "%s\n", error_msg );
|
||||
}
|
||||
if ( matched_msg != NULL && *matched_msg != '\0' ) {
|
||||
fprintf( stderr,
|
||||
"Part of the DN that matches an existing entry: %s\n",
|
||||
matched_msg );
|
||||
}
|
||||
break;
|
||||
}
|
||||
ldap_unbind_s( ld );
|
||||
...</programlisting>
|
||||
</example>
|
||||
<para>The following sample program calls the synchronous <function>ldap_compare_s
|
||||
</function> function. The sample program uses this function to determine if
|
||||
a user entry has the value <literal>bjensen@example.com</literal> in the <literal>
|
||||
mail</literal> attribute.</para>
|
||||
<example id="compare-sync-full-example"><title>Sample Synchronous Compare
|
||||
Program</title>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include "ldap.h"
|
||||
|
||||
/* Change these as needed. */
|
||||
#define HOSTNAME "localhost"
|
||||
#define PORTNUMBER LDAP_PORT
|
||||
#define COMPARE_DN "uid=bjensen,ou=People,dc=example,dc=com"
|
||||
#define COMPARE_ATTR "mail"
|
||||
#define COMPARE_VALUE "bjensen@example.com"
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
LDAP *ld;
|
||||
char *matched_msg = NULL, *error_msg = NULL;
|
||||
int rc;
|
||||
/* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
|
||||
if ( (ld = ldap_init( HOSTNAME, PORTNUMBER )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
return( 1 );
|
||||
}
|
||||
/* Bind anonymously to the server. */
|
||||
rc = ldap_simple_bind_s( ld, NULL, NULL );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr, "ldap_simple_bind_s: %s\n", ldap_err2string( rc ) );
|
||||
ldap_get_lderrno( ld, &matched_msg, &error_msg );
|
||||
if ( error_msg != NULL && *error_msg != '\0' ) {
|
||||
fprintf( stderr, "%s\n", error_msg );
|
||||
}
|
||||
if ( matched_msg != NULL && *matched_msg != '\0' ) {
|
||||
fprintf( stderr,
|
||||
"Part of the DN that matches an existing entry: %s\n",
|
||||
matched_msg );
|
||||
}
|
||||
ldap_unbind_s( ld );
|
||||
return( 1 );
|
||||
}
|
||||
/* Perform the compare operation. */
|
||||
rc = ldap_compare_s( ld, COMPARE_DN, COMPARE_ATTR, COMPARE_VALUE );
|
||||
switch( rc ) {
|
||||
case LDAP_COMPARE_TRUE:
|
||||
printf( "%s has the value %s in the %s attribute.\n",
|
||||
COMPARE_DN, COMPARE_VALUE, COMPARE_ATTR );
|
||||
break;
|
||||
case LDAP_COMPARE_FALSE:
|
||||
printf( "%s does not have the value %s in the %s attribute.\n",
|
||||
COMPARE_DN, COMPARE_VALUE, COMPARE_ATTR );
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "ldap_compare_s: %s\n", ldap_err2string( rc ) );
|
||||
ldap_get_lderrno( ld, &matched_msg, &error_msg );
|
||||
if ( error_msg != NULL && *error_msg != '\0' ) {
|
||||
fprintf( stderr, "%s\n", error_msg );
|
||||
}
|
||||
if ( matched_msg != NULL && *matched_msg != '\0' ) {
|
||||
fprintf( stderr,
|
||||
"Part of the DN that matches an existing entry: %s\n",
|
||||
matched_msg );
|
||||
}
|
||||
break;
|
||||
}
|
||||
ldap_unbind_s( ld );
|
||||
return 0;
|
||||
}</programlisting>
|
||||
</example>
|
||||
</sect1>
|
||||
<sect1 id="bdahe"><title>Performing Asynchronous Comparison Operations With
|
||||
Directory SDK for C</title>
|
||||
<indexterm>
|
||||
<primary>asynchronous functions</primary>
|
||||
<secondary>comparison operation</secondary>
|
||||
</indexterm>
|
||||
<para>You can perform other work in parallel while waiting for the comparison
|
||||
to complete. Call the asynchronous <function>ldap_compare_ext</function> function
|
||||
to compare values in <structname>berval</structname> structures or the asynchronous <function>
|
||||
ldap_compare</function> function to compare string values. These functions
|
||||
send a compare request to the server and return an <errorcode>LDAP_SUCCESS</errorcode> result
|
||||
code if the request was successfully sent, or an LDAP result code if an error
|
||||
occurred.</para>
|
||||
<para>Both functions pass back a message ID identifying the compare operation.
|
||||
To determine whether the server sent a response for this operation to your
|
||||
client, call the <function>ldap_result</function> function and pass in the
|
||||
message ID. The <function>ldap_result</function> function uses the message
|
||||
ID to determine if the server sent the results of the compare operation. The <function>
|
||||
ldap_result</function> function passes back the results in an <structname>LDAPMessage
|
||||
</structname> structure. You can call the <function>ldap_parse_result</function> function
|
||||
to parse the <structname>LDAPMessage</structname> structure to determine if
|
||||
the operation was successful.</para>
|
||||
<itemizedlist>
|
||||
<para>The result code should be one of the following:</para>
|
||||
<listitem><para><errorcode>LDAP_COMPARE_TRUE</errorcode> indicates that the
|
||||
attribute contains the specified value.</para></listitem>
|
||||
<listitem><para><errorcode>LDAP_COMPARE_FALSE</errorcode> indicates that the
|
||||
attribute does not contain the specified value.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>An error code indicates that a problem occurred during the operation.</para>
|
||||
<para>The following example calls the asynchronous <function>ldap_compare</function> function
|
||||
to determine if an entry has the value <literal>bjensen@example.com</literal> in
|
||||
the <literal>mail</literal> attribute.</para>
|
||||
<example id="compare-async-example"><title>Performing an Asynchronous Compare
|
||||
Operation</title>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include "ldap.h"
|
||||
...
|
||||
#define COMPARE_DN "uid=bjensen,ou=People,dc=example,dc=com"
|
||||
#define COMPARE_ATTR "mail"
|
||||
#define COMPARE_VALUE "bjensen@example.com"
|
||||
...
|
||||
LDAP *ld;
|
||||
LDAPMessage *res;
|
||||
LDAPControl **serverctrls;
|
||||
char *matched_msg = NULL, *error_msg = NULL;
|
||||
char **referrals;
|
||||
int rc, parse_rc, msgid, finished = 0;
|
||||
struct timeval zerotime;
|
||||
zerotime.tv_sec = zerotime.tv_usec = 0L;
|
||||
...
|
||||
/* Send the LDAP compare request. */
|
||||
msgid = ldap_compare( ld, COMPARE_DN, COMPARE_ATTR, COMPARE_VALUE );
|
||||
if ( msgid < 0 ) {
|
||||
fprintf( stderr, "ldap_compare: %s\n", ldap_err2string( rc ) );
|
||||
ldap_unbind( ld );
|
||||
return( 1 );
|
||||
}
|
||||
/* Poll the server for the results of the LDAP compare operation. */
|
||||
while ( !finished ) {
|
||||
rc = ldap_result( ld, msgid, 0, &zerotime, &res );
|
||||
switch ( rc ) {
|
||||
|
||||
case -1:
|
||||
/* An error occurred. */
|
||||
rc = ldap_get_lderrno( ld, NULL, NULL );
|
||||
fprintf( stderr, "ldap_result: %s\n", ldap_err2string( rc ) );
|
||||
ldap_unbind( ld );
|
||||
return( 1 );
|
||||
|
||||
case 0:
|
||||
/* The timeout period specified by zerotime was exceeded, so
|
||||
call ldap_result() again and continue to poll for the
|
||||
results. */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* The client has received the results of the
|
||||
LDAP compare operation from the server. */
|
||||
finished = 1;
|
||||
|
||||
/* Parse the results received from the server.*/
|
||||
parse_rc = ldap_parse_result( ld, res, &rc, &matched_msg,
|
||||
&error_msg, &referrals, &serverctrls, 1 );
|
||||
if ( parse_rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr, "ldap_parse_result: %s\n",
|
||||
ldap_err2string( parse_rc ) );
|
||||
ldap_unbind( ld );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Check the results of the LDAP compare operation. */
|
||||
switch ( rc ) {
|
||||
case LDAP_COMPARE_TRUE:
|
||||
printf( "%s has the value %s in the %s attribute.\n",
|
||||
COMPARE_DN, COMPARE_VALUE, COMPARE_ATTR );
|
||||
break;
|
||||
case LDAP_COMPARE_FALSE:
|
||||
printf( "%s does not have the value %s in the %s attribute.\n",
|
||||
COMPARE_DN, COMPARE_VALUE, COMPARE_ATTR );
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "ldap_compare: %s\n", ldap_err2string( rc ) );
|
||||
if ( error_msg != NULL & *error_msg != '\0' ) {
|
||||
fprintf( stderr, "%s\n", error_msg );
|
||||
}
|
||||
if ( matched_msg != NULL && *matched_msg != '\0' ) {
|
||||
fprintf( stderr,
|
||||
"Part of the DN that matches an existing entry: %s\n",
|
||||
matched_msg );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
...</programlisting>
|
||||
</example>
|
||||
<para>The following sample program calls the asynchronous <function>ldap_compare</function> function.
|
||||
The sample program uses this function to determine if a user entry has the
|
||||
value <literal>bjensen@example.com</literal> in the <literal>mail</literal> attribute.
|
||||
</para>
|
||||
<example id="compare-async-full-example"><title>Sample Asynchronous Compare
|
||||
Program</title>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include "ldap.h"
|
||||
void do_other_work();
|
||||
int global_counter = 0;
|
||||
/* Change these as needed. */
|
||||
#define HOSTNAME "localhost"
|
||||
#define PORTNUMBER LDAP_PORT
|
||||
#define COMPARE_DN "uid=bjensen,ou=People,dc=example,dc=com"
|
||||
#define COMPARE_ATTR "mail"
|
||||
#define COMPARE_VALUE "bjensen@example.com"
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
LDAP *ld;
|
||||
LDAPMessage *res;
|
||||
LDAPControl **serverctrls;
|
||||
char *matched_msg = NULL, *error_msg = NULL;
|
||||
char **referrals;
|
||||
int rc, parse_rc, msgid, finished = 0;
|
||||
struct timeval zerotime;
|
||||
zerotime.tv_sec = zerotime.tv_usec = 0L;
|
||||
/* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
|
||||
if ( (ld = ldap_init( HOSTNAME, PORTNUMBER )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
return( 1 );
|
||||
}
|
||||
/* Bind anonymously to the server. */
|
||||
rc = ldap_simple_bind_s( ld, NULL, NULL );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr, "ldap_simple_bind_s: %s\n", ldap_err2string( rc ) );
|
||||
ldap_get_lderrno( ld, NULL, &error_msg );
|
||||
if ( error_msg != NULL && *error_msg != '\0' ) {
|
||||
fprintf( stderr, "%s\n", error_msg );
|
||||
}
|
||||
ldap_unbind_s( ld );
|
||||
return( 1 );
|
||||
}
|
||||
/* Send the LDAP compare request. */
|
||||
msgid = ldap_compare( ld, COMPARE_DN, COMPARE_ATTR, COMPARE_VALUE );
|
||||
if ( msgid < 0 ) {
|
||||
fprintf( stderr, "ldap_compare: %s\n", ldap_err2string( rc ) );
|
||||
ldap_unbind( ld );
|
||||
return( 1 );
|
||||
}
|
||||
/* Poll the server for the results of the LDAP compare operation. */
|
||||
while ( !finished ) {
|
||||
rc = ldap_result( ld, msgid, 0, &zerotime, &res );
|
||||
switch ( rc ) {
|
||||
case -1:
|
||||
/* An error occurred. */
|
||||
rc = ldap_get_lderrno( ld, NULL, NULL );
|
||||
fprintf( stderr, "ldap_result: %s\n", ldap_err2string( rc ) );
|
||||
ldap_unbind( ld );
|
||||
return( 1 );
|
||||
case 0:
|
||||
/* The timeout period specified by zerotime was exceeded.
|
||||
This means that your client has not yet received the
|
||||
results of the LDAP compare operation.
|
||||
Break out of this switch statement, and continue calling
|
||||
ldap_result() to poll for the results. */
|
||||
break;
|
||||
default:
|
||||
/* The client has received the results of the
|
||||
LDAP compare operation from the server. */
|
||||
finished = 1;
|
||||
/* Parse the results received from the server. Note the last
|
||||
argument is a non-zero value, which indicates that the
|
||||
LDAPMessage structure will be freed when done. (No need
|
||||
to call ldap_msgfree().) */
|
||||
parse_rc = ldap_parse_result( ld, res, &rc, &matched_msg,
|
||||
&error_msg, &referrals, &serverctrls, 1 );
|
||||
if ( parse_rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr,
|
||||
"ldap_parse_result: %s\n",
|
||||
ldap_err2string( parse_rc ) );
|
||||
ldap_unbind( ld );
|
||||
return( 1 );
|
||||
}
|
||||
/* Check the results of the LDAP compare operation. */
|
||||
switch ( rc ) {
|
||||
case LDAP_COMPARE_TRUE:
|
||||
printf( "%s has the value %s in the %s attribute.\n"
|
||||
"Counted to %d while waiting for the compare operation.\n",
|
||||
COMPARE_DN, COMPARE_VALUE, COMPARE_ATTR, global_counter );
|
||||
break;
|
||||
case LDAP_COMPARE_FALSE:
|
||||
printf( "%s does not have the value %s in the %s attribute.\n"
|
||||
"Counted to %d while waiting for the compare operation.\n",
|
||||
COMPARE_DN, COMPARE_VALUE, COMPARE_ATTR, global_counter );
|
||||
break;
|
||||
default:
|
||||
fprintf( stderr, "ldap_compare: %s\n", ldap_err2string( rc ) );
|
||||
if ( error_msg != NULL & *error_msg != '\0' ) {
|
||||
fprintf( stderr, "%s\n", error_msg );
|
||||
}
|
||||
if ( matched_msg != NULL && *matched_msg != '\0' ) {
|
||||
fprintf( stderr,
|
||||
"Part of the DN that matches an existing entry: %s\n",
|
||||
matched_msg );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Do other work while waiting for the results of the
|
||||
compare operation. */
|
||||
if ( !finished ) {
|
||||
do_other_work();
|
||||
}
|
||||
}
|
||||
ldap_unbind( ld );
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Perform other work while polling for results. This
|
||||
* doesn't do anything useful, but it could.
|
||||
*/
|
||||
void
|
||||
do_other_work()
|
||||
{
|
||||
global_counter++;
|
||||
}</programlisting>
|
||||
</example>
|
||||
</sect1>
|
||||
</chapter>
|
||||
2028
mozilla/directory/docs/ldapcsdk/csdk-controls.sgm
Normal file
2028
mozilla/directory/docs/ldapcsdk/csdk-controls.sgm
Normal file
File diff suppressed because it is too large
Load Diff
3580
mozilla/directory/docs/ldapcsdk/csdk-datatypes.sgm
Normal file
3580
mozilla/directory/docs/ldapcsdk/csdk-datatypes.sgm
Normal file
File diff suppressed because it is too large
Load Diff
389
mozilla/directory/docs/ldapcsdk/csdk-extendop.sgm
Normal file
389
mozilla/directory/docs/ldapcsdk/csdk-extendop.sgm
Normal file
@@ -0,0 +1,389 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="csdk-extop"><title>Extended Operations With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>extended operations</secondary>
|
||||
</indexterm><highlights>
|
||||
<para>This chapter explains LDAP v3 extended operations. It also explains
|
||||
how to use the extended operations supported by your LDAP server.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="bdajl">How Extended Operations Work With
|
||||
Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdajm">Determining the Extended Operations
|
||||
Supported With Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdajn">Performing an Extended Operation
|
||||
With Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="extendop-pwdmod">Performing an LDAP Password
|
||||
Modify Extended Operation With Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="extendedop-starttls">Using Start TLS With
|
||||
Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="extendop-whoami">Performing a Who Am I?
|
||||
Extended Operation With Directory SDK for C</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="bdajl"><title>How Extended Operations Work With Directory SDK for
|
||||
C</title>
|
||||
<para>Extended operations are part of LDAP v3. Each extended operation is
|
||||
identified by an object identifier (OID). LDAP clients can request the operation
|
||||
by sending an extended operation request.</para>
|
||||
<itemizedlist>
|
||||
<para>Within the request, the client specifies the following:</para>
|
||||
<listitem><para>The OID of the extended operation that should be performed</para>
|
||||
</listitem>
|
||||
<listitem><para>Data specific to the extended operation</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>The server receives the request, then performs the extended operation.
|
||||
The server sends back a response to the client that contains an OID, and any
|
||||
additional data.</para>
|
||||
<para>To use extended operations, both the server and the client must understand
|
||||
the specific extended operation to be performed. From the LDAP server perspective, &cnDirectoryServer; supports
|
||||
a server plug-in interface that you can use to add support for extended operations.
|
||||
</para></sect1>
|
||||
<sect1 id="bdajm"><title>Determining the Extended Operations Supported With &DirectorySDKForC;</title>
|
||||
<para>To determine the extended operations supported by the server, get the
|
||||
root DSE of the server, and check the <literal>supportedExtension</literal> attribute.
|
||||
The values of this attribute are the OIDs of the extended operations supported
|
||||
by this server. If the root DSE does not have a <literal>supportedExtension</literal> attribute,
|
||||
the server does not support any extended operations. See <olink targetptr="bdahv">
|
||||
To Get the Root DSE</olink> for instructions on reading that entry.</para>
|
||||
</sect1>
|
||||
<sect1 id="bdajn"><title>Performing an Extended Operation With &DirectorySDKForC;</title>
|
||||
<itemizedlist>
|
||||
<para>To perform an extended operation, for which no specialized API exists,
|
||||
call one of the following functions:</para>
|
||||
<listitem><para>The synchronous <function>ldap_extended_operation_s</function> function
|
||||
</para></listitem>
|
||||
<listitem><para>The asynchronous <function>ldap_extended_operation</function> function
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>Both of these functions allow you to specify the OID of the extended
|
||||
operation and the data that you want applied to the operation.</para>
|
||||
<para>Before calling the function to perform an LDAP extended operation, make
|
||||
sure to specify that your client is using version 3 of LDAP. If you do not,
|
||||
an <errorcode>LDAP_NOT_SUPPORTED</errorcode> result code is returned. For
|
||||
details, see <olink targetptr="bdaci">Specifying the LDAP Version of Your
|
||||
Client</olink>.</para>
|
||||
<sect2 id="bdajo"><title>Synchronous Extended Operation</title>
|
||||
<para>If you want to wait for the results of an LDAP extended operation to
|
||||
complete before continuing, call the synchronous <function>ldap_extended_operation_s
|
||||
</function> function. This function sends a SASL bind request to the server.
|
||||
The server blocks other work until the server sends the results of the operation
|
||||
back to your client.</para>
|
||||
<para><function>ldap_extended_operation_s</function> returns <errorcode>LDAP_SUCCESS
|
||||
</errorcode> if the operation completed successfully, or an error code if
|
||||
a problem occurred. See the documentation for the <olink targetptr="bdarv">ldap_extended_operation_s
|
||||
</olink> function for a list of the possible result codes.</para></sect2>
|
||||
<sect2 id="bdajp"><title>Asynchronous Extended Operation</title>
|
||||
<para>If you want to perform other work in parallel while waiting for an LDAP
|
||||
extended operation to complete, perform the following procedure.</para>
|
||||
<task><title>To Perform an Asynchronous Extended Operation</title>
|
||||
<procedure>
|
||||
<step><para>Call the asynchronous <function>ldap_extended_operation</function> function
|
||||
to send an LDAP extended operation request.</para><para>This function returns
|
||||
an <errorcode>LDAP_SUCCESS</errorcode> result code if the request was successfully
|
||||
sent, or an LDAP result code if an error occurred while sending the request.
|
||||
The function also sets the <literal>msgidp</literal> argument to point to
|
||||
a message ID identifying the extended operation. To determine whether the
|
||||
server sent a response to your client for this operation, call the <function>ldap_result
|
||||
</function> function and pass in this message ID. The function passes back
|
||||
the response in an <structname>LDAPMessage</structname> structure.</para></step>
|
||||
<step><para>Call the <function>ldap_parse_extended_result</function> function
|
||||
to parse the <structname>LDAPMessage</structname> structure and retrieve information
|
||||
from the server’s response.</para><para>If the server sent an OID of
|
||||
an extended operation to your client, the OID is passed back as the <literal>retoidp
|
||||
</literal> argument. If the server sent data to your client, the data is specified
|
||||
in the <structname>berval</structname> structure passed back as the <literal>retdatap
|
||||
</literal> argument.</para></step>
|
||||
<step><para>Call the <function>ldap_get_lderrno</function> function to get
|
||||
the LDAP result code for the operation.</para><para>The function returns an <errorcode>
|
||||
LDAP_SUCCESS</errorcode> result code if the extended operation was performed
|
||||
successfully, or an LDAP error code if a problem occurred. See the documentation
|
||||
for the <olink targetptr="bdaru">ldap_extended_operation</olink> function
|
||||
for a list of result codes that the server can return for this operation.</para>
|
||||
</step>
|
||||
</procedure>
|
||||
<example id="csdk-extop-example">
|
||||
<title>Perform an Asynchronous Extended Operation</title>
|
||||
<para>This example client requests an asynchronous extended operation from
|
||||
the server with OID <literal>1.2.3.4</literal>.</para>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "ldap.h"
|
||||
|
||||
/* Name and port of the LDAP server you want to connect to. */
|
||||
#define MY_HOST "localhost"
|
||||
#define MY_PORT 389
|
||||
/* DN of user (and password of user) who you want to authenticate as */
|
||||
#define MGR_DN "cn=Directory Manager"
|
||||
#define MGR_PW "23skidoo"
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
/* OID of the extended operation that you are requesting */
|
||||
const char *oidrequest = "1.2.3.4";
|
||||
char *oidresult;
|
||||
struct berval valrequest;
|
||||
struct berval *valresult;
|
||||
LDAP *ld;
|
||||
int rc, version;
|
||||
/* Set up the value that you want to pass to the server */
|
||||
printf( "Setting up value to pass to server...\n" );
|
||||
valrequest.bv_val = "My Value";
|
||||
valrequest.bv_len = strlen( "My Value" );
|
||||
/* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
|
||||
printf( "Getting the handle to the LDAP connection...\n" );
|
||||
if ( (ld = ldap_init( MY_HOST, MY_PORT )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
ldap_unbind( ld );
|
||||
return( 1 );
|
||||
}
|
||||
/* Set the LDAP protocol version supported by the client
|
||||
to 3. (By default, this is set to 2. Extended operations
|
||||
are part of version 3 of the LDAP protocol.) */
|
||||
ldap_get_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
|
||||
printf( "Resetting version %d to 3.0...\n", version );
|
||||
version = LDAP_VERSION3;
|
||||
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
|
||||
/* Authenticate to the directory as the Directory Manager */
|
||||
printf( "Binding to the directory...\n" );
|
||||
if ( ldap_simple_bind_s( ld, MGR_DN, MGR_PW ) != LDAP_SUCCESS ) {
|
||||
ldap_perror( ld, "ldap_simple_bind_s" );
|
||||
ldap_unbind( ld );
|
||||
return( 1 );
|
||||
}
|
||||
/* Initiate the extended operation */
|
||||
printf( "Initiating the extended operation...\n" );
|
||||
if ( ( rc = ldap_extended_operation_s( ld, oidrequest, &valrequest,
|
||||
NULL, NULL, &oidresult, &valresult ) ) !=
|
||||
LDAP_SUCCESS ) {
|
||||
ldap_perror( ld, "ldap_extended_operation failed: " );
|
||||
ldap_unbind( ld );
|
||||
return( 1 );
|
||||
}
|
||||
/* Get the OID and the value from the result returned by the server. */
|
||||
printf( "Operation successful.\n" );
|
||||
printf( "\tReturned OID: %s\n", oidresult );
|
||||
printf( "\tReturned value: %s\n", valresult->bv_val );
|
||||
/* Disconnect from the server. */
|
||||
ldap_unbind( ld );
|
||||
return 0;
|
||||
}</programlisting>
|
||||
</example>
|
||||
</task>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="extendop-pwdmod"><title>Performing an LDAP Password Modify Extended
|
||||
Operation With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>extended operations</secondary>
|
||||
<tertiary>password modify</tertiary>
|
||||
</indexterm>
|
||||
<para><ulink url="http://www.ietf.org/rfc/rfc3062.txt" type="text_url">RFC
|
||||
3062</ulink>, <citetitle>LDAP Password Modify Extended Operation</citetitle>,
|
||||
describes the extended operation, which is particularly useful for changing
|
||||
expired passwords.</para>
|
||||
<task><title>To Perform an LDAP Password Modify Extended Operation</title>
|
||||
<procedure>
|
||||
<step><para>Get a connection to the directory that uses LDAP version 3.</para>
|
||||
</step>
|
||||
<step><para>Authenticate to the directory.</para>
|
||||
<stepalternatives>
|
||||
<step><para>As an administrator, to be able to reset an expired user password
|
||||
if you do not have the old password</para></step>
|
||||
<step><para>Anonymously to reset an expired password if you have the old password
|
||||
</para></step>
|
||||
<step><para>As the user herself to change the password that has not yet expired</para>
|
||||
</step></stepalternatives>
|
||||
</step>
|
||||
<step><para>Modify the password with the synchronous function <function>ldap_passwd_s
|
||||
</function> or the asynchronous function <function>ldap_passwd</function> and
|
||||
use <function>ldap_parse_passwd</function> or <function>ldap_parse_passwd_result</function> to
|
||||
examine the results.</para></step>
|
||||
</procedure>
|
||||
<example>
|
||||
<title>Performing an LDAP Password Modify Extended Operation</title>
|
||||
<para>This example changes a password using <function>ldap_passwd_s</function>.</para>
|
||||
<programlisting>/*
|
||||
* Use the password modify extended operation to change a password.
|
||||
*/
|
||||
|
||||
#include "examples.h"
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
int version;
|
||||
LDAP *ld;
|
||||
char *target;
|
||||
int rc;
|
||||
struct berval userid;
|
||||
struct berval oldpasswd;
|
||||
struct berval newpasswd;
|
||||
struct berval genpasswd;
|
||||
|
||||
/* Use LDAPv3. */
|
||||
version = LDAP_VERSION3;
|
||||
if ( ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version )
|
||||
!= 0 ) {
|
||||
fprintf( stderr,
|
||||
"ldap_set_option protocol version to %d failed\n",
|
||||
version );
|
||||
return ( 1 );
|
||||
}
|
||||
|
||||
/* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
|
||||
if ( (ld = ldap_init( MY_HOST, MY_PORT )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Authenticate to the directory. */
|
||||
if ( ldap_simple_bind_s( ld, ENTRYDN, ENTRYPW ) != LDAP_SUCCESS ) {
|
||||
ldap_perror( ld, "ldap_simple_bind_s" );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Change the password using the extended operation. */
|
||||
userid.bv_val = ENTRYDN;
|
||||
userid.bv_len = strlen(userid.bv_val);
|
||||
|
||||
oldpasswd.bv_val = ENTRYPW;
|
||||
oldpasswd.bv_len = strlen(oldpasswd.bv_val);
|
||||
|
||||
newpasswd.bv_val = "ChangeMe!";
|
||||
newpasswd.bv_len = strlen(newpasswd.bv_val);
|
||||
|
||||
rc = ldap_passwd_s(
|
||||
ld, &userid, &oldpasswd, &newpasswd, &genpasswd, NULL, NULL );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr, "ldap_passwd_s: %s\n", ldap_err2string( rc ) );
|
||||
ldap_unbind( ld );
|
||||
return( 1 );
|
||||
} else {
|
||||
printf( "Successfully changed password for %s\n", userid.bv_val );
|
||||
}
|
||||
|
||||
ldap_unbind( ld );
|
||||
return( 0 );</programlisting>
|
||||
<para>When you compile and run this sample program against &cnDirectoryServer; with
|
||||
a suffix that contains data from <filename>Example.ldif</filename>, the server
|
||||
produces output similar to this:</para>
|
||||
<screen>Successfully changed password for uid=bjensen, ou=People, dc=example,dc=com
|
||||
</screen>
|
||||
</example>
|
||||
</task>
|
||||
</sect1>
|
||||
<sect1 id="extendedop-starttls"><title>Using Start TLS With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>extended operations</secondary>
|
||||
<tertiary>start TLS</tertiary>
|
||||
</indexterm>
|
||||
<para><ulink url="http://www.ietf.org/rfc/rfc4513.txt" type="text_url">RFC
|
||||
4513</ulink>, <citetitle>Lightweight Directory Access Protocol (LDAP): Authentication
|
||||
Methods and Security Mechanisms</citetitle>, describes the extended operation.
|
||||
Start TLS allows you to connect on a non secure port, and then request transport
|
||||
layer security.</para>
|
||||
<para>See <olink targetptr="ssl-start-tls">Starting Transport Layer Security
|
||||
With Directory SDK for C</olink> for an example of how to use Start TLS.</para>
|
||||
</sect1>
|
||||
<sect1 id="extendop-whoami"><title>Performing a Who Am I? Extended Operation
|
||||
With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>extended operations</secondary>
|
||||
<tertiary>Who Am I?</tertiary>
|
||||
</indexterm>
|
||||
<para>The “Who am I?” extended operation allows you to retrieve
|
||||
the authorization identity that is associated with a connection.</para>
|
||||
<para>This method can involve less code than the standard authorization identity
|
||||
controls that are described in <olink targetptr="controls-authzid">Using the
|
||||
Authorization Identity Bind Request Control With Directory SDK for C</olink>.</para>
|
||||
<task><title>To Perform a Who Am I? Extended Operation</title>
|
||||
<procedure>
|
||||
<step><para>Get a connection to the directory that uses LDAP version 3.</para>
|
||||
</step>
|
||||
<step><para>Use <function>ldap_whoami</function> and <function>ldap_parse_whoami_result
|
||||
</function>, or use <function>ldap_whoami_s</function>, to retrieve the authorization
|
||||
identity.</para></step>
|
||||
</procedure>
|
||||
<example>
|
||||
<title>Getting Authorization Identity</title>
|
||||
<para>This example retrieves authorization identity by using <function>ldap_whoami_s
|
||||
</function>.</para>
|
||||
<programlisting>/*
|
||||
* Use the Who Am I? extended operation.
|
||||
*/
|
||||
|
||||
#include "examples.h"
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
int version;
|
||||
LDAP *ld;
|
||||
int rc;
|
||||
char *authzid;
|
||||
|
||||
/* Use LDAPv3. */
|
||||
version = LDAP_VERSION3;
|
||||
if ( ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version )
|
||||
!= 0 ) {
|
||||
fprintf( stderr,
|
||||
"ldap_set_option protocol version to %d failed\n",
|
||||
version );
|
||||
return ( 1 );
|
||||
}
|
||||
|
||||
/* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
|
||||
if ( (ld = ldap_init( MY_HOST, MY_PORT )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Authenticate to the directory. */
|
||||
if ( ldap_simple_bind_s( ld, ENTRYDN, ENTRYPW ) != LDAP_SUCCESS ) {
|
||||
ldap_perror( ld, "ldap_simple_bind_s" );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Examine my authorization ID. */
|
||||
rc = ldap_whoami_s( ld, NULL, NULL, &authzid );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr, "ldap_whoami_s: %s\n", ldap_err2string( rc ) );
|
||||
ldap_unbind( ld );
|
||||
return( 1 );
|
||||
}
|
||||
printf( "Authorization ID: %s\n", authzid );
|
||||
|
||||
ldap_unbind( ld );
|
||||
return( 0 );
|
||||
}</programlisting>
|
||||
<para>When you compile and run this sample program against &cnDirectoryServer;<?Pub
|
||||
Caret> with a suffix that contains data from <filename>Example.ldif</filename>,
|
||||
the server produces output similar to this:</para>
|
||||
<screen>Authorization ID: dn:uid=bjensen,ou=people,dc=example,dc=com</screen>
|
||||
</example>
|
||||
</task>
|
||||
</sect1>
|
||||
</chapter>
|
||||
375
mozilla/directory/docs/ldapcsdk/csdk-filter-conf.sgm
Normal file
375
mozilla/directory/docs/ldapcsdk/csdk-filter-conf.sgm
Normal file
@@ -0,0 +1,375 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="csdk-filter"><title>Using Filter Configuration Files With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>filter configuration files</secondary>
|
||||
</indexterm><highlights>
|
||||
<para>This chapter explains how to use LDAP C API functions to work with filter
|
||||
configuration files.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="bdafi">Understanding Filter Configuration Files for Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdafq">Loading Filter Configuration Files With Directory SDK for C</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="bdafs">Filter Prefixes and Suffixes for Directory SDK for C</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="bdaft">Freeing Filters From Memory With Directory SDK for C</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="bdafu">Creating Filters Programmatically With Directory SDK for C</olink></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="bdafi"><title>Understanding Filter Configuration Files for Directory
|
||||
SDK for C</title>
|
||||
<para>Filter configuration files can help simplify the process of selecting
|
||||
the appropriate filter for a search request. A <firstterm>filter configuration
|
||||
file</firstterm> contains a list of filters that you can load and use in your
|
||||
searches. You might be writing a client that allows users to search the directory.
|
||||
Use different search filters tailored for specific types of search criteria.</para>
|
||||
<para>For example, if the user wants to search for the email address <literal>bjensen@example.com
|
||||
</literal>, you might want to use this search filter:</para>
|
||||
<programlisting>(mail=bjensen@example.com)</programlisting>
|
||||
<para>Similarly, suppose the search term entered by the user contains numbers,
|
||||
as in <literal>555-1212</literal>. In this case, you might want to use this
|
||||
search filter:</para>
|
||||
<programlisting>(telephoneNumber=555-1212)</programlisting>
|
||||
<para>Rather than write code to find and select the appropriate filter, you
|
||||
can include the filters in a filter configuration file. For example, the following
|
||||
section of a filter configuration file specifies one filter for telephone
|
||||
numbers and two filters for email addresses. The telephone number filter is
|
||||
used if the search criteria contain one or more numbers. The email filters
|
||||
are used if the search criteria contain an at sign, <literal>@</literal>.</para>
|
||||
<example id="filter-conf-example"><title>Section of Filter Configuration File</title>
|
||||
<programlisting>"people"
|
||||
"^[0-9][0-9-]*$" " "
|
||||
"(telephoneNumber=*%v))" "phone number ends with"
|
||||
"@" " " "(mail=%v)" "email address is"
|
||||
"(mail=%v*)" "email address starts with"</programlisting>
|
||||
</example>
|
||||
<para>You should specify the filters in the order that you want the filters
|
||||
to be used. For example, if you want to apply the <literal>(mail=%v)</literal> filter
|
||||
before the <literal>(mail=%v*)</literal> filter, make sure that the filters
|
||||
appear in that order.</para>
|
||||
<sect2 id="bdafj"><title>Syntax for Filter Configuration Files</title>
|
||||
<indexterm>
|
||||
<primary>filter configuration files</primary>
|
||||
<secondary>syntax</secondary>
|
||||
</indexterm>
|
||||
<para>A filter configuration file has the following format. The variables
|
||||
are discussed in the following sections.</para>
|
||||
<example id="filter-config-syntax"><title>Syntax for a Filter Configuration
|
||||
File</title>
|
||||
<programlisting><replaceable>tag</replaceable>
|
||||
<replaceable>pattern1</replaceable> <replaceable>delimiters</replaceable> <replaceable>
|
||||
filter1-1</replaceable> <replaceable>desc1-1</replaceable> [<replaceable>scope</replaceable>]
|
||||
<replaceable>filter1-2</replaceable> <replaceable>desc1-2</replaceable> [<replaceable>
|
||||
scope</replaceable>]
|
||||
<replaceable>pattern2</replaceable> <replaceable>delimiters</replaceable> <replaceable>
|
||||
filter2-1</replaceable> <replaceable>desc2-1</replaceable> [<replaceable>scope</replaceable>]
|
||||
…</programlisting>
|
||||
</example>
|
||||
<sect3 id="bdafk"><title>Tag for Filter Groups</title>
|
||||
<para>A <replaceable>tag</replaceable> identifies a group of filters. You
|
||||
can use different tags to distinguish filters for different types of objects.
|
||||
For example, you can use one tag to represent filters for person entries,
|
||||
another tag to represent filters for organization entries, and so on.</para>
|
||||
<programlisting>"people"
|
||||
… (<replaceable>filters for searching "person" entries</replaceable>) …
|
||||
"organization"
|
||||
… (<replaceable>filters for "organization" entries</replaceable>) …
|
||||
</programlisting>
|
||||
<para>When you call functions like <function>ldap_getfirstfilter</function> to
|
||||
retrieve a filter, you can specify a tag, or part of a tag, as a parameter.
|
||||
The tag narrows the list of filters that the function can retrieve.</para>
|
||||
</sect3>
|
||||
<sect3 id="bdafl"><title>Patterns to Select Filters</title>
|
||||
<para><replaceable>pattern1</replaceable> and <replaceable>pattern2</replaceable> are
|
||||
regular expressions used to determine which filter is selected, based on the
|
||||
search criteria. For example, if you specify <literal>"^[0-9]"</literal> as
|
||||
the pattern for a filter, the filter is selected for all search criteria that
|
||||
begin with a number.</para>
|
||||
<programlisting>"people"
|
||||
"^[0-9]" …</programlisting>
|
||||
</sect3>
|
||||
<sect3 id="bdafm"><title>Delimiters for Fields</title>
|
||||
<para><replaceable>Delimiters</replaceable> specifies the delimiters used
|
||||
to distinguish one field from another field within the search criteria. For
|
||||
example, if the search criteria consist of a city name and a state abbreviation
|
||||
separated by a comma, specify a comma as the delimiter.</para></sect3>
|
||||
<sect3 id="bdafn"><title>Filter Lists</title>
|
||||
<para><replaceable>filter1-1</replaceable>, <replaceable>filter1-2</replaceable>,
|
||||
and <replaceable>filter2-1</replaceable> are filters. Use <literal>%v</literal> to
|
||||
represent the search criteria. For example, to search email addresses, use
|
||||
the filter <literal>(mail=%v)</literal>. During runtime, if the search criteria <literal>
|
||||
bjensen@example.com</literal> is entered, the filter becomes <literal>(mail=bjensen@example.com)
|
||||
</literal>.</para>
|
||||
<para>The search criteria might consist of a number of delimited fields. For
|
||||
example, the criteria might have a last name, first name format such as <literal>
|
||||
Jensen, Barbara</literal>. Use <literal>%v1, %v2, …, %vn</literal> to
|
||||
represent the different fields within the search criteria as shown here:</para>
|
||||
<programlisting>"people"
|
||||
"^[A-Z]*," "," (&(sn=%v1)(givenName=%v2))</programlisting>
|
||||
<para>In this example, the delimiter is a comma. The word before the delimiter
|
||||
replaces <literal>%v1</literal> in the filter. The word after the delimiter
|
||||
replaces <literal>%v2</literal> in the filter. If the user searches for <literal>
|
||||
Jensen, Barbara</literal> , the resulting filter is as follows:</para>
|
||||
<programlisting>(&(sn=Jensen)(givenName=Barbara))</programlisting>
|
||||
<para>You can also specify ranges of fields. For example, to specify the values
|
||||
in the first three fields, use <literal>%v1-3</literal>. To specify values
|
||||
from the third field to the last field, use <literal>%v3-</literal>. To specify
|
||||
the value in the last field, use <literal>%v$</literal>.</para></sect3>
|
||||
<sect3 id="bdafo"><title>Descriptions of Filters</title>
|
||||
<para><replaceable>desc1-1</replaceable>, <replaceable>desc1-2</replaceable>,
|
||||
and <replaceable>desc2-1</replaceable> are phrases that briefly describe the
|
||||
filters.</para></sect3>
|
||||
</sect2>
|
||||
<sect2 id="bdafp"><title>Filter Parameters</title>
|
||||
<indexterm>
|
||||
<primary>search filters</primary>
|
||||
<secondary>parameters</secondary>
|
||||
</indexterm>
|
||||
<para>Filter specifications in the configuration file support the following
|
||||
parameters:</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><literal>%v</literal></term>
|
||||
<listitem><para>Insert the search criterion as is in place of <literal>%v</literal>.
|
||||
</para>
|
||||
<para>For example, if the filter specification is <literal>(mail=%v)</literal>,
|
||||
entering <literal>bjensen</literal> results in the filter <literal>(mail=bjensen)
|
||||
</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>%v$</literal></term>
|
||||
<listitem><para>Insert the last word of the search criterion as is in place
|
||||
of <literal>%v</literal>.</para>
|
||||
<para>For example, if the filter specification is <literal>(sn=%v$)</literal>,
|
||||
entering <literal>Barbara Jensen</literal> results in the filter <literal>(sn=Jensen)
|
||||
</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>%v</literal><replaceable>N</replaceable></term>
|
||||
<listitem><para>Insert the <replaceable>N</replaceable>th word of the criteria
|
||||
in place of <literal>%v</literal>, where <replaceable>N</replaceable> is a
|
||||
single digit between 1 and 9.</para>
|
||||
<para>For example, if the filter specification is <literal>(sn=%v2)</literal>,
|
||||
entering <literal>Barbara Jensen</literal> results in the filter <literal>(sn=Jensen)
|
||||
</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>%v</literal><replaceable>M</replaceable><literal>-</literal><replaceable>
|
||||
N</replaceable></term>
|
||||
<listitem><para>Insert the sequence of the <replaceable>M</replaceable>th
|
||||
through <replaceable>N</replaceable>th words of the criteria in place of <literal>
|
||||
%v</literal>. Here, <replaceable>M</replaceable> and <replaceable>N</replaceable> are
|
||||
single digits between 1 and 9.</para>
|
||||
<para>For example, if the filter specification is <literal>(cn=%v1-2)</literal>,
|
||||
entering <literal>Barbara Jensen</literal> results in the filter <literal>(cn=Barbara
|
||||
Jensen)</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>%v</literal><replaceable>N</replaceable><literal>-</literal></term>
|
||||
<listitem><para>Insert the sequence of the <replaceable>N</replaceable>th
|
||||
through last words of the criteria in place of <literal>%v</literal>. Here, <replaceable>
|
||||
N</replaceable> is a single digit between 1 and 9.</para>
|
||||
<para>For example, if the filter specification is <literal>(cn=%v2-)</literal>,
|
||||
entering <literal>Ms. Barbara Jensen</literal> results in the filter <literal>(cn=Barbara
|
||||
Jensen)</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="bdafq"><title>Loading Filter Configuration Files With Directory
|
||||
SDK for C</title>
|
||||
<indexterm>
|
||||
<primary>filter configuration files</primary>
|
||||
<secondary>loading</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>loading filter configuration files</primary>
|
||||
</indexterm>
|
||||
<para>To load a filter configuration file, call the <function>ldap_init_getfilter
|
||||
</function> function. You can also read the filter configuration file from
|
||||
a buffer in memory by calling the <function>ldap_init_getfilter_buf</function> function.
|
||||
Both functions return a pointer to an <structname>LDAPFiltDesc</structname> structure,
|
||||
which contains information about the filter. If an error occurs, both functions
|
||||
return <literal>NULL</literal>.</para>
|
||||
<sect2 id="bdafr"><title>Retrieving Filters</title>
|
||||
<indexterm>
|
||||
<primary>filter configuration file</primary>
|
||||
<secondary>retrieving</secondary>
|
||||
</indexterm>
|
||||
<para>After loading a filter configuration file into memory, you can retrieve
|
||||
filters based on the search criteria. For example, the search criteria might
|
||||
be an email address, <literal>(bjensen@example.com)</literal>. Have your client
|
||||
automatically search for this value in the <literal>mail</literal> attribute
|
||||
of person entries.</para>
|
||||
<para>To retrieve the first filter that matches the search criteria, call
|
||||
the <function>ldap_getfirstfilter</function> function. To get the next filter
|
||||
that matches the search criteria, call the <function>ldap_getnextfilter</function> function.
|
||||
Both functions return a pointer to an <structname>LDAPFiltInfo</structname> structure,
|
||||
which contains information about the filter, as shown here.<?Pub Caret></para>
|
||||
<example id="filter-retrieve-conf-example"><title>Retrieving Configuration
|
||||
Filters</title>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include "ldap.h"
|
||||
…
|
||||
LDAP *ld;
|
||||
LDAPMessage *result, *e;
|
||||
BerElement *ber;
|
||||
char *a, *dn;
|
||||
char **vals;
|
||||
int i;
|
||||
LDAPFiltDesc *ldfp;
|
||||
LDAPFiltInfo *ldfi;
|
||||
char buf[ 80 ]; /* contains the search criteria */
|
||||
int found;
|
||||
…
|
||||
/* Load the filter configuration file into an LDAPFiltDesc structure. */
|
||||
if ( ( ldfp = ldap_init_getfilter( "myfilters.conf" ) ) == NULL ) {
|
||||
perror( "Cannot open filter configuration file" );
|
||||
}
|
||||
|
||||
/* Select a filter to use when searching for the value in buf.
|
||||
Use filters under the "people" tag in the filter configuration file. */
|
||||
found = 0;
|
||||
for ( ldfi = ldap_getfirstfilter( ldfp, "people", buf ); ldfi != NULL;
|
||||
ldfi = ldap_getnextfilter( ldfp ) ) {
|
||||
|
||||
/* Use the selected filter to search the directory. */
|
||||
if ( ldap_search_s( ld, "dc=example,dc=com", ldfi->lfi_scope,
|
||||
ldfi->lfi_filter, NULL, 0, &result ) != LDAP_SUCCESS ) {
|
||||
ldap_perror( ld, "ldap_search_s" );
|
||||
return( 1 );
|
||||
} else {
|
||||
|
||||
/* Once a filter gets results back, stop iterating through
|
||||
the different filters. */
|
||||
if ( ( found = ldap_count_entries( ld, result ) > 0 ) ) {
|
||||
break;
|
||||
} else {
|
||||
ldap_msgfree( result );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( found == 0 ) {
|
||||
printf( "No matching entries found.\n" );
|
||||
} else {
|
||||
printf( "Found %d match%s where %s \"%s\"\n\n", found,
|
||||
found == 1 ? "" : "es", ldfi->lfi_desc, buf );
|
||||
}
|
||||
|
||||
ldap_msgfree( result );
|
||||
ldap_getfilter_free( ldfp );
|
||||
…</programlisting>
|
||||
</example>
|
||||
<para>Suppose that the search criteria is <literal>bjensen@example.com</literal> and
|
||||
that the client application finds a single matching entry. Then the application
|
||||
prints the following output:</para>
|
||||
<programlisting>Found 1 match where email address is bjensen@example.com</programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="bdafs"><title>Filter Prefixes and Suffixes for Directory SDK for
|
||||
C</title>
|
||||
<indexterm>
|
||||
<primary>search filters</primary>
|
||||
<secondary>prefixes</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>search filters</primary>
|
||||
<secondary>suffixes</secondary>
|
||||
</indexterm>
|
||||
<para>If you need to apply a filter to all searches, add a filter prefix and
|
||||
suffix to all filters. Do not add the criteria to all filters. The prefix
|
||||
is automatically added to any filter retrieved through the <function>ldap_getfirstfilter
|
||||
</function> and <function>ldap_getnextfilter</function> functions. The required
|
||||
suffix <literal>)</literal> needed to balance the number of parentheses is
|
||||
also added. For example, suppose you use this filter in a filter configuration
|
||||
file:</para>
|
||||
<programlisting>(cn=Babs Jensen)</programlisting>
|
||||
<para>You can retrieve this filter by using <function>ldap_getfirstfilter</function> or <function>
|
||||
ldap_getnextfilter</function>. These functions get a filter that constrains
|
||||
your client searches to person entries for the defined filter:</para>
|
||||
<programlisting>(&(objectClass=person)(cn=Babs Jensen))</programlisting>
|
||||
<para>To add a prefix and suffix automatically to all filters retrieved from
|
||||
the filter configuration file, call the <function>ldap_set_filter_additions</function> function.
|
||||
The following example adds the prefix <literal>(&(objectClass=person)</literal> and
|
||||
the suffix <literal>)</literal> to each filter retrieved.</para>
|
||||
<example id="filter-add-affixes-example"><title>Adding Prefixes and Suffixes
|
||||
to Filters</title>
|
||||
<programlisting>#include "ldap.h"
|
||||
…
|
||||
LDAPFiltDesc *lfdp;
|
||||
char *filter_file = "myfilters.conf";
|
||||
char *prefix = "(&(objectClass=person)";
|
||||
char *suffix = ")";
|
||||
…
|
||||
lfdp = ldap_init_getfilter( filter_file );
|
||||
ldap_setfilteraffixes( lfdp, prefix, suffix );
|
||||
…</programlisting>
|
||||
</example>
|
||||
</sect1>
|
||||
<sect1 id="bdaft"><title>Freeing Filters From Memory With Directory SDK for
|
||||
C</title>
|
||||
<indexterm>
|
||||
<primary>search filters</primary>
|
||||
<secondary>freeing from memory</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>memory</primary>
|
||||
<secondary>freeing search filters from</secondary>
|
||||
</indexterm>
|
||||
<para>When you complete your search, free the <structname>LDAPFiltDesc</structname> structure
|
||||
from memory. To free <structname>LDAPFiltDesc</structname>, call the <function>ldap_getfilter_free
|
||||
</function> function as shown here. </para>
|
||||
<example id="filter-free-example"><title>Freeing Filters From Memory</title>
|
||||
<programlisting>#include "ldap.h"
|
||||
…
|
||||
LDAPFiltDesc *lfdp;
|
||||
char *filter_file = "myfilters.conf";
|
||||
…
|
||||
/* Read the filter configuration file into an LDAPFiltDesc structure. */
|
||||
lfdp = ldap_init_getfilter( filter_file );
|
||||
…
|
||||
/* Retrieve filters and perform searches. */
|
||||
…
|
||||
/* Free the configuration file (the LDAPFiltDesc structure). */
|
||||
ldap_getfilter_free( lfdp );
|
||||
…</programlisting>
|
||||
</example>
|
||||
</sect1>
|
||||
<sect1 id="bdafu"><title>Creating Filters Programmatically With Directory
|
||||
SDK for C</title>
|
||||
<indexterm>
|
||||
<primary>search filters</primary>
|
||||
<secondary>creating programmatically</secondary>
|
||||
</indexterm>
|
||||
<para>You can build your own filters by calling the <function>ldap_create_filter</function> function.
|
||||
The following example builds the filter <literal>(mail=bjensen@example.com)</literal>.
|
||||
</para>
|
||||
<example id="filter-create-example"><title>Creating Filters</title>
|
||||
<programlisting>char buf[LDAP_FILT_MAXSIZ];
|
||||
char *pattern = "(%a=%v);
|
||||
char *attr = "mail";
|
||||
char *value = "bjensen@example.com";
|
||||
…
|
||||
ldap_create_filter( buf, LDAP_FILT_MAXSIZ, pattern, NULL, NULL, attr,
|
||||
value, NULL );
|
||||
…</programlisting>
|
||||
</example>
|
||||
</sect1>
|
||||
</chapter>
|
||||
20727
mozilla/directory/docs/ldapcsdk/csdk-functions.sgm
Normal file
20727
mozilla/directory/docs/ldapcsdk/csdk-functions.sgm
Normal file
File diff suppressed because it is too large
Load Diff
312
mozilla/directory/docs/ldapcsdk/csdk-ldap-urls.sgm
Normal file
312
mozilla/directory/docs/ldapcsdk/csdk-ldap-urls.sgm
Normal file
@@ -0,0 +1,312 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="csdk-urls"><title>LDAP URLs With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>LDAP URLs</secondary>
|
||||
</indexterm><highlights>
|
||||
<para>This chapter describes how to use LDAP URLs to search and retrieve data
|
||||
from the directory.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="bdahp">Checking an LDAP URL With Directory
|
||||
SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdahq">Getting the Components of an LDAP
|
||||
URL With Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdahr">Freeing the Components of an LDAP
|
||||
URL With Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdahs">Processing an LDAP URL With Directory
|
||||
SDK for C</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights><?Pub Caret1>
|
||||
<sect1 id="bdahp"><title>Checking an LDAP URL With &DirectorySDKForC;</title>
|
||||
<para>To determine whether a URL is an LDAP URL, call the <function>ldap_is_ldap_url
|
||||
</function> function. This function returns a nonzero value if the URL is
|
||||
an LDAP URL. If the URL is not an LDAP URL, the function returns <literal>0</literal>.
|
||||
The following example determines if a URL is an LDAP URL.</para>
|
||||
<example id="ldap-url-is-ldap-url"><title>Determining Whether a URL Is an
|
||||
LDAP URL</title>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include "ldap.h"
|
||||
...
|
||||
char *my_url = "ldap://ldap.example.com/dc=example,dc=com";
|
||||
...
|
||||
if ( ldap_is_ldap_url( my_url ) != 0 ) {
|
||||
printf( "%s is an LDAP URL.\n", my_url );
|
||||
} else {
|
||||
printf( "%s is not an LDAP URL.\n", my_url );
|
||||
}
|
||||
...</programlisting>
|
||||
</example>
|
||||
<para><function>ldap_is_ldap_url</function> determines whether a URL is an
|
||||
LDAP URL. To verify that an LDAP URL complies with the LDAP URL syntax, you
|
||||
should call the <function>ldap_url_parse</function> function as detailed in <olink targetptr="bdahq">Getting the Components of an LDAP URL With Directory SDK
|
||||
for C</olink>.</para></sect1>
|
||||
<sect1 id="bdahq"><title>Getting the Components of an LDAP URL With &DirectorySDKForC;</title>
|
||||
<para>To retrieve the individual components of an LDAP URL, call <function>ldap_url_parse
|
||||
</function>. This function returns the LDAP URL components in an <structname>LDAPURLDesc
|
||||
</structname> structure as shown in this example.</para>
|
||||
<example id="ldap-url-ldapurldesc"><title><structname>LDAPURLDesc</structname> Structure
|
||||
</title>
|
||||
<programlisting>typedef struct ldap_url_desc {
|
||||
char *lud_host;
|
||||
int lud_port;
|
||||
char *lud_dn;
|
||||
char **lud_attrs;
|
||||
int lud_scope;
|
||||
char *lud_filter;
|
||||
unsigned long lud_options;
|
||||
} LDAPURLDesc;</programlisting>
|
||||
</example>
|
||||
<para>The following table describes the structure's fields.</para>
|
||||
<table frame="topbot" pgwide="1" id="ldap-url-ldapurldesc-fields"><title><structname>
|
||||
LDAPURLDesc</structname> Field Descriptions</title>
|
||||
<tgroup cols="2"><colspec colnum="1" colwidth="11.10*"><colspec colnum="2"
|
||||
colwidth="88.90*">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Field Name</para></entry>
|
||||
<entry>
|
||||
<para>Description</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>lud_host</structfield></para></entry>
|
||||
<entry>
|
||||
<para>The name of the host in the URL.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>lud_port</structfield></para></entry>
|
||||
<entry>
|
||||
<para>The number of the port in the URL.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>lud_dn</structfield></para></entry>
|
||||
<entry>
|
||||
<para>The distinguished name in the URL.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>lud_attrs</structfield></para></entry>
|
||||
<entry>
|
||||
<para>A pointer to a <literal>NULL</literal> terminated array of the attributes
|
||||
specified in the URL.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>lud_scope</structfield></para></entry>
|
||||
<entry>
|
||||
<itemizedlist>
|
||||
<para>The scope of the search specified in the URL. This field can have the
|
||||
following values:</para>
|
||||
<listitem><para><literal>LDAP_SCOPE_BASE</literal> specifies a search of the
|
||||
base entry.</para></listitem>
|
||||
<listitem><para><literal>LDAP_SCOPE_ONELEVEL</literal> specifies a search
|
||||
of all entries one level under the base entry, not including the base entry.</para>
|
||||
</listitem>
|
||||
<listitem><para><literal>LDAP_SCOPE_SUBTREE</literal> specifies a search of
|
||||
all entries at all levels under the base entry, including the base entry.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>lud_filter</structfield></para></entry>
|
||||
<entry>
|
||||
<para>Search filter included in the URL.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>lud_options</structfield></para></entry>
|
||||
<entry>
|
||||
<para>Options. If <literal>LDAP_URL_OPT_SECURE</literal>, indicates that the
|
||||
protocol is <literal>ldaps://</literal> instead of <literal>ldap://</literal>.</para>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<para>The following example parses an LDAP URL.</para>
|
||||
<example id="ldap-url-parse-example"><title>Parsing an LDAP URL</title>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include "ldap.h"
|
||||
...
|
||||
char *my_url =
|
||||
"ldap://ldap.example.com:1389/dc=example,dc=com?
|
||||
cn,mail,telephoneNumber?sub?(sn=Jensen)";
|
||||
LDAPURLDesc *ludpp;
|
||||
int res, i;
|
||||
...
|
||||
if ( ( res = ldap_url_parse( my_url, &ludpp ) ) != 0 ) {
|
||||
switch( res ){
|
||||
case LDAP_URL_ERR_NOTLDAP:
|
||||
printf( "URL does not begin with \"ldap://\"\n" );
|
||||
break;
|
||||
case LDAP_URL_ERR_NODN:
|
||||
printf( "URL missing trailing slash after host or port\n" );
|
||||
break;
|
||||
case LDAP_URL_ERR_BADSCOPE:
|
||||
printf( "URL contains an invalid scope\n" );
|
||||
break;
|
||||
case LDAP_URL_ERR_MEM:
|
||||
printf( "Not enough memory\n" );
|
||||
break;
|
||||
default:
|
||||
printf( "Unknown error\n" );
|
||||
}
|
||||
return( 1 );
|
||||
}
|
||||
printf( "Components of the URL:\n" );
|
||||
printf( "Host name: %s\n", ludpp->lud_host );
|
||||
printf( "Port number: %d\n", ludpp->lud_port );
|
||||
if ( ludpp->lud_dn != NULL ) {
|
||||
printf( "Base entry: %s\n", ludpp->lud_dn );
|
||||
} else {
|
||||
printf( "Base entry: Root DN\n" );
|
||||
}
|
||||
if ( ludpp->lud_attrs != NULL ) {
|
||||
printf( "Attributes returned: \n" );
|
||||
for ( i=0; ludpp->lud_attrs[i] != NULL; i++ ) {
|
||||
printf( "\t%s\n", ludpp->lud_attrs[i] );
|
||||
}
|
||||
} else {
|
||||
printf( "No attributes returned.\n" );
|
||||
}
|
||||
printf( "Scope of the search: " );
|
||||
switch( ludpp->lud_scope ) {
|
||||
case LDAP_SCOPE_BASE:
|
||||
printf( "base\n" );
|
||||
break;
|
||||
case LDAP_SCOPE_ONELEVEL:
|
||||
printf( "one\n" );
|
||||
break;
|
||||
case LDAP_SCOPE_SUBTREE:
|
||||
printf( "sub\n" );
|
||||
break;
|
||||
default:
|
||||
printf( "Unknown scope\n" );
|
||||
}
|
||||
printf( "Filter: %s\n", ludpp->lud_filter );
|
||||
...</programlisting>
|
||||
</example>
|
||||
<para>The code in <olink targetptr="ldap-url-parse-example">Example 13–3</olink> prints
|
||||
each component of the URL as shown in the following example.</para>
|
||||
<example id="ldap-url-parse-example-output"><title>Results of Parsing an LDAP
|
||||
URL</title>
|
||||
<screen>Components of the URL:
|
||||
Host name: ldap.example.com
|
||||
Port number: 1389
|
||||
Base entry: dc=example,dc=com
|
||||
Attributes returned:
|
||||
cn
|
||||
mail
|
||||
telephoneNumber
|
||||
Scope of the search: sub
|
||||
Filter: (sn=Jensen)</screen>
|
||||
</example>
|
||||
</sect1>
|
||||
<sect1 id="bdahr"><title>Freeing the Components of an LDAP URL With &DirectorySDKForC;</title>
|
||||
<para>When you have finished working with the components of an LDAP URL, you
|
||||
should free the <structname>LDAPURLDesc</structname> structure from memory
|
||||
by calling the <function>ldap_free_urldesc</function> function. The following
|
||||
example parses an LDAP URL. The example then frees the <structname>LDAPURLDesc</structname> structure
|
||||
from memory, after verifying that the LDAP URL is valid.</para>
|
||||
<example id="ldap-url-free-example"><title>Freeing the <structname>LDAPURLDesc</structname> Structure
|
||||
From Memory</title>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include "ldap.h"
|
||||
...
|
||||
char *my_url = "ldap://ldap.example.com:1389/dc=example,dc=com?cn,mail,
|
||||
telephoneNumber?sub?(sn=Jensen)";
|
||||
LDAPURLDesc *ludpp;
|
||||
int res, i;
|
||||
...
|
||||
if ( ( res = ldap_url_parse( my_url, &ludpp ) ) != 0 ) {
|
||||
switch( res ){
|
||||
case LDAP_URL_ERR_NOTLDAP:
|
||||
printf( "URL does not begin with \"ldap://\"\n" );
|
||||
break;
|
||||
case LDAP_URL_ERR_NODN:
|
||||
printf( "URL does not contain a distinguished name\n" );
|
||||
break;
|
||||
case LDAP_URL_ERR_BADSCOPE:
|
||||
printf( "URL contains an invalid scope\n" );
|
||||
break;
|
||||
case LDAP_URL_ERR_MEM:
|
||||
printf( "Not enough memory\n" );
|
||||
break;
|
||||
default:
|
||||
printf( "Unknown error\n" );
|
||||
}
|
||||
return( 1 );
|
||||
}
|
||||
printf( "URL is a valid LDAP URL\n" );
|
||||
ldap_free_urldesc( ludpp );
|
||||
...</programlisting>
|
||||
</example>
|
||||
</sect1>
|
||||
<sect1 id="bdahs"><title>Processing an LDAP URL With &DirectorySDKForC;</title>
|
||||
<para>To process an LDAP URL search request, call one of the following functions:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem><para><function>ldap_url_search_s</function> is a synchronous function
|
||||
that completes the search operation before returning. Call this function if
|
||||
you need to wait for the operation to finish before continuing other work.
|
||||
The function returns <errorcode>LDAP_SUCCESS</errorcode> if the operation
|
||||
completed successfully. If an error occurred, the function returns an error
|
||||
code.</para></listitem>
|
||||
<listitem><para><function>ldap_url_search_st</function> is a synchronous function
|
||||
that allows a certain amount of time for the completion of the search operation.
|
||||
Call this function to wait for the operation to complete, and to set a timeout
|
||||
period for the operation.</para></listitem>
|
||||
<listitem><para><function>ldap_url_search</function> is an asynchronous function
|
||||
that initiates the search operation but does not wait for the operation to
|
||||
complete. Call this function if you want to perform other work in parallel
|
||||
while waiting for the operation to complete. The function returns a message
|
||||
ID identifying the search operation. To determine whether the operation is
|
||||
completed or still in progress, call the <function>ldap_result</function> function.
|
||||
</para><para>After the operation is completed, call the <function>ldap_result2error
|
||||
</function> function to determine if the operation was successful. If the
|
||||
operation completed successfully, the <function>ldap_result2error</function> function
|
||||
returns <errorcode>LDAP_SUCCESS</errorcode>. If an error occurred, the function
|
||||
returns an error code. </para></listitem>
|
||||
</itemizedlist>
|
||||
<para>The following example processes a search request from an LDAP URL.</para>
|
||||
<example id="ldap-url-search-example"><title>Processing an LDAP URL Search
|
||||
Request</title>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include "ldap.h"
|
||||
...
|
||||
LDAP *ld;
|
||||
LDAPMessage *result;
|
||||
char *my_url = "ldap://ldap.example.com/dc=example,dc=com?cn,mail,
|
||||
telephoneNumber?sub?(sn=Jensen)";
|
||||
/* Process the search request in the URL. */
|
||||
if ( ldap_url_search_s( ld, my_url, 0, &result ) != LDAP_SUCCESS ) {
|
||||
ldap_perror( ld, "ldap_url_search_s" );
|
||||
return( 1 );
|
||||
}</programlisting>
|
||||
</example>
|
||||
</sect1>
|
||||
</chapter>
|
||||
807
mozilla/directory/docs/ldapcsdk/csdk-multithread.sgm
Normal file
807
mozilla/directory/docs/ldapcsdk/csdk-multithread.sgm
Normal file
@@ -0,0 +1,807 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="csdk-multithread"><title>Writing Multithreaded Clients With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>multithreaded clients</secondary>
|
||||
</indexterm><highlights>
|
||||
<para>This chapter shows how to write multithreaded LDAP client applications.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="bdajf">Specifying Thread Functions With Directory SDK for C</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="bdajj">POSIX Thread Client Application With Directory SDK for C</olink></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>The &DirectorySDKForC; APIs are thread-safe. By default, the APIs
|
||||
use POSIX thread-safe primitives. Therefore, unless you specify your own thread
|
||||
functions, standard best practices for POSIX threading apply.</para>
|
||||
</highlights>
|
||||
<sect1 id="bdajf"><title>Specifying Thread Functions With Directory SDK for
|
||||
C</title>
|
||||
<para>You can write a multithreaded client with different threads accessing
|
||||
the same <structname>LDAP</structname> structure. Use the POSIX thread API.
|
||||
Alternatively, set up the session defining your own structures such that threads
|
||||
do not interfere with data of other threads.</para>
|
||||
<para>The <literal>LDAP_OPT_THREAD_FN_PTRS</literal> session option lets you
|
||||
set up an <structname>ldap_thread_fns</structname> structure. The structure
|
||||
identifies the functions that are called in multithreaded environments. For
|
||||
example, the structure can define functions to lock critical sections of code
|
||||
and to handle errors. As this structure lets you specify these functions,
|
||||
you can use &DirectorySDKForC; in different types of threading environments.</para>
|
||||
<sect2 id="bdajg"><title>Setting Up the <structname>ldap_thread_fns</structname> Structure
|
||||
</title>
|
||||
<para>You can write a multithreaded client in which different threads use
|
||||
the same LDAP connection. Set up the <structname>ldap_thread_fns</structname> structure.
|
||||
Then identify the functions that you want to use in the <structname>ldap_thread_fns
|
||||
</structname> structure.</para>
|
||||
<example id="ldap-thread-fns-prototype"><title><structname>ldap_thread_fns</structname> Structure
|
||||
</title>
|
||||
<programlisting>struct ldap_thread_fns {
|
||||
LDAP_TF_MUTEX_ALLOC_CALLBACK *ltf_mutex_alloc;
|
||||
LDAP_TF_MUTEX_FREE_CALLBACK *ltf_mutex_free;
|
||||
LDAP_TF_MUTEX_LOCK_CALLBACK *ltf_mutex_lock;
|
||||
LDAP_TF_MUTEX_UNLOCK_CALLBACK *ltf_mutex_unlock;
|
||||
LDAP_TF_GET_ERRNO_CALLBACK *ltf_get_errno;
|
||||
LDAP_TF_SET_ERRNO_CALLBACK *ltf_set_errno;
|
||||
LDAP_TF_GET_LDERRNO_CALLBACK *ltf_get_lderrno;
|
||||
LDAP_TF_SET_LDERRNO_CALLBACK *ltf_set_lderrno;
|
||||
void *ltf_lderrno_arg;
|
||||
};</programlisting>
|
||||
</example>
|
||||
<para>The fields of the<?Pub Caret> <structname>ldap_thread_fns</structname> structure
|
||||
are described in the following table.</para>
|
||||
<table frame="topbot" pgwide="1" id="ldap-thread-fns-fields"><title><structname>ldap_thread_fns
|
||||
</structname> Field Descriptions</title>
|
||||
<tgroup cols="2"><colspec colnum="1" colwidth="25*"><colspec colnum="2"
|
||||
colwidth="75*">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Field</para></entry>
|
||||
<entry>
|
||||
<para>Description</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>*ltf_mutex_alloc</structfield></para></entry>
|
||||
<entry>
|
||||
<para>Function pointer for allocating a mutex. This function is called by
|
||||
the client when needed if the function pointer is not <literal>NULL</literal>.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>*ltf_mutex_free</structfield></para></entry>
|
||||
<entry>
|
||||
<para>Function pointer for freeing a mutex. This function is called by the
|
||||
client when needed if the function pointer is not <literal>NULL</literal>.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>*ltf_mutex_lock</structfield></para></entry>
|
||||
<entry>
|
||||
<para>Function pointer for locking critical sections of code. This function
|
||||
is called by the client when needed if the function pointer is not <literal>NULL</literal>.
|
||||
</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>*ltf_mutex_unlock</structfield></para></entry>
|
||||
<entry>
|
||||
<para>Function pointer for unlocking critical sections of code. This function
|
||||
is called by the client when needed if the function pointer is not <literal>NULL</literal>.
|
||||
</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>*ltf_get_errno</structfield></para></entry>
|
||||
<entry>
|
||||
<para>Function pointer for getting the value of the <systemitem>errno</systemitem> variable.
|
||||
This function is called by the client when needed if the function pointer
|
||||
is not <literal>NULL</literal>. In a threaded environment, <systemitem>errno</systemitem> is
|
||||
typically redefined. The error structure has a value for each thread, rather
|
||||
than a global value for the entire process. This redefinition is done at compile
|
||||
time. The <filename>libldap</filename> library does not know what method your
|
||||
code and your threading environment use to get the value of <systemitem>errno</systemitem> for
|
||||
each thread. The library therefore calls this function to return the value
|
||||
of <systemitem>errno</systemitem>.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>*ltf_set_errno</structfield></para></entry>
|
||||
<entry>
|
||||
<para>Function pointer for setting the value of the <systemitem>errno</systemitem> variable.
|
||||
This function is called by the client when needed if the function pointer
|
||||
is not <literal>NULL</literal>. In a threaded environment, <systemitem>errno</systemitem> is
|
||||
typically redefined. The error structure has a value for each thread, rather
|
||||
than a global value for the entire process. This redefinition is done at compile
|
||||
time. The <filename>libldap</filename> library does not know what method your
|
||||
code and your threading environment use to get the value of <systemitem>errno</systemitem> for
|
||||
each thread. The library therefore calls this function to set the value of <systemitem>
|
||||
errno</systemitem>.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>*ltf_get_lderrno</structfield></para></entry>
|
||||
<entry>
|
||||
<para>Function pointer for getting error values from calls to functions in
|
||||
the <filename>libldap</filename> library. This function is called by the client
|
||||
when needed if the function pointer is not <literal>NULL</literal>. If this
|
||||
function pointer is not set, the <filename>libldap</filename> library records
|
||||
these errors in fields in the <structname>LDAP</structname> structure.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>*ltf_set_lderrno</structfield></para></entry>
|
||||
<entry>
|
||||
<para>Function pointer for setting error values from calls to functions in
|
||||
the <filename>libldap</filename> library. This function is called by the client
|
||||
when needed if the function pointer is not <literal>NULL</literal>. If this
|
||||
function pointer is not set, the <filename>libldap</filename> library records
|
||||
these errors in fields in the <structname>LDAP</structname> structure.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><structfield>*ltf_lderrno_arg</structfield></para></entry>
|
||||
<entry>
|
||||
<para>Additional parameter passed to the functions for getting and setting
|
||||
error values from calls to functions in the <filename>libldap</filename> library. <literal>
|
||||
*ltf_get_lderrno</literal> and <literal>*ltf_set_lderrno</literal> identify
|
||||
these functions.</para></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect2>
|
||||
<sect2 id="bdajh"><title>Setting Up the <structname>ldap_extra_thread_fns</structname> Structure
|
||||
</title>
|
||||
<para>&DirectorySDKForC; provides a structure, <structname>ldap_extra_thread_fns
|
||||
</structname>, that specifies <emphasis>additional</emphasis> thread functions
|
||||
for locking. The structure also specifies thread functions for <firstterm>semaphores
|
||||
</firstterm>, which are protected variables. The <structname>ldap_extra_thread_fns
|
||||
</structname> structure is defined in the following example.</para>
|
||||
<example id="ldap-extra-thread-fns-prototype"><title>Declaring the <structname>ldap_extra_thread_fns
|
||||
</structname> Structure</title>
|
||||
<programlisting>struct ldap_extra_thread_fns {
|
||||
LDAP_TF_MUTEX_TRYLOCK_CALLBACK *ltf_mutex_trylock;
|
||||
LDAP_TF_SEMA_ALLOC_CALLBACK *ltf_sema_alloc;
|
||||
LDAP_TF_SEMA_FREE_CALLBACK *ltf_sema_free;
|
||||
LDAP_TF_SEMA_WAIT_CALLBACK *ltf_sema_wait;
|
||||
LDAP_TF_SEMA_POST_CALLBACK *ltf_sema_post;
|
||||
LDAP_TF_THREADID_CALLBACK *ltf_threadid_fn;
|
||||
};</programlisting>
|
||||
</example>
|
||||
<para>&DirectorySDKForC; supports only the <literal>LDAP_TF_TREADID_CALLBACK
|
||||
*ltf_threadid_fn</literal> function. You use this function callback in a multithreaded
|
||||
application to improve the performance of thread locking. The supported function
|
||||
must return an identifier that is unique to the calling thread, like <function>pthread_self
|
||||
</function> does. If any of the other extra thread callback functions are
|
||||
set, the extra functions are ignored. </para></sect2>
|
||||
<sect2 id="bdaji"><title>Setting Session Options</title>
|
||||
<para>After you set up the <structname>ldap_thread_fns</structname> structure,
|
||||
associate the structure with the current session. Call the <function>ldap_set_option
|
||||
</function> function and pass <literal>LDAP_OPT_THREAD_FN_PTRS</literal> as
|
||||
the value of the <literal>option</literal> parameter. Pass a pointer to the <structname>
|
||||
ldap_thread_fns</structname> structure as the value of the <literal>optdata</literal> parameter.
|
||||
</para>
|
||||
<example id="ldap-thread-fns-example"><title>Associating the <structname>ldap_thread_fns
|
||||
</structname> Structure With the Current Session</title>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include "ldap.h"
|
||||
|
||||
struct ldap_thread_fns tfns;
|
||||
...
|
||||
/* Set up the ldap_thread_fns structure with pointers
|
||||
to the functions that you want called */
|
||||
memset( &tfns, '\0', sizeof(struct ldap_thread_fns) );
|
||||
|
||||
/* Specify the functions that you want called */
|
||||
|
||||
/* Call the my_mutex_alloc() function whenever mutexes
|
||||
need to be allocated */
|
||||
tfns.ltf_mutex_alloc = (void *(*)(void)) my_mutex_alloc;
|
||||
|
||||
/* Call the my_mutex_free() function whenever mutexes
|
||||
need to be destroyed */
|
||||
tfns.ltf_mutex_free = (void (*)(void *)) my_mutex_free;
|
||||
|
||||
/* Call the pthread_mutex_lock() function whenever a
|
||||
thread needs to lock a mutex. */
|
||||
tfns.ltf_mutex_lock = (int (*)(void *)) pthread_mutex_lock;
|
||||
|
||||
/* Call the pthread_mutex_unlock() function whenever a
|
||||
thread needs to unlock a mutex. */
|
||||
tfns.ltf_mutex_unlock = (int (*)(void *)) pthread_mutex_unlock;
|
||||
|
||||
/* Call the get_errno() function to get the value of errno */
|
||||
tfns.ltf_get_errno = get_errno;
|
||||
|
||||
/* Call the set_errno() function to set the value of errno */
|
||||
tfns.ltf_set_errno = set_errno;
|
||||
|
||||
/* Call the get_ld_error() function to get error values from
|
||||
calls to functions in the libldap library */
|
||||
tfns.ltf_get_lderrno = get_ld_error;
|
||||
|
||||
/* Call the set_ld_error() function to set error values for
|
||||
calls to functions in the libldap library */
|
||||
tfns.ltf_set_lderrno = set_ld_error;
|
||||
|
||||
/* Don’t pass any extra parameter to the functions for
|
||||
getting and setting libldap function call errors */
|
||||
tfns.ltf_lderrno_arg = NULL;
|
||||
...
|
||||
/* Set the session option that specifies the functions to call for
|
||||
multi-threaded clients */
|
||||
if (ldap_set_option( ld, LDAP_OPT_THREAD_FN_PTRS, (void *) &tfns) != 0) {
|
||||
ldap_perror( ld, "ldap_set_option: thread pointers" );
|
||||
}
|
||||
...</programlisting>
|
||||
</example>
|
||||
<para>If you <emphasis>also</emphasis> set up the <structname>ldap_extra_thread_fns
|
||||
</structname> structure, associate the structure with the current session.
|
||||
Call the <function>ldap_set_option</function> function, passing <literal>LDAP_OPT_EXTRA_THREAD_FN_PTRS
|
||||
</literal> as the value of the <literal>option</literal> parameter. Also pass
|
||||
a pointer to the <structname>ldap_extra_thread_fns</structname> structure
|
||||
as the value of the <literal>optdata</literal> parameter.</para></sect2>
|
||||
</sect1>
|
||||
<sect1 id="bdajj"><title>POSIX Thread Client Application With Directory SDK
|
||||
for C</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>POSIX threading</secondary>
|
||||
</indexterm>
|
||||
<para>The following example which uses <firstterm>pthreads</firstterm> (POSIX
|
||||
threads) on Solaris systems, is the source code for a multithreaded client.
|
||||
The client connects to a specified LDAP server. The client then creates several
|
||||
threads to perform multiple search and update operations simultaneously on
|
||||
the directory.</para>
|
||||
<example id="pthread-example"><title>Using POSIX Threading on a Solaris System</title>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <synch.h>
|
||||
#include "ldap.h"
|
||||
|
||||
/* Authentication and search information. */
|
||||
#define NAME "cn=Directory Manager"
|
||||
#define PASSWORD "rtfm11111"
|
||||
#define BASE "dc=example,dc=com"
|
||||
#define SCOPE LDAP_SCOPE_SUBTREE
|
||||
|
||||
/* Function declarations */
|
||||
static void *search_thread();
|
||||
static void *modify_thread();
|
||||
static void *add_thread();
|
||||
static void *delete_thread();
|
||||
static void set_ld_error();
|
||||
static int get_ld_error();
|
||||
static void set_errno();
|
||||
static int get_errno();
|
||||
static void tsd_setup();
|
||||
|
||||
/* Linked list of LDAPMessage structs for search results. */
|
||||
typedef struct ldapmsgwrapper {
|
||||
LDAPMessage *lmw_messagep;
|
||||
struct ldapmsgwrapper *lmw_next;
|
||||
} ldapmsgwrapper;
|
||||
|
||||
LDAP *ld;
|
||||
pthread_key_t key;
|
||||
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
pthread_t search_tid, search_tid2, search_tid3, search_tid4;
|
||||
pthread_t modify_tid, add_tid, delete_tid;
|
||||
void *status;
|
||||
struct ldap_thread_fns tfns;
|
||||
struct ldap_extra_thread_fns extrafns;
|
||||
int rc;
|
||||
|
||||
/* Check command-line syntax. */
|
||||
if ( argc != 3 ) {
|
||||
fprintf( stderr, "usage: %s <host> <port>\n", argv[0] );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* Create a key. */
|
||||
if ( pthread_key_create( &key, free ) != 0 ) {
|
||||
perror( "pthread_key_create" );
|
||||
}
|
||||
tsd_setup();
|
||||
|
||||
/* Initialize the LDAP session. Use prldap_init() for IPv6. */
|
||||
if ( (ld = ldap_init( argv[1], atoi( argv[2] ) )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* Set the function pointers for dealing with mutexes
|
||||
and error information. */
|
||||
memset( &tfns, '\0', sizeof(struct ldap_thread_fns) );
|
||||
tfns.ltf_mutex_alloc = (void *(*)(void)) my_mutex_alloc;
|
||||
tfns.ltf_mutex_free = (void (*)(void *)) my_mutex_free;
|
||||
tfns.ltf_mutex_lock = (int (*)(void *)) pthread_mutex_lock;
|
||||
tfns.ltf_mutex_unlock = (int (*)(void *)) pthread_mutex_unlock;
|
||||
tfns.ltf_get_errno = get_errno;
|
||||
tfns.ltf_set_errno = set_errno;
|
||||
tfns.ltf_get_lderrno = get_ld_error;
|
||||
tfns.ltf_set_lderrno = set_ld_error;
|
||||
tfns.ltf_lderrno_arg = NULL;
|
||||
|
||||
/* Set up this session to use those function pointers. */
|
||||
rc = ldap_set_option( ld, LDAP_OPT_THREAD_FN_PTRS, (void *) &tfns );
|
||||
if ( rc < 0 ) {
|
||||
fprintf( stderr,
|
||||
"ldap_set_option (LDAP_OPT_THREAD_FN_PTRS): %s\n",
|
||||
ldap_err2string( rc ) );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* Set the function pointers for working with semaphores. */
|
||||
memset( &extrafns, '\0', sizeof(struct ldap_extra_thread_fns) );
|
||||
extrafns.ltf_mutex_trylock = (int (*)(void *)) = null;
|
||||
extrafns.ltf_sema_alloc = (void *(*)(void)) = null;
|
||||
extrafns.ltf_sema_free = (void (*)(void *)) = null;
|
||||
extrafns.ltf_sema_wait = (int (*)(void *)) = null;
|
||||
extrafns.ltf_sema_post = (int (*)(void *)) = null;
|
||||
extrafns.ltf_threadid_fn = (void * (*)(void) )pthread_self;
|
||||
/* Set up this session to use those function pointers. */
|
||||
rc = ldap_set_option( ld,
|
||||
LDAP_OPT_EXTRA_THREAD_FN_PTRS,
|
||||
(void *) &extrafns );
|
||||
if ( rc < 0 ) {
|
||||
fprintf( stderr,
|
||||
"ldap_set_option (LDAP_OPT_EXTRA_THREAD_FN_PTRS): %s\n",
|
||||
ldap_err2string( rc ) );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* Attempt to bind to the server. */
|
||||
rc = ldap_simple_bind_s( ld, NAME, PASSWORD );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr, "ldap_simple_bind_s: %s\n", ldap_err2string( rc ) );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* Initialize the attribute. */
|
||||
if ( pthread_attr_init( &attr ) != 0 ) {
|
||||
perror( "pthread_attr_init" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* Specify that the threads are joinable. */
|
||||
pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE );
|
||||
|
||||
/* Create seven threads: one for adding, one for modifying,
|
||||
one for deleting, and four for searching. */
|
||||
if (pthread_create(&search_tid, &attr, search_thread, "1") != 0) {
|
||||
perror( "pthread_create search_thread" );
|
||||
exit( 1 );
|
||||
}
|
||||
if (pthread_create(&modify_tid, &attr, modify_thread, "2") != 0) {
|
||||
perror( "pthread_create modify_thread" );
|
||||
exit( 1 );
|
||||
}
|
||||
if (pthread_create(&search_tid2, &attr, search_thread, "3") != 0) {
|
||||
perror( "pthread_create search_thread2" );
|
||||
exit( 1 );
|
||||
}
|
||||
if (pthread_create(&add_tid, &attr, add_thread, "4" ) != 0) {
|
||||
perror( "pthread_create add_thread" );
|
||||
exit( 1 );
|
||||
}
|
||||
if (pthread_create(&search_tid3, &attr, search_thread, "5") != 0) {
|
||||
perror( "phread_create search_thread3" );
|
||||
exit( 1 );
|
||||
}
|
||||
if (pthread_create(&delete_tid, &attr, delete_thread, "6") != 0) {
|
||||
perror( "pthread_create delete_thread" );
|
||||
exit( 1 );
|
||||
}
|
||||
if (pthread_create(&search_tid4, &attr, search_thread, "7") != 0) {
|
||||
perror( "pthread_create search_thread4" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* Wait until these threads exit. */
|
||||
pthread_join( modify_tid, &status );
|
||||
pthread_join( add_tid, &status );
|
||||
pthread_join( delete_tid, &status );
|
||||
pthread_join( search_tid, &status );
|
||||
pthread_join( search_tid2, &status );
|
||||
pthread_join( search_tid3, &status );
|
||||
pthread_join( search_tid4, &status );
|
||||
}
|
||||
|
||||
/* Thread for searching the directory.
|
||||
The results are not printed out. */
|
||||
static void *
|
||||
search_thread( char *id )
|
||||
{
|
||||
LDAPMessage *res;
|
||||
LDAPMessage *e;
|
||||
char *a;
|
||||
char **v;
|
||||
char *dn;
|
||||
BerElement *ber;
|
||||
int i, rc, parse_rc, msgid, finished;
|
||||
int num_entries, num_refs;
|
||||
void *tsd;
|
||||
struct timeval zerotime;
|
||||
zerotime.tv_sec = zerotime.tv_usec = 0L;
|
||||
|
||||
printf( "Starting search_thread %s.\n", id );
|
||||
tsd_setup();
|
||||
/* Continually search the directory. */
|
||||
for ( ;; ) {
|
||||
printf( "Thread %s: Searching...\n", id );
|
||||
finished = 0;
|
||||
num_entries = 0;
|
||||
num_refs = 0;
|
||||
rc = ldap_search_ext( ld, BASE, SCOPE, "(objectclass=*)",
|
||||
NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &msgid );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr, "Thread %s error: ldap_search: %s\n",
|
||||
id, ldap_err2string( rc ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Iterate through the results. In this example,
|
||||
don't print out all the results. (It's easier
|
||||
to see the output from the other threads this way.) */
|
||||
while ( !finished ) {
|
||||
rc = ldap_result( ld, msgid, LDAP_MSG_ONE, &zerotime, &res );
|
||||
switch ( rc ) {
|
||||
case -1:
|
||||
rc = ldap_get_lderrno( ld, NULL, NULL );
|
||||
fprintf( stderr, "ldap_result: %s\n", ldap_err2string( rc ) );
|
||||
finished = 1;
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
/* Keep track of the number of entries found. */
|
||||
case LDAP_RES_SEARCH_ENTRY:
|
||||
num_entries++;
|
||||
break;
|
||||
/* Keep track of the number of search references. */
|
||||
case LDAP_RES_SEARCH_REFERENCE:
|
||||
num_refs++;
|
||||
break;
|
||||
case LDAP_RES_SEARCH_RESULT:
|
||||
finished = 1;
|
||||
parse_rc = ldap_parse_result( ld, res, &rc,
|
||||
NULL, NULL, NULL, NULL, 1 );
|
||||
if ( parse_rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr,
|
||||
"Thread %s error: can't parse result code.\n",
|
||||
id );
|
||||
break;
|
||||
} else {
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr,
|
||||
"Thread %s error: ldap_search: %s\n",
|
||||
id, ldap_err2string( rc ) );
|
||||
} else {
|
||||
printf( "Thread %s: Got %d results and %d references.\n",
|
||||
id, num_entries, num_refs );
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Thread for modifying directory entries.
|
||||
This thread searches for entries and randomly selects entries from
|
||||
the search results for modification. */
|
||||
static void *
|
||||
modify_thread( char *id )
|
||||
{
|
||||
LDAPMessage *res;
|
||||
LDAPMessage *e;
|
||||
int i, modentry, num_entries, msgid, rc, parse_rc, finished;
|
||||
LDAPMod mod;
|
||||
LDAPMod *mods[2];
|
||||
char *vals[2];
|
||||
char *dn;
|
||||
ldapmsgwrapper *list, *lmwp, *lastlmwp;
|
||||
struct timeval zerotime;
|
||||
zerotime.tv_sec = zerotime.tv_usec = 0L;
|
||||
|
||||
printf( "Starting modify_thread %s.\n", id );
|
||||
tsd_setup();
|
||||
rc = ldap_search_ext( ld, BASE, SCOPE, "(objectclass=*)",
|
||||
NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &msgid );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr, "Thread %s error: Modify thread: "
|
||||
"ldap_search_ext: %s\n", id, ldap_err2string( rc ) );
|
||||
exit( 1 );
|
||||
}
|
||||
list = lastlmwp = NULL;
|
||||
finished = 0;
|
||||
num_entries = 0;
|
||||
while ( !finished ) {
|
||||
rc = ldap_result( ld, msgid, LDAP_MSG_ONE, &zerotime, &res );
|
||||
switch ( rc ) {
|
||||
case -1:
|
||||
rc = ldap_get_lderrno( ld, NULL, NULL );
|
||||
fprintf( stderr, "ldap_result: %s\n", ldap_err2string( rc ) );
|
||||
exit( 1 );
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
|
||||
/* Keep track of the number of entries found. */
|
||||
case LDAP_RES_SEARCH_ENTRY:
|
||||
num_entries++;
|
||||
if (( lmwp = (ldapmsgwrapper *)
|
||||
malloc( sizeof( ldapmsgwrapper ))) == NULL ) {
|
||||
fprintf( stderr, "Thread %s: Modify thread: Cannot malloc\n", id );
|
||||
exit( 1 );
|
||||
}
|
||||
lmwp->lmw_messagep = res;
|
||||
lmwp->lmw_next = NULL;
|
||||
if ( lastlmwp == NULL ) {
|
||||
list = lastlmwp = lmwp;
|
||||
} else {
|
||||
lastlmwp->lmw_next = lmwp;
|
||||
}
|
||||
lastlmwp = lmwp;
|
||||
break;
|
||||
case LDAP_RES_SEARCH_REFERENCE:
|
||||
break;
|
||||
case LDAP_RES_SEARCH_RESULT:
|
||||
finished = 1;
|
||||
parse_rc = ldap_parse_result( ld, res, &rc, NULL, NULL,
|
||||
NULL, NULL, 1 );
|
||||
if ( parse_rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr,
|
||||
"Thread %s error: can't parse result code.\n",
|
||||
id );
|
||||
exit( 1 );
|
||||
} else {
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf( stderr,
|
||||
"Thread %s error: ldap_search: %s\n",
|
||||
id, ldap_err2string( rc ) );
|
||||
} else {
|
||||
printf( "Thread %s: Got %d results.\n", id, num_entries );
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up the modifications to be made. */
|
||||
mods[0] = &mod;
|
||||
mods[1] = NULL;
|
||||
vals[0] = "bar";
|
||||
vals[1] = NULL;
|
||||
|
||||
/* Modify randomly selected entries. */
|
||||
for ( ;; ) {
|
||||
|
||||
/* Randomly select the entries. */
|
||||
modentry = rand() % num_entries;
|
||||
for ( i = 0, lmwp = list; lmwp != NULL && i < modentry;
|
||||
i++, lmwp = lmwp->lmw_next ) {
|
||||
/* Keep iterating. */
|
||||
}
|
||||
if ( lmwp == NULL ) {
|
||||
fprintf( stderr,
|
||||
"Thread %s: Modify thread could not find entry %d of %d\n",
|
||||
id, modentry, num_entries );
|
||||
continue;
|
||||
}
|
||||
e = lmwp->lmw_messagep;
|
||||
printf( "Thread %s: Modify thread picked entry %d of %d\n",
|
||||
id, i, num_entries );
|
||||
|
||||
/* Perform the modification. */
|
||||
dn = ldap_get_dn( ld, e );
|
||||
mod.mod_op = LDAP_MOD_REPLACE;
|
||||
mod.mod_type = "description";
|
||||
mod.mod_values = vals;
|
||||
printf( "Thread %s: Modifying (%s)\n", id, dn );
|
||||
rc = ldap_modify_ext_s( ld, dn, mods, NULL, NULL );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
rc = ldap_get_lderrno( ld, NULL, NULL );
|
||||
fprintf( stderr, "ldap_modify_ext_s: %s\n", ldap_err2string( rc ) );
|
||||
}
|
||||
free( dn );
|
||||
}
|
||||
}
|
||||
|
||||
/* Thread for adding directory entries.
|
||||
This thread randomly generates DNs for entries and attempts to
|
||||
add them to the directory. */
|
||||
static void *
|
||||
add_thread( char *id )
|
||||
{
|
||||
LDAPMod mod[5];
|
||||
LDAPMod *mods[6];
|
||||
char dn[BUFSIZ], name[40];
|
||||
char *cnvals[2], *snvals[2], *ocvals[3];
|
||||
int i, rc;
|
||||
|
||||
printf( "Starting add_thread %s.\n", id );
|
||||
tsd_setup();
|
||||
|
||||
/* Set up the entry to be added. */
|
||||
for ( i = 0; i < 5; i++ ) {
|
||||
mods[i] = &mod[i];
|
||||
}
|
||||
mods[5] = NULL;
|
||||
mod[0].mod_op = 0;
|
||||
mod[0].mod_type = "cn";
|
||||
mod[0].mod_values = cnvals;
|
||||
cnvals[1] = NULL;
|
||||
mod[1].mod_op = 0;
|
||||
mod[1].mod_type = "sn";
|
||||
mod[1].mod_values = snvals;
|
||||
snvals[1] = NULL;
|
||||
mod[2].mod_op = 0;
|
||||
mod[2].mod_type = "objectclass";
|
||||
mod[2].mod_values = ocvals;
|
||||
ocvals[0] = "top";
|
||||
ocvals[1] = "person";
|
||||
ocvals[2] = NULL;
|
||||
mods[3] = NULL;
|
||||
|
||||
/* Randomly generate DNs and add entries. */
|
||||
for ( ;; ) {
|
||||
sprintf( name, "%d", rand() );
|
||||
sprintf( dn, "cn=%s, " BASE, name );
|
||||
cnvals[0] = name;
|
||||
snvals[0] = name;
|
||||
printf( "Thread %s: Adding entry (%s)\n", id, dn );
|
||||
rc = ldap_add_ext_s( ld, dn, mods, NULL, NULL );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
rc = ldap_get_lderrno( ld, NULL, NULL );
|
||||
fprintf( stderr, "ldap_add_ext_s: %s\n", ldap_err2string( rc ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Thread for deleting directory entries.
|
||||
This thread randomly selects entries for deletion. */
|
||||
static void *
|
||||
delete_thread( char *id )
|
||||
{
|
||||
LDAPMessage *res;
|
||||
char dn[BUFSIZ], name[40];
|
||||
|
||||
printf( "Starting delete_thread %s.\n", id );
|
||||
tsd_setup();
|
||||
|
||||
/* Randomly select entries for deletion. */
|
||||
for ( ;; ) {
|
||||
sprintf( name, "%d", rand() );
|
||||
sprintf( dn, "cn=%s, " BASE, name );
|
||||
printf( "Thread %s: Deleting entry (%s)\n", id, dn );
|
||||
if ( ldap_delete_ext_s( ld, dn, NULL, NULL ) != LDAP_SUCCESS ) {
|
||||
ldap_perror( ld, "ldap_delete_ext_s" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Function for allocating a mutex. */
|
||||
static void *
|
||||
my_mutex_alloc( void )
|
||||
{
|
||||
pthread_mutex_t *mutexp;
|
||||
if ( (mutexp = malloc( sizeof(pthread_mutex_t) )) != NULL ) {
|
||||
pthread_mutex_init( mutexp, NULL );
|
||||
}
|
||||
return( mutexp );
|
||||
}
|
||||
|
||||
/* Function for freeing a mutex. */
|
||||
static void
|
||||
my_mutex_free( void *mutexp )
|
||||
{
|
||||
pthread_mutex_destroy( (pthread_mutex_t *) mutexp );
|
||||
free( mutexp );
|
||||
}
|
||||
|
||||
/* Error structure. */
|
||||
struct ldap_error {
|
||||
int le_errno;
|
||||
char *le_matched;
|
||||
char *le_errmsg;
|
||||
};
|
||||
|
||||
/* Function to set up thread-specific data. */
|
||||
static void
|
||||
tsd_setup()
|
||||
{
|
||||
void *tsd;
|
||||
tsd = pthread_getspecific( key );
|
||||
if ( tsd != NULL ) {
|
||||
fprintf( stderr, "tsd non-null!\n" );
|
||||
pthread_exit( NULL );
|
||||
}
|
||||
tsd = (void *) calloc( 1, sizeof(struct ldap_error) );
|
||||
pthread_setspecific( key, tsd );
|
||||
}
|
||||
|
||||
/* Function for setting an LDAP error. */
|
||||
static void
|
||||
set_ld_error( int err, char *matched, char *errmsg, void *dummy )
|
||||
{
|
||||
struct ldap_error *le;
|
||||
le = pthread_getspecific( key );
|
||||
le->le_errno = err;
|
||||
if ( le->le_matched != NULL ) {
|
||||
ldap_memfree( le->le_matched );
|
||||
}
|
||||
le->le_matched = matched;
|
||||
if ( le->le_errmsg != NULL ) {
|
||||
ldap_memfree( le->le_errmsg );
|
||||
}
|
||||
le->le_errmsg = errmsg;
|
||||
}
|
||||
|
||||
/* Function for getting an LDAP error. */
|
||||
static int
|
||||
get_ld_error( char **matched, char **errmsg, void *dummy )
|
||||
{
|
||||
struct ldap_error *le;
|
||||
le = pthread_getspecific( key );
|
||||
if ( matched != NULL ) {
|
||||
*matched = le->le_matched;
|
||||
}
|
||||
if ( errmsg != NULL ) {
|
||||
*errmsg = le->le_errmsg;
|
||||
}
|
||||
return( le->le_errno );
|
||||
}
|
||||
|
||||
/* Function for setting errno. */
|
||||
static void
|
||||
set_errno( int err )
|
||||
{
|
||||
errno = err;
|
||||
}
|
||||
|
||||
/* Function for getting errno. */
|
||||
static int
|
||||
get_errno( void )
|
||||
{
|
||||
return( errno );
|
||||
}</programlisting>
|
||||
</example>
|
||||
</sect1>
|
||||
</chapter>
|
||||
171
mozilla/directory/docs/ldapcsdk/csdk-quickstart.sgm
Normal file
171
mozilla/directory/docs/ldapcsdk/csdk-quickstart.sgm
Normal file
@@ -0,0 +1,171 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="csdk-quickstart"><title>Getting Started With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>quick start</secondary>
|
||||
</indexterm><highlights>
|
||||
<itemizedlist>
|
||||
<para>This chapter shows how to start using &DirectorySDKForC;and covers
|
||||
the following topics:</para>
|
||||
<listitem><para><olink targetptr="bdabt">Sample Directory Client Code</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="bdabu">Compiling Directory SDK for C Client
|
||||
Applications</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdabx">Running the Client</olink></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="bdabt"><title>Sample Directory Client Code</title>
|
||||
<indexterm>
|
||||
<primary>example programs</primary>
|
||||
<secondary>C SDK</secondary>
|
||||
<tertiary>directory entry retrieval<?Pub Caret></tertiary>
|
||||
</indexterm>
|
||||
<para>The following sample source code is for a command-line program that
|
||||
retrieves the full name, last name, email address, and telephone number of
|
||||
Barbara Jensen.</para>
|
||||
<example id="csdk-quick-sample"><title>Retrieving a Directory Entry</title>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include "ldap.h"
|
||||
|
||||
/* Adjust these setting for your own LDAP server */
|
||||
#define HOSTNAME "localhost"
|
||||
#define PORT_NUMBER LDAP_PORT
|
||||
#define FIND_DN "uid=bjensen,ou=People,dc=example,dc=com"
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
LDAP *ld;
|
||||
LDAPMessage *result, *e;
|
||||
BerElement *ber;
|
||||
char *a;
|
||||
char **vals;
|
||||
int i, rc;
|
||||
|
||||
/* Get a handle to an LDAP connection. */
|
||||
/* To get the handle on an IPv6 network, use prldap_init() instead. */
|
||||
if ( (ld = ldap_init( HOSTNAME, PORT_NUMBER )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Bind anonymously to the LDAP server. */
|
||||
rc = ldap_simple_bind_s( ld, NULL, NULL );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
fprintf(stderr, "ldap_simple_bind_s: %s\n", ldap_err2string(rc));
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Search for the entry. */
|
||||
if ( ( rc = ldap_search_ext_s( ld, FIND_DN, LDAP_SCOPE_BASE,
|
||||
"(objectclass=*)", NULL, 0, NULL, NULL, LDAP_NO_LIMIT,
|
||||
LDAP_NO_LIMIT, &result ) ) != LDAP_SUCCESS ) {
|
||||
fprintf(stderr, "ldap_search_ext_s: %s\n", ldap_err2string(rc));
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Since we are doing a base search, there should be only
|
||||
one matching entry. */
|
||||
e = ldap_first_entry( ld, result );
|
||||
if ( e != NULL ) {
|
||||
printf( "\nFound %s:\n\n", FIND_DN );
|
||||
|
||||
/* Iterate through each attribute in the entry. */
|
||||
for ( a = ldap_first_attribute( ld, e, &ber );
|
||||
a != NULL; a = ldap_next_attribute( ld, e, ber ) ) {
|
||||
|
||||
/* For each attribute, print the attribute name and values. */
|
||||
if ((vals = ldap_get_values( ld, e, a)) != NULL ) {
|
||||
for ( i = 0; vals[i] != NULL; i++ ) {
|
||||
printf( "%s: %s\n", a, vals[i] );
|
||||
}
|
||||
ldap_value_free( vals );
|
||||
}
|
||||
ldap_memfree( a );
|
||||
}
|
||||
if ( ber != NULL ) {
|
||||
ber_free( ber, 0 );
|
||||
}
|
||||
}
|
||||
ldap_msgfree( result );
|
||||
ldap_unbind( ld );
|
||||
return( 0 );
|
||||
}</programlisting>
|
||||
</example>
|
||||
</sect1>
|
||||
<sect1 id="bdabu"><title>Compiling &DirectorySDKForC; Client Applications</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>compiling applications</secondary>
|
||||
</indexterm>
|
||||
<para>The method used to compile the source code depends on the operating
|
||||
system on which you run the application. The following sections include instructions
|
||||
for compiling on UNIX and Windows systems.</para>
|
||||
<sect2 id="bdabv"><title>Compiling Programs on UNIX Systems</title>
|
||||
<para>The &DirectorySDKForC; <filename>examples/</filename> directory contains
|
||||
a UNIX <filename>Makefile</filename>. You can modify the <filename>Makefile</filename> to
|
||||
compile the sample by adjusting the flags in the file. The <filename>Makefile</filename> assumes
|
||||
that the &DirectorySDKForC; header files are located in the <filename>../include/
|
||||
</filename> directory.</para></sect2>
|
||||
<sect2 id="bdabw"><title>Compiling Programs on Windows Systems</title>
|
||||
<itemizedlist>
|
||||
<para>If you are compiling the sample client on Windows, set up the build
|
||||
framework for this application. Make sure to do the following:</para>
|
||||
<listitem><para>If you are using Microsoft development tools, create a new
|
||||
project workspace for a console application. Then add the source file to the
|
||||
project.</para></listitem>
|
||||
<listitem><para>Set your options to include <filename>lib\</filename> as one
|
||||
of the directories for library files, and <filename>include\</filename> as
|
||||
one of the directories for include files.</para></listitem>
|
||||
<listitem><para>Link to <filename>nsldap32v60.lib</filename>, the LDAP API
|
||||
import library for Windows.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="bdabx"><title>Running the Client</title>
|
||||
<para>Before running the sample client, make sure that your LDAP server is
|
||||
set up with the entry the sample attempts to find. Unless you change the source
|
||||
code in <olink targetptr="csdk-quick-sample">Example 5–1</olink>, the
|
||||
entry would be for the full name, last name, email address, and telephone
|
||||
number of Barbara Jensen.</para>
|
||||
<sect2 id="bdaby"><title>Running Programs on UNIX Systems</title>
|
||||
<para>If you have linked the client on a UNIX platform, the client requires
|
||||
the SDK library file. Make sure to set your <envar>LD_LIBRARY_PATH</envar> to
|
||||
locate the <filename>libldap60.so</filename> library file and its dependencies.</para>
|
||||
<para>As an alternative, when linking the file, specify the option that identifies
|
||||
the library directories that the runtime linker should search for. For example,
|
||||
on Solaris systems use the <option>R</option> option to specify the location
|
||||
of the <filename>libldap60.so</filename> file.</para></sect2>
|
||||
<sect2 id="bdabz"><title>Running Programs on Windows Systems</title>
|
||||
<para>If you have linked the client with the <filename>nsldap32v60.lib</filename> library
|
||||
on a Windows system, copy the &DirectorySDKForC; DLL files to one of the
|
||||
following directories:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>The directory where the application was loaded</para></listitem>
|
||||
<listitem><para>The current directory</para></listitem>
|
||||
<listitem><para>The Windows system directory, such as <filename>winnt\system32\</filename></para>
|
||||
</listitem>
|
||||
<listitem><para>The Windows directory</para></listitem>
|
||||
<listitem><para>The directories listed in the <envar>PATH</envar> environment
|
||||
variable</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
1480
mozilla/directory/docs/ldapcsdk/csdk-resultcodes.sgm
Normal file
1480
mozilla/directory/docs/ldapcsdk/csdk-resultcodes.sgm
Normal file
File diff suppressed because it is too large
Load Diff
222
mozilla/directory/docs/ldapcsdk/csdk-sasl.sgm
Normal file
222
mozilla/directory/docs/ldapcsdk/csdk-sasl.sgm
Normal file
@@ -0,0 +1,222 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="csdk-sasl"><title>SASL Authentication With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>Simple Authentication and Security Layer (SASL)</secondary>
|
||||
</indexterm><highlights>
|
||||
<para>This chapter describes the process of using a Simple Authentication
|
||||
and Security Layer (SASL) mechanism to authenticate an LDAP client to an LDAP
|
||||
server.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="bdaig">Understanding SASL and Directory
|
||||
SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdaih">Determining Supported SASL Mechanisms
|
||||
With Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdaii">Authenticating Using SASL With Directory
|
||||
SDK for C</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="bdaig"><title>Understanding SASL and &DirectorySDKForC;</title>
|
||||
<para>The ability to authenticate to an LDAP server with a SASL mechanism
|
||||
is a feature that is new to LDAP v3. LDAP v2 servers do not support this method
|
||||
of authentication.</para>
|
||||
<para>SASL is described in <ulink url="http://www.ietf.org/rfc/rfc4422.txt"
|
||||
type="text_url"><?Pub Caret>RFC 4422</ulink>, <citetitle>Simple Authentication
|
||||
and Security Layer (SASL)</citetitle>.</para></sect1>
|
||||
<sect1 id="bdaih"><title>Determining Supported SASL Mechanisms With &DirectorySDKForC;
|
||||
</title>
|
||||
<para>To determine the SASL mechanisms supported by an LDAP v3 server, get
|
||||
the root DSE of the server, and check the <literal>supportedSASLMechanisms</literal> attribute.
|
||||
The values of this attribute are the names of the SASL mechanisms supported
|
||||
by the server.</para>
|
||||
<para>If the root DSE does not have a <literal>supportedSASLMechanisms</literal> attribute,
|
||||
the server does not support any SASL mechanisms.</para>
|
||||
<para>For information about getting the root DSE, see <olink targetptr="bdahv">To
|
||||
Get the Root DSE</olink>.</para></sect1>
|
||||
<sect1 id="bdaii"><title>Authenticating Using SASL With &DirectorySDKForC;</title>
|
||||
<itemizedlist>
|
||||
<para>To authenticate to the server with a SASL mechanism, call one of the
|
||||
following:</para>
|
||||
<listitem><para>The synchronous <function>ldap_sasl_bind_s</function> function</para>
|
||||
</listitem>
|
||||
<listitem><para>The asynchronous <function>ldap_sasl_bind</function> function</para>
|
||||
<para>If you call the asynchronous function <function>ldap_sasl_bind</function>,
|
||||
you need to call the <function>ldap_result</function> and <function>ldap_parse_sasl_bind_result
|
||||
</function> functions to get the result of the SASL bind operation.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>Authentication with a SASL mechanism can take one or more round—trips
|
||||
between your client and the server. The server might send a number of <firstterm>
|
||||
challenges</firstterm> to the client. You might need to call <function>ldap_sasl_bind_s
|
||||
</function> several times, or <function>ldap_sasl_bind</function>, <function>ldap_result
|
||||
</function>, and <function>ldap_parse_sasl_bind_result</function> several
|
||||
times in order to respond to each server challenge.</para>
|
||||
<para>Before calling the function to perform a SASL bind operation, make sure
|
||||
to specify that your client is LDAP v3 compliant. If you do not, an <errorcode>LDAP_NOT_SUPPORTED
|
||||
</errorcode> result code is returned. See <olink targetptr="bdaci">Specifying
|
||||
the LDAP Version of Your Client</olink>.</para>
|
||||
<sect2 id="bdaij"><title>Synchronous SASL Bind Operation</title>
|
||||
<para>If you want to wait for the results of the SASL bind operation to complete
|
||||
before continuing, call the synchronous <function>ldap_sasl_bind_s</function> function.
|
||||
This function sends a SASL bind request to the server. This function blocks
|
||||
other work until the server sends the results of the operation back to your
|
||||
client.</para>
|
||||
<itemizedlist>
|
||||
<para><function>ldap_sasl_bind_s</function> returns one of the following values:</para>
|
||||
<listitem><para><errorcode>LDAP_SUCCESS</errorcode> if your client has successfully
|
||||
authenticated.</para></listitem>
|
||||
<listitem><para><errorcode>LDAP_SASL_BIND_IN_PROGRESS</errorcode> if the server
|
||||
sends a challenge to your client. If you receive this result code, check the <literal>
|
||||
servercredp</literal> argument for the <structname>berval</structname> structure
|
||||
that contains the server’s challenge. Call the <function>ldap_sasl_bind</function> function
|
||||
again to send a response to that challenge.</para></listitem>
|
||||
<listitem><para>An LDAP error code if a problem occurred or if authentication
|
||||
failed. See the <olink targetptr="bdaux">ldap_sasl_bind_s</olink> function
|
||||
documentation for a list of the possible result codes.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<sect2 id="bdaik"><title>Asynchronous SASL Bind Operation</title>
|
||||
<para>If you want to perform other work in parallel while waiting for the
|
||||
SASL bind operation to complete, use the following procedure.</para>
|
||||
<task><title>To Bind Asynchronously Over SASL</title>
|
||||
<procedure>
|
||||
<step><para>Call the asynchronous <function>ldap_sasl_bind</function> function
|
||||
to send an LDAP SASL bind request.</para><para>This function returns an <errorcode>
|
||||
LDAP_SUCCESS</errorcode> result code if the request was successfully sent,
|
||||
or an LDAP result code if an error occurred while sending the request. The
|
||||
function also sets the <literal>msgidp</literal> argument to point to a message
|
||||
ID identifying the SASL bind operation.</para></step>
|
||||
<step><para>Call the <function>ldap_result</function> function, passing in
|
||||
this message ID to determine whether the server sent a response for this operation
|
||||
to your client.</para><para>The <function>ldap_result</function> function
|
||||
uses the message ID to determine if the server sent a SASL bind response.
|
||||
The function passes back the response in an <structname>LDAPMessage</structname> structure.
|
||||
</para></step>
|
||||
<step><para>Call the <function>ldap_parse_sasl_bind_result</function> function
|
||||
to parse the <structname>LDAPMessage</structname> structure and retrieve information
|
||||
from the server’s response.</para><para>If the server sent a challenge
|
||||
to your client, the challenge is specified in the <structname>berval</structname> structure
|
||||
passed back as the <literal>servercredp</literal> argument.</para></step>
|
||||
<step><para>Call the <function>ldap_get_lderrno</function> function to get
|
||||
the LDAP result code for the operation.</para>
|
||||
<itemizedlist>
|
||||
<para>The function can return one of the following values:</para>
|
||||
<listitem><para><errorcode>LDAP_SUCCESS</errorcode> if your client successfully
|
||||
authenticated to the server.</para></listitem>
|
||||
<listitem><para><errorcode>LDAP_SASL_BIND_IN_PROGRESS</errorcode> if the server
|
||||
sent a challenge to your client.</para><para>If the server returned an <errorcode>
|
||||
LDAP_SASL_BIND_IN_PROGRESS</errorcode> result code, check the <literal>servercredp
|
||||
</literal> argument for the <structname>berval</structname> structure that
|
||||
contains the server’s challenge.</para></listitem>
|
||||
<listitem><para>An LDAP error code if a problem occurred or if authentication
|
||||
failed.</para><para>See the <function>ldap_sasl_bind</function> function documentation
|
||||
for a list of result codes that the server can return for this operation.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</step>
|
||||
<step><para>If the result code is <errorcode>LDAP_SASL_BIND_IN_PROGRESS</errorcode> and
|
||||
if the server passed back another challenge, determine the response to that
|
||||
challenge by calling the <function>ldap_sasl_bind</function> function again
|
||||
to send that response to the server.</para><para>You can call <function>ldap_result
|
||||
</function> and <function>ldap_parse_sasl_bind_result</function> again to
|
||||
get the next challenge sent from the server, if the result is again <errorcode>LDAP_SASL_BIND_IN_PROGRESS
|
||||
</errorcode>.</para></step>
|
||||
</procedure>
|
||||
<example>
|
||||
<title>Authenticating Over SASL</title>
|
||||
<para>This example shows an LDAP client that authenticates using the SASL
|
||||
mechanism that is named <literal>babsmechanism</literal>.</para>
|
||||
<programlisting>#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "ldap.h"
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
LDAP *ld;
|
||||
LDAPMod mod0;
|
||||
LDAPMod mod1;
|
||||
LDAPMod *mods[ 3 ];
|
||||
char *vals0[ 2 ];
|
||||
char *vals1[ 2 ];
|
||||
time_t now;
|
||||
char buf[ 128 ];
|
||||
struct berval cred;
|
||||
struct berval *servcred;
|
||||
int version;
|
||||
/* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
|
||||
if ( (ld = ldap_init( "localhost", 389 )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
return( 1 );
|
||||
}
|
||||
/* Set the LDAP protocol version supported by the client
|
||||
to 3. (By default, this is set to 2. SASL authentication
|
||||
is part of version 3 of the LDAP protocol.) */
|
||||
version = LDAP_VERSION3;
|
||||
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
|
||||
/* authenticate */
|
||||
cred.bv_val = "magic";
|
||||
cred.bv_len = sizeof( "magic" ) - 1;
|
||||
if ( ldap_sasl_bind_s( ld, "uid=bjensen,ou=people,dc=example,dc=com",
|
||||
"babsmechanism", &cred, NULL, NULL,
|
||||
&servcred ) != LDAP_SUCCESS ) {
|
||||
ldap_perror( ld, "ldap_sasl_bind_s" );
|
||||
return( 1 );
|
||||
}
|
||||
/* get and print the credentials returned by the server */
|
||||
printf( "Server credentials: %s\n", servcred->bv_val );
|
||||
/* construct the list of modifications to make */
|
||||
mod0.mod_op = LDAP_MOD_REPLACE;
|
||||
mod0.mod_type = "mail";
|
||||
vals0[0] = "babs@example.com";
|
||||
vals0[1] = NULL;
|
||||
mod0.mod_values = vals0;
|
||||
mod1.mod_op = LDAP_MOD_ADD;
|
||||
mod1.mod_type = "description";
|
||||
time( &now );
|
||||
sprintf( buf, "This entry was modified with the modattrs program on %s",
|
||||
ctime( &now ));
|
||||
/* Get rid of \n which ctime put on the end of the time string */
|
||||
if ( buf[ strlen( buf ) - 1 ] == '\n' ) {
|
||||
buf[ strlen( buf ) - 1 ] = '\0';
|
||||
}
|
||||
vals1[ 0 ] = buf;
|
||||
vals1[ 1 ] = NULL;
|
||||
mod1.mod_values = vals1;
|
||||
mods[ 0 ] = &mod0;
|
||||
mods[ 1 ] = &mod1;
|
||||
mods[ 2 ] = NULL;
|
||||
/* make the change */
|
||||
if ( ldap_modify_s(ld, "uid=bjensen,ou=people,dc=example,dc=com", mods)
|
||||
!= LDAP_SUCCESS ) {
|
||||
ldap_perror( ld, "ldap_modify_s" );
|
||||
return( 1 );
|
||||
}
|
||||
ldap_unbind( ld );
|
||||
printf( "modification was successful\n" );
|
||||
return( 0 );
|
||||
}</programlisting>
|
||||
</example>
|
||||
</task>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
1738
mozilla/directory/docs/ldapcsdk/csdk-search.sgm
Normal file
1738
mozilla/directory/docs/ldapcsdk/csdk-search.sgm
Normal file
File diff suppressed because it is too large
Load Diff
374
mozilla/directory/docs/ldapcsdk/csdk-server-info.sgm
Normal file
374
mozilla/directory/docs/ldapcsdk/csdk-server-info.sgm
Normal file
@@ -0,0 +1,374 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="csdk-server-info"><title>Getting Server Information With &DirectorySDKForC;
|
||||
</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>getting server information</secondary>
|
||||
</indexterm><highlights>
|
||||
<para>This chapter explains how to access and modify information about your
|
||||
LDAP server over the LDAP protocol.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="bdahu">Reading DSEs With Directory SDK for
|
||||
C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdahw">Determining LDAP v3 Support With
|
||||
Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdahx">Getting Schema Information With Directory
|
||||
SDK for C</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="bdahu"><title>Reading DSEs With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>getting server information</secondary>
|
||||
<tertiary>DSE</tertiary>
|
||||
</indexterm>
|
||||
<para>A DSA-specific entry, <firstterm>DSE</firstterm>, contains information
|
||||
specific to the server. In a directory tree, the root of the tree is the root
|
||||
DSE. The root DSE is not part of any naming context. For example, the root
|
||||
DSE is superior to <literal>dc=example,dc=com</literal> in the directory tree.</para>
|
||||
<para>The root DSE is specified as part of LDAP v3. Note that LDAP v2 servers
|
||||
do not necessarily have a root DSE.</para>
|
||||
<itemizedlist>
|
||||
<para>The root DSE can contain the following information:</para>
|
||||
<listitem><para>The naming contexts of this server such as, <literal>dc=example,dc=com
|
||||
</literal></para></listitem>
|
||||
<listitem><para>URLs of alternate servers to contact if this server is unavailable
|
||||
</para></listitem>
|
||||
<listitem><para>The versions of LDAP supported by this server, version 2 or
|
||||
version 3</para></listitem>
|
||||
<listitem><para>The LDAP v3 controls supported by the server</para><para>See <olink targetptr="csdk-controls">Chapter 16, LDAP Controls With Directory SDK
|
||||
for C</olink> for details.</para></listitem>
|
||||
<listitem><para>The SASL mechanisms supported by the server</para><para>See <olink targetptr="csdk-sasl">Chapter 17, SASL Authentication With Directory
|
||||
SDK for C</olink> for details.</para></listitem>
|
||||
<listitem><para>The LDAP v3 extended operations supported by the server</para>
|
||||
<para>See <olink targetptr="csdk-extop">Chapter 18, Extended Operations
|
||||
With Directory SDK for C</olink> for details.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>The following lists root DSE attributes and explains the meaning of
|
||||
their values.</para>
|
||||
<table frame="topbot" pgwide="1" id="server-root-dse-info"><title>Root DSE
|
||||
Attributes and Descriptions of Their Values</title>
|
||||
<tgroup cols="2"><colspec colnum="1" colwidth="21.64*"><colspec colnum="2"
|
||||
colwidth="78.36*">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Attribute Name</para></entry>
|
||||
<entry>
|
||||
<para>Description of Values</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>namingContexts</literal></para></entry>
|
||||
<entry>
|
||||
<para>The naming contexts supported by this server, such <literal>dc=example,dc=com
|
||||
</literal>.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>altServer</literal></para></entry>
|
||||
<entry>
|
||||
<para>LDAP URLs that identify other servers to contact if this server is unavailable.
|
||||
</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>supportedExtension</literal></para></entry>
|
||||
<entry>
|
||||
<para>The object identifiers (OIDs) of the LDAP v3 extended operations supported
|
||||
by this server.</para>
|
||||
<para>If this attribute is not in the root DSE, the server does not support
|
||||
any extended operations.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>supportedControl</literal></para></entry>
|
||||
<entry>
|
||||
<para>The OIDs of the LDAP v3 controls supported by this server.</para>
|
||||
<para>If this attribute is not in the root DSE, the server does not support
|
||||
any LDAP v3 controls.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>supportedSASLMechanisms</literal></para></entry>
|
||||
<entry>
|
||||
<para>The names of the SASL mechanisms supported by the server.</para>
|
||||
<para>If this attribute is not in the root DSE, the server does not support
|
||||
any SASL mechanisms.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>supportedLDAPVersion</literal></para></entry>
|
||||
<entry>
|
||||
<para>The value of this attribute is the version of LDAP supported by this
|
||||
server, such as <literal>2</literal> or <literal>3</literal>.</para></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<task id="bdahv"><title>To Get the Root DSE</title>
|
||||
<procedure>
|
||||
<step><para>Initialize an LDAP session by calling the <function>ldap_init</function> or <function>
|
||||
prldap_init</function> function.</para></step>
|
||||
<step><para>Turn off automatic referral handling by calling the <function>ldap_set_option
|
||||
</function> function and setting the <literal>LDAP_OPT_REFERRALS</literal> option
|
||||
to <literal>LDAP_OPT_OFF</literal>.</para></step>
|
||||
<step><para>Search the directory with the following criteria:</para>
|
||||
<substeps>
|
||||
<step><para>Set the search scope to a <literal>base</literal> search.</para>
|
||||
</step>
|
||||
<step><para>Specify an empty string for the base DN.</para></step>
|
||||
<step><para>Use the search filter <literal>(objectclass=*)</literal>.</para>
|
||||
</step></substeps>
|
||||
</step>
|
||||
<step><para>Check the results of the search.</para><para>If the server returns
|
||||
a result code, such as <errorcode>LDAP_OPERATIONS_ERROR</errorcode>, <errorcode>LDAP_PROTOCOL_ERROR
|
||||
</errorcode>, <errorcode>LDAP_REFERRAL</errorcode>, or <errorcode>LDAP_NO_SUCH_OBJECT
|
||||
</errorcode>, the LDAP server probably does not support LDAP v3.</para><para>The
|
||||
following example gets the root DSE for a server and prints the values of
|
||||
the root DSE attributes. The function assumes that you are passing in a valid
|
||||
connection handle, an <structname>LDAP</structname> structure, you have created
|
||||
by calling <function>ldap_init</function> or <function>prldap_init</function>.
|
||||
The function returns <literal>0</literal> if successful or <literal>1</literal> if
|
||||
an error occurred.</para></step>
|
||||
</procedure>
|
||||
<example id="server-dse-attr-example">
|
||||
<title>Getting the Root DSE and Printing its Attribute Values</title>
|
||||
<programlisting>int printdse( LDAP *ld )
|
||||
{
|
||||
int rc, i;
|
||||
char *matched_msg = NULL, *error_msg = NULL;
|
||||
LDAPMessage *result, *e;
|
||||
BerElement *ber;
|
||||
char *a;
|
||||
char **vals;
|
||||
char *attrs[3];
|
||||
/* Verify that the connection handle is valid. */
|
||||
if ( ld == NULL ) {
|
||||
fprintf( stderr, "Invalid connection handle.\n" );
|
||||
return( 1 );
|
||||
}
|
||||
/* Set automatic referral processing off. */
|
||||
if ( ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF ) != 0 ) {
|
||||
rc = ldap_get_lderrno( ld, NULL, NULL );
|
||||
fprintf( stderr, "ldap_set_option: %s\n", ldap_err2string( rc ) );
|
||||
return( 1 );
|
||||
}
|
||||
/* Search for the root DSE. */
|
||||
attrs[0] = "supportedControl";
|
||||
attrs[1] = "supportedExtension";
|
||||
attrs[2] = NULL;
|
||||
rc = ldap_search_ext_s( ld, "", LDAP_SCOPE_BASE, "(objectclass=*)",
|
||||
attrs, 0, NULL, NULL, NULL, 0, &result );
|
||||
/* Check the search results. */
|
||||
switch( rc ) {
|
||||
/* If successful, the root DSE was found. */
|
||||
case LDAP_SUCCESS:
|
||||
break;
|
||||
/* If the root DSE was not found, the server does not comply
|
||||
with the LDAPv3 protocol. */
|
||||
case LDAP_PARTIAL_RESULTS:
|
||||
case LDAP_NO_SUCH_OBJECT:
|
||||
case LDAP_OPERATIONS_ERROR:
|
||||
case LDAP_PROTOCOL_ERROR:
|
||||
printf( "LDAP server returned result code %d (%s).\n"
|
||||
"This server does not support the LDAPv3 protocol.\n",
|
||||
rc, ldap_err2string( rc ) );
|
||||
return( 1 );
|
||||
/* If any other value is returned, an error must have occurred. */
|
||||
default:
|
||||
fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) );
|
||||
return( 1 );
|
||||
}
|
||||
/* Since only one entry should have matched, get that entry. */
|
||||
e = ldap_first_entry( ld, result );
|
||||
if ( e == NULL ) {
|
||||
fprintf( stderr, "ldap_search_ext_s: Unable to get root DSE.\n");
|
||||
ldap_memfree( result );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Iterate through each attribute in the entry. */
|
||||
for ( a = ldap_first_attribute( ld, e, &ber );
|
||||
a != NULL; a = ldap_next_attribute( ld, e, ber ) ) {
|
||||
|
||||
/* Print each value of the attribute. */
|
||||
if ((vals = ldap_get_values( ld, e, a)) != NULL ) {
|
||||
for ( i = 0; vals[i] != NULL; i++ ) {
|
||||
printf( "%s: %s\n", a, vals[i] );
|
||||
}
|
||||
|
||||
/* Free memory allocated by ldap_get_values(). */
|
||||
ldap_value_free( vals );
|
||||
}
|
||||
|
||||
/* Free memory allocated by ldap_first_attribute(). */
|
||||
ldap_memfree( a );
|
||||
}
|
||||
|
||||
/* Free memory allocated by ldap_first_attribute(). */
|
||||
if ( ber != NULL ) {
|
||||
ber_free( ber, 0 );
|
||||
}
|
||||
|
||||
printf( "\n" );
|
||||
/* Free memory allocated by ldap_search_ext_s(). */
|
||||
ldap_msgfree( result );
|
||||
ldap_unbind( ld );
|
||||
return( 0 );
|
||||
}</programlisting>
|
||||
</example>
|
||||
</task>
|
||||
</sect1>
|
||||
<sect1 id="bdahw"><title>Determining LDAP v3 Support With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>getting server information</secondary>
|
||||
<tertiary>LDAP v3 support</tertiary>
|
||||
</indexterm>
|
||||
<para>You can determine what version an LDAP server supports by getting the <literal>
|
||||
supportedLDAPVersion</literal> attribute from the root DSE. This attribute
|
||||
could contain the value <literal>2</literal> or <literal>3</literal>.</para>
|
||||
<para>You do not need to authenticate or bind before searching the directory.
|
||||
Unlike LDAP v2, LDAP v3 states that clients do not need to bind to the server
|
||||
before performing LDAP operations.</para>
|
||||
<para>The following example connects to an LDAP server. The example code then
|
||||
determines whether the server supports LDAP v3.</para>
|
||||
<example id="server-ldapv3-support-example"><title>Determining the Supported
|
||||
LDAP Version</title>
|
||||
<programlisting>/* Function for determining if the LDAP server supports LDAPv3.
|
||||
This function returns 1 if the server supports LDAPv3 or
|
||||
0 if the server does not support LDAPv3.
|
||||
*/
|
||||
int
|
||||
check_version( char *hostname, int portnum )
|
||||
{
|
||||
LDAP *ld;
|
||||
int i, rc, v3supported = 0;
|
||||
LDAPMessage *result, *e;
|
||||
BerElement *ber;
|
||||
LDAPControl **serverctrls = NULL, **clntctrls = NULL;
|
||||
char *a, *dn;
|
||||
char **vals;
|
||||
char *attrs[2];
|
||||
char *filter = "(objectClass=*)";
|
||||
/* Check arguments */
|
||||
if ( !hostname || !hostname[0] || !portnum ) {
|
||||
printf( "Error: hostname or port number not specified\n" );
|
||||
return( -1 );
|
||||
}
|
||||
/* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
|
||||
if ( (ld = ldap_init( hostname, portnum )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
return( -1 );
|
||||
}
|
||||
/* Set automatic referral processing off. */
|
||||
if ( ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF) !=
|
||||
LDAP_SUCCESS) {
|
||||
ldap_perror( ld, "ldap_set_option" );
|
||||
return( -1 );
|
||||
}
|
||||
/* Search for the root DSE and get the supportedLDAPVersion attribute. */
|
||||
attrs[0] = "supportedLDAPVersion";
|
||||
attrs[1] = NULL;
|
||||
rc = ldap_search_ext_s( ld, "", LDAP_SCOPE_BASE, filter, attrs, 0,
|
||||
serverctrls, clntctrls, NULL, 0, &result );
|
||||
/* Check the search results. */
|
||||
switch( rc ) {
|
||||
/* If successful, the root DSE was found. */
|
||||
case LDAP_SUCCESS:
|
||||
break;
|
||||
/* If the root DSE was not found, the server does not comply
|
||||
with the LDAPv3 protocol. */
|
||||
case LDAP_PARTIAL_RESULTS:
|
||||
case LDAP_NO_SUCH_OBJECT:
|
||||
case LDAP_OPERATIONS_ERROR:
|
||||
case LDAP_PROTOCOL_ERROR:
|
||||
ldap_perror( ld, "ldap_search_ext_s" );
|
||||
return( 0 );
|
||||
break;
|
||||
/* If an different result code is returned, an error may have
|
||||
occurred (for example, the server may be down. */
|
||||
default:
|
||||
ldap_perror( ld, "ldap_search_ext_s" );
|
||||
return( -1 );
|
||||
break;
|
||||
}
|
||||
/* Get the values of the supportedLDAPVersion attribute in the entry. */
|
||||
if (( e = ldap_first_entry( ld, result )) != NULL &&
|
||||
( a = ldap_first_attribute( ld, e, &ber )) != NULL &&
|
||||
(vals = ldap_get_values( ld, e, a)) != NULL ) {
|
||||
for ( i = 0; vals[i] != NULL; i++ ) {
|
||||
if ( !strcmp( "3", vals[i] ) ) {
|
||||
v3supported = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Free any memory allocated. */
|
||||
ldap_value_free( vals );
|
||||
ldap_memfree( a );
|
||||
if ( ber != NULL ) {
|
||||
ber_free( ber, 0 );
|
||||
}
|
||||
}
|
||||
/* Free memory allocated by ldap_search_ext_s(). */
|
||||
ldap_msgfree( result );
|
||||
/* Free the ld structure. */
|
||||
ldap_unbind_s( ld );
|
||||
/* Return a value indicating whether or not LDAPv3 is supported. */
|
||||
return( v3supported );
|
||||
}
|
||||
...</programlisting>
|
||||
</example>
|
||||
</sect1>
|
||||
<sect1 id="bdahx"><title>Getting Schema Information With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>getting server information</secondary>
|
||||
<tertiary>schema</tertiary>
|
||||
</indexterm>
|
||||
<para>In LDAP v3, an entry can specify the schema that defines the object
|
||||
classes, attributes, and matching rules used by the directory. This entry
|
||||
is called the <literal>subschema</literal> entry. To find the DN of the <literal>
|
||||
subschema</literal> entry, get the <literal>subschemaSubentry</literal> operational
|
||||
attribute from the root DSE or any entry.</para>
|
||||
<itemizedlist>
|
||||
<para>The <literal>subschema</literal> entry can have the following attributes:</para>
|
||||
<listitem><para><literal>objectClasses</literal> specifies the object class
|
||||
definitions in the schema. Each value of this attribute is an object class
|
||||
that is known to the server.</para></listitem>
|
||||
<listitem><para><literal>attributeTypes</literal> specifies the attribute
|
||||
type definitions in the schema. Each value of this attribute is an attribute
|
||||
type that is known to the server.</para></listitem>
|
||||
<listitem><para><literal>matchingRules</literal> specifies the matching rule
|
||||
definitions in the schema. Each value of this attribute is a matching rule
|
||||
that is known to the server.</para></listitem>
|
||||
<listitem><para><literal>matchingRuleUse</literal> specifies the use of a
|
||||
matching rule in the schema. This rule specifies the attributes that can be
|
||||
used with this extensible matching rule. Each value of this attribute is a
|
||||
matching rule use description.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>For information about the format of the attribute values, see <ulink
|
||||
url="http://www.ietf.org/rfc/rfc4517.txt" type="text_url"><?Pub Caret>RFC
|
||||
4517</ulink>, <citetitle>Lightweight Directory Access Protocol (v3): Attribute
|
||||
Syntax Definitions</citetitle>.</para></sect1>
|
||||
</chapter>
|
||||
382
mozilla/directory/docs/ldapcsdk/csdk-ssl.sgm
Normal file
382
mozilla/directory/docs/ldapcsdk/csdk-ssl.sgm
Normal file
@@ -0,0 +1,382 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="csdk-ssl"><title>SSL Connections With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>Secure Sockets Layer (SSL)</secondary>
|
||||
</indexterm><highlights>
|
||||
<para>This chapter describes the process of enabling an LDAP client to connect
|
||||
to an LDAP server over the Secure Sockets Layer (SSL) protocol.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="bdahz">How SSL Works With Directory SDK
|
||||
for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdaia">Connecting to a Server Over SSL With
|
||||
Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdaic">Handling Errors With Directory SDK
|
||||
for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="ssl-start-tls">Starting Transport Layer
|
||||
Security With Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdaid">Installing Your Own SSL I/O Functions
|
||||
With Directory SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdaie">Using Certificate-Based Client Authentication
|
||||
With Directory SDK for C</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="bdahz"><title>How SSL Works With &DirectorySDKForC;</title>
|
||||
<para>The primary goal of the SSL protocol is to provide privacy and reliability
|
||||
between two communicating applications.</para>
|
||||
<note><para>SSL is not supported on all LDAP servers.</para><para>SSL communication
|
||||
must take place on a separate TCP port unless the server supports Start TLS.</para>
|
||||
</note>
|
||||
<para>When an LDAP client connects to an LDAP server over SSL, the server
|
||||
identifies itself by sending a certificate to the client. The client needs
|
||||
to determine whether or not the certificate authority (CA) that issued the
|
||||
certificate is trusted. The client therefore searches a certificate database
|
||||
for the certificate of the CA. If the client cannot find the certificate,
|
||||
the client refuses to connect to the server. If the certificate is marked <firstterm>
|
||||
not trusted</firstterm>, the client also refuses to connect to the server.</para>
|
||||
<para>The LDAP server can also request that the client send a certificate
|
||||
to authenticate itself. This part of the process is called <firstterm>certificate-based
|
||||
client authentication</firstterm>. If the client receives a request for a
|
||||
certificate from the server, the client retrieves its certificate from the
|
||||
certificate database. The client sends the certificate to the server for authentication.
|
||||
After receiving the client’s certificate, the LDAP server determines
|
||||
whether or not the CA that issued the certificate is trusted. If the server
|
||||
cannot find the CA certificate in the certificate database, the server refuses
|
||||
to authenticate the client. If the CA certificate is marked as <firstterm>not
|
||||
trusted</firstterm>, the server also refuses to authenticate the client. If
|
||||
the CA is trusted, the server uses the certificate subject name to determine
|
||||
whether the client has access to perform the requested operation.</para>
|
||||
<itemizedlist>
|
||||
<para>&DirectorySDKForC; includes functions that allow you to connect an
|
||||
LDAP client to an LDAP server over SSL. The functions make the following assumptions:
|
||||
</para>
|
||||
<listitem><para>Your client has access to a certificate database. The function
|
||||
call uses this certificate database to determine if the client can trust the
|
||||
certificate sent from the server.</para><para>Different certificate database
|
||||
versions can be incompatible, which might result in database errors.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<itemizedlist>
|
||||
<para>The database used contains any one of the following:</para>
|
||||
<listitem><para>The certificate of the CA that issued the server’s certificate
|
||||
</para></listitem>
|
||||
<listitem><para>If the CAs are organized in a hierarchy, the certificate of
|
||||
any of the CAs in the hierarchy</para></listitem>
|
||||
<listitem><para>The certificate of the LDAP server</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>The CA certificate is marked as <firstterm>trusted</firstterm> in
|
||||
the certificate database.</para></listitem>
|
||||
<listitem>
|
||||
<itemizedlist>
|
||||
<para>If you plan to use certificate-based client authentication, you also
|
||||
need the following:</para>
|
||||
<listitem><para>A client certificate in the certificate database issued by
|
||||
a CA that is trusted by the LDAP server</para></listitem>
|
||||
<listitem><para>A public-private key pair in a key file</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<para>The functions allow you to do the following:</para>
|
||||
<listitem><para>Set the session option for communicating with the server over
|
||||
SSL.</para><para>See <olink targetptr="bdaia">Connecting to a Server Over
|
||||
SSL With Directory SDK for C</olink> for details.</para></listitem>
|
||||
<listitem><para>Start transport layer security by using the Start TLS extended
|
||||
operation</para><para>See <olink targetptr="ssl-start-tls">Starting Transport
|
||||
Layer Security With Directory SDK for C</olink> for details.</para></listitem>
|
||||
<listitem><para>Replace the default I/O functions with your own I/O functions
|
||||
for communicating over SSL</para><para>See <olink targetptr="bdaid">Installing
|
||||
Your Own SSL I/O Functions With Directory SDK for C</olink> for details.</para>
|
||||
</listitem>
|
||||
<listitem><para>Enable your client to send certificates to authenticate itself</para>
|
||||
<para>See <olink targetptr="bdaie">Using Certificate-Based Client Authentication
|
||||
With Directory SDK for C</olink> for details.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="bdaia"><title>Connecting to a Server Over SSL With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>Secure Sockets Layer (SSL)</secondary>
|
||||
<tertiary>connecting to the server</tertiary>
|
||||
</indexterm>
|
||||
<para>To enable your LDAP client to connect to an LDAP server with SSL, you
|
||||
need to perform the following procedure.</para>
|
||||
<task><title>To Initialize a Client SSL Connection by Using <function>ldapssl_init
|
||||
</function></title>
|
||||
<procedure>
|
||||
<step><para>Initialize your client by calling one of the following functions:</para>
|
||||
<substeps>
|
||||
<step><para>Call <function>ldapssl_client_init</function> if you do not plan
|
||||
to use certificate-based client authentication.</para></step>
|
||||
<step><para>Call <function>ldapssl_clientauth_init</function> if you plan
|
||||
to use certificate-based client authentication.</para></step>
|
||||
<step><para>Call <function>ldapssl_advclientauth_init</function>.</para><para>If
|
||||
you use certificate-based client authentication, you need to specify the path
|
||||
of the security module database, or to specify the method to verify the server
|
||||
certificate.</para></step></substeps>
|
||||
<para>You must initialize your client before initializing the LDAP session.
|
||||
The process of initializing the client opens the certificate database.</para>
|
||||
</step>
|
||||
<step><para>Initialize an LDAP session with the secure server by calling the <function>
|
||||
ldapssl_init</function> function.</para><para>For an alternative way to accomplish
|
||||
this step, see <olink targetptr="bdaib">Alternative to ldapssl_init</olink>.</para>
|
||||
</step>
|
||||
</procedure>
|
||||
<example id="ssl-init-connection-example">
|
||||
<title>To Initialize a Client SSL Connection by using <function>ldapssl_init</function></title>
|
||||
<para>This example initializes a client to connect to a secure LDAP server
|
||||
over SSL.</para>
|
||||
<programlisting>if ( ldapssl_client_init( "/local/examples/alias/", NULL ) < 0) {
|
||||
printf( "Failed to initialize SSL client...\n" );
|
||||
return( 1 );
|
||||
}
|
||||
/* get a handle to an LDAP connection */
|
||||
if ( (ld = ldapssl_init( "cert.example.com", LDAPS_PORT, 1 )) == NULL {
|
||||
perror( "ldapssl_init" );
|
||||
return( 1 );
|
||||
}
|
||||
...
|
||||
/* Client can now perform LDAP operations on the secure LDAP server. */
|
||||
...</programlisting>
|
||||
</example>
|
||||
</task>
|
||||
<sect2 id="bdaib"><title>Alternative to <function>ldapssl_init</function></title>
|
||||
<para>As an alternative to calling the <function>ldapssl_init</function> function,
|
||||
you can use the following procedure.</para>
|
||||
<task><title>To Initialize a Client SSL Connection (Alternative Method Using <function>
|
||||
ldap_init</function></title>
|
||||
<procedure>
|
||||
<step><para>After initializing your client, initialize an LDAP session with
|
||||
the server by calling the standard initialization function <function>ldap_init</function>.
|
||||
</para></step>
|
||||
<step><para>Install the standard SSL I/O functions by calling <function>ldapssl_install_routines
|
||||
</function>.</para></step>
|
||||
<step><para>Set the SSL option in the LDAP structure by calling <function>ldap_set_option
|
||||
</function>.</para></step>
|
||||
</procedure>
|
||||
<example id="ssl-init-alt-connection-example">
|
||||
<title>Initializing a Client SSL Initialization (Alternative Method Using <function>
|
||||
ldap_init</function>)</title>
|
||||
<para>This example prepares a client to connect to a secure LDAP server over
|
||||
SSL using <function>ldap_init</function>.</para>
|
||||
<programlisting>if ( ldapssl_client_init( "/local/examples/alias/", NULL ) < 0) {
|
||||
printf( "Failed to initialize SSL client...\n" );
|
||||
return( 1 );
|
||||
}
|
||||
/* Initialize LDAP session. Use prldap_init() for IPv6. */
|
||||
if ( (ld = ldap_init( MY_HOST, LDAPS_PORT )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Load SSL routines */
|
||||
if ( ldapssl_install_routines( ld ) != 0 ) {
|
||||
ldap_perror( ld, "ldapssl_install_routines" );
|
||||
return( 1 );
|
||||
}
|
||||
/* Set up option in LDAP struct for using SSL */
|
||||
if ( ldap_set_option( ld, LDAP_OPT_SSL, LDAP_OPT_ON ) != 0 ) {
|
||||
ldap_perror( ld, "ldap_set_option" );
|
||||
return( 1 );
|
||||
}
|
||||
/* Client can now perform LDAP operations on the secure LDAP server. */
|
||||
...</programlisting>
|
||||
</example>
|
||||
</task>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="bdaic"><title>Handling Errors With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>Secure Sockets Layer (SSL)</secondary>
|
||||
<tertiary>handling errors</tertiary>
|
||||
</indexterm>
|
||||
<para>After calling any of the SSL initialization functions, you can convert
|
||||
SSL-specific error codes to text strings by calling <function>ldapssl_err2string</function>.
|
||||
The <function>ldapssl_err2string</function> function provides support for
|
||||
special SSL error messages that are not handled by the normal error conversion
|
||||
routine <function>ldap_err2string</function>. </para></sect1>
|
||||
<sect1 id="ssl-start-tls"><title>Starting Transport Layer Security With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>Secure Sockets Layer (SSL)</secondary>
|
||||
<tertiary>start TLS</tertiary>
|
||||
</indexterm>
|
||||
<para><ulink url="http://www.ietf.org/rfc/rfc4513.txt" type="text_url">RFC
|
||||
4513</ulink>, <citetitle>Lightweight Directory Access Protocol (LDAP): Authentication
|
||||
Methods and Security Mechanisms</citetitle>, describes the extended operation.
|
||||
Start TLS allows you to connect to a nonsecure port, and then request transport
|
||||
layer security.</para>
|
||||
<task><title>To Use Start TLS</title>
|
||||
<procedure>
|
||||
<step><para>Initialize your client with <function>ldapssl_client_init</function>.
|
||||
</para><para>The process of initializing the client opens the certificate
|
||||
database.</para></step>
|
||||
<step><para>Get a handle to an LDAP connection.</para></step>
|
||||
<step><para>Request Start TLS with <function>ldap_start_tls_s</function>.</para>
|
||||
</step>
|
||||
<step><para>Authenticate to the directory to perform additional operations.</para>
|
||||
</step>
|
||||
</procedure>
|
||||
<example>
|
||||
<title>Using Start TLS</title>
|
||||
<para>This example connects and uses Start TLS, then requests the Who am I?
|
||||
extended operation. The example relies on a certificate database directory, <filename
|
||||
class="directory">/local/examples/alias/</filename>.</para>
|
||||
<programlisting>/*
|
||||
* Use the Start TLS extended operation.
|
||||
*/
|
||||
|
||||
#include "examples.h"
|
||||
#include <ldap_ssl.h>
|
||||
|
||||
/*
|
||||
* Path to certificate database for SSL
|
||||
*/
|
||||
#define CERT_DB_PATH "/local/examples/alias/"
|
||||
|
||||
int
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
int version;
|
||||
LDAP *ld;
|
||||
int rc;
|
||||
char *authzid;
|
||||
|
||||
/* Initialize access to the certificate database. */
|
||||
if ( ldapssl_client_init( CERT_DB_PATH, NULL ) != 0 ) {
|
||||
fprintf( stderr, "ldapssl_client_init failed\n" );
|
||||
fprintf( stderr, "certificate database path: %s\n", CERT_DB_PATH );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Use LDAPv3. */
|
||||
version = LDAP_VERSION3;
|
||||
if ( ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version )
|
||||
!= 0 ) {
|
||||
fprintf( stderr,
|
||||
"ldap_set_option protocol version to %d failed\n",
|
||||
version );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
|
||||
if ( (ld = ldap_init( MY_HOST, MY_PORT )) == NULL ) {
|
||||
perror( "ldap_init" );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Request Start TLS. */
|
||||
if ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
|
||||
ldap_perror( ld, "ldap_start_tls_s" );
|
||||
return( 1 );
|
||||
}
|
||||
printf( "Start TLS operation successful.\n" );
|
||||
|
||||
/* Authenticate to the directory. */
|
||||
if ( ldap_simple_bind_s( ld, ENTRYDN, ENTRYPW ) != LDAP_SUCCESS ) {
|
||||
ldap_perror( ld, "ldap_simple_bind_s" );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
/* Examine my authorization ID. */
|
||||
if ( (rc = ldap_whoami_s( ld, NULL, NULL, &authzid ) )
|
||||
!= LDAP_SUCCESS ) {
|
||||
fprintf( stderr, "ldap_whoami_s: %s\n", ldap_err2string( rc ) );
|
||||
ldap_unbind( ld );
|
||||
return( 1 );
|
||||
}
|
||||
printf( "Authorization ID: %s\n", authzid );
|
||||
|
||||
ldap_unbind( ld );
|
||||
return( 0 );
|
||||
}</programlisting>
|
||||
<para>See <olink targetptr="extendop-whoami">Performing a Who Am I? Extended
|
||||
Operation With Directory SDK for C</olink> for details on using the “Who
|
||||
am I?” extended operation.</para></example>
|
||||
<taskrelated role="troubleshooting">
|
||||
<para>To troubleshoot Start TLS problems, call the <function>PR_GetError</function> function.
|
||||
This function gives you access to many Network Security Services (NSS) errors
|
||||
further documented in the <ulink
|
||||
url="http://www.mozilla.org/projects/security/pki/nss/ref/ssl/sslerr.html"
|
||||
type="text_url">Mozilla.org SSL Reference</ulink>.</para></taskrelated>
|
||||
</task>
|
||||
</sect1>
|
||||
<sect1 id="bdaid"><title>Installing Your Own SSL I/O Functions With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>Secure Sockets Layer (SSL)</secondary>
|
||||
<tertiary>custom I/O functions</tertiary>
|
||||
</indexterm>
|
||||
<para>The <function>ldapssl_init</function> and <function>ldapssl_install_routines
|
||||
</function> functions both set up the session to use the standard SSL I/O
|
||||
functions provided with &DirectorySDKForC;. If you want to use your own
|
||||
SSL I/O functions, use the <structname>ldap_x_ext_io_fns</structname> structure.</para>
|
||||
<task><title>To Install Your Own SSL I/O Functions</title>
|
||||
<procedure>
|
||||
<step><para>Create an <structname>ldap_x_ext_io_fns</structname> structure,
|
||||
and set the fields to point to your I/O functions.</para></step>
|
||||
<step><para>Call <function>ldap_set_option</function> to point to that structure.
|
||||
</para>
|
||||
<programlisting>if (ldap_set_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS, &my_io_struct) != 0 ) {
|
||||
ldap_perror( ld, "ldap_set_option" );
|
||||
return( 1 );
|
||||
}</programlisting>
|
||||
</step>
|
||||
</procedure>
|
||||
</task>
|
||||
</sect1>
|
||||
<sect1 id="bdaie"><title>Using Certificate-Based Client Authentication With &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>Secure Sockets Layer (SSL)</secondary>
|
||||
<tertiary>certificate-based authentication</tertiary>
|
||||
</indexterm>
|
||||
<para>Some LDAP servers can be configured to use certificate-based client
|
||||
authentication. The server requests that your client send a certificate to
|
||||
identify itself. Use the following procedure to configure your client to use
|
||||
certificates for authentication.</para>
|
||||
<task><title>To Use Certificate-Based Client Authentication</title>
|
||||
<procedure>
|
||||
<step><para>Initialize your LDAP client by calling either <function>ldapssl_clientauth_init
|
||||
</function> or <function>ldapssl_advclientauth_init</function>, not <function>ldapssl_client_init
|
||||
</function>.</para><para>U<?Pub Caret1>se <function>ldapssl_advclientauth_init</function> if
|
||||
you want to specify the path of a security module database, or to specify
|
||||
the method used to verify the server certificate.</para><para>You can use
|
||||
one of these functions to initialize your client even if you do not plan to
|
||||
use certificate-based client authentication. The functions are equivalent
|
||||
to <function>ldapssl_client_init</function>.</para></step>
|
||||
<step><para>Initialize an LDAP session with the secure server by calling <function>
|
||||
ldapssl_init</function>.</para></step>
|
||||
<step><para>Enable your client to authenticate with the secure server by calling <function>
|
||||
ldapssl_enable_clientauth</function>.</para></step>
|
||||
<step><para>Perform a Simple Authentication and Security Layer (SASL) bind
|
||||
operation by using the mechanism <literal>EXTERNAL</literal>. This mechanism
|
||||
indicates to the directory server that certificates should be used to authenticate
|
||||
clients.</para><para>With &cnDirectoryServer;, if you perform a SASL bind
|
||||
operation, but the server cannot find the corresponding directory entry for
|
||||
a client certificate, the server returns an <literal>LDAP_INVALID_CREDENTIALS</literal> result
|
||||
code with the error message <literal>Client Certificate Mapping Failed</literal>.
|
||||
</para></step>
|
||||
</procedure>
|
||||
</task>
|
||||
</sect1>
|
||||
</chapter>
|
||||
970
mozilla/directory/docs/ldapcsdk/csdk-understanding.sgm
Normal file
970
mozilla/directory/docs/ldapcsdk/csdk-understanding.sgm
Normal file
@@ -0,0 +1,970 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="csdk-using"><title>About &DirectorySDKForC;</title>
|
||||
<highlights>
|
||||
<itemizedlist>
|
||||
<para>This chapter introduces &DirectorySDKForC; and covers the following
|
||||
topics:</para>
|
||||
<listitem><para><olink targetptr="bdaas">Overview of Directory SDK for C</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="bdaaw">Files Provided With Directory SDK
|
||||
for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdabi">Compiling Applications with Directory
|
||||
SDK for C</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bdabp">Sample Programs for Directory SDK
|
||||
for C</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="bdaas"><title>Overview of &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>overview of</secondary>
|
||||
</indexterm>
|
||||
<para>&DirectorySDKForC; includes the C libraries for the LDAP API as well
|
||||
as sample code that demonstrates how to call many functions. The APIs are
|
||||
defined by the header files that declare all of the functions, data types,
|
||||
and code values in the SDK. You use the functions in this API to write C or
|
||||
C++ client applications that take full advantage of server capabilities.</para>
|
||||
<para>The APIs are built around core functions of the LDAP v2 and v3 standards.
|
||||
Therefore, the APIs can be used to interact with any conforming LDAP server.
|
||||
This API conforms to the standard that is proposed in <citetitle>The C LDAP
|
||||
Application Programming Interface</citetitle>.</para>
|
||||
<sect2 id="bdaat"><title>LDAP API</title>
|
||||
<indexterm>
|
||||
<primary>LDAP Application Programming Interface (API)</primary>
|
||||
<see>LDAP API</see></indexterm><indexterm>
|
||||
<primary>LDAP API</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>APIs</primary>
|
||||
<secondary>LDAP</secondary>
|
||||
</indexterm>
|
||||
<para><ulink url="http://www.ietf.org/rfc/rfc4511.txt" type="text_url">RFC
|
||||
4511</ulink>, <citetitle>Lightweight Directory Access Protocol (v3)</citetitle>,
|
||||
defines a set of operations to access data in an LDAP v3 compliant directory
|
||||
server. The functionality implemented in &DirectorySDKForC; closely follows
|
||||
these operations because a C API is defined for each operation.</para>
|
||||
<itemizedlist>
|
||||
<para>With the C API, you can enable client applications to connect to LDAP
|
||||
v3 compliant directory servers. Client applications can then perform both
|
||||
standard and extended LDAP operations such as the following:</para>
|
||||
<listitem><para>Search for and retrieve a list of entries.</para></listitem>
|
||||
<listitem><para>Add new entries to the database.</para></listitem>
|
||||
<listitem><para>Update existing directory entries.</para></listitem>
|
||||
<listitem><para>Delete entries.</para></listitem>
|
||||
<listitem><para>Rename entries.</para><para>For example, if you are writing
|
||||
an email application, you can use the functions in the API to retrieve email
|
||||
addresses from an LDAP server.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<sect2 id="bdaau"><title>Synchronous and Asynchronous Operations</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>synchronous functions</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>asynchronous functions</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>operations</primary>
|
||||
<secondary>asynchronous</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>operations</primary>
|
||||
<secondary>synchronous</secondary>
|
||||
</indexterm>
|
||||
<para>The API functions allow you to perform LDAP operations synchronously
|
||||
or asynchronously. The only differences between these two options are in the
|
||||
calling convention. The LDAP exchanges are identical.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Call a synchronous function to wait for the operation to complete
|
||||
before receiving the return value of a function.</para></listitem>
|
||||
<listitem><para>Call an asynchronous function to perform other work while
|
||||
waiting for an operation to complete. Your application must then poll for
|
||||
results.</para><para>For more information, see <olink targetptr="bdabq">Synchronous
|
||||
Examples</olink>, and <olink targetptr="bdabr">Asynchronous Examples</olink>.<?Pub
|
||||
Caret></para></listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="bdaaw"><title>Files Provided With Directory SDK for C</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>files installed</secondary>
|
||||
</indexterm>
|
||||
<para>&DirectorySDKForC; includes a number of sample files, headers, libraries,
|
||||
and tools. This section helps you to locate the files. All locations are relative
|
||||
to the directory where the software is installed, which depends on your operating
|
||||
system.</para>
|
||||
<table frame="topbot" pgwide="1"><title>&DirectorySDKForC; Content</title>
|
||||
<tgroup cols="2"><colspec colnum="1" colwidth="19.69*"><colspec colnum="2"
|
||||
colwidth="80.31*">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Directory Location</para></entry>
|
||||
<entry>
|
||||
<para>Description</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>etc/</filename></para></entry>
|
||||
<entry>
|
||||
<para>Contains miscellaneous files for you to use. The files are described
|
||||
in <olink targetptr="bdabc">Miscellaneous Files</olink></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>examples/</filename></para></entry>
|
||||
<entry>
|
||||
<para>Contains sample source code and Makefiles for LDAP clients. See the <literal>
|
||||
README</literal> file in this directory for more information.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>include/</filename></para></entry>
|
||||
<entry>
|
||||
<para>Contains the header files. You must include the files in this directory
|
||||
in your client source files. The header files are described in <olink targetptr="bdaax">Directory SDK for C Header Files</olink></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>include-nspr/</filename></para></entry>
|
||||
<entry>
|
||||
<para>Contains Netscape Portable Runtime (NSPR) header files. NSPR provides
|
||||
a platform-neutral API for system—level and <literal>libc</literal>—style
|
||||
functions.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>include-private/</filename></para></entry>
|
||||
<entry>
|
||||
<para>Contains private header files that are not documented in this guide.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>lib/</filename></para></entry>
|
||||
<entry>
|
||||
<para>Contains the C library files. The specific library used is dependent
|
||||
on the type of application you are building. For details see <olink targetptr="bdabd">Directory SDK for C Libraries</olink>.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>lib-private/</filename></para></entry>
|
||||
<entry>
|
||||
<para>Contains private libraries that are not documented in this guide.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>tools/</filename></para></entry>
|
||||
<entry>
|
||||
<para>Contains the LDAP command-line tools. To use these applications, you
|
||||
must ensure that the tools can find the LDAP API shared library or dynamic
|
||||
link library.</para></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<sect2 id="bdaax"><title>&DirectorySDKForC; Header Files</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>header files</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>header files</primary>
|
||||
<secondary>C SDK</secondary>
|
||||
</indexterm>
|
||||
<para>The following table describes &DirectorySDKForC; header files that
|
||||
are in the <filename>include/</filename> directory. </para>
|
||||
<note><para>All locations are relative to the directory where the software
|
||||
is installed, which depends on your operating system.</para></note>
|
||||
<table frame="topbot" pgwide="1" id="csdk-headers"><title>&DirectorySDKForC; Header
|
||||
Files</title>
|
||||
<tgroup cols="2"><colspec colnum="1" colwidth="22.89*"><colspec colnum="2"
|
||||
colwidth="77.11*">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Header File</para></entry>
|
||||
<entry>
|
||||
<para>Description</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>disptmpl.h</filename></para></entry>
|
||||
<entry>
|
||||
<para>A header file related to the templates (<literal>ldaptemplates.conf</literal>).
|
||||
</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>lber.h</literal></para></entry>
|
||||
<entry>
|
||||
<para>Contains prototypes for the standard Basic Encoding Rules (BER) functions,
|
||||
structures, and defines. For details see <olink targetptr="bdaaz">lber.h Header
|
||||
File</olink></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>ldap-deprecated.h</filename></para></entry>
|
||||
<entry>
|
||||
<para>Contains deprecated functions that should not be used. This header is
|
||||
included in <filename>ldap.h</filename>.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>ldap-extension.h</filename></para></entry>
|
||||
<entry>
|
||||
<para>Contains functions, structures, and defines that extend the standard
|
||||
LDAP C API specification. This header is included in <filename>ldap.h</filename>.
|
||||
</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>ldap-platform.h</filename></para></entry>
|
||||
<entry>
|
||||
<para>A private header file that contains platform-specific definitions, which
|
||||
allow abstraction from the underlying system.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>ldap-standard.h</filename></para></entry>
|
||||
<entry>
|
||||
<para>Contains the standard LDAP functions, structures, and defines. This
|
||||
header is included in <filename>ldap.h</filename>.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>ldap-to-be-deprecated.h</filename></para></entry>
|
||||
<entry>
|
||||
<para>Contains functions, structures, and defines that might be deprecated
|
||||
in future releases. This header is included in <filename>ldap.h</filename>.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>ldap.h</filename></para></entry>
|
||||
<entry>
|
||||
<para>This base header contains LDAP functions, structures, and defines to
|
||||
mirror the latest LDAP C API specifications.</para>
|
||||
<itemizedlist>
|
||||
<para>This header also includes the following header files:</para>
|
||||
<listitem><para><filename>ldap-deprecated.h</filename></para></listitem>
|
||||
<listitem><para><filename>ldap-extension.h</filename></para></listitem>
|
||||
<listitem><para><filename>ldap-standard.h</filename></para></listitem>
|
||||
<listitem><para><filename>ldap-to-be-deprecated.h</filename></para></listitem>
|
||||
</itemizedlist>
|
||||
<para>For details, see <olink targetptr="bdaay">ldap.h Header File</olink>.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>ldap_ssl.h</filename></para></entry>
|
||||
<entry colsep="0">
|
||||
<para>Contains prototypes for LDAP over SSL functions, structures, and defines.
|
||||
For details, see <olink targetptr="bdaba">ldap_ssl.h Header File</olink></para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>ldappr.h</filename></para></entry>
|
||||
<entry>
|
||||
<para>Contains prototypes for the functions, structures, and defines that
|
||||
are contained in the Netscape Portable Runtime (NSPR) API. For details see<olink targetptr="bdabb">ldappr.h Header File</olink></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>srchpref.h</filename></para></entry>
|
||||
<entry>
|
||||
<para>A header file related to the search preferences (<filename>ldapsearchprefs.conf
|
||||
</filename> ).</para></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<sect3 id="bdaay"><title><filename>ldap.h</filename> Header File</title>
|
||||
<para><indexterm>
|
||||
<primary><filename>ldap.h</filename> header file</primary>
|
||||
<secondary>including</secondary>
|
||||
</indexterm>To make use of the &DirectorySDKForC; functions, include the <filename>
|
||||
ldap.h</filename> header file in your C source files as shown in this line
|
||||
of code:</para>
|
||||
<programlisting>#include "ldap.h"</programlisting>
|
||||
<itemizedlist>
|
||||
<para>By including this file, you also include the following header files:</para>
|
||||
<listitem><para><filename>ldap-deprecated.h</filename></para></listitem>
|
||||
<listitem><para><filename>ldap-extension.h</filename></para></listitem>
|
||||
<listitem><para><filename>ldap-standard.h</filename></para></listitem>
|
||||
<listitem><para><filename>ldap-platform.h</filename></para></listitem>
|
||||
<listitem><para><filename>ldap-to-be-deprecated.h</filename></para></listitem>
|
||||
</itemizedlist>
|
||||
</sect3>
|
||||
<sect3 id="bdaaz"><title><filename>lber.h</filename> Header File</title>
|
||||
<indexterm>
|
||||
<primary><filename>lber.h</filename> header file</primary>
|
||||
<secondary>including</secondary>
|
||||
</indexterm>
|
||||
<para><filename>lber.h</filename> is included in <filename>ldap-standard.h</filename>.
|
||||
You do not need to include the header explicitly. Basic Encoding Rules (BER)
|
||||
is a simple tag-value scheme to encode requests and decode results.</para>
|
||||
</sect3>
|
||||
<sect3 id="bdaba"><title><filename>ldap_ssl.h</filename> Header File</title>
|
||||
<para><indexterm>
|
||||
<primary><filename>ldap_ssl.h</filename> header file</primary>
|
||||
<secondary>including</secondary>
|
||||
</indexterm>If you are calling LDAP over SSL functions, you also need to include
|
||||
the <filename>ldap_ssl.h</filename> header file, as follows:</para>
|
||||
<programlisting>#include "ldap_ssl.h"</programlisting>
|
||||
</sect3>
|
||||
<sect3 id="bdabb"><title><filename>ldappr.h</filename> Header File</title>
|
||||
<indexterm>
|
||||
<primary><filename>ldappr.h</filename> header file</primary>
|
||||
<secondary>including</secondary>
|
||||
</indexterm>
|
||||
<para>To make use of the Netscape Portable Runtime (NSPR) API with your LDAP
|
||||
applications, you must include the <filename>ldappr.h</filename> file. The
|
||||
NSPR is a set of platform-neutral APIs that provides system functions such
|
||||
as threads, thread synchronization, I/O, interval timing, and atomic operations.
|
||||
This header file contains prototypes for functions that tie the LDAP libraries
|
||||
to NSPR. You include the header file as follows:</para>
|
||||
<programlisting>#include "ldappr.h"</programlisting>
|
||||
<para>For more information about NSPR, see the <literal>ldappr.h</literal> header
|
||||
file and the Netscape Portable Runtime project page at <ulink
|
||||
url="
|
||||
http://www.mozilla.org/projects/nspr/" type="text_url">http://www.mozilla.org/projects/nspr/
|
||||
</ulink>.</para></sect3>
|
||||
</sect2>
|
||||
<sect2 id="bdabc"><title>Miscellaneous Files</title>
|
||||
<indexterm>
|
||||
<primary><filename>ldapfilter.conf</filename>sample file</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary><filename>ldapfriendly</filename>sample file</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary><filename>ldapsearchprefs.conf</filename>sample file</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary><filename>ldaptemplates.conf</filename>sample file</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>sample files</secondary>
|
||||
</indexterm>
|
||||
<para>&DirectorySDKForC; includes the sample files described in the following
|
||||
table. Sample files can be retrieved when using certain APIs. Sample files
|
||||
are located in the <filename>etc/</filename> directory. All locations are
|
||||
relative to the directory where the software is installed, which depends on
|
||||
your operating system.</para>
|
||||
<table frame="topbot" pgwide="1" id="csdk-sample-config"><title>Sample Configuration
|
||||
Files</title>
|
||||
<tgroup cols="2"><colspec colnum="1" colwidth="24.27*"><colspec colnum="2"
|
||||
colwidth="75.73*">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>
|
||||
<para>File Name</para></entry>
|
||||
<entry>
|
||||
<para>Description</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>ldapfilter.conf</filename></para></entry>
|
||||
<entry>
|
||||
<para>This filter configuration file can be used in context with <function>ldap_init_getfilter
|
||||
</function>.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>ldapfriendly</filename></para></entry>
|
||||
<entry>
|
||||
<para>This file is used to map the two—letter country codes to their
|
||||
full names by <function>ldap_friendly_name</function>.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>ldapsearchprefs.conf</filename></para></entry>
|
||||
<entry>
|
||||
<para>This configuration file was used in context with a deprecated function.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>ldaptemplates.conf</filename></para></entry>
|
||||
<entry>
|
||||
<para>This configuration file was used in context with a deprecated function.</para>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect2>
|
||||
<sect2 id="bdabd"><title>&DirectorySDKForC; Libraries</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>libraries</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>libraries</primary>
|
||||
<secondary>C SDK</secondary>
|
||||
</indexterm>
|
||||
<para>&DirectorySDKForC; includes several different libraries. A library
|
||||
is a set of ready-made functions that are linked into a program. &DirectorySDKForC; uses <firstterm>
|
||||
shared</firstterm> libraries. Shared libraries are dynamically loaded into
|
||||
memory when needed, reducing the size of the executable.</para>
|
||||
<sect3 id="bdabe"><title>Library Naming Conventions</title>
|
||||
<para>Libraries on different systems have different naming conventions. The
|
||||
following table shows the&DirectorySDKForC; naming conventions.</para>
|
||||
<table frame="topbot" pgwide="1" id="csdk-naming-conventions"><title>Library
|
||||
Naming Convention by Operating System</title>
|
||||
<tgroup cols="3">
|
||||
<?PubTbl tgroup dispwid="712.00px">
|
||||
<colspec colnum="1" colwidth="25.72*"><colspec colnum="2" colwidth="28.14*">
|
||||
<colspec colnum="3" colwidth="46.13*">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Operating System</para></entry>
|
||||
<entry>
|
||||
<para>Static Library Name</para></entry>
|
||||
<entry>
|
||||
<para>Shared Library Name</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Solaris and Red Hat systems</para></entry>
|
||||
<entry>
|
||||
<para><filename>lib<replaceable>libraryname</replaceable>.a</filename></para>
|
||||
</entry>
|
||||
<entry>
|
||||
<para><filename>lib<replaceable>libraryname</replaceable>.so.<replaceable>versionnumber
|
||||
</replaceable></filename></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>HP-UX systems</para></entry>
|
||||
<entry>
|
||||
<para><filename>lib<replaceable>libraryname</replaceable>.a</filename></para>
|
||||
</entry>
|
||||
<entry>
|
||||
<para><filename>lib<replaceable>libraryname</replaceable>.sl</filename></para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Windows systems</para></entry>
|
||||
<entry>
|
||||
<para><filename>ns<replaceable>libraryname</replaceable>.lib</filename></para>
|
||||
</entry>
|
||||
<entry>
|
||||
<para><filename>ns<replaceable>libraryname</replaceable>.dll</filename></para>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
<para>On <trademark class="registered">UNIX</trademark> systems, the shared
|
||||
library file name can be fully qualified by prefixing path information.</para>
|
||||
</sect3>
|
||||
<sect3 id="bdabf"><title>Installed Shared Libraries</title>
|
||||
<para>The following table describes the installed libraries that are in the <filename>
|
||||
lib/</filename> directory. All locations are relative to the directory where
|
||||
the software is installed, which depends on your operating system.</para>
|
||||
<table frame="topbot" pgwide="1" id="csdk-shared-libs"><title>Shared Libraries</title>
|
||||
<tgroup cols="3"><colspec colnum="1" colwidth="17.02*"><colspec colnum="2"
|
||||
colwidth="18.77*"><colspec colnum="3" colwidth="64.22*">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>
|
||||
<para>UNIX Library</para></entry>
|
||||
<entry>
|
||||
<para>Windows Library</para></entry>
|
||||
<entry>
|
||||
<para>Description</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>libldap60.so</filename></para></entry>
|
||||
<entry>
|
||||
<para><filename>nsldap32v60.dll</filename></para></entry>
|
||||
<entry>
|
||||
<para>LDAP library.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>libprldap60.so</literal></para></entry>
|
||||
<entry>
|
||||
<para><literal>nsldappr32v60.dll</literal></para></entry>
|
||||
<entry>
|
||||
<para>LDAP library built with NSPR.</para>
|
||||
<para>This library requires the <filename>libnspr4.so</filename> library in
|
||||
the <filename>lib-private/</filename> directory.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>libssldap60.so</literal></para></entry>
|
||||
<entry>
|
||||
<para><literal>nsldapssl32v60.dll</literal></para></entry>
|
||||
<entry>
|
||||
<para>LDAP library that is built with support for the Secure Sockets Layer
|
||||
protocol.</para>
|
||||
<para>This library depends on the <filename>libnss3.so</filename> and <filename>libnspr4.so
|
||||
</filename> libraries in the <filename>lib-private/</filename> directory.</para>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect3>
|
||||
<sect3 id="bdabg"><title>&DirectorySDKForC; Dependencies</title>
|
||||
<itemizedlist>
|
||||
<para>&DirectorySDKForC; resolves dependencies for the following APIs at
|
||||
run—time:</para>
|
||||
<listitem><para>Netscape Portable Runtime (NSPR) provides core cross-platform
|
||||
functions.</para></listitem>
|
||||
<listitem><para>Netscape Security Services (NSS) provides encryption, cryptographic,
|
||||
Secure Sockets Layer (SSL), and Public Key Infrastructure (PKI) support.</para>
|
||||
</listitem>
|
||||
<listitem><para>Simple Authentication and Security Layer (SASL) provides support
|
||||
for applications that require SASL.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect3>
|
||||
</sect2>
|
||||
<sect2 id="bdabh"><title>LDAP Tools</title>
|
||||
<indexterm>
|
||||
<primary>LDAP tools</primary>
|
||||
</indexterm>
|
||||
<para>&DirectorySDKForC; includes several utilities to help you work with
|
||||
LDAP data sets. These utilities are installed in the <filename>tools/</filename> directory.
|
||||
For details on each tool described in the following table, see the corresponding
|
||||
man pages. A list of options can be retrieved by typing the tool name at the
|
||||
command line.</para>
|
||||
<table frame="topbot" pgwide="1" id="csdk-tools"><title>&DirectorySDKForC; LDAP
|
||||
Tools</title>
|
||||
<tgroup cols="2"><colspec colnum="1" colwidth="13.45*"><colspec colnum="2"
|
||||
colwidth="86.55*">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Command</para></entry>
|
||||
<entry>
|
||||
<para>Description</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para><command>ldapcmp</command></para></entry>
|
||||
<entry>
|
||||
<para>Compares the contents of a single LDAP entry or subtree in two directories.
|
||||
</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><command>ldapcompare</command></para></entry>
|
||||
<entry>
|
||||
<para>Compares an attribute value against the contents of a given LDAP entry.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><command>ldapdelete</command></para></entry>
|
||||
<entry>
|
||||
<para>Deletes existing LDAP entries.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><command>ldapmodify</command></para></entry>
|
||||
<entry>
|
||||
<para>Edits the contents of an LDAP directory, either by adding new entries
|
||||
or modifying existing ones.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><command>ldappasswd</command></para></entry>
|
||||
<entry>
|
||||
<para>Changes user passwords on LDAP entries.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><command>ldapsearch</command></para></entry>
|
||||
<entry>
|
||||
<para>Issues search requests to an LDAP directory, then displays the result
|
||||
as LDAP Data Interchange Format (LDIF) text.</para></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="bdabi"><title>Compiling Applications with Directory SDK for C</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>compiling applications</secondary>
|
||||
</indexterm>
|
||||
<para>When compiling applications, you must include the header files and link
|
||||
to the libraries required. Information about including the header files is
|
||||
in <olink targetptr="bdaax">Directory SDK for C Header Files</olink>. Linking
|
||||
to shared libraries is covered in this section. &DirectorySDKForC; is qualified
|
||||
to work with C compilers.</para>
|
||||
<caution><para>&DirectorySDKForC; is not guaranteed to work with C++ compilers.
|
||||
</para></caution>
|
||||
<sect2 id="bdabj"><title>Compiling on UNIX Platforms</title>
|
||||
<para>When compiling clients on UNIX platforms, specify link options correctly
|
||||
to link the application to the appropriate shared libraries. See the <filename>Makefile
|
||||
</filename> in the <filename>examples/</filename> directory for details on
|
||||
compiling your applications on UNIX platforms.</para></sect2>
|
||||
<sect2 id="bdabk"><title>Compiling on Windows Systems With &DirectorySDKForC;</title>
|
||||
<itemizedlist>
|
||||
<para>A Windows application can use either a command-line interface or a graphical
|
||||
user interface (GUI). Windows systems refer to a console application. In a
|
||||
console application, all user interaction happens through the command shell
|
||||
interface, with a <structname>FILE</structname> pointer as found in UNIX systems.
|
||||
Given this difference, make sure that you define the following:</para>
|
||||
<listitem><para><literal>_CONSOLE</literal> if you are writing a console application
|
||||
</para></listitem>
|
||||
<listitem><para><literal>_WINDOWS</literal> if you are writing a standard
|
||||
Windows GUI application</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<sect2 id="bdabo"><title>Linking Dependencies</title>
|
||||
<indexterm>
|
||||
<primary>libraries</primary>
|
||||
<secondary>runtime</secondary>
|
||||
</indexterm>
|
||||
<para>When you run LDAP clients, you must ensure that the operating system
|
||||
can find the shared libraries that support the functions called by your application.
|
||||
Generally, these files are referred to as <emphasis>runtime</emphasis> libraries.
|
||||
Any of the following options ensure that the operating system can find the
|
||||
shared libraries.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Make sure that the shared library file, such as <filename>libldap60.so
|
||||
</filename>, is in a location specified by environment variables.</para>
|
||||
</listitem>
|
||||
<listitem><para>On some platforms, clients can be complied with flags that
|
||||
let you set the runtime path to load libraries as an environment variable.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>On <trademark>Solaris</trademark> and Red Hat systems, you
|
||||
can use the <envar>LD_LIBRARY_PATH</envar> environment variable if you use
|
||||
the <literal>-Wl,+s+b</literal> flag when compiling and linking.</para>
|
||||
</listitem>
|
||||
<listitem><para>On HP-UX system, use the <envar>SHLIB_PATH</envar> environment
|
||||
variable.</para></listitem>
|
||||
<listitem>
|
||||
<orderedlist>
|
||||
<para>On Windows systems, copy all dynamic link libraries (DLLs) needed for
|
||||
your application to a directory where your client can find the libraries.
|
||||
Other software might install a different version of the DLLs in the Windows <filename>
|
||||
system32\</filename> directory. Make sure that your client finds the DLLs
|
||||
included with &DirectorySDKForC; before your client finds the version in
|
||||
the <filename>system32\</filename> directory. At runtime, your client searches
|
||||
for the DLL in the following locations in the order shown:</para>
|
||||
<listitem><para>The directory from which the application loaded</para>
|
||||
</listitem>
|
||||
<listitem><para>The current directory</para></listitem>
|
||||
<listitem><para>The Windows system directory, typically <filename>winnt\system32\
|
||||
</filename></para><para>To avoid potential conflicts, do not copy the DLL
|
||||
to this directory</para></listitem>
|
||||
<listitem><para>The directories listed in the <envar>PATH</envar> environment
|
||||
variable</para></listitem>
|
||||
</orderedlist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>Use a link flag that specifies the path where the executable
|
||||
can find the library. For example, on Solaris systems, you can use the <literal>-R
|
||||
</literal> flag to specify the path where the executable can find the library.</para>
|
||||
<para>See the <filename>Makefile</filename> in the <filename>examples/</filename> directory
|
||||
for examples of additional settings for compiling and linking your LDAP client.
|
||||
Different platforms might require different sets of define statements.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="bdabp"><title>Sample Programs for Directory SDK for C</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>sample programs</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>example programs</primary>
|
||||
<secondary>C SDK</secondary>
|
||||
</indexterm>
|
||||
<para>&DirectorySDKForC; includes several examples that demonstrate the
|
||||
use of the functions that the SDK provides. The examples are located in the <filename>
|
||||
examples/</filename> directory. The example code is designed to run against
|
||||
the LDAP v3 compliant &cnDirectoryServer;. Furthermore, the example code is
|
||||
designed to work with sample data that has been properly loaded. For details
|
||||
on the source files, refer to the <filename>README</filename> in the <filename>examples/
|
||||
</filename> directory.</para>
|
||||
<para>The samples use synchronous LDAP calls and their asynchronous counterparts.
|
||||
Because synchronous LDAP calls are more straightforward than their asynchronous
|
||||
counterparts, look at the synchronous examples first.</para>
|
||||
<sect2 id="bdabq"><title>Synchronous Examples</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>synchronous examples</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>example programs</primary>
|
||||
<secondary>C SDK</secondary>
|
||||
<tertiary>synchronous</tertiary>
|
||||
</indexterm>
|
||||
<para>The synchronous calls block the calling process until all results have
|
||||
been returned. As these programs usually rely on event loops, the programs
|
||||
are not appropriate for use with clients that implement a GUI in a single-threaded
|
||||
environment. However, these sample programs do work with command-line clients
|
||||
and CGI programs.</para>
|
||||
<table frame="topbot" pgwide="1" id="csdk-sync-examples"><title>Synchronous
|
||||
Example Programs</title>
|
||||
<tgroup cols="2"><colspec colnum="1" colwidth="18.17*"><colspec colnum="2"
|
||||
colwidth="81.83*">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Example Source</para></entry>
|
||||
<entry>
|
||||
<para>Description</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>authzid.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use the authorization ID control, which allows you to get
|
||||
the authorization ID for an LDAP operation.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>compare.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use <function>ldap_compare_s</function>, which allows you
|
||||
to test if a particular value is contained in an attribute of an entry.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>crtfilt.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use the <function>ldap_create_filter</function> function
|
||||
to generate LDAP filters.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>csearch.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Like <filename>search.c</filename>, but enables an in-memory cache.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>effright.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use the get effective rights control, which allows you
|
||||
to determine access rights to entries and their attributes.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>getattrs.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Retrieves specific attributes from an entry.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>getfilt.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use the <function>ldap_getfilter*</function> family of
|
||||
functions, which generate LDAP filters that are based on an arbitrary search
|
||||
string provided by a user.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>modattrs.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use <function>ldap_modify_s</function> to replace and add
|
||||
to values in an attribute.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>modrdn.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use <function>ldap_modrdn2_s</function> to change the relative
|
||||
distinguished name (RDN) of an entry.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>pwdextop.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use the LDAP password modify extended operation to change
|
||||
a password.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>pwdpolicy.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use the password policy control. This control allows you
|
||||
to retrieve information about the password policy that applies to the user
|
||||
binding to the directory.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>rdentry.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use <function>ldap_search_s</function> to retrieve a particular
|
||||
entry from the directory.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>realattr.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use the control to retrieve only real attributes during
|
||||
a search.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>search.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use <function>ldap_search_s</function> to search for all
|
||||
entries that have an attribute value that exactly matches what you search
|
||||
for. </para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>srvrsort.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use server-side sorting in conjunction with the <function>ldap_search_ext_s
|
||||
</function> function.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>ssearch.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Like <filename>ssnoauth.c</filename>, but includes certificate-based
|
||||
authentication.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>ssnoauth.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Like <filename>search.c</filename>, but the search is done over an SSL-protected
|
||||
TCP connection.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>starttls.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use the Start TLS extended operation.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>userstatus.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use the account status control to retrieve information
|
||||
about the account of the user binding to the directory.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>virtattr.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use the control to retrieve only virtual attributes during
|
||||
a search.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>whoami.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use the Who am I? extended operation to retrieve the authorization
|
||||
ID.</para></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect2>
|
||||
<sect2 id="bdabr"><title>Asynchronous Examples</title>
|
||||
<indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>asynchronous examples</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>example programs</primary>
|
||||
<secondary>C SDK</secondary>
|
||||
<tertiary>asynchronous programs</tertiary>
|
||||
</indexterm>
|
||||
<para>These examples use the asynchronous LDAP calls. You begin an operation.
|
||||
You then periodically poll to see if any results have been returned.</para>
|
||||
<table frame="topbot" pgwide="1" id="csdk-async-examples"><title>Asynchronous
|
||||
Example Programs</title>
|
||||
<tgroup cols="2"><colspec colnum="1" colwidth="16.64*"><colspec colnum="2"
|
||||
colwidth="83.36*">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Example Source</para></entry>
|
||||
<entry>
|
||||
<para>Description</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>add.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Adds an entry to the directory.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>asearch.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Initiates a search for entries, printing the results on arrival.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>del.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Deletes an entry from the directory.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>nsprio.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Like <literal>asearch.</literal> but uses the PerLDAP routines to incorporate
|
||||
the Netscape Portable Runtime (NSPR) API.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>ppolicy.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Attempts to bind to the directory and reports back any password expiration
|
||||
information received. This program demonstrates how clients can process password
|
||||
policy information.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><filename>psearch.c</filename></para></entry>
|
||||
<entry>
|
||||
<para>Shows how to use Persistent Search, an LDAP v3 extension, to monitor
|
||||
a directory for changes.</para></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
178
mozilla/directory/docs/ldapcsdk/csdk-whatsnew.sgm
Normal file
178
mozilla/directory/docs/ldapcsdk/csdk-whatsnew.sgm
Normal file
@@ -0,0 +1,178 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="csdk-whatsnew"><title>What's New In &DirectorySDKForC;</title>
|
||||
<indexterm>
|
||||
<primary>upgrading</primary>
|
||||
<secondary>C SDK</secondary>
|
||||
</indexterm><highlights>
|
||||
<para>This chapter compares the current version of &DirectorySDKForC; API
|
||||
with the previous version.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="csdk-changed-features">Deprecated and Changed
|
||||
Directory SDK for C Features</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-new-features">New Directory SDK for
|
||||
C Features</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights><?Pub Caret1>
|
||||
<sect1 id="csdk-changed-features"><title>Deprecated and Changed &DirectorySDKForC; Features
|
||||
</title>
|
||||
<indexterm>
|
||||
<primary>deprecated features</primary>
|
||||
<secondary>C SDK</secondary>
|
||||
</indexterm>
|
||||
<para>This section covers the following changes and deprecated features in
|
||||
this release. Where possible, &DirectorySDKForC; provides replacement features
|
||||
for deprecated features.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para><literal>liblber</literal> API</para></listitem>
|
||||
<listitem><para>File layout</para></listitem>
|
||||
<listitem><para>IPv6 support</para></listitem>
|
||||
<listitem><para>NSS and NSPR version updates</para></listitem>
|
||||
<listitem><para>NSS security tools</para></listitem>
|
||||
</itemizedlist>
|
||||
<sect2 id="liblber-changes"><title><filename class="libraryfile">liblber</filename> API
|
||||
</title>
|
||||
<indexterm>
|
||||
<primary>APIs</primary>
|
||||
<secondary><filename class="libraryfile">liblber</filename></secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>libraries</primary>
|
||||
<secondary><filename class="libraryfile">liblber</filename></secondary>
|
||||
</indexterm>
|
||||
<para>The Basic Encoding Rules library, <filename class="libraryfile">liblber</filename>,
|
||||
changed for portability reasons and to comply with <citetitle>The C LDAP Application
|
||||
Program Interface</citetitle> Internet draft. In particular, according to
|
||||
section 17.1., <citetitle>BER Data Structures and Types,</citetitle> the following
|
||||
structures have changed.</para>
|
||||
<programlisting role="fragment">The following additional integral types are defined for use in manipula-
|
||||
tion of BER encoded ASN.1 values:
|
||||
|
||||
typedef <impl_tag_t> ber_tag_t; /* for BER tags */
|
||||
typedef <impl_int_t> ber_int_t; /* for BER ints, enums, and Booleans */
|
||||
typedef <impl_unit_t> ber_uint_t; /* unsigned equivalent of ber_uint_t */
|
||||
typedef <impl_slen_t> ber_slen_t; /* signed equivalent of ber_len_t */
|
||||
|
||||
Note that the actual definition for these four integral types is imple-
|
||||
mentation specific; that is, `<impl_tag_t>', `<impl_int_t>',
|
||||
`<impl_uint_t>', and `<impl_slen_t>' MUST each be replaced with an
|
||||
appropriate implementation-specific type.</programlisting>
|
||||
<para>Programs that do not use the <filename class="libraryfile">liblber</filename> API
|
||||
directly need not be changed. You can continue to build and use those applications
|
||||
as before.</para>
|
||||
<para>If, however, your programs call the <filename class="libraryfile">liblber</filename> API
|
||||
directly, you must change your application code to reflect the type definitions
|
||||
in <filename>include/lber.h</filename>. Compilers typically issue type mismatch
|
||||
warnings when compiling old code that has not been fixed.</para></sect2>
|
||||
<sect2 id="csdk-file-layout-changes"><title>File Layout</title>
|
||||
<para>The file layout has changed. All files are unpacked in a base directory
|
||||
that is named according to the platform and to the operating system of the
|
||||
binary distribution. The file layout is covered in the section on <olink targetptr="bdaaw">Files Provided With Directory SDK for C</olink>.</para>
|
||||
</sect2>
|
||||
<sect2 id="csdk-ipv6-support"><title>IPv6 Support</title>
|
||||
<para>IPv6 support is provided by means of the NSPR library. Therefore, to
|
||||
use LDAP over IPv6, use <function>prldap_init</function> instead of <function>ldap_init
|
||||
</function>.</para></sect2>
|
||||
<sect2 id="csdk-nss-nspr-versions"><title>NSS and NSPR Version Updates</title>
|
||||
<para>This version of &DirectorySDKForC; uses NSS 3.11and NSPR 4.6. Both
|
||||
components are included in binary form for your convenience.</para></sect2>
|
||||
<sect2 id="nss-security-tools"><title>NSS Security Tools</title>
|
||||
<para>NSS security tools, used to maintain NSS databases so your application
|
||||
can do LDAP over SSL, are not delivered with &DirectorySDKForC;.</para>
|
||||
<para>For access to NSS security tools, refer to the <ulink
|
||||
url="http://www.mozilla.org/projects/security/pki/nss/tools/" type="text_url">NSS
|
||||
security tools project</ulink>.</para></sect2>
|
||||
</sect1>
|
||||
<sect1 id="csdk-new-features"><title>New &DirectorySDKForC; Features</title>
|
||||
<indexterm>
|
||||
<primary>new features</primary>
|
||||
<secondary>C SDK</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>C SDK</primary>
|
||||
<secondary>new features of</secondary>
|
||||
</indexterm>
|
||||
<itemizedlist remap="jumplist">
|
||||
<para>This section describes the features introduced in this release:</para>
|
||||
<listitem><para><olink targetptr="csdk-ldap-v3-default">LDAP Version 3 Default</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="csdk-more-supported-controls">Supported
|
||||
Controls</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-more-extop-support">Supported Extended
|
||||
Operations</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-more-sample-code">Additional Directory
|
||||
SDK for C Examples</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
<sect2 id="csdk-ldap-v3-default"><title>LDAP Version 3 Default</title>
|
||||
<para>&DirectorySDKForC; now uses LDAP v3 by default. You can therefore
|
||||
use LDAP v3 features in your applications even if you do not specifically
|
||||
set the version to 3.</para></sect2>
|
||||
<sect2 id="csdk-more-supported-controls"><title>Supported Controls</title>
|
||||
<para>This version of &DirectorySDKForC; adds support for developing client
|
||||
applications, including more than 10 LDAP v3 controls. See <olink targetptr="controls-oids">Table 16–1</olink> for a complete list.</para>
|
||||
<para>For instructions on using controls supported by &DirectorySDKForC;,
|
||||
see <olink targetptr="csdk-controls">Chapter 16, LDAP Controls With Directory
|
||||
SDK for C</olink>.</para></sect2>
|
||||
<sect2 id="csdk-more-extop-support"><title>Supported Extended Operations</title>
|
||||
<indexterm>
|
||||
<primary>extended operations</primary>
|
||||
<secondary>C SDK support of</secondary>
|
||||
</indexterm>
|
||||
<para>This version of &DirectorySDKForC; adds support for developing client
|
||||
applications that use the following extended operations.</para>
|
||||
<variablelist>
|
||||
<varlistentry><term>LDAP Password Modify Extended Operation</term>
|
||||
<listitem><para>The LDAP Password Modify extended operation lets your client
|
||||
application modify a user password through LDAP. A user can modify his password
|
||||
even if the password is not stored as an attribute in the directory, the user
|
||||
is not identified by a DN, or the user does not have an entry in the directory.
|
||||
The LDAP Password Modify extended operation is defined in <ulink
|
||||
url="http://www.ietf.org/rfc/rfc3062.txt" type="text_url">RFC 3062</ulink>.</para>
|
||||
<para>The extended operation has identifier <literal>1.3.6.1.4.1.4203.1.11.1</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term>Start TLS Extended Operation</term>
|
||||
<listitem><para>The Start TLS extended operation lets your client application
|
||||
connect to a nonsecure port, and then request transport layer security.</para>
|
||||
<para>The extended operation has identifier <literal>1.3.6.1.4.1.1466.20037</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term>Who Am I? Extended Operation</term>
|
||||
<listitem><para>The “Who am I?” extended operation lets your client
|
||||
application determine the authorization identity that the server currently
|
||||
associates with your client.</para>
|
||||
<para>The extended operation has identifier <literal>1.3.6.1.4.1.4203.1.11.3</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>For instructions on using extended operations supported by &DirectorySDKForC;,
|
||||
see <olink targetptr="csdk-extop">Chapter 18, Extended Operations With
|
||||
Directory SDK for C</olink>.</para></sect2>
|
||||
<sect2 id="csdk-more-sample-code"><title>Additional &DirectorySDKForC; Examples
|
||||
</title>
|
||||
<indexterm>
|
||||
<primary>example programs</primary>
|
||||
<secondary>C SDK</secondary>
|
||||
</indexterm>
|
||||
<para>More sample code is provided in the <filename>examples/</filename> directory.
|
||||
The additional samples demonstrate newly supported controls and extended operations.
|
||||
</para></sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
2118
mozilla/directory/docs/ldapcsdk/csdk-write.sgm
Normal file
2118
mozilla/directory/docs/ldapcsdk/csdk-write.sgm
Normal file
File diff suppressed because it is too large
Load Diff
BIN
mozilla/directory/docs/ldapcsdk/figures/hierovrw.eps
Normal file
BIN
mozilla/directory/docs/ldapcsdk/figures/hierovrw.eps
Normal file
Binary file not shown.
113
mozilla/directory/docs/ldapcsdk/legal.sgm
Normal file
113
mozilla/directory/docs/ldapcsdk/legal.sgm
Normal file
@@ -0,0 +1,113 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<para>Copyright 2000-2007 Sun Microsystems, Inc., 4150 Network Circle,
|
||||
Santa Clara, California 95054, U.S.A. All rights reserved. Portions
|
||||
copyright 1999 Netscape Communications Corporations. All rights
|
||||
reserved.</para>
|
||||
<para>Sun Microsystems, Inc. has intellectual property rights relating
|
||||
to technology embodied in the product that is described in this
|
||||
document. In particular, and without limitation, these intellectual
|
||||
property rights may include one or more U.S. patents or pending patent
|
||||
applications in the U.S. and in other countries.</para>
|
||||
<para>U.S. Government Rights - Commercial software. Government users
|
||||
are subject to the Sun Microsystems, Inc. standard license agreement
|
||||
and applicable provisions of the FAR and its supplements.</para>
|
||||
<para>This distribution may include materials developed by third
|
||||
parties.</para>
|
||||
<para>Parts of the product may be derived from Berkeley BSD systems,
|
||||
licensed from the University of California. UNIX is a registered
|
||||
trademark in the U.S. and in other countries, exclusively licensed
|
||||
through X/Open Company, Ltd.</para>
|
||||
<para>Sun, Sun Microsystems, the Sun logo, Java, Solaris, JavaBeans,
|
||||
JavaScript and the SunTone Certified logo are trademarks or registered
|
||||
trademarks of Sun Microsystems, Inc. in the U.S. and other
|
||||
countries.</para>
|
||||
<para>All SPARC trademarks are used under license and are trademarks
|
||||
or registered trademarks of SPARC International, Inc. in the U.S. and
|
||||
other countries. Products bearing SPARC trademarks are based upon
|
||||
architecture developed by Sun Microsystems, Inc.</para>
|
||||
<para>Mozilla, Netscape, and Netscape Navigator are trademarks or
|
||||
registered trademarks of Netscape Communications Corporation in the
|
||||
United States and other countries.</para>
|
||||
<para>Products covered by and information contained in this service
|
||||
manual are controlled by U.S. Export Control laws and may be subject
|
||||
to the export or import laws in other countries. Nuclear, missile,
|
||||
chemical biological weapons or nuclear maritime end uses or end users,
|
||||
whether direct or indirect, are strictly prohibited. Export or
|
||||
reexport to countries subject to U.S. embargo or to entities
|
||||
identified on U.S. export exclusion lists, including, but not limited
|
||||
to, the denied persons and specially designated nationals lists is
|
||||
strictly prohibited.</para>
|
||||
<para>DOCUMENTATION IS PROVIDED “AS IS” AND ALL EXPRESS OR
|
||||
IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
|
||||
IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
|
||||
OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH
|
||||
DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.</para>
|
||||
<para>Copyright 2000-2007 Sun Microsystems, Inc., 4150 Network Circle,
|
||||
Santa Clara, California 95054, Etats-Unis. Tous droits
|
||||
réservés. Certaines parties copyright 1999 Netscape
|
||||
Communications Corporations. Tous droits réservés.</para>
|
||||
<para>Sun Microsystems, Inc. détient les droits de
|
||||
propriété intellectuelle relatifs à la
|
||||
technologie incorporée dans le produit qui est décrit
|
||||
dans ce document. En particulier, et ce sans limitation, ces droits de
|
||||
propriété intellectuelle peuvent inclure un ou plusieurs
|
||||
brevets américains ou des applications de brevet en attente aux
|
||||
Etats-Unis et dans d'autres pays.</para>
|
||||
<para>Cette distribution peut comprendre des composants
|
||||
développés par des tierces parties.</para>
|
||||
<para>Des parties de ce produit pourront être
|
||||
dérivées des systèmes Berkeley BSD
|
||||
licenciés par l'Université de Californie. UNIX est une
|
||||
marque déposée aux Etats-Unis et dans d'autres pays et
|
||||
licenciée exclusivement par X/Open Company, Ltd.</para>
|
||||
<para>Sun, Sun Microsystems, le logo Sun, Java, Solaris, JavaBeans,
|
||||
JavaScript et le logo SunTone Certified sont des marques de fabrique
|
||||
ou des marques déposées de Sun Microsystems, Inc. aux
|
||||
Etats-Unis et dans d'autres pays.</para>
|
||||
<para>Toutes les marques SPARC sont utilisées sous licence et
|
||||
sont des marques de fabrique ou des marques déposées de
|
||||
SPARC International, Inc. aux Etats-Unis et dans d'autres pays. Les
|
||||
produits portant les marques SPARC sont basés sur une
|
||||
architecture développée par Sun Microsystems,
|
||||
Inc.</para>
|
||||
<para>Mozilla, Netscape, et Netscape Navigator sont des marques de
|
||||
Netscape Communications Corporation aux Etats-Unis et dans d'autres
|
||||
pays.</para>
|
||||
<para>Les produits qui font l'objet de ce manuel d'entretien et les
|
||||
informations qu'il contient sont regis par la legislation americaine
|
||||
en matiere de controle des exportations et peuvent etre soumis au
|
||||
droit d'autres pays dans le domaine des exportations et
|
||||
importations. Les utilisations finales, ou utilisateurs finaux, pour
|
||||
des armes nucleaires, des missiles, des armes biologiques et chimiques
|
||||
ou du nucleaire maritime, directement ou indirectement, sont
|
||||
strictement interdites. Les exportations ou reexportations vers des
|
||||
pays sous embargo des Etats-Unis, ou vers des entites figurant sur les
|
||||
listes d'exclusion d'exportation americaines, y compris, mais de
|
||||
maniere non exclusive, la liste de personnes qui font objet d'un ordre
|
||||
de ne pas participer, d'une facon directe ou indirecte, aux
|
||||
exportations des produits ou des services qui sont regi par la
|
||||
legislation americaine en matiere de controle des exportations et la
|
||||
liste de ressortissants specifiquement designes, sont rigoureusement
|
||||
interdites.</para>
|
||||
<para>LA DOCUMENTATION EST FOURNIE “EN L'ETAT” ET TOUTES
|
||||
AUTRES CONDITIONS, DECLARATIONS ET GARANTIES EXPRESSES OU TACITES SONT
|
||||
FORMELLEMENT EXCLUES, DANS LA MESURE AUTORISEE PAR LA LOI APPLICABLE,
|
||||
Y COMPRIS NOTAMMENT TOUTE GARANTIE IMPLICITE RELATIVE A LA QUALITE
|
||||
MARCHANDE, A L'APTITUDE A UNE UTILISATION PARTICULIERE OU A L'ABSENCE
|
||||
DE CONTREFACON. </para>
|
||||
226
mozilla/directory/docs/ldapcsdk/license.txt
Normal file
226
mozilla/directory/docs/ldapcsdk/license.txt
Normal file
@@ -0,0 +1,226 @@
|
||||
Attribution-ShareAlike 2.5
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL
|
||||
SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT
|
||||
RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS.
|
||||
CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND
|
||||
DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE.
|
||||
|
||||
License
|
||||
|
||||
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS
|
||||
PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR
|
||||
OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS
|
||||
LICENSE OR COPYRIGHT LAW IS PROHIBITED.
|
||||
|
||||
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE
|
||||
BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED
|
||||
HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
|
||||
|
||||
1. Definitions
|
||||
|
||||
1. "Collective Work" means a work, such as a periodical issue, anthology or
|
||||
encyclopedia, in which the Work in its entirety in unmodified form, along with a
|
||||
number of other contributions, constituting separate and independent works in
|
||||
themselves, are assembled into a collective whole. A work that constitutes a
|
||||
Collective Work will not be considered a Derivative Work (as defined below) for
|
||||
the purposes of this License.
|
||||
2. "Derivative Work" means a work based upon the Work or upon the Work and
|
||||
other pre-existing works, such as a translation, musical arrangement,
|
||||
dramatization, fictionalization, motion picture version, sound recording, art
|
||||
reproduction, abridgment, condensation, or any other form in which the Work may
|
||||
be recast, transformed, or adapted, except that a work that constitutes a
|
||||
Collective Work will not be considered a Derivative Work for the purpose of this
|
||||
License. For the avoidance of doubt, where the Work is a musical composition or
|
||||
sound recording, the synchronization of the Work in timed-relation with a moving
|
||||
image ("synching") will be considered a Derivative Work for the purpose of this
|
||||
License.
|
||||
3. "Licensor" means the individual or entity that offers the Work under the
|
||||
terms of this License.
|
||||
4. "Original Author" means the individual or entity who created the Work.
|
||||
5. "Work" means the copyrightable work of authorship offered under the terms
|
||||
of this License.
|
||||
6. "You" means an individual or entity exercising rights under this License
|
||||
who has not previously violated the terms of this License with respect to the
|
||||
Work, or who has received express permission from the Licensor to exercise
|
||||
rights under this License despite a previous violation.
|
||||
7. "License Elements" means the following high-level license attributes as
|
||||
selected by Licensor and indicated in the title of this License: Attribution,
|
||||
ShareAlike.
|
||||
|
||||
2. Fair Use Rights. Nothing in this license is intended to reduce, limit, or
|
||||
restrict any rights arising from fair use, first sale or other limitations on
|
||||
the exclusive rights of the copyright owner under copyright law or other
|
||||
applicable laws.
|
||||
|
||||
3. License Grant. Subject to the terms and conditions of this License, Licensor
|
||||
hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the
|
||||
duration of the applicable copyright) license to exercise the rights in the Work
|
||||
as stated below:
|
||||
|
||||
1. to reproduce the Work, to incorporate the Work into one or more Collective
|
||||
Works, and to reproduce the Work as incorporated in the Collective Works;
|
||||
2. to create and reproduce Derivative Works;
|
||||
3. to distribute copies or phonorecords of, display publicly, perform
|
||||
publicly, and perform publicly by means of a digital audio transmission the Work
|
||||
including as incorporated in Collective Works;
|
||||
4. to distribute copies or phonorecords of, display publicly, perform
|
||||
publicly, and perform publicly by means of a digital audio transmission
|
||||
Derivative Works.
|
||||
5.
|
||||
|
||||
For the avoidance of doubt, where the work is a musical composition:
|
||||
1. Performance Royalties Under Blanket Licenses. Licensor waives the
|
||||
exclusive right to collect, whether individually or via a performance rights
|
||||
society (e.g. ASCAP, BMI, SESAC), royalties for the public performance or public
|
||||
digital performance (e.g. webcast) of the Work.
|
||||
2. Mechanical Rights and Statutory Royalties. Licensor waives the
|
||||
exclusive right to collect, whether individually or via a music rights society
|
||||
or designated agent (e.g. Harry Fox Agency), royalties for any phonorecord You
|
||||
create from the Work ("cover version") and distribute, subject to the compulsory
|
||||
license created by 17 USC Section 115 of the US Copyright Act (or the equivalent
|
||||
in other jurisdictions).
|
||||
6. Webcasting Rights and Statutory Royalties. For the avoidance of doubt,
|
||||
where the Work is a sound recording, Licensor waives the exclusive right to
|
||||
collect, whether individually or via a performance-rights society (e.g.
|
||||
SoundExchange), royalties for the public digital performance (e.g. webcast) of
|
||||
the Work, subject to the compulsory license created by 17 USC Section 114 of the
|
||||
US Copyright Act (or the equivalent in other jurisdictions).
|
||||
|
||||
The above rights may be exercised in all media and formats whether now known or
|
||||
hereafter devised. The above rights include the right to make such modifications
|
||||
as are technically necessary to exercise the rights in other media and formats.
|
||||
All rights not expressly granted by Licensor are hereby reserved.
|
||||
|
||||
4. Restrictions.The license granted in Section 3 above is expressly made subject
|
||||
to and limited by the following restrictions:
|
||||
|
||||
1. You may distribute, publicly display, publicly perform, or publicly
|
||||
digitally perform the Work only under the terms of this License, and You must
|
||||
include a copy of, or the Uniform Resource Identifier for, this License with
|
||||
every copy or phonorecord of the Work You distribute, publicly display, publicly
|
||||
perform, or publicly digitally perform. You may not offer or impose any terms on
|
||||
the Work that alter or restrict the terms of this License or the recipients'
|
||||
exercise of the rights granted hereunder. You may not sublicense the Work. You
|
||||
must keep intact all notices that refer to this License and to the disclaimer of
|
||||
warranties. You may not distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform the Work with any technological measures that control
|
||||
access or use of the Work in a manner inconsistent with the terms of this
|
||||
License Agreement. The above applies to the Work as incorporated in a Collective
|
||||
Work, but this does not require the Collective Work apart from the Work itself
|
||||
to be made subject to the terms of this License. If You create a Collective
|
||||
Work, upon notice from any Licensor You must, to the extent practicable, remove
|
||||
from the Collective Work any credit as required by clause 4(c), as requested. If
|
||||
You create a Derivative Work, upon notice from any Licensor You must, to the
|
||||
extent practicable, remove from the Derivative Work any credit as required by
|
||||
clause 4(c), as requested.
|
||||
2. You may distribute, publicly display, publicly perform, or publicly
|
||||
digitally perform a Derivative Work only under the terms of this License, a
|
||||
later version of this License with the same License Elements as this License, or
|
||||
a Creative Commons iCommons license that contains the same License Elements as
|
||||
this License (e.g. Attribution-ShareAlike 2.5 Japan). You must include a copy
|
||||
of, or the Uniform Resource Identifier for, this License or other license
|
||||
specified in the previous sentence with every copy or phonorecord of each
|
||||
Derivative Work You distribute, publicly display, publicly perform, or publicly
|
||||
digitally perform. You may not offer or impose any terms on the Derivative Works
|
||||
that alter or restrict the terms of this License or the recipients' exercise of
|
||||
the rights granted hereunder, and You must keep intact all notices that refer to
|
||||
this License and to the disclaimer of warranties. You may not distribute,
|
||||
publicly display, publicly perform, or publicly digitally perform the Derivative
|
||||
Work with any technological measures that control access or use of the Work in a
|
||||
manner inconsistent with the terms of this License Agreement. The above applies
|
||||
to the Derivative Work as incorporated in a Collective Work, but this does not
|
||||
require the Collective Work apart from the Derivative Work itself to be made
|
||||
subject to the terms of this License.
|
||||
3. If you distribute, publicly display, publicly perform, or publicly
|
||||
digitally perform the Work or any Derivative Works or Collective Works, You must
|
||||
keep intact all copyright notices for the Work and provide, reasonable to the
|
||||
medium or means You are utilizing: (i) the name of the Original Author (or
|
||||
pseudonym, if applicable) if supplied, and/or (ii) if the Original Author and/or
|
||||
Licensor designate another party or parties (e.g. a sponsor institute,
|
||||
publishing entity, journal) for attribution in Licensor's copyright notice,
|
||||
terms of service or by other reasonable means, the name of such party or
|
||||
parties; the title of the Work if supplied; to the extent reasonably
|
||||
practicable, the Uniform Resource Identifier, if any, that Licensor specifies to
|
||||
be associated with the Work, unless such URI does not refer to the copyright
|
||||
notice or licensing information for the Work; and in the case of a Derivative
|
||||
Work, a credit identifying the use of the Work in the Derivative Work (e.g.,
|
||||
"French translation of the Work by Original Author," or "Screenplay based on
|
||||
original Work by Original Author"). Such credit may be implemented in any
|
||||
reasonable manner; provided, however, that in the case of a Derivative Work or
|
||||
Collective Work, at a minimum such credit will appear where any other comparable
|
||||
authorship credit appears and in a manner at least as prominent as such other
|
||||
comparable authorship credit.
|
||||
|
||||
5. Representations, Warranties and Disclaimer
|
||||
|
||||
UNLESS OTHERWISE AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK
|
||||
AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE
|
||||
MATERIALS, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT
|
||||
LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY,
|
||||
OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME
|
||||
JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH
|
||||
EXCLUSION MAY NOT APPLY TO YOU.
|
||||
|
||||
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN
|
||||
NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS
|
||||
LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
7. Termination
|
||||
|
||||
1. This License and the rights granted hereunder will terminate automatically
|
||||
upon any breach by You of the terms of this License. Individuals or entities who
|
||||
have received Derivative Works or Collective Works from You under this License,
|
||||
however, will not have their licenses terminated provided such individuals or
|
||||
entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7,
|
||||
and 8 will survive any termination of this License.
|
||||
2. Subject to the above terms and conditions, the license granted here is
|
||||
perpetual (for the duration of the applicable copyright in the Work).
|
||||
Notwithstanding the above, Licensor reserves the right to release the Work under
|
||||
different license terms or to stop distributing the Work at any time; provided,
|
||||
however that any such election will not serve to withdraw this License (or any
|
||||
other license that has been, or is required to be, granted under the terms of
|
||||
this License), and this License will continue in full force and effect unless
|
||||
terminated as stated above.
|
||||
|
||||
8. Miscellaneous
|
||||
|
||||
1. Each time You distribute or publicly digitally perform the Work or a
|
||||
Collective Work, the Licensor offers to the recipient a license to the Work on
|
||||
the same terms and conditions as the license granted to You under this License.
|
||||
2. Each time You distribute or publicly digitally perform a Derivative Work,
|
||||
Licensor offers to the recipient a license to the original Work on the same
|
||||
terms and conditions as the license granted to You under this License.
|
||||
3. If any provision of this License is invalid or unenforceable under
|
||||
applicable law, it shall not affect the validity or enforceability of the
|
||||
remainder of the terms of this License, and without further action by the
|
||||
parties to this agreement, such provision shall be reformed to the minimum
|
||||
extent necessary to make such provision valid and enforceable.
|
||||
4. No term or provision of this License shall be deemed waived and no breach
|
||||
consented to unless such waiver or consent shall be in writing and signed by the
|
||||
party to be charged with such waiver or consent.
|
||||
5. This License constitutes the entire agreement between the parties with
|
||||
respect to the Work licensed here. There are no understandings, agreements or
|
||||
representations with respect to the Work not specified here. Licensor shall not
|
||||
be bound by any additional provisions that may appear in any communication from
|
||||
You. This License may not be modified without the mutual written agreement of
|
||||
the Licensor and You.
|
||||
|
||||
Creative Commons is not a party to this License, and makes no warranty
|
||||
whatsoever in connection with the Work. Creative Commons will not be liable to
|
||||
You or any party on any legal theory for any damages whatsoever, including
|
||||
without limitation any general, special, incidental or consequential damages
|
||||
arising in connection to this license. Notwithstanding the foregoing two (2)
|
||||
sentences, if Creative Commons has expressly identified itself as the Licensor
|
||||
hereunder, it shall have all rights and obligations of Licensor.
|
||||
|
||||
Except for the limited purpose of indicating to the public that the Work is
|
||||
licensed under the CCPL, neither party will use the trademark "Creative Commons"
|
||||
or any related trademark or logo of Creative Commons without the prior written
|
||||
consent of Creative Commons. Any permitted use will be in compliance with
|
||||
Creative Commons' then-current trademark usage guidelines, as may be published
|
||||
on its website or otherwise made available upon request from time to time.
|
||||
|
||||
Creative Commons may be contacted at http://creativecommons.org/.
|
||||
375
mozilla/directory/docs/ldapcsdk/preface.sgm
Normal file
375
mozilla/directory/docs/ldapcsdk/preface.sgm
Normal file
@@ -0,0 +1,375 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<preface id="preface"><title>Preface</title>
|
||||
<highlights>&abstract;
|
||||
</highlights>
|
||||
<sect1 id="who-should-read"><title>Who Should Use This Book</title>
|
||||
<para>This guide is intended for developers creating directory client applications.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<para>Before using this guide, you must be familiar with the following:</para>
|
||||
<listitem><para>&cnDirectoryServer; functionality</para></listitem>
|
||||
<listitem><para>Developing programs in the C programming
|
||||
language</para></listitem>
|
||||
<listitem><para>Specifications for LDAP and related protocols, such as DSML
|
||||
v2</para></listitem>
|
||||
<listitem><para>Internet and World Wide Web technologies</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="before-you-read"><title>Before You Read This Book</title>
|
||||
<para>Before developing directory client applications, install &DirectorySDKForJava;.
|
||||
</para>
|
||||
<!-- TODO: Need an XREF to installation instructions -->
|
||||
</sect1>
|
||||
<sect1 id="reading-for-developers"><title>Additional Recommended Reading</title>
|
||||
<itemizedlist>
|
||||
<para>Directory client application developers might benefit from reading the
|
||||
following books:</para>
|
||||
<listitem><para><citetitle>LDAP Programming with Java</citetitle> by Weltman
|
||||
and Dabhura (ISBN 0-201-65758-96)</para></listitem>
|
||||
<listitem><para><citetitle>LDAP Programming, Management and Integration</citetitle> by
|
||||
Donley (ISBN 1930110405)</para></listitem>
|
||||
<listitem><para><citetitle>LDAP: Programming Directory-Enabled Applications
|
||||
with Lightweight Directory Access Protocol</citetitle> by Howes and Smith
|
||||
(ISBN 1-57870-000-00)</para></listitem>
|
||||
<listitem><para><citetitle>Understanding and Deploying LDAP Directory Services</citetitle> by
|
||||
Howes, et al. (ISBN 1-57870-070-10)</para></listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<para>In addition, keep bookmarks to the following IETF documents:</para>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2251.txt" type="text_url">
|
||||
RFC 2251</ulink>, <citetitle>Lightweight Directory Access Protocol (v3)</citetitle></para>
|
||||
</listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2252.txt" type="text_url">
|
||||
RFC 2252</ulink>, <citetitle>Lightweight Directory Access Protocol (v3): Attribute
|
||||
Syntax Definitions</citetitle></para></listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2253.txt" type="text_url">
|
||||
RFC 2253</ulink>, <citetitle>Lightweight Directory Access Protocol (v3): UTF-8
|
||||
String Representation of Distinguished Names</citetitle></para></listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2254.txt" type="text_url">
|
||||
RFC 2254</ulink>, <citetitle>The String Representation of LDAP Search Filters</citetitle></para>
|
||||
</listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2255.txt" type="text_url">
|
||||
RFC 2255</ulink>, <citetitle>The LDAP URL Format</citetitle></para></listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2256.txt" type="text_url">
|
||||
RFC 2256</ulink>, <citetitle>A Summary of the X.500(96) User Schema for use
|
||||
with LDAPv3</citetitle></para></listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2829.txt" type="text_url">
|
||||
RFC 2829</ulink>, <citetitle>Authentication Methods for LDAP</citetitle></para>
|
||||
</listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2830.txt" type="text_url">
|
||||
RFC 2830</ulink>, <citetitle>Lightweight Directory Access Protocol (v3): Extension
|
||||
for Transport Layer Security</citetitle></para></listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2849.txt" type="text_url">
|
||||
RFC 2849</ulink>, <citetitle>The LDAP Data Interchange Format (LDIF) - Technical
|
||||
Specification</citetitle></para></listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc3377.txt" type="text_url">
|
||||
RFC 3377</ulink>, <citetitle>Lightweight Directory Access Protocol (v3): Technical
|
||||
Specification</citetitle></para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="organization"><title>How This Book Is Organized</title>
|
||||
<itemizedlist>
|
||||
<para>This guide includes the following chapters.</para>
|
||||
<listitem><para><olink targetptr="understanding-ldap">Chapter 1, Understanding
|
||||
LDAP</olink> describes LDAP and directory concepts.</para></listitem>
|
||||
<listitem><para><olink targetptr="best-practices-choose">Chapter 2, Choosing
|
||||
a Client SDK</olink> covers what to consider when choosing a software development
|
||||
kit for building directory client applications.</para></listitem>
|
||||
<listitem><para><olink targetptr="best-practices-overview">Chapter 3,
|
||||
Best Practices for Writing Client Applications</olink> reviews what and what
|
||||
not to do when building directory client applications.</para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-using">Chapter 4, About Directory
|
||||
SDK for C</olink> describes what &DirectorySDKForC; offers you as a directory
|
||||
client developer.</para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-quickstart">Chapter 5, Getting
|
||||
Started With Directory SDK for C</olink> gets you started using &DirectorySDKForC;.
|
||||
</para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-whatsnew">Chapter 6, What's New
|
||||
In Directory SDK for C</olink> presents new features, and changes from previous
|
||||
versions of &DirectorySDKForC;.</para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-client">Chapter 7, Writing an
|
||||
LDAP Client With Directory SDK for C</olink> covers the basics of writing
|
||||
a directory client application.</para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-api">Chapter 8, Using the LDAP
|
||||
C API</olink> shows how to write an application with &DirectorySDKForC;.</para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="csdk-searching">Chapter 9, Searching
|
||||
the Directory With Directory SDK for C</olink> shows how to write client application
|
||||
code for searching a directory.</para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-filter">Chapter 10, Using Filter
|
||||
Configuration Files With Directory SDK for C</olink> shows how to write code
|
||||
to search a directory using filter configuration files.</para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-write">Chapter 11, Adding, Updating,
|
||||
and Deleting Entries With Directory SDK for C</olink> shows how to write client
|
||||
application code for changing directory entries.</para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-compare">Chapter 12, Comparing
|
||||
Attribute Values With Directory SDK for C</olink> shows how to compare attribute
|
||||
values in a directory with known values.</para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-urls">Chapter 13, LDAP URLs With
|
||||
Directory SDK for C</olink> shows how to handle LDAP URLs.</para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-server-info">Chapter 14, Getting
|
||||
Server Information With Directory SDK for C</olink> shows how to retrieve
|
||||
information about the directory and directory service.</para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-ssl">Chapter 15, SSL Connections
|
||||
With Directory SDK for C</olink> shows how to write client application code
|
||||
that connects to the directory over SSL.</para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-controls">Chapter 16, LDAP Controls
|
||||
With Directory SDK for C</olink> shows how to handle supported LDAP controls.</para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="csdk-sasl">Chapter 17, SASL Authentication
|
||||
With Directory SDK for C</olink> shows how to connect to the directory by
|
||||
using SASL.</para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-extop">Chapter 18, Extended Operations
|
||||
With Directory SDK for C</olink> shows how to write client application code
|
||||
for handling LDAP v3 extended operations.</para></listitem>
|
||||
<listitem><para><olink targetptr="csdk-multithread">Chapter 19, Writing
|
||||
Multithreaded Clients With Directory SDK for C</olink> shows how to write
|
||||
multithreaded client application code.</para></listitem>
|
||||
<listitem><para><olink targetptr="bdajr">Chapter 20, Directory SDK for C Data Type Reference</olink> covers &DirectorySDKForC; data types</para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="bdane">Chapter 21, Directory SDK for C Function Reference</olink> covers &DirectorySDKForC; functions</para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="bdaxx">Chapter 22, Directory SDK for C Result Codes</olink> covers &DirectorySDKForC; function result codes</para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="share-alike">Appendix A, Creative Commons Attribution-ShareAlike 2.5</olink> provides the full text of the license governing this guide</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="related-reading"><title>Related Reading</title>
|
||||
<para><indexterm>
|
||||
<primary>SLAMD Distributed Load Generation Engine</primary>
|
||||
</indexterm>The SLAMD Distributed Load Generation Engine (SLAMD) is a <trademark>
|
||||
Java</trademark> application that is designed to stress test and analyze the
|
||||
performance of network-based applications. It was originally developed by
|
||||
Sun Microsystems, Inc. to benchmark and analyze the performance of LDAP directory
|
||||
servers. SLAMD is available as an open source application under the Sun Public
|
||||
License, an OSI-approved open source license. To obtain information about
|
||||
SLAMD, go to <ulink url="http://www.slamd.com/" type="url"></ulink>. SLAMD
|
||||
is also available as a java.net project. See <ulink
|
||||
url="https://slamd.dev.java.net/" type="url"></ulink>.</para>
|
||||
<para><indexterm>
|
||||
<primary>Java Naming and Directory Interface</primary>
|
||||
</indexterm>Java Naming and Directory Interface (JNDI) technology supports
|
||||
accessing the Directory Server using LDAP and DSML v2 from Java applications.
|
||||
For information about JNDI, see <ulink url="http://java.sun.com/products/jndi/"
|
||||
type="url"></ulink>. The <citetitle>JNDI Tutorial</citetitle> contains detailed
|
||||
descriptions and examples of how to use JNDI. This tutorial is at <ulink
|
||||
url="http://java.sun.com/products/jndi/tutorial/" type="url"></ulink>.</para>
|
||||
</sect1>
|
||||
<sect1 id="FWBKX"><title>Typographic Conventions</title>
|
||||
<para>The following table describes the typographic changes that are used
|
||||
in this book.</para>
|
||||
<table frame="topbot" id="FWBTE"><title>Typographic Conventions</title>
|
||||
<tgroup cols="3" colsep="0" rowsep="0"><colspec colwidth="15*"><colspec
|
||||
colwidth="40*"><colspec colwidth="45*">
|
||||
<thead>
|
||||
<row rowsep="1">
|
||||
<entry align="left">
|
||||
<para>Typeface</para></entry>
|
||||
<entry align="left">
|
||||
<para>Meaning</para></entry>
|
||||
<entry align="left">
|
||||
<para>Example</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>AaBbCc123</literal></para></entry>
|
||||
<entry>
|
||||
<para>The names of commands, files, and directories, and onscreen computer
|
||||
output</para></entry>
|
||||
<entry>
|
||||
<para>Edit your <filename>.login</filename> file.</para>
|
||||
<para>Use <command>ls <option>a</option></command> to list all files.</para>
|
||||
<para><computeroutput>machine_name% you have mail.</computeroutput></para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><userinput>AaBbCc123</userinput></para></entry>
|
||||
<entry>
|
||||
<para>What you type, contrasted with onscreen computer output</para></entry>
|
||||
<entry>
|
||||
<para><computeroutput>machine_name%</computeroutput> <userinput>su</userinput></para>
|
||||
<para><computeroutput>Password:</computeroutput></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><replaceable>AaBbCc123</replaceable></para></entry>
|
||||
<entry>
|
||||
<para>A placeholder to be replaced with a real name or value</para></entry>
|
||||
<entry>
|
||||
<para>The command to remove a file is <command>rm</command> <replaceable>filename
|
||||
</replaceable>.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><emphasis>AaBbCc123</emphasis></para></entry>
|
||||
<entry>
|
||||
<para>Book titles, new terms, and terms to be emphasized (note that some emphasized
|
||||
items appear bold online)</para></entry>
|
||||
<entry>
|
||||
<para>Read Chapter 6 in the <citetitle>User's Guide</citetitle>.</para>
|
||||
<para>A <emphasis>cache</emphasis> is a copy that is stored locally.</para>
|
||||
<para>Do <emphasis>not</emphasis> save the file.</para></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect1>
|
||||
<sect1 id="FWBMK"><title>Shell Prompts in Command Examples</title>
|
||||
<para>The following table shows default system prompts and superuser prompts.</para>
|
||||
<table frame="topbot" id="GCTTT"><title>Shell Prompts</title>
|
||||
<tgroup cols="2" colsep="0" rowsep="0"><colspec colwidth="75*"><colspec
|
||||
colwidth="25*">
|
||||
<thead>
|
||||
<row rowsep="1">
|
||||
<entry>
|
||||
<para>Shell</para></entry>
|
||||
<entry>
|
||||
<para>Prompt</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para>C shell on UNIX and Linux systems</para></entry>
|
||||
<entry>
|
||||
<para><literal>machine_name%</literal></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>C shell superuser on UNIX and Linux systems</para></entry>
|
||||
<entry>
|
||||
<para><literal>machine_name#</literal></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Bourne shell and Korn shell on UNIX and Linux systems</para></entry>
|
||||
<entry>
|
||||
<para><literal>$</literal></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Bourne shell and Korn shell superuser on UNIX and Linux systems</para>
|
||||
</entry>
|
||||
<entry>
|
||||
<para><literal>#</literal></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Microsoft Windows command line</para></entry>
|
||||
<entry>
|
||||
<para><literal>C:\</literal></para></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect1>
|
||||
<sect1 id="FQUVC"><title>Symbol Conventions</title>
|
||||
<para>The following table explains symbols that might be used in this book.</para>
|
||||
<table frame="topbot" id="FQUVR"><title>Symbol Conventions</title>
|
||||
<tgroup cols="4" colsep="0" rowsep="0"><colspec colnum="1" colwidth="8*"
|
||||
align="center"><colspec colnum="2" colwidth="28*"><colspec colnum="3"
|
||||
colwidth="28*"><colspec colnum="4" colwidth="36*">
|
||||
<thead>
|
||||
<row rowsep="1">
|
||||
<entry>
|
||||
<para>Symbol</para></entry>
|
||||
<entry>
|
||||
<para>Description</para></entry>
|
||||
<entry>
|
||||
<para>Example</para></entry>
|
||||
<entry>
|
||||
<para>Meaning</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>[ ]</literal></para></entry>
|
||||
<entry>
|
||||
<para>Contains optional arguments and command options.</para></entry>
|
||||
<entry>
|
||||
<para><literal>ls [-l]</literal></para></entry>
|
||||
<entry>
|
||||
<para>The <literal>-l</literal> option is not required.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>{ | }</literal></para></entry>
|
||||
<entry>
|
||||
<para>Contains a set of choices for a required command option.</para></entry>
|
||||
<entry>
|
||||
<para><literal>-d {y|n}</literal></para></entry>
|
||||
<entry>
|
||||
<para>The <literal>-d</literal> option requires that you use either the <literal>
|
||||
y</literal> argument or the <literal>n</literal> argument.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>${ }</literal></para></entry>
|
||||
<entry>
|
||||
<para>Indicates a variable reference.</para></entry>
|
||||
<entry>
|
||||
<para><literal>${com.sun.javaRoot}</literal></para></entry>
|
||||
<entry>
|
||||
<para>References the value of the <literal>com.sun.javaRoot</literal> variable.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>-</para></entry>
|
||||
<entry>
|
||||
<para>Joins simultaneous multiple keystrokes.</para></entry>
|
||||
<entry>
|
||||
<para>Control-A</para></entry>
|
||||
<entry>
|
||||
<para>Press the Control key while you press the A key.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>+</para></entry>
|
||||
<entry>
|
||||
<para>Joins consecutive multiple keystrokes.</para></entry>
|
||||
<entry>
|
||||
<para>Ctrl+A+N</para></entry>
|
||||
<entry>
|
||||
<para>Press the Control key, release it, and then press the subsequent keys.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>→</para></entry>
|
||||
<entry>
|
||||
<para>Indicates menu item selection in a graphical user interface.</para>
|
||||
</entry>
|
||||
<entry>
|
||||
<para>File → New → Templates</para></entry>
|
||||
<entry>
|
||||
<para>From the File menu, choose New. From the New submenu, choose Templates.</para>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect1>
|
||||
</preface>
|
||||
|
||||
274
mozilla/directory/docs/ldapcsdk/understanding-ldap.sgm
Normal file
274
mozilla/directory/docs/ldapcsdk/understanding-ldap.sgm
Normal file
@@ -0,0 +1,274 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="understanding-ldap"><title>Understanding LDAP</title>
|
||||
<indexterm>
|
||||
<primary>LDAP</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>Lightweight Directory Access Protocol</primary>
|
||||
<see>LDAP</see></indexterm><highlights>
|
||||
<para><firstterm>Lightweight Directory Access Protocol</firstterm> (LDAP)
|
||||
is the Internet directory protocol. Developed at the University of Michigan
|
||||
at Ann Arbor in conjunction with the Internet Engineering Task Force, LDAP
|
||||
is a protocol for accessing and managing directory services.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter explains the LDAP protocol, and the concepts behind LDAP.
|
||||
This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="how-ds-works">How Directory Services Work</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="how-ds-organizes-data">How LDAP Servers
|
||||
Organize Directories</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="how-ldap-clients-servers-work">How LDAP
|
||||
Clients and Servers Work</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="understanding-ldapv3">Understanding LDAP
|
||||
v3</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="how-ds-works"><title>How Directory Services Work</title>
|
||||
<indexterm>
|
||||
<primary>directory</primary>
|
||||
<secondary>definition of</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>entries</primary>
|
||||
<secondary>definition of</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>attributes</primary>
|
||||
<secondary>definition of</secondary>
|
||||
</indexterm>
|
||||
<para>A <firstterm>directory</firstterm> consists of <firstterm>entries</firstterm> that
|
||||
contain descriptive information. For example, a directory might contain entries
|
||||
that describe people or network resources, such as printers or fax machines.</para>
|
||||
<para>The descriptive information is stored in the <firstterm>attributes</firstterm> of
|
||||
the entry. Each attribute describes a specific type of information. For example,
|
||||
attributes that describe a person might include her name, also referred to
|
||||
as her common name (CN), telephone number, and email address.</para>
|
||||
<para><indexterm>
|
||||
<primary>entries</primary>
|
||||
<secondary>example of</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>attributes</primary>
|
||||
<secondary>example of</secondary>
|
||||
</indexterm>The entry for <literal>Barbara Jensen</literal> might have the
|
||||
following attributes:</para>
|
||||
<programlisting>cn: Barbara Jensen
|
||||
mail: babs@example.com
|
||||
telephoneNumber: 555-1212
|
||||
roomNumber: 3995</programlisting>
|
||||
<para>An attribute can have more than one value. For example, a person might
|
||||
have two common names, both a formal name and also a nickname:</para>
|
||||
<programlisting>cn: Barbara Jensen
|
||||
cn: Babs Jensen
|
||||
mail: babs@example.com
|
||||
telephoneNumber: 555-1212
|
||||
roomNumber: 3995</programlisting>
|
||||
<para>Attributes can also contain binary data. For example, a person's attributes
|
||||
might include her photo in JPEG format, a recording of her voice as an audio
|
||||
file, or her SSL certificate.</para>
|
||||
<para><indexterm>
|
||||
<primary>directory service</primary>
|
||||
<secondary>definition of</secondary>
|
||||
</indexterm>A <firstterm>directory service</firstterm> is a distributed database
|
||||
application for managing the entries and attributes in a directory. A directory
|
||||
service also makes the entries and attributes available to users and other
|
||||
applications.</para>
|
||||
<para>&cnDirectoryServer; is an example of a directory service. For example,
|
||||
a user might use the directory service to look up someone's telephone number.
|
||||
Another application might use the directory service to retrieve a list of
|
||||
email addresses.</para>
|
||||
<para><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
</indexterm>LDAP is a protocol that defines a directory service and access
|
||||
to that service. LDAP is based on a client-server model. LDAP servers provide
|
||||
the directory service. LDAP clients use the directory service to access entries
|
||||
and attributes.</para>
|
||||
<para><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>example of</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>example of</secondary>
|
||||
</indexterm>&cnDirectoryServer; is an example of an LDAP server that manages
|
||||
and provides information about users and organizational structures. Examples
|
||||
of LDAP clients include Identity Manager, Access Manager, <trademark>Solaris</trademark> naming
|
||||
services, Messaging Server, Portal Server, NameFinder, and the Mozilla mail
|
||||
client. Such clients use &cnDirectoryServer; to find, update, and add information
|
||||
about users.</para></sect1>
|
||||
<sect1 id="how-ds-organizes-data"><title>How LDAP Servers Organize Directories</title>
|
||||
<indexterm>
|
||||
<primary>LDAP</primary>
|
||||
<secondary>organization of data</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>entries</primary>
|
||||
<secondary>organization in LDAP</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>how data is organized</secondary>
|
||||
</indexterm>
|
||||
<para>Because LDAP is intended to be a global directory service, data is organized
|
||||
hierarchically, starting at a root and branching down into individual entries.</para>
|
||||
<para>At the top level of the hierarchy, entries represent larger organizations.
|
||||
Under larger organizations in the hierarchy, you might find entries for smaller
|
||||
organizations. The hierarchy might end with entries for individual people,
|
||||
or resources, as shown in the following figure.</para>
|
||||
<figure id="hierarchy-in-ldap"><title>Hierarchy of Entries in a Directory</title>
|
||||
<mediaobject>
|
||||
<imageobject><imagedata entityref="hierovrw"></imageobject>
|
||||
<textobject><simpara>Simple directory information tree with two organizational
|
||||
unit entries and two user entries</simpara></textobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
<para><indexterm>
|
||||
<primary>relative distinguished names (RDNs)</primary>
|
||||
<secondary>definition of</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>RDNs</primary>
|
||||
<see>relative distinguished names (RDNs)</see></indexterm><indexterm>
|
||||
<primary>distinguished names (DNs)</primary>
|
||||
<secondary>definition of </secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>CNs</primary>
|
||||
<see>common names (CNs)</see></indexterm><indexterm>
|
||||
<primary>DNs</primary>
|
||||
<see>distinguished names (DNs)</see></indexterm><indexterm>
|
||||
<primary>common names (CNs)</primary>
|
||||
</indexterm>Each entry is uniquely identified by a <firstterm>distinguished
|
||||
name</firstterm> (DN). A DN includes a relative distinguished name (RDN),
|
||||
that uniquely identifies the entry at that hierarchical level. For example, <literal>
|
||||
bjensen</literal> and <literal>kjensen</literal> are different user IDs that
|
||||
identify different entries at the same level. Following the RDN is a path
|
||||
of names that trace the entry back to the root of the tree, such as <literal>ou=People,dc=example,dc=com
|
||||
</literal>. <literal>DC</literal> is short for domain component. The full
|
||||
DN for this example would be <literal>uid=bjensen,ou=People,dc=example,dc=com</literal>.
|
||||
Here, <literal>uid</literal> is the user ID of the entry. <literal>ou</literal> is
|
||||
short for organizational unit.</para>
|
||||
<para><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>how data is distributed</secondary>
|
||||
</indexterm>The data stored in a directory can be distributed among several
|
||||
LDAP servers. For example, one LDAP server at <literal>Example.com</literal> might
|
||||
contain entries representing North American organizational units and employees,
|
||||
while another LDAP server might contain entries representing European organizational
|
||||
units and employees.</para>
|
||||
<para><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>how referrals work</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>referrals</primary>
|
||||
</indexterm>Some LDAP servers are set up to refer requests to other LDAP servers.
|
||||
For example, if the LDAP server at <literal>Example.com</literal> receives
|
||||
a request for information about an employee in a Pacific Rim branch, that
|
||||
server can refer the request to the LDAP server at the Pacific Rim branch.
|
||||
In this way, LDAP servers can appear to be a single source of directory information.
|
||||
Even if an LDAP server does not contain the information you request, the server
|
||||
can refer you to another server that does contain the information.</para>
|
||||
</sect1>
|
||||
<sect1 id="how-ldap-clients-servers-work"><title>How LDAP Clients and Servers
|
||||
Work</title>
|
||||
<indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>LDAP clients and</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>LDAP servers and</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>operations performed by</secondary>
|
||||
</indexterm>
|
||||
<para>In the LDAP client-server model, LDAP servers such as &cnDirectoryServer;
|
||||
make information about people, organizations, and resources accessible to
|
||||
LDAP clients. LDAP defines operations that clients use to search and update
|
||||
the directory.</para>
|
||||
<itemizedlist>
|
||||
<para>An LDAP client can perform these operations, among others:</para>
|
||||
<listitem><para>Search for and retrieve entries from the directory</para>
|
||||
</listitem>
|
||||
<listitem><para>Add new entries to the directory</para></listitem>
|
||||
<listitem><para>Update entries in the directory</para></listitem>
|
||||
<listitem><para>Delete entries from the directory</para></listitem>
|
||||
<listitem><para>Rename entries in the directory</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>For example, to update an entry, an LDAP client submits the distinguished
|
||||
name of the entry with updated attribute information to the LDAP server. The
|
||||
LDAP server uses the distinguished name to find the entry. The server then
|
||||
performs a modify operation to update the entry in the directory.</para>
|
||||
<para><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>connecting with LDAP clients</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>connecting with LDAP servers</secondary>
|
||||
</indexterm>To perform any of these LDAP operations, an LDAP client needs
|
||||
to establish a connection with an LDAP server. The LDAP protocol specifies
|
||||
the use of TCP/IP port number 389, although servers can run on other ports.</para>
|
||||
<para><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>authentication</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>authentication</secondary>
|
||||
</indexterm>The LDAP protocol also defines a simple method for authentication.
|
||||
LDAP servers can be set up to restrict permissions to the directory. Before
|
||||
an LDAP client can perform an operation on an LDAP server, the client must
|
||||
authenticate to the server. Clients typically authenticate by supplying a
|
||||
distinguished name and password. If the user identified by the distinguished
|
||||
name does not have permission to perform the operation, the server does not
|
||||
execute the operation.</para></sect1>
|
||||
<sect1 id="understanding-ldapv3"><title>Understanding LDAP v3</title>
|
||||
<indexterm>
|
||||
<primary>LDAP</primary>
|
||||
<secondary>version 3</secondary>
|
||||
</indexterm>
|
||||
<para><ulink url="http://www.ietf.org/rfc/rfc4511.txt" type="text_url">RFC
|
||||
4511</ulink> specifies LDAP version 3. Use this version of the protocol when
|
||||
writing new client applications.</para>
|
||||
<para>Many LDAP servers continue to support LDAP version 2 for use with legacy
|
||||
clients. This version of the protocol is specified in <ulink
|
||||
url="http://www.ietf.org/rfc/rfc1777.txt" type="text_url">RFC 1777</ulink>.</para>
|
||||
<itemizedlist>
|
||||
<para>LDAP v3 includes new features not present in version 2:</para>
|
||||
<listitem><para>Clients and servers can specify <firstterm>controls</firstterm> that
|
||||
extend the functionality of an LDAP operation.</para></listitem>
|
||||
<listitem><para>Clients can request that the server perform <firstterm>extended
|
||||
operations</firstterm>, operations not included in the list of standard LDAP
|
||||
operations.</para></listitem>
|
||||
<listitem><para>Clients can use <firstterm>Simple Authentication and Security
|
||||
Layer</firstterm> (SASL) mechanisms to authenticate to the directory. SASL
|
||||
is specified in <ulink url="http://www.ietf.org/rfc/rfc4422.txt" type="text_url">
|
||||
RFC 4422</ulink>.</para></listitem><?Pub Caret>
|
||||
<listitem><para>Servers, known as <firstterm>Directory System Agents</firstterm> (DSAs),
|
||||
have <firstterm>DSA-specific entries</firstterm> (DSEs). DSEs provide information
|
||||
about the versions of the LDAP protocol that the server supports. DSEs also
|
||||
provide a list of the controls, extended operations, and SASL mechanisms supported
|
||||
by the server. Finally, DSEs specify the naming contexts of the server. Naming
|
||||
contexts are portions of the directory information tree managed by the server.</para>
|
||||
</listitem>
|
||||
<listitem><para>Servers make their <firstterm>schemas</firstterm>, which define
|
||||
the object classes, attributes, syntaxes, and matching rules enforced by the
|
||||
directory, available to clients through the root DSE.</para></listitem>
|
||||
<listitem><para><indexterm>
|
||||
<primary>UTF-8</primary>
|
||||
<secondary>support of</secondary>
|
||||
</indexterm>Both client and server applications can support data in UTF-8. <firstterm>
|
||||
UTF-8</firstterm> is a transformation format of the Universal Character Set
|
||||
standard. UTF-8 is specified in <ulink url="http://www.ietf.org/rfc/rfc3269.txt"
|
||||
type="text_url">RFC 3269</ulink>. With UTF-8, clients can request and receive
|
||||
data that is tagged with language information.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
</chapter>
|
||||
108
mozilla/directory/docs/ldapjdk/00-Programmers-Guide.book
Normal file
108
mozilla/directory/docs/ldapjdk/00-Programmers-Guide.book
Normal file
@@ -0,0 +1,108 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<!DOCTYPE BOOK PUBLIC "-//OASIS//DTD DocBook V4.3//EN" [
|
||||
<!ENTITY abstract SYSTEM "abstract.sgm">
|
||||
<!ENTITY best-practices SYSTEM "best-practices.sgm">
|
||||
<!ENTITY BookTitle "Programmer's Guide">
|
||||
<!ENTITY choose-api SYSTEM "choose-api.sgm">
|
||||
<!ENTITY cnDirectoryServer "Directory Server">
|
||||
<!ENTITY DirectorySDKForC "Directory SDK for C">
|
||||
<!ENTITY DirectorySDKForJava "Directory SDK for Java">
|
||||
<!ENTITY entries SYSTEM "figures/entries.eps" NDATA eps>
|
||||
<!ENTITY hier1lvl SYSTEM "figures/hier1lvl.eps" NDATA eps>
|
||||
<!ENTITY hierbase SYSTEM "figures/hierbase.eps" NDATA eps>
|
||||
<!ENTITY hierovrw SYSTEM "figures/hierovrw.eps" NDATA eps>
|
||||
<!ENTITY hiersrch SYSTEM "figures/hiersrch.eps" NDATA eps>
|
||||
<!ENTITY jdk-adding SYSTEM "jdk-adding.sgm">
|
||||
<!ENTITY jdk-asynchronous SYSTEM "jdk-asynchronous.sgm">
|
||||
<!ENTITY jdk-common-classes SYSTEM "jdk-common-classes.sgm">
|
||||
<!ENTITY jdk-comparing SYSTEM "jdk-comparing.sgm">
|
||||
<!ENTITY jdk-controls SYSTEM "jdk-controls.sgm">
|
||||
<!ENTITY jdk-extended-ops SYSTEM "jdk-extended-ops.sgm">
|
||||
<!ENTITY jdk-filter-conf SYSTEM "jdk-filter-conf.sgm">
|
||||
<!ENTITY jdk-ldap-urls SYSTEM "jdk-ldap-urls.sgm">
|
||||
<!ENTITY jdk-quickstart SYSTEM "jdk-quickstart.sgm">
|
||||
<!ENTITY jdk-sasl SYSTEM "jdk-sasl.sgm">
|
||||
<!ENTITY jdk-searching SYSTEM "jdk-searching.sgm">
|
||||
<!ENTITY jdk-server-info SYSTEM "jdk-server-info.sgm">
|
||||
<!ENTITY jdk-ssl SYSTEM "jdk-ssl.sgm">
|
||||
<!ENTITY jdk-writing-client SYSTEM "jdk-writing-client.sgm">
|
||||
<!ENTITY legal SYSTEM "legal.sgm">
|
||||
<!ENTITY license SYSTEM "license.txt">
|
||||
<!ENTITY preface SYSTEM "preface.sgm">
|
||||
<!ENTITY understanding-ldap SYSTEM "understanding-ldap.sgm">
|
||||
<!NOTATION graphic SYSTEM "graphic">
|
||||
]>
|
||||
<book lang="en">
|
||||
<title>Programmer's Guide for LDAP Java SDK</title>
|
||||
<bookinfo>
|
||||
<authorgroup><author><firstname>Mark</firstname><surname>Craig</surname>
|
||||
</author></authorgroup>
|
||||
<pubdate>June 2007</pubdate>
|
||||
<publisher>
|
||||
<publishername>Sun Microsystems, Inc.</publishername>
|
||||
<address>
|
||||
<street>4150 Network Circle</street>
|
||||
<city>Santa Clara</city><state>CA</state><postcode>95054</postcode>
|
||||
<country>U.S.A.</country>
|
||||
</address></publisher>
|
||||
<copyright><year>2000-2007</year><holder>Sun Microsystems, Inc. All Rights Reserved.</holder></copyright>
|
||||
<legalnotice><para><emphasis role="strong">License</emphasis> -
|
||||
<emphasis>The contents of this document are subject to the terms of
|
||||
the Creative Commons Attribution-ShareAlike 2.5 license or any later version (the
|
||||
"License"). You may not use this document except in compliance with
|
||||
the License.</emphasis></para>
|
||||
<para><emphasis>See the License for the specific language governing
|
||||
permissions and limitations under the License. The full text of the
|
||||
License is provided at the end of this
|
||||
document.</emphasis></para>&legal;
|
||||
</legalnotice>
|
||||
<abstract>&abstract;
|
||||
</abstract>
|
||||
</bookinfo>&preface;
|
||||
&understanding-ldap;
|
||||
&choose-api;
|
||||
&best-practices;
|
||||
&jdk-quickstart;
|
||||
&jdk-writing-client;
|
||||
&jdk-common-classes;
|
||||
&jdk-searching;
|
||||
&jdk-filter-conf;
|
||||
&jdk-adding;
|
||||
&jdk-comparing;
|
||||
&jdk-ldap-urls;
|
||||
&jdk-server-info;
|
||||
&jdk-ssl;
|
||||
&jdk-controls;
|
||||
&jdk-sasl;
|
||||
&jdk-extended-ops;
|
||||
&jdk-asynchronous;
|
||||
<appendix id="share-alike">
|
||||
<title>Creative Commons Attribution-ShareAlike 2.5</title>
|
||||
<para>The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license (the
|
||||
"License"). You may not use this document except in compliance with
|
||||
the License.</para>
|
||||
<para>See the License for the specific language governing permissions
|
||||
and limitations under the License. The full text of the License is as
|
||||
follows.</para>
|
||||
<programlisting>&license;</programlisting>
|
||||
</appendix>
|
||||
<index><title>Index</title>
|
||||
<indexentry><primaryie></primaryie></indexentry></index>
|
||||
</book>
|
||||
20
mozilla/directory/docs/ldapjdk/abstract.sgm
Normal file
20
mozilla/directory/docs/ldapjdk/abstract.sgm
Normal file
@@ -0,0 +1,20 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<para>This <citetitle>&BookTitle;</citetitle> shows you how to
|
||||
create LDAP client applications in the Java language to connect to LDAP servers.
|
||||
This guide also shows you how to perform standard LDAP operations.</para>
|
||||
378
mozilla/directory/docs/ldapjdk/best-practices.sgm
Normal file
378
mozilla/directory/docs/ldapjdk/best-practices.sgm
Normal file
@@ -0,0 +1,378 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="best-practices-overview"><title>Best Practices for
|
||||
Writing Client Applications</title>
|
||||
<highlights>
|
||||
<itemizedlist>
|
||||
<para>This chapter includes best practices for developing client applications
|
||||
and cover the following topics:</para>
|
||||
<listitem><para><olink targetptr="best-ldapv3">Creating Your Application</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-troubleshooting">Troubleshooting Problems</olink></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="best-ldapv3"><title>Creating Your Application</title>
|
||||
<itemizedlist>
|
||||
<para>This section identifies practices to observe when creating directory
|
||||
client applications.</para>
|
||||
<listitem><para><olink targetptr="specify-ldapv3">Specify LDAP v3</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-authenticating">Authenticate Correctly</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-connect">Limit Connection Overhead</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-inactivity-timeouts">Handle Potential
|
||||
Inactivity Timeouts</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="best-entries">Retrieve Entries Intelligently</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-filters">Write Simple, Conforming LDAP
|
||||
Filters</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="best-mods">Performing Specific Modifications</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-rc">Trust Result Codes</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-groups">Limit Dealings With Groups
|
||||
and Roles</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="best-dse">Read the DSE</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-resources">Use Resource-Intensive Features Sparingly</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="best-dit">Avoid Hard Coding Certain Information
|
||||
</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="best-schema">Define Schemas Only When Necessary
|
||||
</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="best-refer">Handle Referrals</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="best-not-rdbm">Treat a Directory as a Directory
|
||||
</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
<sect2 id="specify-ldapv3"><title>Specify LDAP v3</title>
|
||||
<itemizedlist>
|
||||
<para>Many client libraries default to LDAP v2, but you can elect to use LDAP
|
||||
v3. To benefit from LDAP v3 features, you can set up the connection, and then
|
||||
authenticate explicitly using LDAP v3.</para>
|
||||
<listitem><para>With JNDI, you could use LDAP v3 as shown here.</para>
|
||||
<programlisting role="fragment">import java.util.Hashtable;
|
||||
import javax.naming.ldap.InitialLdapContext;
|
||||
|
||||
Hashtable env = new Hashtable();
|
||||
env.put("java.naming.ldap.version", "<emphasis>3</emphasis>");
|
||||
InitialLdapContext ctx = new InitialLdapContext(env, null);</programlisting>
|
||||
</listitem>
|
||||
<listitem><para>With &DirectorySDKForC;, you could use LDAP v3 as shown
|
||||
here.</para>
|
||||
<programlisting role="fragment">#include "ldap.h"
|
||||
|
||||
int version = <emphasis>LDAP_VERSION3</emphasis>;
|
||||
ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version );</programlisting>
|
||||
<para>&DirectorySDKForC; uses LDAP v3 by default.</para></listitem>
|
||||
<listitem><para>With &DirectorySDKForJava;, you could use LDAP v3 as shown
|
||||
here.</para>
|
||||
<programlisting role="fragment">import netscape.ldap.LDAPConnection;
|
||||
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.setOption(LDAPv3.PROTOCOL_VERSION, new Integer(<emphasis>3</emphasis>));
|
||||
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<sect2 id="best-authenticating"><title>Authenticate Correctly</title>
|
||||
<para>Your SDK uses terminology that is slightly different from LDAP v3. In
|
||||
LDAP v3, you connect, then you bind and perform LDAP operations, then you
|
||||
unbind and disconnect. The bind is the authentication operation in LDAP. Your
|
||||
application can hold onto a connection but change the authentication credentials
|
||||
by using the bind operation again.</para>
|
||||
<para>Some directories do not allow anonymous access, even for reads. When
|
||||
you build your application, keep the option that allows users to authenticate
|
||||
to the directory. Furthermore, the information sent across the network can
|
||||
be sensitive. You can protect sensitive data by allowing the application to
|
||||
secure the connection by using Secure Sockets Layer (SSL) or Start Transport
|
||||
Layer Security (TLS).</para>
|
||||
<para>If your application needs to authenticate, obtain a regular account
|
||||
to authenticate with the directory, rather than using the directory superuser
|
||||
account such as <literal>cn=Directory Manager</literal>. When you authenticate
|
||||
as directory superuser, you often bypass normal access control mechanisms.
|
||||
Bypassing normal access control renders auditing directory access more difficult.
|
||||
</para>
|
||||
<para>When authenticating, have your application use SSL or SASL DIGEST MD5
|
||||
to avoid sending passwords over the network in clear text. Furthermore, when
|
||||
using password-based authentication, have your application check password
|
||||
policy controls, especially to determine when a password must be renewed.</para>
|
||||
</sect2>
|
||||
<sect2 id="best-connect"><title>Limit Connection Overhead</title>
|
||||
<para>A new connection requires system resources. The LDAP model allows you
|
||||
to reuse connections by binding again with a different identity on the same
|
||||
connection. Thus, you can avoid the costs of new connections, particularly
|
||||
negotiated connections such as connections that use SSL, by reusing connections.
|
||||
Your application can use a pool of connections, rebinding when necessary.
|
||||
Your application can alternatively use the proxy authorization control to
|
||||
remain authenticated as the application but perform operations on behalf of
|
||||
a particular user.</para>
|
||||
<para>When establishing a connection, your application can provide alternate
|
||||
server host names and port numbers to facilitate failover that is transparent
|
||||
to the application. You can also set time limits for LDAP operations to avoid
|
||||
getting blocked.</para>
|
||||
<para>When finished with a connection, your application should perform an
|
||||
unbind.</para></sect2>
|
||||
<sect2 id="best-inactivity-timeouts"><title>Handle Potential Inactivity Timeouts</title>
|
||||
<para>Most network equipment can use timeouts to drop stale connections, ensuring
|
||||
the equipment keeps a maximum number of connections that are available.</para>
|
||||
<para>If your application pools connections or opens connections for persistent
|
||||
search, than guard against timeouts that drop those connections. Use the connections
|
||||
occasionally to reset inactivity timers present in the network.</para>
|
||||
<para>Alternatively, if you have control over the connection, consider disabling
|
||||
inactivity time outs for your applications that need to keep persistent connections
|
||||
open. Load balancers and proxy software often use inactivity timeouts.</para>
|
||||
</sect2>
|
||||
<sect2 id="best-entries"><title>Retrieve Entries Intelligently</title>
|
||||
<para>&cnDirectoryServer; typically responds quickly to requests for entries.
|
||||
Yet, &cnDirectoryServer; can respond most quickly when your application asks
|
||||
it to do only necessary work. If you need to read only a few attributes in
|
||||
an entry, request each attribute explicitly. Avoid reading the entire entry,
|
||||
then parsing the entire entry to obtain the required data.</para>
|
||||
<para>Furthermore, when you do request attributes in an entry, retrieve all
|
||||
the required attributes at once. Each new request involves a new operation
|
||||
on the server.</para>
|
||||
<para>If any of the attributes that you require are operational attributes,
|
||||
you must request those attributes specifically. Such attributes are identifiable
|
||||
in directory schema by their <literal>USAGE</literal>, which is <literal>directoryOperation
|
||||
</literal> or <literal>dsaOperation</literal>.</para>
|
||||
<para>When retrieving entries and attributes, recognize that you might not
|
||||
have access to all the attributes that exist.</para></sect2>
|
||||
<sect2 id="best-filters"><title>Write Simple, Conforming LDAP Filters</title>
|
||||
<indexterm>
|
||||
<primary>LDAP filters</primary>
|
||||
<secondary>writing</secondary>
|
||||
</indexterm>
|
||||
<para>The best filters use attributes that are indexed according to the way
|
||||
the attributes are indexed. For example, if <literal>employeeNumber</literal> is
|
||||
indexed for equality, your filter should be an equality filter such as <literal>(employeeNumber=123456)
|
||||
</literal>. Do not use a substring filter instead.</para>
|
||||
<para>Avoid deeply nested complex filters when you can. When you must use
|
||||
complex filters, place the most specific filters first to narrow the list
|
||||
of candidate entries the directory must check. For best results, use <literal>not
|
||||
</literal>, <literal>!</literal>, only with <literal>and</literal>, <literal>&
|
||||
</literal>, for example <literal>(&(cn=Barbara)(!(sn=Jensen)))</literal>.
|
||||
When you use <literal>not</literal> with <literal>or</literal> in a filter,
|
||||
the directory must construct a candidate list of everything except what your
|
||||
filter specifies.</para></sect2>
|
||||
<sect2 id="best-mods"><title>Performing Specific Modifications</title>
|
||||
<para>Modifications are atomic on the entry to which the modifications apply.
|
||||
When modifying multivalued attributes, delete and replace specific values.
|
||||
Do not replace an entire list of multiple values to change only a few values.
|
||||
Replacing specific values is particularly good practice when the changes must
|
||||
be replicated across a set of servers.</para>
|
||||
<para>Moreover, when you have large values to store in an attribute, store
|
||||
a reference to the data instead of storing the data object.</para></sect2>
|
||||
<sect2 id="best-rc"><title>Trust Result Codes</title>
|
||||
<indexterm>
|
||||
<primary>result codes</primary>
|
||||
<secondary>trust</secondary>
|
||||
</indexterm>
|
||||
<para>&cnDirectoryServer; trades tight consistency across replica servers
|
||||
for very high performance, availability, and scalability. By allowing <firstterm>
|
||||
loose consistency</firstterm> of data across sets of replica servers, &cnDirectoryServer; instances
|
||||
can respond very quickly to your application. Yet, data replication is not
|
||||
instantaneous. A short but detectable delay can ensue after a server returns
|
||||
success for a write operation, but before the effects are seen on other replicas.
|
||||
</para>
|
||||
<para>Therefore, when your application receives a result code from &cnDirectoryServer; to
|
||||
indicate that an operation was successful, your application should trust the
|
||||
result code. When application requests are balanced across replicas, reading
|
||||
from another replica might result in errors due to a slight delay in replication.
|
||||
</para></sect2>
|
||||
<sect2 id="best-groups"><title>Limit Dealings With Groups and Roles</title>
|
||||
<indexterm>
|
||||
<primary>groups</primary>
|
||||
<secondary>working with</secondary>
|
||||
</indexterm>
|
||||
<para>When you want to know whether an account belongs to a group or a role,
|
||||
read only the necessary attribute values. Do not read the entire list of group
|
||||
members.</para>
|
||||
<orderedlist>
|
||||
<para>For <literal>dynamic groups</literal>, do the following:</para>
|
||||
<listitem><para>Read the URL from the group definition.</para></listitem>
|
||||
<listitem><para>Examine the host, DN, and scope of the URL.</para></listitem>
|
||||
<listitem><para>Apply the filter part of the URL to the entry for the account.</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para><indexterm>
|
||||
<primary>roles</primary>
|
||||
<secondary>working with</secondary>
|
||||
</indexterm>For <literal>roles</literal>, compare the DN of the role to the <literal>
|
||||
nsRole</literal> attribute of the entry for the account, such as <literal>(nsrole=cn=management,ou=people,dc=example,dc=com)
|
||||
</literal>. You can then retrieve all the values of the <literal>nsRole</literal> attribute
|
||||
for the account.</para></sect2>
|
||||
<sect2 id="best-dse"><title>Read the DSE</title>
|
||||
<indexterm>
|
||||
<primary>DSE, root</primary>
|
||||
<secondary>reading</secondary>
|
||||
</indexterm>
|
||||
<para>The root DSE is the entry that is retrieved by <command>ldapsearch -b
|
||||
"" -s base "(objectclass=*)"</command>. The root DSE describes server capabilities.
|
||||
The root DSE contains information about supported LDAP protocol versions,
|
||||
naming contexts (suffixes), LDAP v3 controls, LDAP v3 extensions, and authentication
|
||||
mechanisms. The root DSE can contain information about the server version.</para>
|
||||
<para>Some directory administrators protect access to the root DSE. Yet, applications
|
||||
might read the root DSE to confirm that the server in fact supports functionality
|
||||
required by applications.</para></sect2>
|
||||
<sect2 id="best-resources"><title>Use Resource-Intensive Features Sparingly</title>
|
||||
<para>Directories offer powerful features that can nevertheless place a heavy
|
||||
load on the server. Two such features are persistent search, and server-side
|
||||
sorting.</para>
|
||||
<para>Persistent search lets you start a search that does not stop when complete,
|
||||
but instead allows you to receive updates when entries are modified. To provide
|
||||
this feature, the server must handle your search when anything happens to
|
||||
an entry in its scope.</para>
|
||||
<para>Server-side sorting requires that the server sort the entries that are
|
||||
returned during a search. Instead of returning entries as quickly as possible,
|
||||
the server must therefore get the list to return, and sort the list.</para>
|
||||
</sect2>
|
||||
<sect2 id="best-dit"><title>Avoid Hard Coding Certain Information</title>
|
||||
<para>The container entry for a subtree might be not be identical on different
|
||||
directories. Rather than hard code the container entry throughout your application,
|
||||
locate the container entry. Then navigate beneath the container entry in the
|
||||
tree.</para>
|
||||
<para>Object classes and attribute types for the same information can also
|
||||
differ from directory to directory. Use configuration files, properties files,
|
||||
or other easily modifiable variables rather than hard coding object class
|
||||
and attribute type identifiers into your application.</para>
|
||||
<para>Be aware as well that object class and attribute type identifiers are <emphasis>
|
||||
not case-sensitive</emphasis> in LDAP. Your application should therefore recognize
|
||||
that <literal>inetOrgPerson</literal> and <literal>inetorgperson</literal> are
|
||||
equivalent, as are <literal>isMemberOf</literal> and <literal>ismemberof</literal>.
|
||||
</para></sect2>
|
||||
<sect2 id="best-schema"><title>Define Schemas Only When Necessary</title>
|
||||
<indexterm>
|
||||
<primary>schema</primary>
|
||||
<secondary>defining</secondary>
|
||||
</indexterm>
|
||||
<para>Schemas define the object classes and attribute types that are recognized
|
||||
by the directory. If your application can use a standard schema, use the standard
|
||||
schema. &cnDirectoryServer; contains schemas that define numerous standard
|
||||
object classes, and attribute types.</para>
|
||||
<itemizedlist>
|
||||
<para>When you must define your own schema objects, follow these guidelines:</para>
|
||||
<listitem><para>Extend existing object classes by using <literal>AUXILIARY</literal> classes.
|
||||
</para></listitem>
|
||||
<listitem><para>Create new attributes rather than redefining existing attributes.
|
||||
</para><para>Other applications might depend on existing attributes to keep
|
||||
their existing semantics.</para></listitem>
|
||||
<listitem><para>Obtain new object identifiers for the schema elements you
|
||||
define, rather than reusing existing object identifiers.</para></listitem>
|
||||
<listitem><para>Obtain new names for the schema elements you define, rather
|
||||
than reusing existing names.</para></listitem>
|
||||
<listitem><para>Update &cnDirectoryServer; schema over LDAP if you can.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<sect2 id="best-refer"><title>Handle Referrals</title>
|
||||
<indexterm>
|
||||
<primary>referrals</primary>
|
||||
<secondary>following</secondary>
|
||||
</indexterm>
|
||||
<para>LDAP v3 allows directories that are unable to handle your request to
|
||||
refer your application to other directories. Your application should follow
|
||||
those referrals.</para>
|
||||
<para>When following referrals, realize that authentication procedures might
|
||||
not be exactly the same on different directories. Also, directories that refer
|
||||
to each other could potentially cause a referral loop. With &DirectorySDKForC; and &DirectorySDKForJava;,
|
||||
you can limit referral hops to prevent your application from being referred
|
||||
endlessly from one directory to another directory. The JNDI interface enables
|
||||
you to follow referrals automatically.</para></sect2>
|
||||
<sect2 id="best-not-rdbm"><title>Treat a Directory as a Directory</title>
|
||||
<para>A directory is typically a repository for identity data, and for information
|
||||
that you expect to keep for awhile and read often. You might typically find
|
||||
relational databases better adapted to hold transient data such as session
|
||||
keys and presence information, or voluminous accumulated data such as application
|
||||
logs.</para></sect2>
|
||||
</sect1>
|
||||
<sect1 id="best-troubleshooting"><title>Troubleshooting Problems</title>
|
||||
<para>This section covers basic troubleshooting approaches and techniques
|
||||
to use when developing directory client applications. You can check result
|
||||
codes, check server log files, and inspect network packets.</para>
|
||||
<sect2 id="trouble-rc"><title>Check Result Codes</title>
|
||||
<indexterm>
|
||||
<primary>troubleshooting</primary>
|
||||
<secondary>result codes</secondary>
|
||||
</indexterm>
|
||||
<para>When an LDAP request from your application fails on the server, the
|
||||
server sends back a result code, and possibly an explanatory message. Your
|
||||
application should check the result codes, and for explanatory messages. Common
|
||||
failure result codes include the following, which are expressed as decimal
|
||||
values. Others result codes are defined as well.</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><errorcode>1</errorcode></term>
|
||||
<listitem><para>LDAP operations error. The server encountered an error while
|
||||
processing your request.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><errorcode>32</errorcode></term>
|
||||
<listitem><para>No such object. The entry is not present on the server. Also,
|
||||
no referral is defined for the entry.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><errorcode>49</errorcode></term>
|
||||
<listitem><para>Invalid credentials. Your application failed to authenticate
|
||||
properly.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><errorcode>53</errorcode></term>
|
||||
<listitem><para>LDAP unwilling to perform. The directory does not support
|
||||
the request. Alternatively, the directory is not currently in a state in which
|
||||
to complete your request. For example, the directory might be in read-only
|
||||
mode when your application requests a modification.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><errorcode>65</errorcode></term>
|
||||
<listitem><para>Object class violation. Your write request would cause an
|
||||
entry to no longer conform to the schema defined for the directory.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><errorcode>68</errorcode></term>
|
||||
<listitem><para>Already exists. Your application is requesting to add an entry
|
||||
that has the same DN as an entry already present in the directory.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para><ulink url="http://ietf.org/rfc/rfc4511.txt" type="text_url">RFC 4511</ulink> defines
|
||||
LDAP error codes, as does <olink targetptr="bdaxx">Chapter 22, Directory
|
||||
SDK for C Result Codes</olink>.</para></sect2>
|
||||
<sect2 id="trouble-logs"><title>Check Server Log Files</title>
|
||||
<indexterm>
|
||||
<primary>troubleshooting</primary>
|
||||
<secondary>log files</secondary>
|
||||
</indexterm>
|
||||
<para>&cnDirectoryServer; logs messages related to server operation in its <filename>
|
||||
logs/errors</filename> file. If you have access to this file, you might find
|
||||
useful troubleshooting information there.</para>
|
||||
<para>When debugging your application against &cnDirectoryServer;, you can
|
||||
adjust the log level, as well. See the server documentation for instructions.</para>
|
||||
</sect2>
|
||||
<sect2 id="trouble-network-tools"><title>Inspect Network Packets</title>
|
||||
<indexterm>
|
||||
<primary>troubleshooting</primary>
|
||||
<secondary>decoding packets</secondary>
|
||||
</indexterm>
|
||||
<para>Although LDAP is not a textual protocol, tools such as <citerefentry>
|
||||
<refentrytitle>snoop</refentrytitle><manvolnum>1M</manvolnum></citerefentry>, <command>
|
||||
ethereal</command>, and <command>tcpdump</command> can decode the packets,
|
||||
sometimes providing you with important debugging information.</para></sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
98
mozilla/directory/docs/ldapjdk/choose-api.sgm
Normal file
98
mozilla/directory/docs/ldapjdk/choose-api.sgm
Normal file
@@ -0,0 +1,98 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="best-practices-choose"><title>Choosing a Client
|
||||
SDK</title>
|
||||
<highlights>
|
||||
<para>This chapter discusses software development kits to help you select
|
||||
the appropriate directory SDK for your particular situation.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="choose-jndi">Java Naming and Directory Interface
|
||||
</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="choose-ljdk">Directory SDK for Java</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="choose-cdsk">Directory SDK for C</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="choose-solaris-libldap">Operating System libldap Library</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="choose-other">Support for Other Programming
|
||||
Languages</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="choose-jndi"><title>Java Naming and Directory Interface</title>
|
||||
<indexterm>
|
||||
<primary>Java Naming and Directory Interface</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>JNDI</primary>
|
||||
<see>Java Naming and Directory Interface</see></indexterm>
|
||||
<para>Java Naming and Directory Interface (JNDI) technology supports directory
|
||||
access through LDAP and DSML v2 from <trademark>Java</trademark> applications,
|
||||
and is part of the Java platform. With JNDI, you can build powerful, portable,
|
||||
directory-enabled applications that do not depend on classes outside the Java
|
||||
platform.</para>
|
||||
<para>JNDI provides an abstract model that lets you access not only directories,
|
||||
but also naming services in general, including DNS, RMI, COS, and file systems.</para>
|
||||
<para>For information about JNDI, see <ulink
|
||||
url="http://java.sun.com/products/jndi/" type="url"></ulink>. The <citetitle>JNDI
|
||||
Tutorial</citetitle> contains descriptions and examples of how to use JNDI.
|
||||
The tutorial is at <ulink url="http://java.sun.com/products/jndi/tutorial/"
|
||||
type="url"></ulink>.</para></sect1>
|
||||
<sect1 id="choose-cdsk"><title>&DirectorySDKForC;</title>
|
||||
<para>&DirectorySDKForC; lets you access LDAP directories from C and C++
|
||||
applications. &DirectorySDKForC; applications depend on &DirectorySDKForC; libraries,
|
||||
which are available on a wide range of platforms.</para>
|
||||
<para>&DirectorySDKForC; was the subject of Internet-Draft work but never
|
||||
became a standard API. &DirectorySDKForC; closely follows LDAP v3, providing
|
||||
support for core LDAP operations and for LDAP v3 extensions and widely used
|
||||
controls. &DirectorySDKForC; offers a rich API to the C and C++ developer
|
||||
familiar with the LDAP model. &cnDirectoryServer; relies on &DirectorySDKForC;.
|
||||
</para>
|
||||
<para>This document demonstrates how to use &DirectorySDKForC;. &DirectorySDKForC; code
|
||||
is published in open source form as part of the Mozilla Directory SDK project.</para>
|
||||
</sect1>
|
||||
<sect1 id="choose-ljdk"><title>&DirectorySDKForJava;</title>
|
||||
<para>&DirectorySDKForJava; lets you access LDAP directories from Java
|
||||
applications, but it is not part of the Java platform.</para>
|
||||
<para>Although not a standard API, &DirectorySDKForJava; closely follows
|
||||
LDAP v3 idioms. &DirectorySDKForJava; provides a rich set of interfaces
|
||||
to the Java developer familiar with the LDAP model.</para>
|
||||
<para>This document demonstrates how to use &DirectorySDKForJava;. &DirectorySDKForJava; code
|
||||
is published in open source form as part of the Mozilla Directory SDK project.</para>
|
||||
</sect1>
|
||||
<sect1 id="choose-solaris-libldap"><title>Operating System <filename>libldap</filename> Library
|
||||
</title>
|
||||
<indexterm>
|
||||
<primary>libraries</primary>
|
||||
<secondary><filename>libldap</filename></secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary><filename>libldap</filename></primary>
|
||||
</indexterm>
|
||||
<para>The native LDAP library on <trademark>Solaris</trademark> systems provides
|
||||
essentially the same API as &DirectorySDKForC;. Many &DirectorySDKForC; need
|
||||
only be recompiled to work with <filename>libldap</filename>.</para>
|
||||
<para>The LDAP library is sometimes not compatible with <filename>libldap</filename> on
|
||||
many GNU/Linux distributions. Many GNU/Linux distributions provide OpenLDAP
|
||||
support by default.</para></sect1>
|
||||
<sect1 id="choose-other"><title>Support for Other Programming Languages</title>
|
||||
<para>Support for directory access is available in a number of contexts where
|
||||
you do not choose to use the C or Java languages.</para>
|
||||
<para>For example, Perl has the PerLDAP module and the Net::LDAP collection
|
||||
of modules. Python has the <literal>python-ldap</literal> package. PHP can
|
||||
be compiled with LDAP support. Ruby has the Ruby/LDAP extension module. In
|
||||
many cases, you can choose the language that fits the task and find that LDAP
|
||||
support is available.</para></sect1>
|
||||
</chapter>
|
||||
BIN
mozilla/directory/docs/ldapjdk/figures/entries.eps
Normal file
BIN
mozilla/directory/docs/ldapjdk/figures/entries.eps
Normal file
Binary file not shown.
BIN
mozilla/directory/docs/ldapjdk/figures/hier1lvl.eps
Normal file
BIN
mozilla/directory/docs/ldapjdk/figures/hier1lvl.eps
Normal file
Binary file not shown.
BIN
mozilla/directory/docs/ldapjdk/figures/hierbase.eps
Normal file
BIN
mozilla/directory/docs/ldapjdk/figures/hierbase.eps
Normal file
Binary file not shown.
BIN
mozilla/directory/docs/ldapjdk/figures/hierovrw.eps
Normal file
BIN
mozilla/directory/docs/ldapjdk/figures/hierovrw.eps
Normal file
Binary file not shown.
BIN
mozilla/directory/docs/ldapjdk/figures/hiersrch.eps
Normal file
BIN
mozilla/directory/docs/ldapjdk/figures/hiersrch.eps
Normal file
Binary file not shown.
677
mozilla/directory/docs/ldapjdk/jdk-adding.sgm
Normal file
677
mozilla/directory/docs/ldapjdk/jdk-adding.sgm
Normal file
@@ -0,0 +1,677 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="adding"><title>Adding, Updating, and Deleting Entries With &DirectorySDKForJava;</title>
|
||||
<highlights>
|
||||
<para>This chapter explains how to use the LDAP Java classes to add, modify,
|
||||
delete, and rename entries in the directory.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="add-entry">Adding an Entry With Directory
|
||||
SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="mod-entry">Modifying an Entry With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="del-entry">Deleting an Entry With Directory
|
||||
SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="rename-entry">Renaming an Entry With Directory
|
||||
SDK for Java</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="add-entry"><title>Adding an Entry With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>adding</primary>
|
||||
<secondary>entries</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>entries</primary>
|
||||
<secondary>adding</secondary>
|
||||
</indexterm>
|
||||
<orderedlist>
|
||||
<para>To add an entry to the directory, follow this general procedure:</para>
|
||||
<listitem><para>Create individual attributes for the entry.</para></listitem>
|
||||
<listitem><para>Create the set of attributes that make up the entry and add
|
||||
each of the attributes to this set.</para></listitem>
|
||||
<listitem><para>Create the new entry, specifying a unique distinguished name
|
||||
(DN) to identify the entry and the set of attributes that make up the entry.</para>
|
||||
</listitem>
|
||||
<listitem><para>Add the new entry to directory.</para></listitem></orderedlist>
|
||||
<sect2 id="add-new-attr"><title>Creating a New Attribute</title>
|
||||
<para>An attribute can have a single value or multiple values. An attribute
|
||||
can contain string values or binary data. In the LDAP Java classes, an attribute
|
||||
is represented by an <classname>LDAPAttribute</classname> object.</para>
|
||||
<para>To create a new attribute, use the <classname>LDAPAttribute</classname> constructor.
|
||||
You can specify a single string value, multiple string values, or a binary
|
||||
value when constructing the object.</para>
|
||||
<para>For example, the following section of code creates a new object for
|
||||
the attribute <literal>cn</literal> with the value <literal>Jane St. Clair</literal>.
|
||||
</para>
|
||||
<programlisting>LDAPAttribute attr = new LDAPAttribute("cn", "Jane St. Clair");</programlisting>
|
||||
<para>The following section of code creates an attribute <literal>objectclass</literal> with
|
||||
the values <literal>top</literal>, <literal>person</literal>, <literal>organizationalPerson
|
||||
</literal>, and <literal>inetOrgPerson</literal>.</para>
|
||||
<programlisting>String objectclasses[] = {"top", "person", "organizationalPerson",
|
||||
"inetOrgPerson"};
|
||||
LDAPAttribute attr = new LDAPAttribute("objectclass", objectclasses);</programlisting>
|
||||
<para>You can also add string or binary values to an <classname>LDAPAttribute</classname> object
|
||||
by invoking the <literal>addValue</literal> method.</para></sect2>
|
||||
<sect2 id="add-new-set"><title>Creating a New Attribute Set</title>
|
||||
<para>To specify the set of attributes in an entry, you need to create an
|
||||
attribute set. In the LDAP Java classes, a set of one or more attributes is
|
||||
represented by an <classname>LDAPAttributeSet</classname> object.</para>
|
||||
<para>To create a new attribute set, use the <classname>LDAPAttributeSet</classname> constructor.
|
||||
Invoke the <literal>add</literal> method to add <classname>LDAPAttribute</classname> objects
|
||||
to the set.</para>
|
||||
<programlisting>LDAPAttribute attr1 = new LDAPAttribute("cn", "Jane St. Clair");
|
||||
String objectclasses[] = {"top", "person", "organizationalPerson",
|
||||
"inetOrgPerson"};
|
||||
LDAPAttribute attr2 = new LDAPAttribute("objectclass", objectclasses);
|
||||
LDAPAttributeSet attrSet = new LDAPAttributeSet();
|
||||
attrSet.add(attr1);
|
||||
attrSet.add(attr2);</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="add-new-entry"><title>Creating a New Entry</title>
|
||||
<para>An entry contains a distinguished name (DN), which identifies the entry
|
||||
in the directory, and a set of attributes. In the LDAP Java classes, an entry
|
||||
is represented by an <classname>LDAPEntry</classname> object.</para>
|
||||
<para>To create a new entry, use the <literal>LDAPEntry</literal> constructor.</para>
|
||||
<programlisting>LDAPAttribute attr1 = new LDAPAttribute("cn", "Jane St. Clair");
|
||||
String objectclasses[] = {"top", "person", "organizationalPerson",
|
||||
"inetOrgPerson"};
|
||||
LDAPAttribute attr2 = new LDAPAttribute("objectclass", objectclasses);
|
||||
LDAPAttributeSet attrSet = new LDAPAttributeSet();
|
||||
attrSet.add(attr1);
|
||||
attrSet.add(attr2);
|
||||
String dn = "uid=jsclair,ou=People,dc=example,dc=com";
|
||||
LDAPEntry newEntry = new LDAPEntry(dn, attrs);</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="add-entry-dir"><title>Adding the New Entry to the Directory</title>
|
||||
<itemizedlist>
|
||||
<para>Before you add an entry to the directory, make sure that you have done
|
||||
the following:</para>
|
||||
<listitem><para>You have specified the object classes of the entry using the <literal>
|
||||
objectclass</literal> attribute, and have specified the required attributes
|
||||
for those object classes.</para>
|
||||
<itemizedlist>
|
||||
<para>For example, organizational units might be represented by entries of
|
||||
the <literal>organizationalUnit</literal> object class. To add an entry for
|
||||
an organizational unit, you need to specify the following attributes in the
|
||||
entry:</para>
|
||||
<listitem><para><literal>objectclass</literal> with value <literal>top</literal></para>
|
||||
</listitem>
|
||||
<listitem><para><literal>objectclass</literal> with value <literal>organizationalUnit
|
||||
</literal></para></listitem>
|
||||
<listitem><para><literal>ou</literal> with the value for the organizational
|
||||
unit, such as <literal>People</literal></para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>You have authenticated as a user who has the access permissions
|
||||
to add the entry to the directory.</para><para>If you do not have permission
|
||||
to add the entry, an <classname>LDAPException</classname> is returned with
|
||||
result code <constant>LDAPException.INSUFFICIENT_ACCESS_RIGHTS</constant>.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>To add the entry to the directory, invoke the <literal>add</literal> method
|
||||
of the <classname>LDAPConnection</classname> object.</para>
|
||||
<programlisting>try {
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect("localhost", LDAPv3.DEFAULT_PORT);
|
||||
ld.authenticate(bindDNWithWriteAccess, bindPassword);
|
||||
LDAPEntry newEntry = new LDAPEntry(dn, attrs);
|
||||
ld.add(newEntry);
|
||||
} catch (LDAPException e) {
|
||||
System.err.println("Could not add " + dn + ":" + e.toString());
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="add-entry-example"><title>Example of Adding an Entry</title>
|
||||
<para>The following example adds a new entry to the directory for the user
|
||||
who is named William Jensen.</para>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
|
||||
public class Add {
|
||||
public static void main(String[] args) {
|
||||
/* Specify the DN to add */
|
||||
String dn = "uid=wbjensen, ou=People, dc=example,dc=com";
|
||||
|
||||
/* Specify the attributes of the entry */
|
||||
String objectclass_values[] =
|
||||
{"top", "person", "organizationalPerson", "inetOrgPerson"};
|
||||
String cn_values[] =
|
||||
{"William B Jensen", "William Jensen", "Bill Jensen"};
|
||||
String sn_values[] = {"Jensen"};
|
||||
String givenname_values[] = {"William", "Bill"};
|
||||
String telephonenumber_values[] = {"+1 800 555 1212"};
|
||||
|
||||
LDAPAttributeSet attrs = new LDAPAttributeSet();
|
||||
LDAPAttribute attr = new LDAPAttribute("objectclass");
|
||||
for (int i = 0; i < objectclass_values.length; i++) {
|
||||
attr.addValue(objectclass_values[i]);
|
||||
}
|
||||
attrs.add(attr);
|
||||
attr = new LDAPAttribute("cn");
|
||||
for (int i = 0; i < cn_values.length; i++) {
|
||||
attr.addValue(cn_values[i]);
|
||||
}
|
||||
attrs.add(attr);
|
||||
attr = new LDAPAttribute("sn");
|
||||
for (int i = 0; i < sn_values.length; i++) {
|
||||
attr.addValue(sn_values[i]);
|
||||
}
|
||||
attrs.add(attr);
|
||||
attr = new LDAPAttribute("givenname");
|
||||
for (int i = 0; i < givenname_values.length; i++) {
|
||||
attr.addValue(givenname_values[i]);
|
||||
}
|
||||
attrs.add(attr);
|
||||
attr = new LDAPAttribute("telephonenumber");
|
||||
for (int i = 0; i < telephonenumber_values.length; i++) {
|
||||
attr.addValue(telephonenumber_values[i]);
|
||||
}
|
||||
attrs.add(attr);
|
||||
attrs.add(new LDAPAttribute("uid", "wbjensen"));
|
||||
|
||||
/* Create an entry with this DN and these attributes */
|
||||
LDAPEntry myEntry = new LDAPEntry(dn, attrs);
|
||||
|
||||
try {
|
||||
/* Connect and authenticate as a user with write access. */
|
||||
UserArgs userArgs = new UserArgs("Add", args, true);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
ld.authenticate(userArgs.getBindDN(), userArgs.getPassword());
|
||||
|
||||
/* Now add the entry to the directory */
|
||||
ld.add(myEntry);
|
||||
System.out.println("Entry added");
|
||||
|
||||
ld.disconnect();
|
||||
} catch(LDAPException e) {
|
||||
if (e.getLDAPResultCode() ==
|
||||
LDAPException.ENTRY_ALREADY_EXISTS) {
|
||||
System.out.println("Error: Entry already present");
|
||||
} else {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="mod-entry"><title>Modifying an Entry With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>modifying</primary>
|
||||
<secondary>entries</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>entries</primary>
|
||||
<secondary>modifying</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>attributes</primary>
|
||||
<secondary>modifying</secondary>
|
||||
</indexterm>
|
||||
<orderedlist>
|
||||
<para>To modify an entry in the directory, follow this general procedure:</para>
|
||||
<listitem><para>Specify each attribute change to make.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>If you are making only one change to the entry, construct
|
||||
an <classname>LDAPModification</classname> object that specifies the change
|
||||
that needs to be made.</para></listitem>
|
||||
<listitem><para>If you are making more than one change, you need to construct
|
||||
an <classname>LDAPModificationSet</classname> object that specifies the changes
|
||||
that need to be made.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>Use the DN of the entry to find and update the
|
||||
entry in the directory.</para></listitem></orderedlist>
|
||||
<sect2 id="mod-entry-spec-changes"><title>Specifying Attribute Changes</title>
|
||||
<para>You can add new values to an attribute, remove existing attribute values,
|
||||
or change the values of an existing attribute. You can also remove an attribute
|
||||
by removing all values for the attribute or by not providing values for the
|
||||
attribute.</para>
|
||||
<sect3 id="mod-entry-new-values"><title>Adding New Attribute Values</title>
|
||||
<indexterm>
|
||||
<primary>attributes</primary>
|
||||
<secondary>adding values to</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>adding</primary>
|
||||
<secondary>values to an attribute</secondary>
|
||||
</indexterm>
|
||||
<itemizedlist>
|
||||
<para>To add new values to an attribute in an entry, construct a new <classname>LDAPAttribute
|
||||
</classname> object. Specify the name of the attribute. Also, specify the
|
||||
values to add. Then, perform one of the following operations:</para>
|
||||
<listitem><para>If you are making a single change to the entry, construct
|
||||
a new <classname>LDAPModification</classname> object to specify that change.
|
||||
Pass <constant>LDAPModification.ADD</constant> and the <classname>LDAPAttribute</classname> object
|
||||
as arguments to the <literal>LDAPModification</literal> constructor.</para>
|
||||
</listitem>
|
||||
<listitem><para>If you are collecting multiple changes to an entry in an <classname>
|
||||
LDAPModificationSet</classname> object, invoke the <literal>add</literal> method.
|
||||
This method adds the change to the set of modifications. Pass <constant>LDAPModification.ADD
|
||||
</constant> and the <classname>LDAPAttribute</classname> object as arguments
|
||||
to this method.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>For example, the following code excerpt adds the value <literal>babs@example.com
|
||||
</literal> to the <literal>mail</literal> attribute:</para>
|
||||
<programlisting>LDAPModificationSet mods = new LDAPModificationSet();
|
||||
LDAPAttribute attrMail = new LDAPAttribute("mail", "babs@example.com");
|
||||
mods.add(LDAPModification.ADD, attrMail);</programlisting>
|
||||
<para>If the specified attribute does not exist in the entry, the attribute
|
||||
is created for the entry.</para></sect3>
|
||||
<sect3 id="mod-entry-del-values"><title>Deleting Attribute Values</title>
|
||||
<indexterm>
|
||||
<primary>attributes</primary>
|
||||
<secondary>removing values from</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>deleting</primary>
|
||||
<secondary>values from an attribute</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>removing</primary>
|
||||
<secondary>values from an attribute</secondary>
|
||||
</indexterm>
|
||||
<itemizedlist>
|
||||
<para>To remove values from an attribute in an entry, construct a new <classname>
|
||||
LDAPAttribute</classname> object, specifying the name of the attribute and
|
||||
the values to remove. Then, perform one of the following operations:</para>
|
||||
<listitem><para>If you are making a single change to the entry, construct
|
||||
a new <classname>LDAPModification</classname> object to specify that change.
|
||||
Pass <constant>LDAPModification.DELETE</constant> and the <classname>LDAPAttribute
|
||||
</classname> object as arguments to the <literal>LDAPModification</literal> constructor.
|
||||
</para></listitem>
|
||||
<listitem><para>If you are collecting multiple changes to an entry in an <classname>
|
||||
LDAPModificationSet</classname> object, invoke the <literal>add</literal> method.
|
||||
The method adds the change to the set of modifications. Pass <constant>LDAPModification.DELETE
|
||||
</constant> and the <classname>LDAPAttribute</classname> object as arguments
|
||||
to this method.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>For example, the following code excerpt removes the value <literal>babs@example.com
|
||||
</literal> from the <literal>mail</literal> attribute:</para>
|
||||
<programlisting>LDAPModificationSet mods = new LDAPModificationSet();
|
||||
LDAPAttribute attrMail = new LDAPAttribute("mail", "babs@example.com");
|
||||
mods.add(LDAPModification.DELETE, attrMail);</programlisting>
|
||||
<para>If you remove all values from an attribute, the attribute is removed
|
||||
from the entry. If you do not specify any values in the <classname>LDAPAttribute</classname> object,
|
||||
the attribute is also removed from the entry.</para></sect3>
|
||||
<sect3 id="mod-entry-replace-values"><title>Replacing Attribute Values</title>
|
||||
<indexterm>
|
||||
<primary>attributes</primary>
|
||||
<secondary>replacing values of</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>changing</primary>
|
||||
<secondary>values of an attribute</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>modifying</primary>
|
||||
<secondary>values of an attribute</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>replacing</primary>
|
||||
<secondary>values of an attribute</secondary>
|
||||
</indexterm>
|
||||
<itemizedlist>
|
||||
<para>To replace values for an attribute in an entry, construct a new <classname>
|
||||
LDAPAttribute</classname> object, specifying the name of the attribute and
|
||||
the values to replace. Then, perform one of the following operations:</para>
|
||||
<listitem><para>If you are making a single change to the entry, construct
|
||||
a new <classname>LDAPModification</classname> object to specify that change.
|
||||
Pass <constant>LDAPModification.REPLACE</constant> and the <classname>LDAPAttribute
|
||||
</classname> object as arguments to the <literal>LDAPModification</literal> constructor.
|
||||
</para></listitem>
|
||||
<listitem><para>If you are collecting multiple changes to an entry in an <classname>
|
||||
LDAPModificationSet</classname> object, invoke the <literal>add</literal> method.
|
||||
The method adds the change to the set of modifications. Pass <constant>LDAPModification.REPLACE
|
||||
</constant> and the <classname>LDAPAttribute</classname> object as arguments
|
||||
to this method.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>For example, the following code excerpt replaces the existing value
|
||||
of the <literal>mail</literal> attribute with <literal>babs@example.com</literal>:
|
||||
</para>
|
||||
<programlisting>LDAPModificationSet mods = new LDAPModificationSet();
|
||||
LDAPAttribute attrMail = new LDAPAttribute("mail", "babs@example.com");
|
||||
mods.add(LDAPModification.REPLACE, attrMail);</programlisting>
|
||||
<para>If the specified attribute does not exist in the entry, the attribute
|
||||
is created for the entry. If you do not specify any values in the <classname>LDAPAttribute
|
||||
</classname> object, the attribute is removed from the entry.</para></sect3>
|
||||
<sect3 id="mode-entry-del-attr"><title>Removing an Attribute</title>
|
||||
<indexterm>
|
||||
<primary>attributes</primary>
|
||||
<secondary>removing from an entry</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>entries</primary>
|
||||
<secondary>removing attributes from</secondary>
|
||||
</indexterm>
|
||||
<itemizedlist>
|
||||
<para>To remove an attribute from an entry, perform one of the following operations:
|
||||
</para>
|
||||
<listitem><para>Replace the values of the attribute with an <classname>LDAPAttribute
|
||||
</classname> object that contains no values.</para></listitem>
|
||||
<listitem><para>Remove the values of the attribute with an <classname>LDAPAttribute
|
||||
</classname> object that contains no values.</para></listitem>
|
||||
<listitem><para>Remove all values for the attribute.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>For example, the following code excerpt demonstrates the first two options
|
||||
by preparing an <classname>LDAPModificationSet</classname> object to remove
|
||||
the <literal>mail</literal> and <literal>description</literal> attributes:</para>
|
||||
<programlisting>LDAPModificationSet mods = new LDAPModificationSet();
|
||||
LDAPAttribute attrMail = new LDAPAttribute("mail");
|
||||
LDAPAttribute attrDesc = new LDAPAttribute("description");
|
||||
mods.add(LDAPModification.REPLACE, attrMail);
|
||||
mods.add(LDAPModification.DELETE, attrDesc);</programlisting>
|
||||
</sect3>
|
||||
</sect2>
|
||||
<sect2 id="mod-entry-dir"><title>Modifying the Entry in the Directory</title>
|
||||
<itemizedlist>
|
||||
<para>Before you modify an entry, make sure of the following:</para>
|
||||
<listitem><para>You have not removed any of the required attributes for that
|
||||
object class.</para></listitem>
|
||||
<listitem><para>You have authenticated as a user who has the access permissions
|
||||
to modify the entry in the directory.</para><para>If you do not have permission
|
||||
to modify the entry, an <classname>LDAPException</classname> is returned with
|
||||
the result code <constant>LDAPException.INSUFFICIENT_ACCESS_RIGHTS</constant>.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>You specify the change with an <classname>LDAPModification</classname> object.
|
||||
You specify a list of changes with an <classname>LDAPModificationSet</classname> object.
|
||||
When finished specifying the change, pass the object with the DN of the entry
|
||||
to the <literal>modify</literal> method of the <classname>LDAPConnection</classname> object.
|
||||
</para></sect2>
|
||||
<sect2 id="mod-entry-example"><title>Example of Modifying an Entry</title>
|
||||
<para>The following example modifies an entry in the directory.</para>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ModAttrs {
|
||||
public static void main(String[] args) {
|
||||
String ENTRYDN = "uid=bjensen, ou=People, dc=example,dc=com";
|
||||
|
||||
LDAPModificationSet mods = new LDAPModificationSet();
|
||||
LDAPAttribute attrEmail =
|
||||
new LDAPAttribute("mail", "babs@example.com");
|
||||
mods.add(LDAPModification.REPLACE, attrEmail);
|
||||
LDAPAttribute attrDesc = new LDAPAttribute("description",
|
||||
"This entry was modified with the ModAttrs program");
|
||||
mods.add(LDAPModification.ADD, attrDesc);
|
||||
|
||||
try {
|
||||
/* Connect and authenticate as a user with write access. */
|
||||
UserArgs userArgs = new UserArgs("ModAttrs", args, true);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
ld.authenticate(userArgs.getBindDN(), userArgs.getPassword());
|
||||
|
||||
/* Now modify the entry in the directory */
|
||||
ld.modify(ENTRYDN, mods);
|
||||
System.out.println("Entry modified" );
|
||||
|
||||
ld.disconnect();
|
||||
} catch(LDAPException e) {
|
||||
if (e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT) {
|
||||
System.out.println("Error: No such entry");
|
||||
} else if (e.getLDAPResultCode() ==
|
||||
LDAPException.INSUFFICIENT_ACCESS_RIGHTS) {
|
||||
System.out.println("Error: Insufficient rights");
|
||||
} else if (e.getLDAPResultCode() ==
|
||||
LDAPException.ATTRIBUTE_OR_VALUE_EXISTS) {
|
||||
System.out.println("Error: Attribute or value exists");
|
||||
} else {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="del-entry"><title>Deleting an Entry With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>deleting an entry</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>entries</primary>
|
||||
<secondary>deleting</secondary>
|
||||
</indexterm>
|
||||
<para>Before you delete an entry, authenticate as a user who has the access
|
||||
permissions to remove the entry from the directory. If you do not have permission
|
||||
to delete the entry, an <classname>LDAPException</classname> is returned with
|
||||
result code <constant>LDAPException.INSUFFICIENT_ACCESS_RIGHTS</constant>.</para>
|
||||
<para>To remove an entry from the directory, invoke the <literal>delete</literal> method
|
||||
of the <classname>LDAPConnection</classname> object. Specify the DN of the
|
||||
entry that you want to remove.</para>
|
||||
<para>The following example deletes the entry that is added in <olink type="auto-generated" targetptr="add-entry-example">Example of Adding an Entry</olink>.
|
||||
</para>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
|
||||
public class Del {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
/* Connect and authenticate as a user with write access. */
|
||||
UserArgs userArgs = new UserArgs("Del", args, true);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
ld.authenticate(userArgs.getBindDN(), userArgs.getPassword());
|
||||
|
||||
/* Specify the DN we're deleting */
|
||||
String dn = "uid=wbjensen, ou=People, dc=example,dc=com";
|
||||
|
||||
ld.delete(dn);
|
||||
System.out.println("Entry deleted");
|
||||
|
||||
ld.disconnect();
|
||||
} catch(LDAPException e) {
|
||||
if (e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT) {
|
||||
System.out.println("Error: No such entry");
|
||||
} else if (e.getLDAPResultCode() ==
|
||||
LDAPException.INSUFFICIENT_ACCESS_RIGHTS) {
|
||||
System.out.println("Error: Insufficient rights");
|
||||
} else {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</sect1>
|
||||
<sect1 id="rename-entry"><title>Renaming an Entry With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>changing the name of an entry</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>moving an entry</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>renaming an entry</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>entries</primary>
|
||||
<secondary>renaming</secondary>
|
||||
</indexterm>
|
||||
<para>Before you rename an entry, authenticate as a user who has the access
|
||||
permissions to perform the operation. If you do not have permission to rename
|
||||
the entry, an <classname>LDAPException</classname> is returned with result
|
||||
code <constant>LDAPException.INSUFFICIENT_ACCESS_RIGHTS</constant>.</para>
|
||||
<itemizedlist>
|
||||
<para>To rename an entry, invoke the <literal>rename</literal> method of the <classname>
|
||||
LDAPConnection</classname> object. With this method, you can change the following:
|
||||
</para>
|
||||
<listitem><para>The relative distinguished name (RDN) of the entry</para>
|
||||
</listitem>
|
||||
<listitem><para>The location of the entry in the directory by changing the
|
||||
DN and not just the RDN</para><para>Some LDAP servers do not support moving
|
||||
entries by changing their DNs. Check your LDAP server documentation for further
|
||||
information.</para></listitem>
|
||||
</itemizedlist>
|
||||
<sect2 id="rename-entry-newrdn"><title>Changing the Relative Distinguished
|
||||
Name</title>
|
||||
<para>When invoking the <literal>rename</literal> method of the <classname>LDAPConnection
|
||||
</classname> object, you can specify a <parameter>deleteoldrdn</parameter> parameter.
|
||||
The parameter allows you to remove the old RDN from the entry. Suppose an
|
||||
entry has the following values for the <literal>uid</literal> attribute:</para>
|
||||
<programlisting>uid: wbjensen
|
||||
uid: wbj</programlisting>
|
||||
<para>The following code excerpt changes the user ID value <literal>wbjensen</literal> to <literal>
|
||||
wjensen</literal> and removes the <literal>wbjensen</literal> value:</para>
|
||||
<programlisting>ld.rename("uid=wbjensen,ou=People,dc=example,dc=com", "uid=wjensen", true);
|
||||
</programlisting>
|
||||
<para>The resulting values in the entry do not include the old RDN:</para>
|
||||
<programlisting>uid: wbjensen
|
||||
uid: wbj</programlisting>
|
||||
<para>The following code excerpt retains the existing user ID value after
|
||||
the rename operation:</para>
|
||||
<programlisting>ld.rename("uid=wbjensen,ou=People,dc=example,dc=com", "uid=wjensen", false);
|
||||
</programlisting>
|
||||
<para>In this case, the resulting values in the entry <emphasis>do</emphasis> include
|
||||
the old RDN:</para>
|
||||
<programlisting>uid: wbjensen
|
||||
uid: wjensen
|
||||
uid: wbj</programlisting>
|
||||
<para>The DN after the rename operation is, however, <literal>uid=wjensen,ou=People,dc=example,dc=com
|
||||
</literal>.</para>
|
||||
<para>The following example creates an entry and then renames it:</para>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ModRdn {
|
||||
public static void main(String[] args) {
|
||||
/* Values for creating the entry */
|
||||
String objectclass_values[] =
|
||||
{"top", "person", "organizationalPerson", "inetOrgPerson"};
|
||||
String cn_values[] = {"Jacques Smith"};
|
||||
String sn_values[] = {"Smith"};
|
||||
String givenname_values[] = {"Jacques"};
|
||||
|
||||
/* Specify the DN to add */
|
||||
String base = "ou=People, dc=example,dc=com";
|
||||
String dn = "uid=jsmith" + "," + base;
|
||||
String nrdn = "uid=jmsmith"; // The new RDN
|
||||
String ndn = nrdn + "," + base; // The target DN
|
||||
|
||||
/* Create an attribute set with all desired attributes */
|
||||
LDAPAttributeSet attrs = new LDAPAttributeSet();
|
||||
LDAPAttribute attr =
|
||||
new LDAPAttribute("objectclass", objectclass_values);
|
||||
attrs.add(attr);
|
||||
attr = new LDAPAttribute("cn", cn_values);
|
||||
attrs.add(attr);
|
||||
attr = new LDAPAttribute("sn", sn_values);
|
||||
attrs.add(attr);
|
||||
attr = new LDAPAttribute("givenname", givenname_values);
|
||||
attrs.add(attr);
|
||||
attrs.add(new LDAPAttribute("uid", nrdn));
|
||||
|
||||
/* Create an entry with this DN and these attributes */
|
||||
LDAPEntry myEntry = new LDAPEntry(dn, attrs);
|
||||
|
||||
try {
|
||||
/* Connect and authenticate as a user with write access. */
|
||||
UserArgs userArgs = new UserArgs("ModRdn", args, true);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
ld.authenticate(userArgs.getBindDN(), userArgs.getPassword());
|
||||
|
||||
/* Add the entry */
|
||||
try {
|
||||
ld.add(myEntry);
|
||||
} catch(LDAPException e) {
|
||||
/* If entry exists already, fine. Ignore this error. */
|
||||
if (e.getLDAPResultCode() !=
|
||||
LDAPException.ENTRY_ALREADY_EXISTS) throw e;
|
||||
}
|
||||
|
||||
/* Delete the destination entry, for this example */
|
||||
try {
|
||||
ld.delete(ndn);
|
||||
}
|
||||
catch(LDAPException e) {
|
||||
/* If entry does not exist, fine. Ignore this error. */
|
||||
if (e.getLDAPResultCode() != LDAPException.NO_SUCH_OBJECT)
|
||||
throw e;
|
||||
}
|
||||
|
||||
/* Do the modrdn operation */
|
||||
ld.rename(dn, nrdn, false);
|
||||
System.out.println("The modrdn operation was successful. ");
|
||||
System.out.println(
|
||||
"Entry " + dn + " has been changed to " + ndn);
|
||||
|
||||
ld.disconnect();
|
||||
}
|
||||
catch(LDAPException e) {
|
||||
if (e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT) {
|
||||
System.out.println("Error: No such entry");
|
||||
} else if (e.getLDAPResultCode() ==
|
||||
LDAPException.INSUFFICIENT_ACCESS_RIGHTS) {
|
||||
System.out.println("Error: Insufficient rights");
|
||||
} else if (e.getLDAPResultCode() ==
|
||||
LDAPException.ATTRIBUTE_OR_VALUE_EXISTS) {
|
||||
System.out.println("Error: Attribute or value exists");
|
||||
} else {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="rename-entry-newdn"><title>Changing the Distinguished Name</title>
|
||||
<para>When invoking the <literal>rename</literal> method of the <classname>LDAPConnection
|
||||
</classname> object, you can specify a <parameter>newParentDN</parameter> parameter.
|
||||
The parameter allows you to move the entry from one part of the directory
|
||||
to another part by changing its DN. You can use the parameter even if the
|
||||
RDN does not change.</para>
|
||||
<para>The following example moves Sam Carter's entry from the organizational
|
||||
unit People, to the organizational unit Special Users:</para>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ModDn {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
/* Connect and authenticate as a user with write access. */
|
||||
UserArgs userArgs = new UserArgs("ModDn", args, true);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
ld.authenticate(3, userArgs.getBindDN(),userArgs.getPassword());
|
||||
|
||||
/* Elevate Sam Carter from mere person to Special User. */
|
||||
String rdn = "uid=scarter";
|
||||
String oldParent = "ou=people,dc=example,dc=com";
|
||||
String newParent = "ou=special users,dc=example,dc=com";
|
||||
String dn = rdn + "," + oldParent;
|
||||
String ndn = rdn + "," + newParent;
|
||||
|
||||
/* Read Sam's entry to make sure it exists before moving it. */
|
||||
try {
|
||||
LDAPEntry le = ld.read(dn);
|
||||
}
|
||||
catch(LDAPException e) {
|
||||
System.err.println(
|
||||
"Cannot read " + dn + ": " + e.toString());
|
||||
throw e;
|
||||
}
|
||||
|
||||
/* Delete the moved entry if it already exists. */
|
||||
try {
|
||||
ld.delete(ndn);
|
||||
}
|
||||
catch(LDAPException e) {
|
||||
/* Ignore notification that the new entry is not there. */
|
||||
if (e.getLDAPResultCode() != e.NO_SUCH_OBJECT) throw e;
|
||||
}
|
||||
|
||||
/* Move Sam's entry. */
|
||||
ld.rename(dn, rdn, newParent, false);
|
||||
System.out.println("Entry " + dn + " has moved to " + ndn);
|
||||
|
||||
ld.disconnect();
|
||||
}
|
||||
catch(LDAPException e) {
|
||||
System.err.println("Error: " + e.toString());
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
277
mozilla/directory/docs/ldapjdk/jdk-asynchronous.sgm
Normal file
277
mozilla/directory/docs/ldapjdk/jdk-asynchronous.sgm
Normal file
@@ -0,0 +1,277 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="asynchronous"><title>Writing Asynchronous Clients With &DirectorySDKForJava;</title>
|
||||
<highlights>
|
||||
<para>This chapter shows how to use the asynchronous interface to LDAP in
|
||||
Java applications.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="async-vs-sync">Synchronous and Asynchronous Connections With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="async-using">Common Uses for the Asynchronous Interface With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="async-new">Classes in the Asynchronous Interface for Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="async-search">Performing Asynchronous Searches With Directory SDK for Java</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="async-further">Further Reading About the Asynchronous Interface for Directory SDK for Java</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="async-vs-sync"><title>Synchronous and Asynchronous Connections
|
||||
With Directory SDK for Java</title>
|
||||
<indexterm>
|
||||
<primary>asynchronous interface</primary>
|
||||
<secondary>explained</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>synchronous interface</primary>
|
||||
<secondary>explained</secondary>
|
||||
</indexterm>
|
||||
<para>Most operations with &DirectorySDKForJava; are performed synchronously.
|
||||
A connection is established, a request is sent, the results are returned.
|
||||
Then the application resumes. Though the &DirectorySDKForJava; can deliver
|
||||
one search result at a time, other operations block until completion when
|
||||
accessing an LDAP server.</para>
|
||||
<para>Sometimes, initiating a new request while another request executes can
|
||||
be useful. An additional interface is provided to access the built-in support
|
||||
in &DirectorySDKForJava; for these asynchronous requests. By returning
|
||||
control to an application before obtaining a response, the asynchronous interface
|
||||
allows you to perform complex operations requiring access to low-level LDAP
|
||||
mechanisms.</para>
|
||||
<para><classname>LDAPConnection</classname> methods support both asynchronous
|
||||
requests and synchronous requests. Synchronous methods wait for response messages
|
||||
from a server and then process the responses for you. Asynchronous methods
|
||||
require that you check for the messages. You then perform the processing in
|
||||
your code. This mechanism allows you to make additional LDAP requests while
|
||||
waiting for results to return.</para></sect1>
|
||||
<sect1 id="async-using"><title>Common Uses for the Asynchronous Interface
|
||||
With Directory SDK for Java</title>
|
||||
<indexterm>
|
||||
<primary>asynchronous interface</primary>
|
||||
<secondary>common uses</secondary>
|
||||
</indexterm>
|
||||
<para>Since using the asynchronous interface involves managing more complex
|
||||
code in an application, use the asynchronous methods only when required. The
|
||||
most common use is for merging the results of searches that involve multiple
|
||||
servers or that are executed simultaneously on different subtrees. This method
|
||||
is sometimes referred to as <firstterm>multiplexing</firstterm>.</para>
|
||||
<para>A search that multiplexes servers can make a request to an array of
|
||||
hosts. A search that multiplexes query statements can make different requests
|
||||
to different subtrees of a server. If you combine these search methods, you
|
||||
can perform complex searches across a number of servers without having to
|
||||
wait for individual responses.</para>
|
||||
<para>The following example illustrates a practical use of multiplexed searches
|
||||
and the asynchronous interface.</para>
|
||||
<para>Suppose event notification must be implemented as a generic service
|
||||
with LDAP persistent search. Synchronous methods require a new thread for
|
||||
every request to the service. This solution is not scalable and can exhaust
|
||||
system resources very quickly.</para>
|
||||
<para>After the search is rewritten using the asynchronous interface, performance
|
||||
improves dramatically. Since asynchronous searches do not block until completion,
|
||||
the persistent search results can be multiplexed into one queue and then processed
|
||||
on a single thread.</para></sect1>
|
||||
<sect1 id="async-new"><title>Classes in the Asynchronous Interface for Directory
|
||||
SDK for Java</title>
|
||||
<indexterm>
|
||||
<primary>asynchronous interface</primary>
|
||||
<secondary>classes</secondary>
|
||||
</indexterm>
|
||||
<para>&DirectorySDKForJava; handles asynchronous communication through
|
||||
the <classname>LDAPAsynchronousConnection</classname> interface and its dependent
|
||||
classes. These files collectively form the asynchronous extensions to the
|
||||
LDAP API.</para>
|
||||
<para><classname>LDAPAsynchronousConnection</classname> defines methods for
|
||||
authenticating to a server, as well as for searching, modifying, comparing,
|
||||
and deleting entries in the directory.</para>
|
||||
<para>When you call a method of <classname>LDAPAsynchronousConnection</classname>,
|
||||
the method returns a listener object. This object acts as a message queue.
|
||||
The object accepts search results and server-generated responses to LDAP requests.
|
||||
The LDAP client has the responsibility to read and process these messages.</para>
|
||||
<itemizedlist>
|
||||
<para><classname>LDAPAsynchronousConnection</classname> incorporates the following
|
||||
classes for handling asynchronous client-server interactions:</para>
|
||||
<listitem><para><classname>LDAPMessage</classname>, which is the base class
|
||||
for LDAP request and response messages.</para></listitem>
|
||||
<listitem><para><classname>LDAPResponse</classname>, which extends <classname>LDAPMessage
|
||||
</classname>, represents a message received from an LDAP server in response
|
||||
to a request.</para></listitem>
|
||||
<listitem><para><classname>LDAPExtendedResponse</classname>, which extends <classname>
|
||||
LDAPResponse</classname>. This response is the response that an LDAP server
|
||||
returns when handling an extended operation request.</para></listitem>
|
||||
<listitem><para><classname>LDAPResponseListener</classname> queues <classname>LDAPResponse
|
||||
</classname> messages.</para></listitem>
|
||||
<listitem><para><classname>LDAPSearchResult</classname>, which extends <classname>
|
||||
LDAPMessage</classname>. The response contains a single LDAP entry. The response
|
||||
is one of the responses an LDAP server can return when handling a search request.
|
||||
</para></listitem>
|
||||
<listitem><para><classname>LDAPSearchResultReference</classname>, which extends <classname>
|
||||
LDAPMessage</classname>. The response contains a referral. The response is
|
||||
one of the responses that an LDAP server can return when handling a search
|
||||
request.</para></listitem>
|
||||
<listitem><para><classname>LDAPSearchListener</classname> queues search results
|
||||
and references.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="async-search"><title>Performing Asynchronous Searches With Directory
|
||||
SDK for Java</title>
|
||||
<para>One of the most common uses of the asynchronous interface is for performing
|
||||
multiplexed searches using more than one server or suffix.</para>
|
||||
<task id="async-search-mult-servers"><title>To Search Across Multiple Servers</title>
|
||||
<indexterm>
|
||||
<primary>asynchronous interface</primary>
|
||||
<secondary>search multiple servers</secondary>
|
||||
</indexterm>
|
||||
<tasksummary>
|
||||
<para>To search on more than one server, perform the following steps.</para>
|
||||
</tasksummary>
|
||||
<procedure>
|
||||
<step><para>Connect to all the servers.</para></step>
|
||||
<step><para>Create a response listener for one search.</para></step>
|
||||
<step><para>Share the response listener with all the other searches.</para>
|
||||
</step>
|
||||
<step><para>Obtain and process the results.</para></step>
|
||||
<step><para>Disconnect from the servers.</para></step>
|
||||
</procedure>
|
||||
<example id="async-search-mult-servers-example">
|
||||
<title>Searching Across Multiple Servers</title>
|
||||
<para>This example demonstrates how to search on two servers at the same time.</para>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
|
||||
public class MultiplexServers {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
LDAPConnection[] ld = new LDAPConnection[2];
|
||||
String[] hosts = {"server1", "server2"};
|
||||
int[] ports = {389, 389};
|
||||
String[] bases = {"dc=example,dc=com", "dc=example,dc=com"};
|
||||
|
||||
/* search for all entries with surname of Jensen */
|
||||
String MY_FILTER = "(sn=Jensen)";
|
||||
for (int i = 0; i < ld.length; i++) {
|
||||
ld[i] = new LDAPConnection();
|
||||
ld[i].connect(hosts[i], ports[i]);
|
||||
}
|
||||
/* Get a response listener for one search */
|
||||
LDAPSearchListener l = ld[0].search(bases[0], ld[0].SCOPE_SUB,
|
||||
MY_FILTER, null, false, (LDAPSearchListener)null);
|
||||
/* Share the listener */
|
||||
for (int i = 1; i < ld.length; i++) {
|
||||
ld[i].search(bases[i], ld[i].SCOPE_SUB,
|
||||
MY_FILTER, null, false, l);
|
||||
}
|
||||
|
||||
/* Loop on results until finished */
|
||||
LDAPMessage msg;
|
||||
while ((msg = l.getResponse()) != null) {
|
||||
if (msg instanceof LDAPSearchResultReference) {
|
||||
; // Ignore referrals
|
||||
} else if (msg instanceof LDAPSearchResult) {
|
||||
LDAPEntry entry = ((LDAPSearchResult)msg).getEntry();
|
||||
System.out.println("Found entry: " + entry.getDN());
|
||||
} else if (msg instanceof LDAPResponse) {
|
||||
int result = ((LDAPResponse)msg).getResultCode();
|
||||
if (result != 0) {
|
||||
System.out.println("Result code: " + result);
|
||||
System.out.println("Error message: " +
|
||||
((LDAPResponse)msg).getErrorMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < ld.length; i++) {
|
||||
ld[i].disconnect();
|
||||
}
|
||||
} catch (LDAPException e) {
|
||||
System.err.println(e.toString());
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</example>
|
||||
</task>
|
||||
<task id="async-search-mult-suffixes"><title>To Search Across Multiple Suffixes
|
||||
on a Single Server</title>
|
||||
<indexterm>
|
||||
<primary>asynchronous interface</primary>
|
||||
<secondary>search multiple suffixes</secondary>
|
||||
</indexterm>
|
||||
<tasksummary>
|
||||
<para>To search on more than one suffix, perform the following steps.</para>
|
||||
</tasksummary>
|
||||
<procedure>
|
||||
<step><para>Connect to the server.</para></step>
|
||||
<step><para>Create a response listener for one search.</para></step>
|
||||
<step><para>Share (multiplex) the response listener with the other searches.</para>
|
||||
</step>
|
||||
<step><para>Obtain and process the results.</para></step>
|
||||
<step><para>Disconnect from the server.</para></step>
|
||||
</procedure>
|
||||
<example id="async-search-mult-suffixes-example">
|
||||
<title>Searching Across Multiple Suffixes</title>
|
||||
<para>This example demonstrates how to search across two suffixes at the same
|
||||
time.</para>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
|
||||
public class MultiplexSuffixes {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
UserArgs userArgs =
|
||||
new UserArgs("MultipleSuffixes", args, false);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
|
||||
String[] bases = {"dc=example,dc=com",
|
||||
"ou=groups,dc=example,dc=com"};
|
||||
String MY_FILTER = "(objectclass=*)";
|
||||
|
||||
/* Get a response listener for one search */
|
||||
LDAPSearchListener l = ld.search(bases[0], ld.SCOPE_ONE,
|
||||
MY_FILTER, null, false, (LDAPSearchListener)null);
|
||||
/* Share the listener */
|
||||
for (int i = 1; i < bases.length; i++) {
|
||||
ld.search(bases[i], ld.SCOPE_ONE,
|
||||
MY_FILTER, null, false, l);
|
||||
}
|
||||
|
||||
/* Loop on results until finished */
|
||||
LDAPMessage msg;
|
||||
while ((msg = l.getResponse()) != null) {
|
||||
if (msg instanceof LDAPSearchResultReference) {
|
||||
; // Ignore referrals
|
||||
} else if (msg instanceof LDAPSearchResult) {
|
||||
LDAPEntry entry = ((LDAPSearchResult)msg).getEntry();
|
||||
System.out.println("Found entry: " + entry.getDN());
|
||||
} else if (msg instanceof LDAPResponse) {
|
||||
int result = ((LDAPResponse)msg).getResultCode();
|
||||
if (result != 0) {
|
||||
System.out.println("Result code: " + result);
|
||||
System.out.println("Error message: " +
|
||||
((LDAPResponse)msg).getErrorMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
ld.disconnect();
|
||||
} catch (LDAPException e) {
|
||||
System.err.println(e.toString());
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</example>
|
||||
</task>
|
||||
</sect1>
|
||||
<sect1 id="async-further"><title>Further Reading About the Asynchronous Interface
|
||||
for Directory SDK for Java</title>
|
||||
<para>The asynchronous interface is defined in an Internet Draft, <citetitle>The
|
||||
Java LDAP Application Programming Interface</citetitle>.</para></sect1>
|
||||
</chapter>
|
||||
617
mozilla/directory/docs/ldapjdk/jdk-common-classes.sgm
Normal file
617
mozilla/directory/docs/ldapjdk/jdk-common-classes.sgm
Normal file
@@ -0,0 +1,617 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="common-classes"><title>Using the LDAP Java Classes</title>
|
||||
<highlights>
|
||||
<para>This chapter covers general LDAP Java classes that are commonly used
|
||||
when writing LDAP clients.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="jdk-info">Getting Information About Directory
|
||||
SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="handling-exceptions">Handling Exceptions
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="handling-referrals">Handling Referrals With
|
||||
Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="in-memory-cache">Using In-Memory Cache With
|
||||
Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="cloning-connection">Cloning a Connection
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="handling-dns">Manipulating Distinguished
|
||||
Names With Directory SDK for Java</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="jdk-info"><title>Getting Information About &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>&DirectorySDKForJava;</primary>
|
||||
<secondary>getting information about</secondary>
|
||||
</indexterm>
|
||||
<para>You can get information about the version of &DirectorySDKForJava; that
|
||||
you are using. Version information tells you the version of the LDAP Java
|
||||
classes. Version information can also tell you the highest version of the
|
||||
LDAP protocol that &DirectorySDKForJava; supports.</para>
|
||||
<para>To get this information, use the <literal>getProperty</literal> method
|
||||
of the <classname>LDAPConnection</classname> object.</para>
|
||||
<programlisting>LDAPConnection ld = new LDAPConnection();
|
||||
try {
|
||||
System.out.println("LDAP Java Classes Version: " +
|
||||
(Float) ld.getProperty(LDAPConnection.LDAP_PROPERTY_SDK));
|
||||
System.out.println("Highest version of LDAP supported: " +
|
||||
(Float) ld.getProperty(LDAPConnection.LDAP_PROPERTY_PROTOCOL));
|
||||
System.out.println("Authentication methods supported: " +
|
||||
(String) ld.getProperty(LDAPConnection.LDAP_PROPERTY_SECURITY));
|
||||
} catch (LDAPException e) {
|
||||
System.out.println("Could not get SDK properties.");
|
||||
System.out.println("Error: " + e.toString());
|
||||
}</programlisting>
|
||||
<para>Although a <literal>setProperty</literal> method is provided, currently
|
||||
no properties exist that you can set. If you invoke the <literal>setProperty</literal> method,
|
||||
the method returns an <classname>LDAPException</classname>.</para></sect1>
|
||||
<sect1 id="handling-exceptions"><title>Handling Exceptions With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>exceptions</primary>
|
||||
<secondary>handling</secondary>
|
||||
</indexterm>
|
||||
<para>In LDAP, the success or failure of an operation is specified by an LDAP
|
||||
result code sent back to the client. For example, the result code <returnvalue>0</returnvalue> indicates
|
||||
that the operation was successful. A non zero result code usually indicates
|
||||
that an error occurred.</para>
|
||||
<sect2 id="getting-info"><title>Getting Information About the Error</title>
|
||||
<indexterm>
|
||||
<primary>exceptions</primary>
|
||||
<secondary>getting information about</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP result code</primary>
|
||||
</indexterm>
|
||||
<para>In the LDAP Java classes, when an error occurs, an <classname>LDAPException
|
||||
</classname> is returned. Referrals cause an <classname>LDAPReferralException</classname> to
|
||||
be returned as described in <olink targetptr="handling-referrals">Handling
|
||||
Referrals With Directory SDK for Java</olink>.</para>
|
||||
<itemizedlist>
|
||||
<para>An <classname>LDAPException</classname> contains the following information:
|
||||
</para>
|
||||
<listitem><para>The LDAP result code for the error that occurred</para>
|
||||
</listitem>
|
||||
<listitem><para>A message that contains any additional information about the
|
||||
error from the server</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>An error can occur when an entry specified by a DN cannot be found.
|
||||
The <classname>LDAPException</classname> then also contains the DN of the <firstterm>
|
||||
closest matching entry</firstterm> that can be found.</para>
|
||||
<itemizedlist>
|
||||
<para>To get information from the <classname>LDAPException</classname>, use
|
||||
one of the following methods:</para>
|
||||
<listitem><para>To get the string representation of the exception, use the <literal>
|
||||
toString</literal> method.</para></listitem>
|
||||
<listitem><para>To get the LDAP result code, use the <literal>getLDAPResultCode</literal> method.
|
||||
</para></listitem>
|
||||
<listitem><para>To get any additional information sent by the server, use
|
||||
the <literal>getLDAPErrorMessage</literal> method.</para></listitem>
|
||||
<listitem><para>To get the closest matching DN in cases where your client
|
||||
specified a DN to a nonexistent entry, use the <literal>getMatchedDN</literal> method.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>To get the error message describing the LDAP result code, use the <literal>
|
||||
errorCodeToString</literal> method, as described in <olink
|
||||
targetptr="error-message">Getting the Error Message</olink>.</para>
|
||||
<para>The following section of code gets and prints information about an <classname>
|
||||
LDAPException</classname>.</para>
|
||||
<programlisting>try {
|
||||
/* Attempt to perform an LDAP operation here. */
|
||||
} catch (LDAPException e) {
|
||||
/* Get and print the result code and any other info. */
|
||||
int resultCode = e.getLDAPResultCode();
|
||||
String serverInfo = e.getLDAPErrorMessage();
|
||||
System.out.println("LDAP Result Code: " + resultCode);
|
||||
if (serverInfo != null) {
|
||||
System.out.println("Additional Info: " + serverInfo);
|
||||
}
|
||||
/*
|
||||
* If the exception was returned because an entry was
|
||||
* not found, print the DN of the closest entry found.
|
||||
*/
|
||||
switch (resultCode) {
|
||||
case LDAPException.NO_SUCH_OBJECT:
|
||||
case LDAPException.ALIAS_PROBLEM:
|
||||
case LDAPException.INVALID_DN_SYNTAX:
|
||||
case LDAPException.ALIAS_DEREFERENCING_PROBLEM:
|
||||
String matchedDN = e.getMatchedDN();
|
||||
if (matchedDN != null) {
|
||||
System.out.println("Closest Entry: " + matchedDN);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="error-message"><title>Getting the Error Message</title>
|
||||
<indexterm>
|
||||
<primary>LDAP result code</primary>
|
||||
<secondary>string description for</secondary>
|
||||
</indexterm>
|
||||
<para>To get the error message for an LDAP result code, use the <literal>errorCodeToString
|
||||
</literal> method.</para>
|
||||
<programlisting>try {
|
||||
/* Attempt to perform an LDAP operation here. */
|
||||
} catch (LDAPException e) {
|
||||
/* Get and print the error message. */
|
||||
int resultCode = e.getLDAPResultCode();
|
||||
System.out.println("Error: " + e.errorCodeToString(resultCode));
|
||||
}</programlisting>
|
||||
<para>Error messages corresponding to each LDAP result code are located either
|
||||
inside the <filename>ldapjdk.jar</filename> file or under another directory
|
||||
in your <envar>CLASSPATH</envar>, in a properties file named <filename>netscape/ldap/errors/ErrorCodes.props
|
||||
</filename> or <filename>netscape/ldap/errors/ErrorCodes_<replaceable>locale</replaceable>.props
|
||||
</filename>. <replaceable>locale</replaceable> can be a two-letter version
|
||||
of the locale, such as <literal>de</literal>, <literal>fr</literal>, or <literal>
|
||||
ja</literal>, or it can be a full version of the locale, such as <literal>en_US</literal>.
|
||||
</para>
|
||||
<para>When you invoke the <literal>errorCodeToString</literal> method of an <classname>
|
||||
LDAPException</classname>, the method retrieves the error message string for
|
||||
the specified locale. If no locale is specified, the method retrieves the
|
||||
default locale from the properties file. The <literal>errorCodeToString</literal> method
|
||||
looks for locale-specific properties files in the following order, retrieving
|
||||
the first property that is found:</para>
|
||||
<programlisting>netscape/ldap/error/ErrorCodes_<replaceable>language</replaceable>_<replaceable>
|
||||
country</replaceable>.props
|
||||
netscape/ldap/error/ErrorCodes_<replaceable>language</replaceable>.props
|
||||
netscape/ldap/error/ErrorCodes.props</programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="handling-referrals"><title>Handling Referrals With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>referrals</primary>
|
||||
</indexterm>
|
||||
<para>An LDAP server can receive a request for a DN that is not under its
|
||||
directory tree. The server can then refer clients to another LDAP server that
|
||||
might contain that DN. The response is known as a <firstterm>referral</firstterm>.
|
||||
This section explains how to set up your LDAP client to handle referrals automatically.
|
||||
</para>
|
||||
<sect2 id="understanding-referrals"><title>Understanding Referrals</title>
|
||||
<itemizedlist>
|
||||
<para>Suppose an LDAP server has a directory that starts under <literal>dc=example,dc=com
|
||||
</literal>. Your client might send the server a request to modify the entry
|
||||
with the DN <literal>uid=bjensen,ou=People,o=example.com</literal>. The entry
|
||||
is not under <literal>dc=example,dc=com</literal>. One of the following can
|
||||
occur.</para>
|
||||
<listitem><para>If the server is not configured to send a referral, an <classname>
|
||||
LDAPException</classname> is returned with the LDAP result code <constant>LDAPException.NO_SUCH_OBJECT
|
||||
</constant>.</para></listitem>
|
||||
<listitem><para>If the server is configured to refer you to another LDAP server,
|
||||
the server sends a referral back to your client.</para>
|
||||
<itemizedlist>
|
||||
<para>Depending on how your LDAP client is configured, one of the following
|
||||
can occur:</para>
|
||||
<listitem><para>If your client handles referrals automatically, your client
|
||||
connects to the LDAP server specified in the referral and requests to modify
|
||||
the entry. The client binds anonymously to that server. To bind as a specific
|
||||
user, refer to <olink targetptr="enabling-referrals">Enabling or Disabling
|
||||
Referral Handling</olink>.</para></listitem>
|
||||
<listitem><para>If your client does not handle referrals automatically, an <classname>
|
||||
LDAPReferralException</classname> is returned. You can get the LDAP URL specified
|
||||
in the referral by catching the exception, and then invoking the <literal>getURLs
|
||||
</literal> method.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>By default, clients built with &DirectorySDKForJava; are configured
|
||||
to follow referrals automatically.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>Another concept that is similar to a referral is a search reference.
|
||||
A <firstterm>search reference</firstterm> is an entry with the object class <literal>
|
||||
referral</literal>. The <literal>ref</literal> attribute of this object contains
|
||||
an LDAP URL that points to another LDAP server.</para>
|
||||
<para>When your client searches a subtree of the directory that contains search
|
||||
references, the server returns a mix of matching entries and search references.
|
||||
As you iterate through the enumeration of search results, you can encounter
|
||||
a search reference although your client does not handle referrals automatically.
|
||||
An <classname>LDAPReferralException</classname> is then returned.</para></sect2>
|
||||
<sect2 id="enabling-referrals"><title>Enabling or Disabling Referral Handling</title>
|
||||
<indexterm>
|
||||
<primary>referrals</primary>
|
||||
<secondary>handling automatically</secondary>
|
||||
</indexterm>
|
||||
<para>By default, clients built with &DirectorySDKForJava; automatically
|
||||
follow referrals to other servers.</para>
|
||||
<itemizedlist>
|
||||
<para>To change the way your client handles referrals, use one of two methods.
|
||||
Use the <literal>setOption</literal> method of the <classname>LDAPConnection</classname> object
|
||||
to change the behavior for all LDAP operations. Alternatively, use the <literal>setReferrals
|
||||
</literal> method of the <classname>LDAPConstraints</classname> object to
|
||||
change the behavior for a specific search request.</para>
|
||||
<listitem><para>To prevent the client from automatically following referrals,
|
||||
pass <literal>LDAPv3.REFERRALS</literal> and <literal>false</literal> as arguments
|
||||
to the <literal>setOption</literal> method. Alternatively, pass <literal>false</literal> as
|
||||
the argument to the <literal>setReferrals</literal> method.</para></listitem>
|
||||
<listitem><para>To enable the client to follow referrals automatically again,
|
||||
pass <literal>LDAPv3.REFERRALS</literal> and <literal>true</literal> as arguments
|
||||
to the <literal>setOption</literal> method. Alternatively, pass <literal>true</literal> as
|
||||
the argument to the <literal>setReferrals</literal> method.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<sect2 id="limiting-referral-hops"><title>Limiting Referral Hops</title>
|
||||
<indexterm>
|
||||
<primary>referrals</primary>
|
||||
<secondary>specifying maximum hops</secondary>
|
||||
</indexterm>
|
||||
<para>You can specify the maximum number of referral hops that should be followed
|
||||
in a sequence of referrals. You can set the preference for the connection.
|
||||
You can also set the maximum as a constraint for specific search operations.
|
||||
The maximum is called the <firstterm>referral hop limit</firstterm>.</para>
|
||||
<para>For example, suppose you set a limit of two referral hops. If LDAP server
|
||||
A refers to server B, B to C, and C to D, your client is being referred three
|
||||
times in a row. Your client does not follow the referral to LDAP server D
|
||||
because this referral exceeds the referral hop limit.</para>
|
||||
<para>If the referral hop limit is exceeded, an <classname>LDAPReferralException</classname> is
|
||||
returned.</para>
|
||||
<para>To set the referral hop limit, use either of two methods. Use the <literal>
|
||||
LDAPv3.REFERRALS_HOP_LIMIT</literal> preference with the <literal>setOption</literal> method
|
||||
of the <classname>LDAPConnection</classname> object to change the behavior
|
||||
for all LDAP operations. Alternatively, use the <literal>setHopLimit</literal> method
|
||||
of the <classname>LDAPConstraints</classname> object to change the behavior
|
||||
for a specific search request.</para>
|
||||
<para>By default, the maximum number of referral hops is 10.</para></sect2>
|
||||
<sect2 id="referral-bind"><title>Binding When Following Referrals</title>
|
||||
<indexterm>
|
||||
<primary>authentication</primary>
|
||||
<secondary>authenticating during referrals</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>referrals</primary>
|
||||
<secondary>authenticating</secondary>
|
||||
</indexterm>
|
||||
<para>If the connection is set up so that referrals are always followed, the
|
||||
LDAP server that you connect to can refer you to another server. By default,
|
||||
the client binds anonymously such that no user names or passwords are specified
|
||||
when following referrals.</para>
|
||||
<para>To authenticate to the LDAP server that you are referred to, specify
|
||||
how to get the DN and password for authentication. You need to define a class
|
||||
that implements the <classname>LDAPRebind</classname> interface. Then, specify
|
||||
an object of this new class with either of two methods. Use the <literal>LDAPv3.REFERRALS_REBIND_PROC
|
||||
</literal> preference with the <literal>setOption</literal> method of the <classname>
|
||||
LDAPConnection</classname> object to set the preference for all LDAP operations.
|
||||
Alternatively, use the <literal>setRebindProc</literal> method of the <classname>
|
||||
LDAPConstraints</classname> object to change the behavior for a specific search
|
||||
request.</para>
|
||||
<para>The <classname>LDAPRebind</classname> interface specifies a <literal>getRebindAuthentication
|
||||
</literal> method that returns an <classname>LDAPRebindAuth</classname> object.
|
||||
The <literal>getRebindAuthentication</literal> method and the <classname>LDAPRebindAuth
|
||||
</classname> object that the method returns are used to get the DN and password
|
||||
for authentication.</para>
|
||||
<orderedlist>
|
||||
<para>The following steps explain how this works.</para>
|
||||
<listitem><para>The LDAP server sends a referral back to the client. The referral
|
||||
contains an LDAP URL that points to another LDAP server.</para></listitem>
|
||||
<listitem><para>The client creates a new <classname>LDAPConnection</classname> object.
|
||||
</para></listitem>
|
||||
<listitem><para>The client connects to the host and port specified in the
|
||||
LDAP URL.</para></listitem>
|
||||
<listitem><para>You can use the <literal>getRebindProc</literal> method to
|
||||
find your object, the object that implements the <classname>LDAPRebind</classname> interface.
|
||||
The client then invokes the <literal>getRebindAuthentication</literal> method,
|
||||
passing in the host and port specified in the LDAP URL.</para></listitem>
|
||||
<listitem><para>The <literal>getRebindAuthentication</literal> method in your
|
||||
object returns an <classname>LDAPRebindAuth</classname> object.</para>
|
||||
</listitem>
|
||||
<listitem><para>The client invokes the <literal>getDN</literal> and <literal>getPassword
|
||||
</literal> methods of the returned <classname>LDAPRebindAuth</classname> object
|
||||
to get the DN and password to use for authentication.</para></listitem>
|
||||
<listitem><para>The client invokes the authenticate method of the <classname>LDAPConnection
|
||||
</classname> object and passes the DN and password to authenticate to the
|
||||
server.</para></listitem>
|
||||
</orderedlist>
|
||||
<itemizedlist>
|
||||
<para>Basically, you need to define the following:</para>
|
||||
<listitem><para>A class that implements the <classname>LDAPRebind</classname> interface
|
||||
</para></listitem>
|
||||
<listitem><para>A <literal>getRebindAuthentication</literal> that takes a
|
||||
host name and port number. </para></listitem>
|
||||
<listitem><para>This method creates an <classname>LDAPRebindAuth</classname> object
|
||||
that specifies the DN and password to use for authentication.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="in-memory-cache"><title>Using In-Memory Cache With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>cache</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>in-memory cache</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>connection</primary>
|
||||
<secondary>caching results</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP session</primary>
|
||||
<secondary>caching results</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>search results</primary>
|
||||
<secondary>caching</secondary>
|
||||
</indexterm>
|
||||
<para>&DirectorySDKForJava; includes an <classname>LDAPCache</classname> class
|
||||
that allows you to create an in-memory cache of search results for your client.
|
||||
When you send a search request, you receive results. The search request and
|
||||
its results are then cached. The next time your client issues the same search
|
||||
request, the results are read from the cache.</para>
|
||||
<sect2 id="understanding-cache"><title>How the Cache Operates</title>
|
||||
<itemizedlist>
|
||||
<para>Each item in the cache represents a search request and its results.
|
||||
When you create the cache, you can specify the maximum size of the cache.
|
||||
You can also specify the maximum amount of time that an item can be cached.</para>
|
||||
<listitem><para>When an item's age exceeds that time limit, the item is removed
|
||||
from the cache. The cache is checked once a minute for expired items.</para>
|
||||
</listitem>
|
||||
<listitem><para>If adding a new item causes the cache to exceed its maximum
|
||||
size, items are removed from the cache. Removal makes space for the new item.
|
||||
Items are removed on a first in, first out basis.</para></listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<para>Each item is uniquely identified by the search criteria, which includes
|
||||
the following:</para>
|
||||
<listitem><para>Host name and port number of the LDAP server</para></listitem>
|
||||
<listitem><para>Base DN of the search</para></listitem>
|
||||
<listitem><para>Search filter</para></listitem>
|
||||
<listitem><para>Scope of the search</para></listitem>
|
||||
<listitem><para>Attributes to be returned in the search results</para>
|
||||
</listitem>
|
||||
<listitem><para>DN used to authenticate the client when binding to the server</para>
|
||||
</listitem>
|
||||
<listitem><para>LDAP v3 controls specified in the search request</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>After a search request is cached, if your client performs the same search
|
||||
again, the results are read from the cache instead of from the server.</para>
|
||||
<para>Note that if any part of a search request differs from a cached search
|
||||
request, the results are read from the server. For example, a different DN
|
||||
might be used when authenticating to the server. Alternatively, the search
|
||||
request might specify that a different set of attributes should be returned.
|
||||
In either case, the results are not read from the cache. Instead, the search
|
||||
request is sent to the server.</para>
|
||||
<para>Finally, when creating the cache, you can specify a list of the base
|
||||
DNs in search requests that you want to cache. For example, if you specify <literal>
|
||||
ou=People,dc=example,dc=com</literal> as a base DN to cache, your client caches
|
||||
search requests where the base DN is <literal>ou=People,dc=example,dc=com</literal>.
|
||||
</para></sect2>
|
||||
<sect2 id="cache-setup"><title>Setting Up an In-Memory Cache</title>
|
||||
<indexterm>
|
||||
<primary>cache</primary>
|
||||
<secondary>setting up</secondary>
|
||||
</indexterm>
|
||||
<orderedlist>
|
||||
<para>To set up a cache for your connection, do the following:</para>
|
||||
<listitem><para>Construct a new <classname>LDAPCache</classname> object that
|
||||
represents the cache.</para></listitem>
|
||||
<listitem><para>Invoke the <literal>setCache</literal> method of an <classname>LDAPConnection
|
||||
</classname> object to associate the cache with the connection.</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>For example, the following section of code creates a cache with the
|
||||
maximum size of 1 Mbyte. Items in the cache expire and are automatically removed
|
||||
after one hour.</para>
|
||||
<programlisting>try {
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
|
||||
/* Create a cache for the connection */
|
||||
int MAX_TIME_CACHED = 3600; // 3600 seconds == 1 hour
|
||||
int MAX_SIZE = 1000000; // 1000000 bytes == 1 MB
|
||||
LDAPCache myCache = new LDAPCache(MAX_TIME_CACHED, MAX_SIZE);
|
||||
ld.setCache(myCache);
|
||||
|
||||
/* Connect to server */
|
||||
ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
|
||||
|
||||
/*
|
||||
* Perform operations...
|
||||
*/
|
||||
} catch (LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="caching-basedn"><title>Caching Requests by Base DN</title>
|
||||
<para>If you do not want all search requests cached, specify an array of base
|
||||
DNs for search requests to cache in the <classname>LDAPCache</classname> constructor.
|
||||
</para>
|
||||
<para>For example, the following section of code constructs a cache that only
|
||||
tracks search requests that specify the base DNs <literal>ou=People,dc=example,dc=com
|
||||
</literal> and <literal>ou=Groups,dc=example,dc=com</literal>.</para>
|
||||
<programlisting>/* Create a cache for the connection */
|
||||
int MAX_TIME_CACHED = 3600;
|
||||
int MAX_SIZE = 1000000;
|
||||
String [] BASE_DN_CACHED = {"ou=People,dc=example,dc=com",
|
||||
"ou=Groups,dc=example,dc=com"};
|
||||
LDAPCache myCache = new LDAPCache(MAX_TIME_CACHED, MAX_SIZE,
|
||||
BASE_DN_CACHED);</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="sharing-cache"><title>Sharing a Cache Among Connections</title>
|
||||
<indexterm>
|
||||
<primary>cache</primary>
|
||||
<secondary>sharing between connections</secondary>
|
||||
</indexterm>
|
||||
<para>You can also share the same in-memory cache among different connections.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Invoke the <literal>getCache</literal> method of an <classname>LDAPConnection
|
||||
</classname> object to get the <classname>LDAPCache</classname> object that
|
||||
is used.</para></listitem>
|
||||
<listitem><para>Invoke the <literal>setCache</literal> method of a different <classname>
|
||||
LDAPConnection</classname> object to associate the retrieved <classname>LDAPCache
|
||||
</classname> object with the connection.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>When you clone an <classname>LDAPConnection</classname> object, the
|
||||
new object automatically shares the same <classname>LDAPCache</classname> object
|
||||
with the original object.</para></sect2>
|
||||
<sect2 id="flushing-cache"><title>Flushing the Cache</title>
|
||||
<indexterm>
|
||||
<primary>cache</primary>
|
||||
<secondary>flushing</secondary>
|
||||
</indexterm>
|
||||
<para>To flush items from the cache, invoke the <literal>flushEntries</literal> method
|
||||
of the <classname>LDAPCache</classname> object. You can flush either selected
|
||||
items or all items from the cache.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>To flush selected items from the cache, specify the base DN
|
||||
of the search requests that you want to flush. Specify a DN and search scope
|
||||
as arguments to the <literal>flushEntries</literal> method. If the base DN
|
||||
of a cached search request falls within the scope you specified, the search
|
||||
request is flushed from the cache.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>For example, the following section of code flushes selected search requests
|
||||
from the cache. If the base DN of a search request falls under the <literal>ou=People,dc=example,dc=com
|
||||
</literal> subtree, the item is removed from the cache.</para>
|
||||
<programlisting>LDAPCache myCache;
|
||||
|
||||
/* Perform search requests... */
|
||||
|
||||
/*
|
||||
* Flush search requests with base DNs under
|
||||
* ou=People,dc=example,dc=com.
|
||||
*/
|
||||
myCache.flushEntries("ou=People,dc=example,dc=com",
|
||||
LDAPConnection.SCOPE_SUB);</programlisting>
|
||||
<itemizedlist>
|
||||
<listitem><para>To flush all items from the cache, pass <literal>null</literal> as
|
||||
the first argument of the <literal>flushEntries</literal> method:</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<programlisting>myCache.flushEntries(null, 0);</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="cache-stats"><title>Getting Cache Statistics</title>
|
||||
<indexterm>
|
||||
<primary>cache</primary>
|
||||
<secondary>getting statistics</secondary>
|
||||
</indexterm>
|
||||
<itemizedlist>
|
||||
<para>You can invoke the following methods of the <classname>LDAPCache</classname> object
|
||||
to get statistics on the cache.</para>
|
||||
<listitem><para>To get the total amount of available space in bytes that are
|
||||
left in the cache, invoke the <literal>getAvailableSize</literal> method.</para>
|
||||
</listitem>
|
||||
<listitem><para>To get the array of base DNs of the search requests to be
|
||||
cached, invoke the <literal>getBaseDNs</literal> method.</para></listitem>
|
||||
<listitem><para>To get the total number of items that have been flushed from
|
||||
the cache, not including items flushed when invoking the <literal>flushEntries</literal> method,
|
||||
invoke the <literal>getNumFlushes</literal> method.</para></listitem>
|
||||
<listitem><para>To get the maximum size of the cache in bytes, invoke the <literal>
|
||||
getSize</literal> method.</para></listitem>
|
||||
<listitem><para>To get the maximum amount of time that an item can be cached
|
||||
in seconds, get the <literal>getTimeToLive</literal> method.</para></listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<para>You can also get a running count of the number of requests that access
|
||||
the cache.</para>
|
||||
<listitem><para>To get the total number of requests for retrieving items from
|
||||
the cache, invoke the <literal>getTotalOperation</literal> method.</para>
|
||||
</listitem>
|
||||
<listitem><para>To get the total number of requests that retrieved an item
|
||||
from the cache, invoke the <literal>getNumHits</literal> method.</para>
|
||||
</listitem>
|
||||
<listitem><para>To get the total number of requests that failed to find and
|
||||
retrieve an item from the cache, invoke the <literal>getNumMisses</literal> method.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>For example, the following section of code gets and prints cache statistics.
|
||||
</para>
|
||||
<programlisting>LDAPConnection ld;
|
||||
|
||||
if ((ld != null) && ld.isConnected()) {
|
||||
LDAPCache connCache = ld.getCache();
|
||||
if (connCache != null) {
|
||||
System.out.println("Cache size:\t\t" +
|
||||
connCache.getSize()/1000 + " kbytes");
|
||||
System.out.println("Available:\t\t" +
|
||||
connCache.getAvailableSize()/1000 + " kbytes");
|
||||
System.out.println( "Maximum age:\t\t" +
|
||||
connCache.getTimeToLive()/1000 + " seconds");
|
||||
System.out.println("Total hits:\t\t" +
|
||||
connCache.getNumHits() + " hits" );
|
||||
System.out.println("Total misses:\t\t" +
|
||||
connCache.getNumMisses() + " misses" );
|
||||
System.out.println("Total requests:\t\t" +
|
||||
connCache.getTotalOperations() + " requests");
|
||||
} else {
|
||||
System.out.println(
|
||||
"No cache associated with the connection.");
|
||||
}
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="cloning-connection"><title>Cloning a Connection With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>connection</primary>
|
||||
<secondary>cloning</secondary>
|
||||
</indexterm>
|
||||
<para>You can create several <classname>LDAPConnection</classname> objects
|
||||
that share a single physical network connection to the LDAP server by invoking
|
||||
the <literal>LDAPConnection.clone</literal> method.</para>
|
||||
<itemizedlist>
|
||||
<para>Clones have the following properties:</para>
|
||||
<listitem><para>If you clone an object before a connection is made to the
|
||||
server, the cloned object does not share the same connection as the original
|
||||
object.</para></listitem>
|
||||
<listitem><para>Each clone can disconnect from the server without affecting
|
||||
the connection for the other clones. The network connection remains in an
|
||||
open state until all clones have either disconnected or gone out of scope.</para>
|
||||
</listitem>
|
||||
<listitem><para>If the clone disconnects or reconnects, the clone is completely
|
||||
dissociated from the source object and other clones.</para></listitem>
|
||||
<listitem><para>A cloned <classname>LDAPConnection</classname> object has
|
||||
a separate set of session preferences and constraints. In other words, the
|
||||
clone is associated with its own <classname>LDAPSearchConstraints</classname> object.
|
||||
Changes to an option or to a search constraint only affect requests issued
|
||||
using that object.</para><para>For example, suppose an <classname>LDAPConnection</classname> object
|
||||
allows a maximum of 100 results to be returned from a search. If you clone
|
||||
an <classname>LDAPConnection</classname> object, you can change the maximum
|
||||
number of results in the clone from 100 to 200. Yet, the initial object still
|
||||
allows only 100 results to be returned.</para></listitem>
|
||||
<listitem><para>All clones are authenticated to the server as the same user.
|
||||
If you authenticate again to the server as a different user, the current clone
|
||||
is disconnected. The clone connects separately to the server. The <classname>LDAPConnection
|
||||
</classname> object is no longer a clone of another <classname>LDAPConnection</classname> object.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="handling-dns"><title>Manipulating Distinguished Names With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>distinguished names</primary>
|
||||
<secondary>manipulating</secondary>
|
||||
</indexterm>
|
||||
<para>A distinguished name (DN) uniquely identifies an entry in the directory
|
||||
tree. You can get the DN for an entry as explained in <olink
|
||||
type="auto-generated" targetptr="searching-results-dns">Getting Distinguished
|
||||
Names</olink>. Alternatively, you can specify a DN to read an entry from the
|
||||
directory as explained in <olink type="auto-generated" targetptr="searching-read">
|
||||
Reading an Entry With Directory SDK for Java</olink>. &DirectorySDKForJava; includes
|
||||
a utility class, <classname>LDAPDN</classname>, that provides
|
||||
methods for manipulating DNs.</para>
|
||||
<para>If you want to access individual components of a distinguished name
|
||||
or a relative distinguished name, invoke the <literal>LDAPDN.explodeDN</literal> method
|
||||
or the <literal>LDAPDN.explodeRDN</literal> method.</para>
|
||||
<para>Both methods return an array of <classname>String</classname> objects
|
||||
that represent the individual components of the distinguished name.</para>
|
||||
<para>You can specify whether or not you want the names of the components
|
||||
included in the array by using the <parameter>notypes</parameter> parameter.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Set <parameter>notypes</parameter> to <literal>false</literal> if
|
||||
you want to include component attribute types in the array.</para>
|
||||
<programlisting>LDAPDN.explodeDN("uid=bjensen,ou=People,dc=example,dc=com", false);
|
||||
</programlisting>
|
||||
<para>The method returns the array <literal>{"uid=bjensen", "ou=People", "dc=example",
|
||||
"dc=com"}</literal>.</para></listitem>
|
||||
<listitem><para>Set <parameter>notypes</parameter> to <literal>true</literal> if
|
||||
you do not want component attribute types returned in the array.</para>
|
||||
<programlisting>LDAPDN.explodeDN("uid=bjensen,ou=People,dc=example,dc=com", true);
|
||||
</programlisting>
|
||||
<para>The method returns the array <literal>{"bjensen", "People", "example",
|
||||
"com"}</literal>.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
</chapter>
|
||||
123
mozilla/directory/docs/ldapjdk/jdk-comparing.sgm
Normal file
123
mozilla/directory/docs/ldapjdk/jdk-comparing.sgm
Normal file
@@ -0,0 +1,123 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="comparing"><title>Comparing Attribute Values With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>attributes</primary>
|
||||
<secondary>comparing values</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>comparing attribute values</primary>
|
||||
</indexterm><highlights>
|
||||
<para>This chapter explains how to compare the value of an attribute in an
|
||||
entry against a specified value.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="compare-specify-attr-value">Specifying the
|
||||
Attribute and Value With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="compare-perform">Performing the Comparison
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="compare-example">Example Attribute Value
|
||||
Comparison With Directory SDK for Java</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
<para>The LDAP Java classes allow you to compare a specified value against
|
||||
the value of an entry in the directory. For example, you can check to see
|
||||
if the <literal>mail</literal> attribute of an entry contains the value <literal>
|
||||
bjensen@example.com</literal>.</para>
|
||||
<orderedlist>
|
||||
<para>To compare a specified value against an attribute of an entry in the
|
||||
directory, you need to follow this general procedure.</para>
|
||||
<listitem><para>Specify the name of the attribute that you want to check and
|
||||
the value that you want to use for comparison.</para></listitem>
|
||||
<listitem><para>Use the distinguished name of the entry to find the entry
|
||||
in the directory. The entry that is found is then used to perform the comparison.
|
||||
</para></listitem></orderedlist>
|
||||
</highlights>
|
||||
<sect1 id="compare-specify-attr-value"><title>Specifying the Attribute and
|
||||
Value With &DirectorySDKForJava;</title>
|
||||
<para>Use an <classname>LDAPAttribute</classname> object to specify the name
|
||||
of the attribute to check. Also use the object to specify the value to use
|
||||
in the comparison.</para>
|
||||
<programlisting>LDAPAttribute attr = new LDAPAttribute("mail", "bjensen@example.com");
|
||||
</programlisting>
|
||||
</sect1>
|
||||
<sect1 id="compare-perform"><title>Performing the Comparison With &DirectorySDKForJava;</title>
|
||||
<para>To perform the comparison, use the <literal>compare</literal> method
|
||||
of the <classname>LDAPConnection</classname> object. Specify the distinguished
|
||||
name of the entry that you want to compare. The method returns <literal>true</literal> if
|
||||
the attribute contains the specified value.</para>
|
||||
<programlisting>try {
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect("localhost", LDAPv3.DEFAULT_PORT);
|
||||
LDAPAttribute attr = new LDAPAttribute("mail", "bjensen@example.com");
|
||||
if (ld.compare("uid=bjensen,ou=People,dc=example,dc=com", attr)) {
|
||||
System.out.println("Found a match.");
|
||||
}
|
||||
} catch (LDAPException e) {
|
||||
System.err.println("Error:" + e.toString());
|
||||
}</programlisting>
|
||||
</sect1>
|
||||
<sect1 id="compare-example"><title>Example Attribute Value Comparison With &DirectorySDKForJava;</title>
|
||||
<para>The following example compares values for the <literal>objectclass</literal> attribute
|
||||
with values on Barbara Jensen's entry.</para>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
|
||||
public class Compare {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
UserArgs userArgs = new UserArgs("Compare", args, false);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
|
||||
/* Entry to compare */
|
||||
String ENTRYDN = "uid=bjensen,ou=People,dc=example,dc=com";
|
||||
|
||||
/* Compare the value "person" and the attr. "objectclass" */
|
||||
LDAPAttribute attr =
|
||||
new LDAPAttribute("objectclass", "person");
|
||||
boolean ok = ld.compare(ENTRYDN, attr);
|
||||
reportResults(ok, attr);
|
||||
|
||||
/* Compare the value "xyzzy" and the attr. objectclass */
|
||||
attr = new LDAPAttribute("objectclass", "xyzzy");
|
||||
ok = ld.compare(ENTRYDN, attr);
|
||||
reportResults(ok, attr);
|
||||
|
||||
ld.disconnect();
|
||||
} catch(LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private static void reportResults(boolean ok, LDAPAttribute attr) {
|
||||
String result;
|
||||
if (ok) {
|
||||
result = new String();
|
||||
} else {
|
||||
result = new String("not ");
|
||||
}
|
||||
Enumeration en = attr.getStringValues();
|
||||
if (en != null) {
|
||||
String val = (String)en.nextElement();
|
||||
System.out.println(
|
||||
"The value *" + val + "* is " + result +
|
||||
"contained in the " + attr.getName() + " attribute.");
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</sect1>
|
||||
</chapter>
|
||||
940
mozilla/directory/docs/ldapjdk/jdk-controls.sgm
Normal file
940
mozilla/directory/docs/ldapjdk/jdk-controls.sgm
Normal file
@@ -0,0 +1,940 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="controls"><title>LDAP Controls With &DirectorySDKForJava;</title>
|
||||
<highlights>
|
||||
<para>This chapter explains how LDAP controls work and how to use the LDAP
|
||||
controls.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="controls-overview">How LDAP Controls Work
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="controls-using">Using Controls in the LDAP
|
||||
Java Classes</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="controls-server">Determining the Controls Supported the Server With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="controls-sort">Using the Server-Side Sorting
|
||||
Control With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="controls-psearch">Using the Persistent Search
|
||||
Control With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="controls-entry-change">Using the Entry Change
|
||||
Notification Control With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="controls-vlv">Using the Virtual List Control With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="controls-managedsait">Using the Manage DSA
|
||||
IT Control With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="controls-pwp">Using Password Policy Controls
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="controls-proxyauth">Using the Proxied Authorization
|
||||
Control With Directory SDK for Java</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="controls-overview"><title>How LDAP Controls Work With &DirectorySDKForJava;</title>
|
||||
<para>LDAP v3 allows clients and servers to use controls as a mechanism for
|
||||
extending an LDAP operation. A control is a way to specify additional information
|
||||
as part of a request and a response.</para>
|
||||
<para>For example, a client can send a control to a server as part of a search
|
||||
request. The control indicates that the server should sort the search results
|
||||
before sending the results back to the client.</para>
|
||||
<para>Servers can also send controls back to clients. For example, the server
|
||||
can send a control back to a client during the authentication process. The
|
||||
control can indicate that the client password has expired. The control can
|
||||
alternatively indicate that the client password is going to expire.</para>
|
||||
<itemizedlist>
|
||||
<para>A control specifies the following information:</para>
|
||||
<listitem><para>A unique object identifier (OID)</para></listitem>
|
||||
<listitem><para>An indication of whether the control is critical to the operation
|
||||
</para></listitem>
|
||||
<listitem><para>Optional data related to the control, such as the server-side
|
||||
sorting control, where attributes used for sorting search results are needed</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>The OID identifies the control. If you plan to use a control, you need
|
||||
to make sure that the server supports the control. Refer to <olink targetptr="controls-server">Determining the Controls Supported the Server With Directory SDK for Java</olink> for instructions.</para>
|
||||
<itemizedlist>
|
||||
<para>When your client includes a control in a request for an LDAP operation,
|
||||
the server can respond in one of the following ways:</para>
|
||||
<listitem><para>If the server supports this control and if the control is
|
||||
appropriate, the server should use the control when performing the operation.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<itemizedlist>
|
||||
<para>If the server does not support the control type or if the control is
|
||||
not appropriate, the server should do one of the following:</para>
|
||||
<listitem><para>If the control is marked as critical to the operation, the
|
||||
server should not perform the operation. Instead, the server should send an <firstterm>
|
||||
unavailable critical extension</firstterm> result code. When receiving this
|
||||
result code, your client returns an <classname>LDAPException</classname> with
|
||||
the result code <returnvalue>LDAPException.UNAVAILABLE_CRITICAL_EXTENSION</returnvalue>.
|
||||
</para></listitem>
|
||||
<listitem><para>If the control is marked as not critical to the operation,
|
||||
the server should ignore the control. The server should proceed to perform
|
||||
the operation.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>Servers can also send controls back to clients.</para>
|
||||
<itemizedlist>
|
||||
<para>Two types of controls exist:</para>
|
||||
<listitem><para>Server controls can be included in requests sent by clients
|
||||
and in responses sent by servers.</para></listitem>
|
||||
<listitem><para>Client controls affect the behavior of the LDAP Java classes
|
||||
only and are never sent to the server.</para><para>&DirectorySDKForJava; does
|
||||
not support client controls.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="controls-using"><title>Using Controls in the LDAP Java Classes</title>
|
||||
<para>This section describes how controls are implemented in the LDAP Java
|
||||
classes. This section also describes which methods to use to create, send,
|
||||
and parse data from LDAP controls.</para>
|
||||
<para>In the LDAP Java classes, a control is represented by an object of the <classname>
|
||||
LDAPControl</classname> class.</para>
|
||||
<orderedlist>
|
||||
<para>To include a control in a request, do the following:</para>
|
||||
<listitem><para>Invoke the <literal>getSearchConstraints</literal> method
|
||||
of the <classname>LDAPConnection</classname> object to get a clone of <classname>
|
||||
LDAPSearchConstraints</classname> for this connection.</para></listitem>
|
||||
<listitem><para>Invoke the <literal>setServerControls</literal> method of
|
||||
the cloned constraints object, passing in the <classname>LDAPControl</classname> object
|
||||
that represents the control to include.</para></listitem>
|
||||
<listitem><para>Invoke the appropriate method to perform the LDAP operation,
|
||||
passing in the constraints object.</para><para>For example, if you are performing
|
||||
a search, invoke the <literal>search</literal> method. Pass the search constraints
|
||||
as an argument.</para></listitem></orderedlist>
|
||||
<para>You can also include controls by invoking the <literal>setServerControls</literal> method
|
||||
for the default set of search constraints. Alternatively, invoke the <literal>setOption
|
||||
</literal> method to set the <constant>LDAPv3.SERVERCONTROLS</constant> option.
|
||||
These controls are sent to the server with every request, however. In general,
|
||||
controls tend to be specific to a type of operation. Include a control in
|
||||
a request only for the operation to which the control applies.</para>
|
||||
<para>You can then retrieve data from the returned controls through accessor
|
||||
methods in the <classname>LDAPControl</classname> object.</para></sect1>
|
||||
<sect1 id="controls-server"><title>Determining the Controls Supported the
|
||||
Server With &DirectorySDKForJava;</title>
|
||||
<para>LDAP v3 states that servers should list any controls that servers support
|
||||
in the <literal>supportedControl</literal> attribute in the root DSE. The
|
||||
following OIDs have corresponding constants that are defined in the LDAP Java
|
||||
classes.</para>
|
||||
<variablelist termlength="wholeline">
|
||||
<varlistentry><term><literal>1.2.840.113556.1.4.473</literal></term><term><constant>
|
||||
netscape.ldap.controls.LDAPSortControl.SORTREQUEST</constant></term>
|
||||
<listitem><para>For instructions on using this control, refer to <olink targetptr="controls-sort">Using the Server-Side Sorting Control With Directory SDK for Java</olink>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>2.16.840.1.113730.3.4.2</literal></term><term><constant>
|
||||
netscape.ldap.LDAPControl.MANAGEDSAIT</constant></term>
|
||||
<listitem><para>For instructions on using this control, refer to <olink type="auto-generated" targetptr="controls-managedsait">Using the Manage DSA
|
||||
IT Control With Directory SDK for Java</olink>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>2.16.840.1.113730.3.4.3</literal></term><term><constant>
|
||||
netscape.ldap.controls.LDAPPersistSearchControl.PERSISTENTSEARCH</constant></term>
|
||||
<listitem><para>For instructions on using this control, refer to <olink type="auto-generated" targetptr="controls-psearch">Using the Persistent Search
|
||||
Control With Directory SDK for Java</olink>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>2.16.840.1.113730.3.4.4</literal></term><term><constant>
|
||||
netscape.ldap.LDAPControl.PWEXPIRED</constant></term>
|
||||
<listitem><para>For instructions on using this control, refer to <olink type="auto-generated" targetptr="controls-pwp">Using Password Policy Controls
|
||||
With Directory SDK for Java</olink>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>2.16.840.1.113730.3.4.5</literal></term><term><constant>
|
||||
netscape.ldap.LDAPControl.PWEXPIRING</constant></term>
|
||||
<listitem><para>For instructions on using this control, refer to <olink type="auto-generated" targetptr="controls-pwp">Using Password Policy Controls
|
||||
With Directory SDK for Java</olink>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>2.16.840.1.113730.3.4.9</literal></term><term><constant>
|
||||
netscape.ldap.controls.LDAPVirtualListControl.VIRTUALLIST</constant></term>
|
||||
<listitem><para>For instructions on using this control, refer to <olink type="auto-generated" targetptr="controls-vlv">Using the Virtual List Control With Directory SDK for Java</olink>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>2.16.840.1.113730.3.4.12</literal></term><term><constant>
|
||||
netscape.ldap.controls.LDAPProxiedAuthControl.PROXIEDAUTHREQUEST</constant></term>
|
||||
<listitem><para>For instructions on using this control, refer to <olink targetptr="controls-proxyauth">Using the Proxied Authorization Control With Directory SDK for Java</olink>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>The following example searches for the root DSE. Then the example prints
|
||||
the values of the <literal>supportedControl</literal> attribute.</para>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ListCtrl {
|
||||
public static void main(String[] args) {
|
||||
|
||||
/* Hashtable mapping OIDs of controls to a description */
|
||||
Hashtable knownControls = new Hashtable();
|
||||
knownControls.put(LDAPSortControl.SORTREQUEST,
|
||||
"Sort control");
|
||||
knownControls.put(LDAPControl.MANAGEDSAIT,
|
||||
"ManageDsaIT control");
|
||||
knownControls.put(LDAPPersistSearchControl.PERSISTENTSEARCH,
|
||||
"Persistent Search control");
|
||||
knownControls.put(LDAPControl.PWEXPIRED,
|
||||
"Password Expiration Notification control");
|
||||
knownControls.put(LDAPControl.PWEXPIRING,
|
||||
"Password Expiration Warning control");
|
||||
knownControls.put(LDAPVirtualListControl.VIRTUALLIST,
|
||||
"Virtual List View control");
|
||||
knownControls.put(LDAPProxiedAuthControl.PROXIEDAUTHREQUEST,
|
||||
"Proxied Authorization control");
|
||||
|
||||
try {
|
||||
UserArgs userArgs = new UserArgs("ListCtrl", args, false);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
|
||||
/* Retreive the list of supported controls from the DSE. */
|
||||
String getAttrs[] = {"supportedControl"};
|
||||
LDAPSearchResults res = ld.search("", LDAPv3.SCOPE_BASE,
|
||||
"(objectclass=*)", getAttrs, false);
|
||||
LDAPEntry DSE = (LDAPEntry)res.nextElement();
|
||||
LDAPAttributeSet findAttrs = DSE.getAttributeSet();
|
||||
Enumeration enumAttrs = findAttrs.getAttributes();
|
||||
|
||||
while (enumAttrs.hasMoreElements()) {
|
||||
LDAPAttribute anAttr =
|
||||
(LDAPAttribute)enumAttrs.nextElement();
|
||||
String attrName = anAttr.getName();
|
||||
System.out.println(attrName);
|
||||
|
||||
Enumeration enumVals = anAttr.getStringValues();
|
||||
if (enumVals == null) {
|
||||
System.out.println("\tNo values.");
|
||||
continue;
|
||||
}
|
||||
while (enumVals.hasMoreElements()) {
|
||||
String aVal = (String)enumVals.nextElement();
|
||||
/*
|
||||
* Each value should be the OID of a control.
|
||||
* Look up its description in the hash table.
|
||||
*/
|
||||
String aDesc = (String)knownControls.get(aVal);
|
||||
if (aDesc != null) {
|
||||
System.out.println("\t" + aDesc+ " (" + aVal + ")");
|
||||
} else {
|
||||
System.out.println("\t" + aVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ld.disconnect();
|
||||
} catch(LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</sect1>
|
||||
<sect1 id="controls-sort"><title>Using the Server-Side Sorting Control With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>search results</primary>
|
||||
<secondary>sorting</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>sorting search results</primary>
|
||||
</indexterm>
|
||||
<para>The control represented with the OID that corresponds to the constant <constant>
|
||||
netscape.ldap.LDAPControl.SORTREQUEST</constant> is a server-side sorting
|
||||
control. The server-side sorting control is defined in <ulink
|
||||
url="http://www.ietf.org/rfc/rfc2891.txt" type="text_url">RFC 2891</ulink>.
|
||||
When you send a search request with this control to the server, the server
|
||||
should sort the results before sending them back to you.</para>
|
||||
<sect2 id="controls-sort-order"><title>Specifying the Server-Side Sort Order
|
||||
With Directory SDK for Java</title>
|
||||
<para>To specify the sort order of the results, construct one or more <classname>
|
||||
LDAPSortKey</classname> objects. Each object represents a sort key that is
|
||||
generated from a string in the following format:</para>
|
||||
<programlisting>[-]<replaceable>attrName</replaceable>[:<replaceable>matchingRuleOID
|
||||
</replaceable>]</programlisting>
|
||||
<para>Here, <replaceable>attrName</replaceable> represents the name of the
|
||||
attribute to use for sorting. <replaceable>matchingRuleOID</replaceable> represents
|
||||
the optional OID of the matching rule to use for sorting. The optional minus
|
||||
sign (<literal>-</literal>) indicates that the results should be sorted in
|
||||
reverse order for that attribute.</para>
|
||||
<para>For example, the following string specifies that results should be sorted
|
||||
by first name (<literal>givenname</literal>) in descending order:</para>
|
||||
<programlisting>-givenname</programlisting>
|
||||
<para>Pass this string to the <classname>LDAPSortKey</classname> constructor
|
||||
to create a sort key:</para>
|
||||
<programlisting>LDAPSortKey reverseSortByFirstName = new LDAPSortKey("-givenname");
|
||||
</programlisting>
|
||||
<para>To sort by more than one attribute, construct more than one <classname>LDAPSortKey
|
||||
</classname> object and create an array of the objects.</para>
|
||||
<para>For example, suppose you want to sort the result by last name (<literal>sn</literal>)
|
||||
in ascending order. If two or more entries have the same last name, you want
|
||||
to sort the result by first name (<literal>givenname</literal>) in ascending
|
||||
order. To specify this sort order, you construct two <classname>LDAPSortKey</classname> objects.
|
||||
Then create an array:</para>
|
||||
<programlisting>LDAPSortKey sortByLastName = new LDAPSortKey("sn");
|
||||
LDAPSortKey sortByFirstName = new LDAPSortKey("givenname");
|
||||
LDAPSortKey[] sortOrder = { sortByLastName, sortByFirstName };</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="controls-sort-create"><title>Creating the Server-Side Sorting Control
|
||||
With &DirectorySDKForJava;</title>
|
||||
<para>Next, to create the server-side sorting control, construct a new <classname>
|
||||
LDAPSortControl</classname> object. Pass the <classname>LDAPSortKey</classname> object,
|
||||
or the array of <classname>LDAPSortKey</classname> objects, to the <literal>LDAPSortControl
|
||||
</literal> constructor.</para>
|
||||
<para>In the constructor, you can also specify whether or not the control
|
||||
is critical to the search operation. The control can be marked as critical,
|
||||
but the server cannot sort the results. If the situation occurs, the server
|
||||
should not send back any entries.</para>
|
||||
<para>For example, the following section of code creates a server-side sorting
|
||||
control. Also, the code specifies that the control is critical to the search
|
||||
operation:</para>
|
||||
<programlisting>LDAPSortKey sortOrder = new LDAPSortKey("-givenname");
|
||||
LDAPSortControl sortCtrl = new LDAPSortControl(sortOrder, true);</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="controls-sort-search"><title>Performing the Server—Side Sort
|
||||
With &DirectorySDKForJava;</title>
|
||||
<orderedlist>
|
||||
<para>To specify that you want the server to sort the results, do the following:</para>
|
||||
<listitem><para>Get a clone of <classname>LDAPSearchConstraints</classname> for
|
||||
the current connection by invoking the <literal>getSearchConstraints</literal> method
|
||||
of the <classname>LDAPConnection</classname> object.</para></listitem>
|
||||
<listitem><para>Invoke the <literal>setServerControls</literal> method for
|
||||
the copied <classname>LDAPSearchConstraints</classname> object, and pass in
|
||||
the <classname>LDAPSortControl</classname> object that you have constructed.</para>
|
||||
</listitem>
|
||||
<listitem><para>Invoke the <literal>search</literal> method of the <classname>LDAPConnection
|
||||
</classname> object, passing in the <classname>LDAPSearchConstraints</classname> object.
|
||||
</para><para>The server returns a result for the search operation and a response
|
||||
control. The response control indicates the success or failure of the sorting.</para>
|
||||
</listitem>
|
||||
<listitem><para>Invoke the <literal>getResponseControls</literal> method of
|
||||
the <classname>LDAPSearchResults</classname> object to retrieve any controls
|
||||
sent back by the server in response to the search.</para><para>Response controls
|
||||
are passed back as an array of <classname>LDAPControl</classname> objects.</para>
|
||||
</listitem>
|
||||
<listitem><para>Examine the type of each returned control. </para></listitem>
|
||||
</orderedlist>
|
||||
<para>If a control is an instance of <classname>LDAPSortControl</classname>,
|
||||
you can read the result code for the sorting operation with the <literal>getResultCode
|
||||
</literal> method.</para>
|
||||
<para>If the sorting operation failed, the server can also return the name
|
||||
of the attribute that caused the failure. You can read the name of this attribute
|
||||
with the <literal>getFailedAttribute</literal> method.</para>
|
||||
<para>The server can return the following result codes that apply to the sorting
|
||||
operation.</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><returnvalue>LDAPException.ADMIN_LIMIT_EXCEEDED</returnvalue></term>
|
||||
<listitem><para>Too many entries exist for the server to sort.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><returnvalue>LDAPException.BUSY</returnvalue></term>
|
||||
<listitem><para>The server is too busy to sort the results.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><returnvalue>LDAPException.INAPPROPRIATE_MATCHING</returnvalue></term>
|
||||
<listitem><para>The sort key list specifies a matching rule that is not recognized
|
||||
or appropriate.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><returnvalue>LDAPException.INSUFFICIENT_ACCESS_RIGHTS</returnvalue></term>
|
||||
<listitem><para>The server did not send the sorted results because the client
|
||||
has insufficient access rights.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><returnvalue>LDAPException.NO_SUCH_ATTRIBUTE</returnvalue></term>
|
||||
<listitem><para>The sort key list specifies an attribute that does not exist.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><returnvalue>LDAPException.OPERATION_ERROR</returnvalue></term>
|
||||
<listitem><para>An internal server error occurred.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><returnvalue>LDAPException.OTHER</returnvalue></term>
|
||||
<listitem><para>This general result code indicates that the server failed
|
||||
to sort the results for a reason other than the results listed here.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><returnvalue>LDAPException.STRONG_AUTH_REQUIRED</returnvalue></term>
|
||||
<listitem><para>The server refused to send back the sorted search results
|
||||
because the server requires that you use a stronger authentication method.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><returnvalue>LDAPException.SUCCESS</returnvalue></term>
|
||||
<listitem><para>The results were sorted successfully.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><returnvalue>LDAPException.TIME_LIMIT_EXCEEDED</returnvalue></term>
|
||||
<listitem><para>The maximum time allowed for a search was exceeded before
|
||||
the server finished sorting the results.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><returnvalue>LDAPException.UNWILLING_TO_PERFORM</returnvalue></term>
|
||||
<listitem><para>The server is unable to sort the results.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
<sect2 id="controls-sort-results"><title>Interpreting the Server-Side Sort
|
||||
Results With &DirectorySDKForJava;</title>
|
||||
<para>The following table shows the kinds of results to expect from the LDAP
|
||||
server under different conditions.</para>
|
||||
<table frame="topbot" pgwide="1" id="controls-sort-results-interpret"><title>Server
|
||||
Responses to Sort Controls</title>
|
||||
<tgroup cols="4" colsep="0" rowsep="0"><colspec colwidth="25*"><colspec
|
||||
colwidth="25*"><colspec colwidth="25*"><colspec colwidth="25*">
|
||||
<thead>
|
||||
<row rowsep="1">
|
||||
<entry colsep="0">
|
||||
<para>Supports sort control?</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>Sort control marked critical?</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>Any other conditions?</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>Results From LDAP Server</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry colsep="0">
|
||||
<para>Server does not support sort control.</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>Control is not marked as critical.</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>Not applicable</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>The server ignores the sorting control. The server returns the entries
|
||||
unsorted.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry colsep="0">
|
||||
<para>Server does not support sort control.</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>Control is marked as critical.</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>Not applicable</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>The server does not send back any entries.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry colsep="0">
|
||||
<para>Server does support sort control.</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>Control is not marked as critical.</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>The server cannot sort the results with the specified sort key list.</para>
|
||||
</entry>
|
||||
<entry colsep="0">
|
||||
<itemizedlist>
|
||||
<listitem><para>The server returns the entries unsorted.</para></listitem>
|
||||
<listitem><para>The server sends back the sorting response control. The response
|
||||
control specifies the result code of the sort attempt and, optionally, the
|
||||
attribute type that caused the error.</para></listitem>
|
||||
</itemizedlist>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry colsep="0">
|
||||
<para>Server does support sort control.</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>Control is marked as critical.</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>The server cannot sort the results with the specified sort key list.</para>
|
||||
</entry>
|
||||
<entry colsep="0">
|
||||
<itemizedlist>
|
||||
<listitem><para>The server does not return any entries.</para></listitem>
|
||||
<listitem><para>The server sends back the sorting response control. The response
|
||||
control specifies the result code of the sort attempt and, optionally, the
|
||||
attribute type that caused the error.</para></listitem>
|
||||
</itemizedlist>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry colsep="0">
|
||||
<para>Server does support sort control.</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>has no effect on results</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>The search failed.</para></entry>
|
||||
<entry colsep="0">
|
||||
<itemizedlist>
|
||||
<listitem><para>The server returns a result code for the search operation.</para>
|
||||
</listitem>
|
||||
<listitem><para>The server does not send back the sorting response control.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry colsep="0">
|
||||
<para>Server does support sort control.</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>has no effect on results</para></entry>
|
||||
<entry colsep="0">
|
||||
<para>The server successfully sorted the entries.</para></entry>
|
||||
<entry colsep="0">
|
||||
<itemizedlist>
|
||||
<listitem><para>The server returns the entries in sorted order.</para>
|
||||
</listitem>
|
||||
<listitem><para>The server sends back the sorting response control, which
|
||||
specifies the result code of the sort attempt as <returnvalue>LDAPException.SUCCESS
|
||||
</returnvalue>.</para></listitem>
|
||||
</itemizedlist>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect2>
|
||||
<sect2 id="controls-sort-example"><title>Example of Using Server-Side Sorting
|
||||
With &DirectorySDKForJava;</title>
|
||||
<para>The following sample program uses the server-side sorting control to
|
||||
get a list of all users in the directory. The list is sorted in ascending
|
||||
order by last name, then in descending order by first name.</para>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
import java.util.*;
|
||||
|
||||
public class SrchSort {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
UserArgs userArgs = new UserArgs("SrchSort", args, false);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
ld.authenticate(3, null, null); // Anonymous bind, LDAP v3
|
||||
|
||||
String filter = "sn=Jen*";
|
||||
String baseDN = "ou=People,dc=example,dc=com";
|
||||
String[] attrs = {"sn", "givenname"};
|
||||
|
||||
/* Sort by last name, then in reverse by first name. */
|
||||
LDAPSortKey sortByLastName = new LDAPSortKey("sn");
|
||||
LDAPSortKey sortByFirstName = new LDAPSortKey("-givenname");
|
||||
LDAPSortKey[] sortOrder = {sortByLastName, sortByFirstName};
|
||||
|
||||
LDAPSortControl sortCtrl = new LDAPSortControl(sortOrder, true);
|
||||
LDAPSearchConstraints cons = ld.getSearchConstraints();
|
||||
cons.setServerControls(sortCtrl);
|
||||
|
||||
/* Perform the search using the control. */
|
||||
LDAPSearchResults res = ld.search(baseDN, LDAPv3.SCOPE_SUB,
|
||||
filter, attrs, false, cons);
|
||||
|
||||
/* Display the results. */
|
||||
System.out.println("Sorted results from server");
|
||||
System.out.println("==========================");
|
||||
while (res.hasMoreElements()) {
|
||||
LDAPEntry resEntry = null;
|
||||
try {
|
||||
resEntry = res.next();
|
||||
} catch (LDAPReferralException e) {
|
||||
continue; // Skip referrals for now.
|
||||
} catch (LDAPException e) {
|
||||
System.err.println("Error:" + e.toString());
|
||||
continue;
|
||||
}
|
||||
|
||||
LDAPAttributeSet resAttrs = resEntry.getAttributeSet();
|
||||
Enumeration enumAttrs = resAttrs.getAttributes();
|
||||
|
||||
while (enumAttrs.hasMoreElements()) {
|
||||
LDAPAttribute attr =
|
||||
(LDAPAttribute)enumAttrs.nextElement();
|
||||
Enumeration enumVals = attr.getStringValues();
|
||||
if (enumVals == null) {
|
||||
System.out.println("\tNo values.");
|
||||
continue;
|
||||
}
|
||||
while (enumVals.hasMoreElements()) {
|
||||
String val = (String)enumVals.nextElement();
|
||||
System.out.print(val);
|
||||
}
|
||||
System.out.print(", ");
|
||||
}
|
||||
System.out.println("");
|
||||
}
|
||||
|
||||
/* Check whether the server sent back a control. */
|
||||
LDAPControl[] returnedControls = res.getResponseControls();
|
||||
if (returnedControls != null) {
|
||||
for (int i = 0; i < returnedControls.length; ++i) {
|
||||
if (!(returnedControls[i] instanceof LDAPSortControl)) {
|
||||
continue;
|
||||
}
|
||||
LDAPSortControl sortRsp =
|
||||
(LDAPSortControl)returnedControls[i];
|
||||
int resultCode = sortRsp.getResultCode();
|
||||
|
||||
/* Check the result for errors. */
|
||||
if (resultCode != 0) {
|
||||
System.err.println("Result code: " + resultCode);
|
||||
System.err.println(
|
||||
LDAPException.errorCodeToString(resultCode));
|
||||
|
||||
/* Report attribute that caused the failure. */
|
||||
String failedAttr = sortRsp.getFailedAttribute();
|
||||
if (failedAttr != null) {
|
||||
System.err.println("Failed on: " + failedAttr);
|
||||
} else {
|
||||
System.err.println("Server did not indicate " +
|
||||
"which attribute caused sorting to fail.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ld.disconnect();
|
||||
} catch(LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="controls-psearch"><title>Using the Persistent Search Control With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>persistent searches</primary>
|
||||
</indexterm>
|
||||
<para>The control represented with the OID that corresponds to the constant <constant>
|
||||
netscape.ldap.LDAPControl.PERSISTENTSEARCH</constant> is a persistent search
|
||||
control. A <firstterm>persistent search</firstterm>, an ongoing search operation,
|
||||
allows your LDAP client to get notification of changes to the directory.</para>
|
||||
<para>To use persistent searching for change notification, you create a persistent
|
||||
search control that specifies the types of changes that you want to track.
|
||||
You include the control in a search request. If an entry in the directory
|
||||
is changed, the server determines if the entry matches the search criteria
|
||||
in your request. The server also determines if the change is the type of change
|
||||
that you are tracking. If both of the conditions are true, the server sends
|
||||
the entry to your client.</para>
|
||||
<para>You can use this control in conjunction with an entry change notification
|
||||
control, as described in <olink type="auto-generated" targetptr="controls-entry-change">Using the Entry Change Notification Control
|
||||
With Directory SDK for Java</olink>.</para>
|
||||
<sect2 id="controls-psearch-create"><title>Creating the Persistent Search
|
||||
Control With Directory SDK for Java</title>
|
||||
<itemizedlist>
|
||||
<para>To create a persistent search control, you construct a new <classname>LDAPPersistSearchControl
|
||||
</classname> object. When invoking the <literal>LDAPPersistSearchControl</literal> constructor,
|
||||
you can specify the following information:</para>
|
||||
<listitem>
|
||||
<itemizedlist>
|
||||
<para>The type of change you want to track. You can specify any of the following,
|
||||
or any combination of the following, using a bitwise OR (<literal>|</literal>)
|
||||
operator:</para>
|
||||
<listitem><para><literal>ADD</literal> indicates that you want to track added
|
||||
entries.</para></listitem>
|
||||
<listitem><para><literal>DELETE</literal> indicates that you want to track
|
||||
deleted entries.</para></listitem>
|
||||
<listitem><para><literal>MODDN</literal> indicates that you want to track
|
||||
renamed entries.</para></listitem>
|
||||
<listitem><para><literal>MODIFY</literal> indicates that you want to track
|
||||
modified entries.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>A preference indicating whether you want the server to return
|
||||
all entries that initially matched the search criteria</para></listitem>
|
||||
<listitem><para>A preference indicating whether or not you want entry change
|
||||
notification controls included with every modified entry returned by the server</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>This code excerpt shows an example of creating a persistent search control.
|
||||
</para>
|
||||
<programlisting>/* Track all types of changes. */
|
||||
int op = LDAPPersistSearchControl.ADD |
|
||||
LDAPPersistSearchControl.MODIFY |
|
||||
LDAPPersistSearchControl.DELETE |
|
||||
LDAPPersistSearchControl.MODDN;
|
||||
|
||||
/* Return only entries that have changed. */
|
||||
boolean changesOnly = true;
|
||||
|
||||
/* Return an entry change notification control. */
|
||||
boolean returnControls = true;
|
||||
|
||||
/* Mark the control as critical. */
|
||||
boolean isCritical = true;
|
||||
|
||||
/* Create the control. */
|
||||
LDAPPersistSearchControl persistCtrl =
|
||||
new LDAPPersistSearchControl(
|
||||
op, changesOnly, returnControls, isCritical);</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="controls-psearch-search"><title>Performing the Persistent Search
|
||||
With Directory SDK for Java</title>
|
||||
<orderedlist>
|
||||
<para>To specify that you want to start a persistent search, do the following:</para>
|
||||
<listitem><para>Get a clone of <classname>LDAPSearchConstraints</classname> for
|
||||
the current connection by invoking the <literal>getSearchConstraints</literal> method
|
||||
of the <classname>LDAPConnection</classname> object.</para></listitem>
|
||||
<listitem><para>Invoke the <literal>setServerControls</literal> method for
|
||||
the cloned <classname>LDAPSearchConstraints</classname> object, and pass in
|
||||
the <classname>LDAPPersistSearchControl</classname> object that you have constructed.
|
||||
</para></listitem>
|
||||
<listitem><para>Invoke the search method of the <classname>LDAPConnection</classname> object,
|
||||
passing in the <classname>LDAPSearchConstraints</classname> object.</para><para>The
|
||||
server returns entries that match as the entries change. If you specified
|
||||
that you wanted an entry change notification control included with each entry,
|
||||
you can get these controls from the server's results. For instructions, refer
|
||||
to <olink type="auto-generated" targetptr="controls-entry-change">Using the
|
||||
Entry Change Notification Control With Directory SDK for Java</olink>.</para>
|
||||
</listitem></orderedlist>
|
||||
<para>To end the persistent search, invoke the <literal>abandon</literal> method
|
||||
of the <classname>LDAPConnection</classname> object. Alternatively, invoke
|
||||
the <literal>disconnect</literal> method to disconnect from the server.</para>
|
||||
</sect2>
|
||||
<sect2 id="controls-psearch-example"><title>Example of Using the Persistent
|
||||
Search Control With Directory SDK for Java</title>
|
||||
<para>The following example performs a persistent search. The example receives
|
||||
entry change notification controls from the server.</para>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import netscape.ldap.controls.*;
|
||||
import java.util.*;
|
||||
|
||||
public class SrchPrst implements Runnable {
|
||||
private static String [] cliArgs;
|
||||
public static void main(String[] args) {
|
||||
cliArgs = args;
|
||||
/* Start up a new thread. */
|
||||
Thread th = new Thread(new SrchPrst(), "mainConn");
|
||||
th.start();
|
||||
System.out.println("Main thread started.");
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
UserArgs userArgs = new UserArgs("SrchPrst", cliArgs, true);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
ld.authenticate(3, userArgs.getBindDN(),userArgs.getPassword());
|
||||
|
||||
/* Create the control and search constraints. */
|
||||
int op = LDAPPersistSearchControl.ADD |
|
||||
LDAPPersistSearchControl.MODIFY |
|
||||
LDAPPersistSearchControl.DELETE |
|
||||
LDAPPersistSearchControl.MODDN;
|
||||
boolean changesOnly = true;
|
||||
boolean returnControls = true;
|
||||
boolean isCritical = true;
|
||||
LDAPPersistSearchControl persistCtrl =
|
||||
new LDAPPersistSearchControl(op, changesOnly,
|
||||
returnControls, isCritical);
|
||||
LDAPSearchConstraints cons = ld.getSearchConstraints();
|
||||
cons.setServerControls(persistCtrl);
|
||||
|
||||
/* Track changes on all entries. */
|
||||
String filter = "(objectclass=*)";
|
||||
String baseDN = "dc=example,dc=com";
|
||||
/* Start the search. */
|
||||
LDAPSearchResults res =
|
||||
ld.search(
|
||||
baseDN, LDAPv3.SCOPE_SUB, filter, null, false, cons);
|
||||
|
||||
/* Loop through the results until finished. */
|
||||
while (res.hasMoreElements()) {
|
||||
System.out.println("\n===== Changed Entry =====");
|
||||
LDAPEntry findEntry = res.next();
|
||||
LDAPAttributeSet findAttrs = findEntry.getAttributeSet();
|
||||
Enumeration enumAttrs = findAttrs.getAttributes();
|
||||
while (enumAttrs.hasMoreElements()) {
|
||||
LDAPAttribute anAttr =
|
||||
(LDAPAttribute)enumAttrs.nextElement();
|
||||
String attrName = anAttr.getName();
|
||||
System.out.println("\t" + attrName);
|
||||
|
||||
Enumeration enumVals = anAttr.getStringValues();
|
||||
while (enumVals.hasMoreElements()) {
|
||||
String aVal = (String)enumVals.nextElement();
|
||||
System.out.println("\t\t" + aVal);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get any entry change controls. */
|
||||
LDAPControl[] responseCtrls = res.getResponseControls();
|
||||
if (responseCtrls != null) {
|
||||
for (int i=0; i < responseCtrls.length; i++){
|
||||
if (!(responseCtrls[i] instanceof
|
||||
LDAPEntryChangeControl)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LDAPEntryChangeControl entryCtrl =
|
||||
(LDAPEntryChangeControl) responseCtrls[i];
|
||||
|
||||
/* Get information on the type of change */
|
||||
int changeType = entryCtrl.getChangeType();
|
||||
if (changeType != -1) {
|
||||
System.out.print("Change made: ");
|
||||
switch (changeType) {
|
||||
case LDAPPersistSearchControl.ADD:
|
||||
System.out.println("Added new entry.");
|
||||
break;
|
||||
case LDAPPersistSearchControl.MODIFY:
|
||||
System.out.println("Modified entry.");
|
||||
break;
|
||||
case LDAPPersistSearchControl.DELETE:
|
||||
System.out.println("Deleted entry.");
|
||||
break;
|
||||
case LDAPPersistSearchControl.MODDN:
|
||||
System.out.println("Renamed entry.");
|
||||
break;
|
||||
default:
|
||||
System.out.println(
|
||||
"Unknown change type.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the change log number, if present */
|
||||
int changeNumber = entryCtrl.getChangeNumber();
|
||||
if (changeNumber != -1) {
|
||||
System.out.println(
|
||||
"Change log number: " + changeNumber);
|
||||
}
|
||||
|
||||
/* Get the previous DN of the entry, if
|
||||
a rename operation was performed. */
|
||||
String oldDN = entryCtrl.getPreviousDN();
|
||||
if (oldDN != null) {
|
||||
System.out.println("Previous DN: " + oldDN);
|
||||
}
|
||||
}
|
||||
System.out.println("\n");
|
||||
}
|
||||
}
|
||||
} catch(LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="controls-entry-change"><title>Using the Entry Change Notification
|
||||
Control With &DirectorySDKForJava;</title>
|
||||
<para>The control represented with the OID that corresponds to the constant <constant>
|
||||
netscape.ldap.LDAPEntryChangeControl.ENTRYCHANGED</constant> is an <firstterm>entry
|
||||
change notification</firstterm> control. These types of controls can be included
|
||||
with entries sent back from the server during a persistent search.</para>
|
||||
<sect2 id="controls-entry-change-get"><title>Getting the Entry Change Notification
|
||||
Control With Directory SDK for Java</title>
|
||||
<orderedlist>
|
||||
<para>To get an entry change notification control that is included with an
|
||||
entry, do the following:</para>
|
||||
<listitem><para>As you retrieve each entry, invoke the <literal>getResponseControls
|
||||
</literal> method of the <classname>LDAPConnection</classname> object to retrieve
|
||||
any response controls sent back from the server.</para><para>Response controls
|
||||
are passed back as an array of <classname>LDAPControl</classname> objects. </para>
|
||||
</listitem>
|
||||
<listitem><para>Pass this array of <classname>LDAPControl</classname> objects
|
||||
as an argument to the <literal>LDAPPersistSearchControl.parseResponse</literal> static
|
||||
method to retrieve the entry change notification control.</para></listitem>
|
||||
</orderedlist>
|
||||
<para>An entry change notification control is represented by an object of
|
||||
the <classname>LDAPEntryChangeControl</classname> class. To get data from
|
||||
this control, you can invoke the accessor methods, such as <literal>getChangeNumber
|
||||
</literal>, <literal>getChangeType</literal>, and <literal>getPreviousDN</literal>.
|
||||
</para></sect2>
|
||||
<sect2 id="controls-entry-change-work"><title>Working With Change Log Numbers
|
||||
With Directory SDK for Java</title>
|
||||
<para>If the directory server is set up to be a supplier, the server is capable
|
||||
of replicating changes in the directory to other servers. The server therefore
|
||||
keeps a record of the changes made to the directory in a change log. Each
|
||||
record of a change has a number that identifies the change in the log.</para>
|
||||
<para>You can get the change number for a modified entry from the <classname>LDAPEntryChangeControl
|
||||
</classname> object.</para>
|
||||
<para>To look up the record for a particular change log number to get more
|
||||
information about the change that took place, search for the record. With
|
||||
Directory Server, the change log is represented by an entry in the directory.
|
||||
Individual change records are represented by entries in a subtree beneath
|
||||
the change log entry.</para>
|
||||
<para>To determine the DN for the change log entry, search the root DSE to
|
||||
retrieve the <literal>changelog</literal> attribute. For example, the value
|
||||
of this attribute might be <literal>cn=changelog</literal>, which is the DN
|
||||
for the change log entry.</para>
|
||||
<para>Each change log record is an entry under the change log entry. The change
|
||||
log number is the value of the <literal>changenumber</literal> attribute of
|
||||
the record. To get a specific change log record, search with base DN <literal>cn=changelog
|
||||
</literal> and filter <literal>changenumber=</literal><replaceable>value</replaceable>.
|
||||
Here, <replaceable>value</replaceable> is the change number of the record.</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="controls-vlv"><title>Using the Virtual List Control With &DirectorySDKForJava;</title>
|
||||
<para>The control represented with the OID that corresponds to the constant <constant>
|
||||
netscape.ldap.controls.LDAPVirtualListControl.VIRTUALLIST</constant> is a <firstterm>
|
||||
virtual list</firstterm> control. When you send a search request with this
|
||||
control and with a server-side sorting control to the server, the server should
|
||||
sort the results and return the specified subset of entries back to your client.</para>
|
||||
<para>After you set the list size with the <literal>setListSize</literal> method
|
||||
of the <classname>LDAPVirtualListControl</classname> object, invoke the <literal>
|
||||
setRange</literal> method. The method recreates the control with the new data. <literal>
|
||||
setRange</literal> generates the BER-encoded request to be sent to the server. <literal>
|
||||
setListSize</literal> does not generate the request.</para></sect1>
|
||||
<sect1 id="controls-managedsait"><title>Using the Manage DSA IT Control With &DirectorySDKForJava;</title>
|
||||
<para>The control represented with the OID that corresponds to the constant <constant>
|
||||
netscape.ldap.controls.LDAPControl.MANAGEDSAIT</constant> is a <firstterm>manage
|
||||
DSA IT</firstterm> control. The control is for managing search references
|
||||
in the directory and is defined in <ulink
|
||||
url="http://www.ietf.org/rfc/rfc3296.txt" type="text_url">RFC
|
||||
3296</ulink>.</para>
|
||||
<para>To create this control, construct a new <classname>LDAPControl</classname> object.
|
||||
In the <literal>LDAPControl</literal> constructor, set the OID of the control
|
||||
to <constant>netscape.ldap.controls.LDAPControl.MANAGEDSAIT</constant>.</para>
|
||||
<para>Add this control to the array of <classname>LDAPControl</classname> objects.
|
||||
When you pass the array to a method that performs an LDAP operation, the server
|
||||
treats search references as ordinary entries.</para>
|
||||
<para>Rather than returning a reference to you, the server returns the entry
|
||||
that contains the reference. This mechanism allows your client application
|
||||
to manage search references in the directory.</para></sect1>
|
||||
<sect1 id="controls-pwp"><title>Using Password Policy Controls With &DirectorySDKForJava;</title>
|
||||
<itemizedlist>
|
||||
<para>&cnDirectoryServer; uses two server response controls to send information
|
||||
back to a client after an LDAP bind operation.</para>
|
||||
<listitem><para>The control represented with the OID that corresponds to the
|
||||
constant <constant>netscape.ldap.controls.LDAPControl.PWEXPIRED</constant> is
|
||||
the <firstterm>expired password</firstterm> control.</para><para>This control
|
||||
is used if the server is configured to require users to change their passwords
|
||||
on first login. The control is also used whenever the passwords are reset.</para>
|
||||
<para>The user might be logging in for the first time. The user password might
|
||||
have been reset. In either circumstance, the server sends the control to indicate
|
||||
that the client needs to change the password immediately. When receiving this
|
||||
control, the only operation that the client can perform is to change the user's
|
||||
password. If the client requests any other LDAP operation, the server sends
|
||||
back an <returnvalue>LDAP_UNWILLING_TO_PERFORM</returnvalue> result code with
|
||||
an expired password control.</para></listitem>
|
||||
<listitem><para>The control represented with the OID that corresponds to the
|
||||
constant <constant>netscape.ldap.controls.LDAPControl.PWEXPIRING</constant> is
|
||||
the <firstterm>password expiring warning</firstterm> control.</para><para>This
|
||||
control is used if the server is configured to expire user passwords after
|
||||
a certain amount of time.</para><para>The server sends this control back to
|
||||
the client if the client binds with a password that is soon to expire. If
|
||||
you invoke the <literal>getValue</literal> method for this <classname>LDAPControl
|
||||
</classname> object, the method returns the number of seconds before the password
|
||||
expires.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>To get these server response controls when binding, invoke the <literal>getResponseControls
|
||||
</literal> method of the <classname>LDAPConnection</classname> object after
|
||||
you attempt to authenticate to the server.</para></sect1>
|
||||
<sect1 id="controls-proxyauth"><title>Using the Proxied Authorization Control
|
||||
With &DirectorySDKForJava;</title>
|
||||
<para>The control represented with the OID that corresponds to the constant <constant>
|
||||
netscape.ldap.controls.LDAPProxiedAuthControl.PROXIEDAUTHREQUEST</constant> is
|
||||
a <firstterm>proxied authorization</firstterm> control. It allows LDAP clients
|
||||
to use different credentials, without rebinding, when executing LDAP operations.</para>
|
||||
<para>For example, suppose a messaging server stores its user profiles on
|
||||
an LDAP server. For certain types of requests the messaging server needs to
|
||||
use a DN and password other than its own. To use another DN and password without
|
||||
proxied authorization requires the messaging server to rebind, using the different
|
||||
credentials, before executing each operation.</para>
|
||||
<para>If the messaging server uses the proxied authorization control, the
|
||||
server can act as the user when executing an operation. The messaging server
|
||||
maintains only its own binding to the LDAP server. This mechanism drastically
|
||||
improves performance, especially when processing a large number of requests.</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
156
mozilla/directory/docs/ldapjdk/jdk-extended-ops.sgm
Normal file
156
mozilla/directory/docs/ldapjdk/jdk-extended-ops.sgm
Normal file
@@ -0,0 +1,156 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="extended-ops"><title>Extended Operations With &DirectorySDKForJava;</title>
|
||||
<highlights>
|
||||
<para>This chapter explains LDAP v3 extended operations. This chapter also
|
||||
explains how to use the extended operations that are supported by your LDAP
|
||||
server.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="extops-overview">How Extended Operations
|
||||
Work With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="extops-server-side">Implementing Support
|
||||
for Extended Operations on the Server With Directory SDK for Java</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="extopts-view-supported">Determining the
|
||||
Extended Operations Supported With Directory SDK for Java</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="extopts-client-side">Performing an Extended
|
||||
Operation With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="extopts-example">Example Extended Operation
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="extops-overview"><title>How Extended Operations Work With &DirectorySDKForJava;</title>
|
||||
<para>Extended operations are part of LDAP v3. Each extended operation is
|
||||
identified by an object identifier (OID).</para>
|
||||
<itemizedlist>
|
||||
<para>LDAP clients can request the operation by sending an extended operation
|
||||
request. Within the request, the client specifies the following:</para>
|
||||
<listitem><para>The OID of the extended operation to perform</para></listitem>
|
||||
<listitem><para>Data specific to the extended operation</para></listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<para>The server receives the request. The server then performs the extended
|
||||
operation. The server can send back to the client a response containing:</para>
|
||||
<listitem><para>An OID</para></listitem>
|
||||
<listitem><para>Any additional data</para></listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<para>To use extended operations, both the server and the client must know
|
||||
the specific extended operation to be performed.</para>
|
||||
<listitem><para>You must write a client that can send requests for a specific
|
||||
extended operation. The client must also be able to receive extended responses
|
||||
from the server.</para></listitem>
|
||||
<listitem><para>Your LDAP server needs to be able to handle requests for specific
|
||||
extended operations. The server also must be able to send responses back to
|
||||
the client.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="extops-server-side"><title>Implementing Support for Extended Operations
|
||||
on the Server With Directory SDK for Java</title>
|
||||
<indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>extended operations and</secondary>
|
||||
</indexterm>
|
||||
<para>&cnDirectoryServer; supports a plug-in API that allows you to write
|
||||
your own server plug-in to handle extended operations.</para>
|
||||
<itemizedlist>
|
||||
<para>You can write an extended operation that does the following:</para>
|
||||
<listitem><para>Registers the OID of an extended operation as supported, so
|
||||
the OID appears as a value of the <literal>supportedExtension</literal> attribute
|
||||
on the root DSE</para></listitem>
|
||||
<listitem><para>Gets information from an extended operation request</para>
|
||||
</listitem>
|
||||
<listitem><para>Creates and sends an extended operation response back to the
|
||||
client</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="extopts-view-supported"><title>Determining the Extended Operations
|
||||
Supported With &DirectorySDKForJava;</title>
|
||||
<para>To determine the extended operations supported by the server, get the
|
||||
root DSE of the server, and check the <literal>supportedExtension</literal> attribute.
|
||||
The values of this attribute are the OIDs of the extended operations supported
|
||||
by this server.</para>
|
||||
<para>If the root DSE does not have a <literal>supportedExtension</literal> attribute,
|
||||
the server does not support any extended operations. For instructions on reading
|
||||
the root DSE, refer to <olink type="auto-generated" targetptr="server-info-dse-info">Getting the Root DSE With Directory SDK for
|
||||
Java</olink>.</para></sect1>
|
||||
<sect1 id="extopts-client-side"><title>Performing an Extended Operation With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>extended operations and</secondary>
|
||||
</indexterm>
|
||||
<orderedlist>
|
||||
<para>To request an extended operation, do the following:</para>
|
||||
<listitem><para>Construct a new <classname>LDAPExtendedOperation</classname> object,
|
||||
specifying the OID of the extended operation and the data that you want applied
|
||||
to the operation.</para></listitem>
|
||||
<listitem><para>Invoke the <literal>extendedOperation</literal> method of
|
||||
the <classname>LDAPConnection</classname> object, passing the method of the
|
||||
newly constructed <classname>LDAPExtendedOperation</classname> object.</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>The <classname>LDAPExtendedOperation</classname> object that is returned
|
||||
represents the server response. You can invoke the <literal>getID</literal> and <literal>
|
||||
getValue</literal> methods of this object to get the OID and the data from
|
||||
the server's response.</para></sect1>
|
||||
<sect1 id="extopts-example"><title>Example Extended Operation With &DirectorySDKForJava;</title>
|
||||
<para>The following example shows an LDAP client that requests an extended
|
||||
operation with the OID <literal>1.2.3.4</literal> from the server.</para>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
public class ExtOpt {
|
||||
private static String OID = "1.2.3.4";
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
UserArgs userArgs = new UserArgs("ExtOpt", args, true);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
ld.authenticate(3, userArgs.getBindDN(),userArgs.getPassword());
|
||||
System.out.println("Authenticated to directory.");
|
||||
|
||||
/* Create an extended operation object */
|
||||
String myval = "My Value";
|
||||
byte vals[] = myval.getBytes("UTF8");
|
||||
LDAPExtendedOperation exop =
|
||||
new LDAPExtendedOperation(OID, vals);
|
||||
|
||||
/* Request the extended operation from the server. */
|
||||
LDAPExtendedOperation exres = ld.extendedOperation(exop);
|
||||
System.out.println("Performed extended operation.");
|
||||
|
||||
/* Get data from the response sent by the server. */
|
||||
System.out.println("OID returned: " + exres.getID());
|
||||
String retValue = new String(exres.getValue(),"UTF8");
|
||||
System.out.println("Value returned: " + retValue);
|
||||
|
||||
ld.disconnect();
|
||||
}
|
||||
catch(LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}
|
||||
catch(UnsupportedEncodingException e) {
|
||||
System.out.println("Error: UTF8 not supported");
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</sect1>
|
||||
</chapter>
|
||||
545
mozilla/directory/docs/ldapjdk/jdk-filter-conf.sgm
Normal file
545
mozilla/directory/docs/ldapjdk/jdk-filter-conf.sgm
Normal file
@@ -0,0 +1,545 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="filter-conf"><title>Using Filter Configuration Files</title>
|
||||
<highlights>
|
||||
<para>This chapter explains how to use API function to work with filter configuration
|
||||
files. Filter configuration files can help simplify the process of selecting the appropriate
|
||||
search filter for a search request. The chapter contains the following sections:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para><olink targetptr="understanding-filter-conf">Understanding Filter
|
||||
Configuration Files</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="understanding-filter-conf-syntax">Understanding
|
||||
the Configuration File Syntax</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="understanding-filter-parameters">Understanding Filter
|
||||
Parameters</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="loading-filter-conf">Loading Filter Configuration
|
||||
Files</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="retrieving-filters">Retrieving Filters</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="filter-conf-affixes">Adding Filter Prefixes and
|
||||
Suffixes</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="understanding-filter-conf"><title>Understanding Filter Configuration Files
|
||||
</title>
|
||||
<para>Suppose that you are writing a client that allows users to search the directory.
|
||||
You might want to use different search filters tailored for specific types of search
|
||||
criteria. For example, suppose the user wants to search for this:</para>
|
||||
<literallayout><literal>bjensen@example.com</literal></literallayout>
|
||||
<para>You might want to use this search filter:</para>
|
||||
<literallayout><literal>(mail=bjensen@example.com)</literal></literallayout>
|
||||
<para>Similarly, suppose the search term entered by the user contains numbers, like
|
||||
this:</para>
|
||||
<literallayout><literal>555-1212</literal></literallayout>
|
||||
<para>In this case, you might want to use this search filter:</para>
|
||||
<literallayout><literal>(telephoneNumber=555-1212)</literal></literallayout>
|
||||
<para>Rather than write code to construct the search filter explicitly, you can generate
|
||||
filters using a <firstterm>filter configuration file</firstterm>. A filter configuration
|
||||
file specifies a list of filters that you can load and use in your searches.</para>
|
||||
</sect1>
|
||||
<sect1 id="understanding-filter-conf-syntax"><title>Understanding the Configuration
|
||||
File Syntax</title>
|
||||
<indexterm><primary>filter configuration files</primary><secondary>syntax</secondary>
|
||||
</indexterm>
|
||||
<para>A filter configuration file has the following format:</para>
|
||||
<literallayout width="100"><replaceable>tag</replaceable>
|
||||
<replaceable>pattern1</replaceable> <replaceable>delimiters</replaceable> <replaceable>
|
||||
filter1-1</replaceable> <replaceable>desc1-1</replaceable> [<replaceable>scope1
|
||||
</replaceable>]
|
||||
<replaceable>filter1-2</replaceable> <replaceable>
|
||||
desc1-2</replaceable> [<replaceable>scope2</replaceable>]
|
||||
|
||||
<replaceable>pattern2</replaceable> <replaceable>delimiters</replaceable> <replaceable>
|
||||
filter2-1</replaceable> <replaceable>desc2-1</replaceable> [<replaceable>scope3
|
||||
</replaceable>]
|
||||
…</literallayout>
|
||||
<para>Each element in the file is a string, surrounded by quotes (<literal>"</literal>).
|
||||
Comments consist of lines starting with <literal>#</literal>.</para>
|
||||
<para>The format supports these elements:</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><replaceable>tag</replaceable></term>
|
||||
<listitem><para>Identifies a group of filters.</para>
|
||||
<para>You can use different tags to distinguish filters for different types of objects.
|
||||
For example, you can use a <literal>"person"</literal> tag to identify filters for
|
||||
person entries, a <literal>"organization"</literal> tag to represent filters for organization
|
||||
entries, and so forth.</para>
|
||||
<para>You can specify multiple tags for the same group of filters in the configuration
|
||||
file using the keyword <literal>and</literal>, such as <literal>"people and organization"
|
||||
</literal>.</para>
|
||||
<para>You can specify a tag, or part of a tag, as a parameter. The tag narrows the
|
||||
list of filters that the function retrieves.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><replaceable>pattern</replaceable></term>
|
||||
<listitem><para>Specifies a regular expression used to determine which filter is selected
|
||||
based on the search criteria.</para>
|
||||
<para>For example, if you specify <literal>^[0-9]</literal> as the pattern for a filter,
|
||||
the filter is selected for all search criteria beginning with a number.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><replaceable>delimiters</replaceable></term>
|
||||
<listitem><para>Specify what characters separate one field from another within search
|
||||
criteria.</para>
|
||||
<para>For example, if the search criteria consists of a city name and state abbreviation
|
||||
separated by a comma, specify <literal>","</literal> as the delimiter.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><replaceable>filter</replaceable></term>
|
||||
<listitem><para>Specifies an LDAP filter including <literal>%v</literal> to represent
|
||||
the search criteria.</para>
|
||||
<para>For example, to search email addresses, use the filter <literal>(mail=%v)</literal>.
|
||||
During runtime, if the search criteria <literal>bjensen@example.com</literal> is entered,
|
||||
the filter becomes <literal>(mail=bjensen@example.com)</literal>.</para>
|
||||
<para>If the search criteria consists of a number of delimited fields such as a <replaceable>
|
||||
surname</replaceable><literal>,</literal> <replaceable>first name</replaceable> format
|
||||
like <literal>Jensen, Barbara</literal>, use <literal>%v1</literal>, <literal>%v2
|
||||
</literal>, …, <literal>%vn</literal> to represent the fields within the search
|
||||
criteria. For example:</para>
|
||||
<literallayout><literal>"people"
|
||||
"^[A-Z]*," "," "(&(sn=%v1)(givenName=%v2))"</literal></literallayout>
|
||||
<para>In the example, the delimiter is a comma. The word before the delimiter replaces <literal>
|
||||
%v1</literal> in the filter, and the word after the delimiter replaces<literal>%v1
|
||||
</literal>. A search for:</para>
|
||||
<literallayout><literal>Jensen, Barbara</literal></literallayout><para>results in
|
||||
a filter:</para>
|
||||
<literallayout><literal>(&(sn=Jensen)(givenName=Barbara))</literal></literallayout>
|
||||
<para>You can also specify ranges of fields. For example, to specify the values in
|
||||
the first three fields, use <literal>%v1-3</literal>. To specify values from the third
|
||||
field to the last field, use <literal>%v3-</literal>. To specify the value in the
|
||||
last field, use <literal>%v$</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><replaceable>desc</replaceable></term>
|
||||
<listitem><para>Specify short text descriptions of the filters.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><replaceable>scope</replaceable></term>
|
||||
<listitem><para>Specify the scope of each search.</para>
|
||||
<para>This field is optional. It can take the values <literal>"base"</literal>, <literal>
|
||||
"onelevel"</literal>, or <literal>"subtree"</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>For example, the following section of a filter configuration file specifies
|
||||
a filter for telephone numbers and two filters for email addresses. The telephone
|
||||
number filter is used if the search criteria contains one or more numbers. The email
|
||||
filters are used if the search criteria contains an at sign (<literal>@</literal>).
|
||||
</para>
|
||||
<programlisting role="fragment">"people"
|
||||
"^[0-9][0-9-]*$" " " "(telephoneNumber=*%v)" "phone number ends with"
|
||||
"@" " " "(mail=%v)" "email address is"
|
||||
"(mail=%v*)" "email address starts with"
|
||||
</programlisting>
|
||||
<para>Specify the filters in the order that you want them to be used. For example,
|
||||
if you want to apply the <literal>(mail=%v)</literal> filter before the <literal>
|
||||
(mail=%v*)</literal> filter, make sure that the filters appear in that order.</para>
|
||||
</sect1>
|
||||
<sect1 id="understanding-filter-parameters"><title>Understanding Filter Parameters
|
||||
</title>
|
||||
<para>Configuration file filter specifications support the following parameters:</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><literal>%v</literal></term>
|
||||
<listitem><para>Insert the search criterion verbatim in place of <literal>%v</literal>.
|
||||
</para>
|
||||
<para>For example, if the filter specification is <literal>(mail=%v)</literal>, entering <literal>
|
||||
bjensen</literal> results in the filter <literal>(mail=bjensen)</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>%v$</literal></term>
|
||||
<listitem><para>Insert the last word of search criterion verbatim in place of <literal>
|
||||
%v</literal>.</para>
|
||||
<para>For example, if the filter specification is <literal>(sn=%v$)</literal>, entering <literal>
|
||||
Barbara Jensen</literal> results in the filter <literal>(sn=Jensen)</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>%v</literal><replaceable>N</replaceable></term>
|
||||
<listitem><para>Insert the <replaceable>N</replaceable>th word of the criteria in
|
||||
place of <literal>%v</literal>, where <replaceable>N</replaceable> is a single digit
|
||||
between 1 and 9.</para>
|
||||
<para>For example, if the filter specification is <literal>(sn=%v2)</literal>, entering <literal>
|
||||
Barbara Jensen</literal> results in the filter <literal>(sn=Jensen)</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>%v</literal><replaceable>M</replaceable><literal>-</literal><replaceable>
|
||||
N</replaceable></term>
|
||||
<listitem><para>Insert the sequence of the <replaceable>M</replaceable>th through <replaceable>
|
||||
N</replaceable>th words of the criteria in place of <literal>%v</literal>, where <replaceable>
|
||||
M</replaceable> and <replaceable>N</replaceable> are single digits between 1 and 9.
|
||||
</para>
|
||||
<para>For example, if the filter specification is <literal>(cn=%v1-2)</literal>, entering <literal>
|
||||
Barbara Jensen</literal> results in the filter <literal>(cn=Barbara Jensen)</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>%v</literal><replaceable>N</replaceable><literal>-</literal></term>
|
||||
<listitem><para>Insert the sequence of th e<replaceable>N</replaceable>th through
|
||||
last words of the criteria in place of <literal>%v</literal>, where <replaceable>
|
||||
N</replaceable> is a single digit between 1 and 9.</para>
|
||||
<para>For example, if the filter specification is <literal>(cn=%v2-)</literal>, entering <literal>
|
||||
Ms. Barbara Jensen</literal> results in the filter <literal>(cn=Barbara Jensen)</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect1>
|
||||
<sect1 id="loading-filter-conf"><title>Loading Filter Configuration Files</title>
|
||||
<indexterm><primary>filter configuration files</primary><secondary>loading</secondary>
|
||||
</indexterm>
|
||||
<indexterm><primary>loading filter configuration files</primary></indexterm>
|
||||
<para>To use a filter configuration file, you need to create an <classname>LDAPFilterDescriptor
|
||||
</classname> object. The <literal>LDAPFilterDescriptor</literal> constructor allows
|
||||
you to read in the filter configuration file from one of the following:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>A file in the local file system to which you specify the path</para>
|
||||
</listitem>
|
||||
<listitem><para>A file served by a web server to which you specify the URL</para>
|
||||
</listitem>
|
||||
<listitem><para>A location in memory where you specify a <classname>StringBuffer</classname> object
|
||||
containing the configuration information</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>The following section of code reads in a filter configuration file named <filename>
|
||||
ldapfilter.conf</filename> in the current directory.</para>
|
||||
<programlisting>import netscape.ldap.util.*;
|
||||
…
|
||||
|
||||
LDAPFilterDescriptor filtdesc = null;
|
||||
try {
|
||||
/* Read in the filter configuration file. */
|
||||
filtdesc = new LDAPFilterDescriptor("ldapfilter.conf");
|
||||
} catch ( Exception e ) {
|
||||
System.out.println( "Error: " + e.toString() );
|
||||
}</programlisting>
|
||||
</sect1>
|
||||
<sect1 id="retrieving-filters"><title>Retrieving Filters</title>
|
||||
<para>After loading a filter configuration file into memory, you can retrieve filters
|
||||
based on the search criteria. For example, if the search criteria is an email address
|
||||
such as <literal>bjensen@example.com</literal>, you can have your client automatically
|
||||
search for this value in the <literal>mail</literal> attribute.</para>
|
||||
<task id="retrieving-filters-task"><title>Retrieving Filters Using A Filter Configuration
|
||||
File</title>
|
||||
<procedure>
|
||||
<step><para>Invoke the <literal>LDAPFilterDescriptor</literal> constructor to read
|
||||
in the filter configuration file.</para></step>
|
||||
<step><para>Invoke the <literal>getFilters</literal> method of the <classname>LDAPFilterDescriptor
|
||||
</classname> object.</para><para>Specify the tag of the section that you want to use
|
||||
in the filter configuration file.</para><para>You do not need to invoke the <literal>
|
||||
setupFilter</literal> of the <classname>LDAPFilter</classname> object to generate
|
||||
the filter. The <literal>getFilters</literal> method of the <classname>LDAPFilterDescriptor
|
||||
</classname> object does this already. You just need to invoke the <literal>getFilter
|
||||
</literal> method of the <classname>LDAPFilter</classname> object to get the generated
|
||||
filter.</para><para>This method returns an <classname>LDAPFilterList</classname> object,
|
||||
which is an enumeration of <classname>LDAPFilter</classname> objects containing the
|
||||
filters for the specified search term.</para></step>
|
||||
<step><para>Invoke the <literal>next</literal> method of the <classname>LDAPFilterList
|
||||
</classname> object to iterate through the <classname>LDAPFilter</classname> objects.
|
||||
</para></step>
|
||||
<step><para>For each <classname>LDAPFilter</classname> object, get the filter by invoking
|
||||
the <literal>getFilter</literal> method, passing no arguments.</para><para>To get
|
||||
the total number of filter configuration lines that match the specified search term,
|
||||
invoke the <literal>numFilters</literal> method of the <classname>LDAPFilterList</classname> object.
|
||||
This number decrements each time you invoke the next or <literal>nextElement</literal> method.
|
||||
</para></step>
|
||||
</procedure>
|
||||
<example id="retrieving-filters-example">
|
||||
<title>Retrieving Telephone Number and Mail Filters</title>
|
||||
<para>This example uses a filter configuration file, <filename>ldapfilter.conf</filename>,
|
||||
with the following specifications:</para>
|
||||
<programlisting role="fragment">"people"
|
||||
"^[0-9][0-9-]*$" " " "(telephoneNumber=*%v)" "phone number ends with"
|
||||
"@" " " "(mail=%v)" "email address is"
|
||||
"(mail=%v*)" "email address starts with"</programlisting>
|
||||
<para>The following code retrieves, generates, and prints filters matching the criteria:
|
||||
</para>
|
||||
<programlisting>String searchTerm = "bjensen@example.com";
|
||||
LDAPFilterDescriptor filtdesc = null;
|
||||
try {
|
||||
/* Read in the filter configuration file. */
|
||||
filtdesc = new LDAPFilterDescriptor("ldapfilt.conf");
|
||||
|
||||
/* Get filters from the section "people" */
|
||||
LDAPFilterList filtlist = null;
|
||||
try {
|
||||
filtlist = filtdesc.getFilters("people", searchTerm);
|
||||
} catch ( Exception e ) {
|
||||
System.out.println("No matching tag section or filter");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
int totalFilters = filtlist.numFilters();
|
||||
System.out.println("Found " + totalFilters + " applicable filters.\n");
|
||||
|
||||
/* Iterate through the lines in the list. */
|
||||
while ( filtlist.hasMoreElements() ) {
|
||||
LDAPFilter filtline = filtlist.next();
|
||||
System.out.println("Filter #" +
|
||||
(totalFilters - filtlist.numFilters()));
|
||||
|
||||
/* Get and print information about the selected line
|
||||
of filter configuration information. */
|
||||
System.out.println(" Description: " + filtline.getDescription());
|
||||
System.out.println(" Line #: " + filtline.getLineNumber());
|
||||
System.out.println(" Matches pattern: " +
|
||||
filtline.getMatchPattern());
|
||||
System.out.println(" Filter template: " +
|
||||
filtline.getFilterTemplate());
|
||||
System.out.println(" Delimiter: " + filtline.getDelimeter());
|
||||
System.out.println(" Scope: " + filtline.getScope());
|
||||
|
||||
/* Get the generated filter. */
|
||||
String filterString = filtline.getFilter();
|
||||
System.out.println(" Generated filter string: " +
|
||||
filterString + "\n");
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}</programlisting>
|
||||
<para>When built into a program, compiled, and run, this code produces the following
|
||||
output:</para>
|
||||
<screen>Found 2 applicable filters.
|
||||
|
||||
Filter #1
|
||||
Description: email address is
|
||||
Line #: 3
|
||||
Matches pattern: @
|
||||
Filter template: (mail=%v)
|
||||
Delimiter:
|
||||
Scope: subtree
|
||||
Generated filter string: (mail=bjensen@example.com)
|
||||
|
||||
Filter #2
|
||||
Description: email address starts with
|
||||
Line #: 4
|
||||
Matches pattern: @
|
||||
Filter template: (mail=%v*)
|
||||
Delimiter:
|
||||
Scope: subtree
|
||||
Generated filter string: (mail=bjensen@example.com*)</screen>
|
||||
</example>
|
||||
</task>
|
||||
</sect1>
|
||||
<sect1 id="filter-conf-affixes"><title>Adding Filter Prefixes and Suffixes</title>
|
||||
<para>If you need to apply a filter to all searches, you can add a filter prefix and
|
||||
suffix to all filters rather than adding the criteria to all filters. For example,
|
||||
if your client searches only for person entries, you can add the following filter
|
||||
prefix to restrict the search:</para>
|
||||
<literallayout><literal>(&(l=Sunnyvale)</literal></literallayout>
|
||||
<para>The filter prefix now requires the following suffix to balance the number of
|
||||
parentheses:</para>
|
||||
<literallayout><literal>)</literal></literallayout>
|
||||
<para>For example, given the following filter:</para>
|
||||
<literallayout><literal>(sn=Jensen)</literal></literallayout>
|
||||
<para>You can use the filter prefix <literal>(&(l=Sunnyvale</literal> and the
|
||||
filter suffix <literal>)</literal> to narrow down the search to only the entries matching <literal>
|
||||
l=Sunnyvale</literal>:</para>
|
||||
<literallayout><literal>(&(l=Sunnyvale)(sn=Jensen))</literal></literallayout>
|
||||
<para>You can set up the filter prefix and suffix in several ways:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>To set these for all filters generated from the filter configuration
|
||||
file, invoke the <literal>setFilterAffixes</literal> method of the <classname>LDAPFilterDescriptor
|
||||
</classname> object.</para></listitem>
|
||||
<listitem><para>To set the prefix or suffix for a specific filter, do one of the following:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Invoke the <literal>setFilterAffixes</literal> method of the <classname>
|
||||
LDAPFilter</classname> object, then invoke the <literal>getFilter</literal> method,
|
||||
passing in the search term again. This builds the filter again, using the specified
|
||||
search term with the prefix and suffix.</para></listitem>
|
||||
<listitem><para>Invoke the <literal>getFilter</literal> method, passing in the search
|
||||
term, the prefix, and the suffix.</para></listitem>
|
||||
<listitem><para>Invoke the <literal>setupFilter</literal> method, passing the search
|
||||
term, the prefix, and the suffix.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>Setting the prefix and suffix for an individual filter overrides any prefix
|
||||
or suffix set for the entire filter configuration file.</para></listitem>
|
||||
</itemizedlist>
|
||||
<sect2 id="affixes-all-filters"><title>Adding Affixes for All Filters</title>
|
||||
<para>The following code loads a filter configuration file <filename>ldapfilter.conf
|
||||
</filename> into memory, and adds the prefix <literal>(&(l=Sunnyvale</literal> and
|
||||
suffix <literal>)</literal> to each filter retrieved from the file:</para>
|
||||
<programlisting>LDAPFilterDescriptor filtdesc = null;
|
||||
try {
|
||||
/* Read in the filter configuration file. */
|
||||
filtdesc = new LDAPFilterDescriptor("ldapfilter.conf");
|
||||
|
||||
/* Add the specified prefix and suffix to all filters. */
|
||||
String prefix = "(&(l=Sunnyvale)";
|
||||
String suffix = ")";
|
||||
<emphasis>filtdesc.setFilterAffixes(prefix, suffix);</emphasis>
|
||||
|
||||
/* Get filters from the section "people" */
|
||||
LDAPFilterList filtlist = null;
|
||||
try {
|
||||
filtlist = filtdesc.getFilters("people", searchTerm);
|
||||
} catch (Exception e) {
|
||||
System.out.println("No matching tag section or filter");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/* Iterate through the lines in the list. */
|
||||
while (filtlist.hasMoreElements()) {
|
||||
LDAPFilter filtline = filtlist.next();
|
||||
|
||||
/* Get and print each filter. */
|
||||
String filterString = filtline.getFilter();
|
||||
System.out.println(" Generated filter string: " +
|
||||
filterString + "\n");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}</programlisting>
|
||||
<para>For example, if the following search term is passed to the <literal>LDAPFilterDescriptor.getFilters
|
||||
</literal> method:</para>
|
||||
<literallayout><literal>bjensen@example.com</literal></literallayout>
|
||||
<para>and the corresponding filter, not including the prefix or suffix, is:</para>
|
||||
<literallayout><literal>(mail=bjensen@example.com)</literal></literallayout>
|
||||
<para>the entire filter string retrieved by the <literal>LDAPFilter.getFilter</literal> method
|
||||
is:</para>
|
||||
<literallayout><literal>(&(l=Sunnyvale)(mail=bjensen@example.com))</literal></literallayout>
|
||||
</sect2>
|
||||
<sect2 id="affixes-setFilterAffixes"><title>Adding Affixes Using <literal>setFilterAffixes
|
||||
</literal></title>
|
||||
<para>The following code loads a filter configuration file <filename>ldapfilter.conf
|
||||
</filename> into memory, and uses the <literal>LDAPFilter.setFilterAffixes</literal> method
|
||||
to add the prefix <literal>(&(l=Sunnyvale</literal> and suffix <literal>)</literal> to
|
||||
a generated filter:</para>
|
||||
<programlisting>LDAPFilterDescriptor filtdesc = null;
|
||||
try {
|
||||
/* Read in the filter configuration file. */
|
||||
filtdesc = new LDAPFilterDescriptor("ldapfilter.conf");
|
||||
|
||||
/* Get filters from the section "people" */
|
||||
LDAPFilterList filtlist = null;
|
||||
try {
|
||||
filtlist = filtdesc.getFilters("people", searchTerm);
|
||||
} catch (Exception e) {
|
||||
System.out.println("No matching tag section or filter");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/* Iterate through the lines in the list. */
|
||||
while (filtlist.hasMoreElements()) {
|
||||
LDAPFilter filtline = filtlist.next();
|
||||
|
||||
/* Add the prefix and suffix, and generate the filter. */
|
||||
String prefix = "(&(l=Sunnyvale)";
|
||||
String suffix = ")";
|
||||
<emphasis>filtline.setFilterAffixes(prefix, suffix);</emphasis>
|
||||
String filterString = filtline.getFilter(searchTerm);
|
||||
System.out.println(" Generated filter string: " +
|
||||
filterString + "\n");
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
System.out.println( "Error: " + e.toString() );
|
||||
}</programlisting>
|
||||
<para>For example, if the following search term is passed to the <literal>LDAPFilterDescriptor.getFilters
|
||||
</literal> method:</para>
|
||||
<literallayout><literal>bjensen@example.com</literal></literallayout>
|
||||
<para>and the corresponding filter, not including the prefix or suffix, is:</para>
|
||||
<literallayout><literal>(mail=bjensen@example.com)</literal></literallayout>
|
||||
<para>the entire filter string retrieved by the <literal>LDAPFilter.getFilter</literal> method
|
||||
is:</para>
|
||||
<literallayout><literal>(&(l=Sunnyvale)(mail=bjensen@example.com))</literal></literallayout>
|
||||
</sect2>
|
||||
<sect2 id="affixes-getFilter"><title>Adding Affixes Using <literal>getFilter</literal></title>
|
||||
<para>The following code loads a filter configuration file <filename>ldapfilter.conf
|
||||
</filename> into memory, and uses the <literal>LDAPFilter.getFilter</literal> method
|
||||
to add the prefix <literal>(&(l=Sunnyvale</literal> and suffix <literal>)</literal> to
|
||||
a generated filter:</para>
|
||||
<programlisting>LDAPFilterDescriptor filtdesc = null;
|
||||
try {
|
||||
/* Read in the filter configuration file. */
|
||||
filtdesc = new LDAPFilterDescriptor("ldapfilter.conf");
|
||||
|
||||
/* Get filters from the section "people" */
|
||||
LDAPFilterList filtlist = null;
|
||||
try {
|
||||
filtlist = filtdesc.getFilters("people", searchTerm);
|
||||
} catch (Exception e) {
|
||||
System.out.println("No matching tag section or filter");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/* Iterate through the lines in the list. */
|
||||
while (filtlist.hasMoreElements()) {
|
||||
LDAPFilter filtline = filtlist.next();
|
||||
|
||||
/* Add the prefix and suffix, and generate the filter. */
|
||||
String prefix = "(&(l=Sunnyvale)";
|
||||
String suffix = ")";
|
||||
<emphasis>String filterString =
|
||||
filtline.getFilter(searchTerm, prefix, suffix);</emphasis>
|
||||
System.out.println(" Generated filter string: " +
|
||||
filterString + "\n");
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
System.out.println( "Error: " + e.toString() );
|
||||
}</programlisting>
|
||||
<para>For example, if the following search term is passed to the <literal>LDAPFilterDescriptor.getFilters
|
||||
</literal> method:</para>
|
||||
<literallayout><literal>bjensen@example.com</literal></literallayout>
|
||||
<para>and the corresponding filter, not including the prefix or suffix, is:</para>
|
||||
<literallayout><literal>(mail=bjensen@example.com)</literal></literallayout>
|
||||
<para>the entire filter string retrieved by the <literal>LDAPFilter.getFilter</literal> method
|
||||
is:</para>
|
||||
<literallayout><literal>(&(l=Sunnyvale)(mail=bjensen@example.com))</literal></literallayout>
|
||||
</sect2>
|
||||
<sect2 id="affixes-setupFilter"><title>Adding Affixes Using <literal>setupFilter</literal></title>
|
||||
<para>The following code loads a filter configuration file <filename>ldapfilter.conf
|
||||
</filename> into memory, and uses the <literal>LDAPFilter.setupFilter</literal> method
|
||||
to add the prefix <literal>(&(l=Sunnyvale</literal> and suffix <literal>)</literal> to
|
||||
a generated filter:</para>
|
||||
<programlisting>LDAPFilterDescriptor filtdesc = null;
|
||||
try {
|
||||
/* Read in the filter configuration file. */
|
||||
filtdesc = new LDAPFilterDescriptor("ldapfilter.conf");
|
||||
|
||||
/* Get filters from the section "people" */
|
||||
LDAPFilterList filtlist = null;
|
||||
try {
|
||||
filtlist = filtdesc.getFilters("people", searchTerm);
|
||||
} catch (Exception e) {
|
||||
System.out.println("No matching tag section or filter");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/* Iterate through the lines in the list. */
|
||||
while (filtlist.hasMoreElements()) {
|
||||
LDAPFilter filtline = filtlist.next();
|
||||
|
||||
/* Add the prefix and suffix, and generate the filter. */
|
||||
String prefix = "(&(l=Sunnyvale)";
|
||||
String suffix = ")";
|
||||
<emphasis>filtline.setupFilter(searchTerm, prefix, suffix);</emphasis>
|
||||
String filterString = filtline.getFilter();
|
||||
System.out.println(" Generated filter string: "
|
||||
+ filterString + "\n");
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
System.out.println( "Error: " + e.toString() );
|
||||
}</programlisting>
|
||||
<para>For example, if the following search term is passed to the <literal>LDAPFilterDescriptor.getFilters
|
||||
</literal> method:</para>
|
||||
<literallayout><literal>bjensen@example.com</literal></literallayout>
|
||||
<para>and the corresponding filter, not including the prefix or suffix, is:</para>
|
||||
<literallayout><literal>(mail=bjensen@example.com)</literal></literallayout>
|
||||
<para>the entire filter string retrieved by the <literal>LDAPFilter.getFilter</literal> method
|
||||
is:</para>
|
||||
<literallayout><literal>(&(l=Sunnyvale)(mail=bjensen@example.com))</literal></literallayout>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
202
mozilla/directory/docs/ldapjdk/jdk-ldap-urls.sgm
Normal file
202
mozilla/directory/docs/ldapjdk/jdk-ldap-urls.sgm
Normal file
@@ -0,0 +1,202 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="ldap-urls"><title>LDAP URLs With &DirectorySDKForJava;</title>
|
||||
<highlights>
|
||||
<para>This chapter describes how to use LDAP URLs to search and retrieve data
|
||||
from the directory.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="url-components">Getting the Components of
|
||||
an LDAP URL With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="url-processing">Processing an LDAP URL With
|
||||
Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="url-search-example">Searching Using an LDAP
|
||||
URL With Directory SDK for Java</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="url-components"><title>Getting the Components of an LDAP URL With &DirectorySDKForJava;</title>
|
||||
<itemizedlist>
|
||||
<para>To get the individual components of an LDAP URL, pass the URL to the <literal>
|
||||
LDAPUrl</literal> constructor to create a new <classname>LDAPUrl</classname> object.
|
||||
Then, use the following methods:</para>
|
||||
<listitem><para>To get an array of the attributes that should be returned
|
||||
in the search results, use the <literal>getAttributeArray</literal> method.
|
||||
To get these attributes as an enumeration, use the <literal>getAttributes</literal> method.
|
||||
</para></listitem>
|
||||
<listitem><para>To get the host name of the LDAP server, use the <literal>getHost
|
||||
</literal> method.</para></listitem>
|
||||
<listitem><para>To get the port number of the LDAP server, use the <literal>getPort
|
||||
</literal> method.</para></listitem>
|
||||
<listitem><para>To get the base DN, use the <literal>getDN</literal> method.</para>
|
||||
</listitem>
|
||||
<listitem><para>To get the scope of the search, use the <literal>getScope</literal> method.
|
||||
</para></listitem>
|
||||
<listitem><para>To get the search filter, use the <literal>getFilter</literal> method.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="url-processing"><title>Processing an LDAP URL With &DirectorySDKForJava;</title>
|
||||
<itemizedlist>
|
||||
<para>To process the search request specified by an LDAP URL, you can invoke
|
||||
one of the following methods, passing in the <classname>LDAPUrl</classname> object:
|
||||
</para>
|
||||
<listitem><para>If the URL specifies a base search for a single entry, invoke
|
||||
the <literal>read</literal> method of the <classname>LDAPConnection</classname> object.
|
||||
This method reads the entry from the directory.</para></listitem>
|
||||
<listitem><para>Otherwise, invoke the <literal>search</literal> method of
|
||||
the <classname>LDAPConnection</classname> object to perform the search.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>Both methods create a new <classname>LDAPConnection</classname> object
|
||||
and connect to the LDAP server specified in the URL. Next, the methods perform
|
||||
the search. Then the methods disconnect.</para></sect1>
|
||||
<sect1 id="url-search-example"><title>Searching Using an LDAP URL With &DirectorySDKForJava;</title>
|
||||
<para>The following example demonstrates a search that uses an LDAP URL, invoking
|
||||
the <literal>search</literal> method of the <classname>LDAPConnection</classname> object
|
||||
to perform the search. Before the search is performed, the LDAP URL is exploded
|
||||
using the methods suggested previously in this chapter.</para>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import netscape.ldap.util.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.*;
|
||||
|
||||
public class SrchUrl {
|
||||
public static void main( String[] args ) {
|
||||
LDAPConnection ld = null;
|
||||
LDAPEntry findEntry = null;
|
||||
int status = -1;
|
||||
try {
|
||||
UserArgs userArgs = new UserArgs("SrchUrl", args, false);
|
||||
ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
|
||||
LDAPUrl myUrl = new LDAPUrl(
|
||||
"ldap://" +
|
||||
userArgs.getHost() + // server host
|
||||
":" +
|
||||
userArgs.getPort() + // server port
|
||||
"/" +
|
||||
"dc=example,dc=com" + // base DN
|
||||
"?" +
|
||||
"cn,sn,mail,telephonenumber" + // attrs to retrieve
|
||||
"?" +
|
||||
"sub" + // search scope
|
||||
"?" +
|
||||
"(uid=bjensen)"); // search filter
|
||||
|
||||
System.out.println( "LDAP URL : " + myUrl.toString() );
|
||||
System.out.println( " host : " + myUrl.getHost() );
|
||||
System.out.println( " port : " + myUrl.getPort() );
|
||||
System.out.println( " baseDN: " + myUrl.getDN() );
|
||||
String [] myAttrs = myUrl.getAttributeArray();
|
||||
for ( String myAttr: myAttrs ) {
|
||||
System.out.println( " attrs : " + myAttr );
|
||||
}
|
||||
System.out.println( " scope : " + myUrl.getScope() );
|
||||
System.out.println( " filter: " + myUrl.getFilter() );
|
||||
|
||||
LDAPSearchResults res = ld.search( myUrl );
|
||||
|
||||
/* Loop on results until finished; will only be one! */
|
||||
while ( res.hasMoreElements() ) {
|
||||
|
||||
/* Next directory entry, really only one at most */
|
||||
try {
|
||||
findEntry = res.next();
|
||||
} catch ( LDAPReferralException e ) {
|
||||
System.out.println( "Search reference: " );
|
||||
LDAPUrl refUrls[] = e.getURLs();
|
||||
for (int i=0; i<refUrls.length; i++) {
|
||||
System.out.println( "\t" + refUrls[i].getUrl() );
|
||||
}
|
||||
continue;
|
||||
} catch ( LDAPException e ) {
|
||||
System.err.println( "Error: " + e.toString() );
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the attributes of the entry */
|
||||
LDAPAttributeSet findAttrs = findEntry.getAttributeSet();
|
||||
Enumeration enumAttrs = findAttrs.getAttributes();
|
||||
|
||||
/* Loop on attributes */
|
||||
while ( enumAttrs.hasMoreElements() ) {
|
||||
LDAPAttribute anAttr =
|
||||
(LDAPAttribute)enumAttrs.nextElement();
|
||||
String attrName = anAttr.getName();
|
||||
if ( attrName.equals( "cn" ) )
|
||||
System.out.println( "Full name:" );
|
||||
else if ( attrName.equals( "sn" ) )
|
||||
System.out.println( "Last name (surname):" );
|
||||
else if ( attrName.equals( "mail" ) )
|
||||
System.out.println( "Email address:" );
|
||||
else if ( attrName.equals( "telephonenumber" ) )
|
||||
System.out.println( "Telephone number:" );
|
||||
/* Loop on values for this attribute */
|
||||
Enumeration enumVals = anAttr.getStringValues();
|
||||
if (enumVals != null) {
|
||||
while ( enumVals.hasMoreElements() ) {
|
||||
String aVal = ( String )enumVals.nextElement();
|
||||
System.out.println( "\t" + aVal );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( LDAPException e ) {
|
||||
System.err.println( "Error: " + e.toString() );
|
||||
}
|
||||
catch( MalformedURLException e ) {
|
||||
System.err.println( "Error: " + e.toString() );
|
||||
}
|
||||
|
||||
/* Done, so disconnect */
|
||||
if ( (ld != null) && ld.isConnected() ) {
|
||||
try {
|
||||
ld.disconnect();
|
||||
} catch ( LDAPException e ) {
|
||||
System.out.println( "Error: " + e.toString() );
|
||||
}
|
||||
}
|
||||
System.exit(status);
|
||||
}
|
||||
}</programlisting>
|
||||
<para>When this program is compiled and run against a directory that holds
|
||||
Barbara Jensen's entry, the program generates the following output.</para>
|
||||
<screen>$ <userinput>java SrchUrl -h myhost -p 1389</userinput>
|
||||
LDAP URL : ldap://myhost:1389/dc=example,dc=com?cn,sn,mail,telephonenumber?sub?(uid=bjensen)
|
||||
host : mykryten
|
||||
port : 1389
|
||||
baseDN: dc=example,dc=com
|
||||
attrs : cn
|
||||
attrs : sn
|
||||
attrs : mail
|
||||
attrs : telephonenumber
|
||||
scope : 2
|
||||
filter: (uid=bjensen)
|
||||
Full name:
|
||||
Barbara Jensen
|
||||
Babs Jensen
|
||||
Last name (surname):
|
||||
Jensen
|
||||
Email address:
|
||||
bjensen@example.com
|
||||
Telephone number:
|
||||
+1 408 555 1862</screen>
|
||||
</sect1>
|
||||
</chapter>
|
||||
212
mozilla/directory/docs/ldapjdk/jdk-quickstart.sgm
Normal file
212
mozilla/directory/docs/ldapjdk/jdk-quickstart.sgm
Normal file
@@ -0,0 +1,212 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="quickstart-jdk"><title>Getting Started With &DirectorySDKForJava;</title>
|
||||
<highlights>
|
||||
<para>This chapter shows how to develop a first LDAP client with the &DirectorySDKForJava;.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="understanding-java-classes">Understanding
|
||||
the LDAP Java Classes</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="understanding-sample">Understanding the
|
||||
Sample Java Client</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="sample-code">Sample Java Code</olink></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="understanding-java-classes"><title>Understanding the LDAP Java
|
||||
Classes</title>
|
||||
<indexterm>
|
||||
<primary>packages</primary>
|
||||
<secondary>summary of</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>&DirectorySDKForJava;</primary>
|
||||
<secondary>packages</secondary>
|
||||
</indexterm>
|
||||
<para>&DirectorySDKForJava; includes the LDAP Java classes, which you use
|
||||
to build LDAP clients. The LDAP Java classes allow you to write client applications
|
||||
that connect to LDAP servers. The classes also allow you to perform standard
|
||||
LDAP operations. For example, you can search for entries. You can also add,
|
||||
update, or delete entries.</para>
|
||||
<para>The classes are organized in the following packages.</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><literal>com.netscape.sasl</literal></term>
|
||||
<listitem><para>Contains the interfaces and classes that you can use to enable
|
||||
your client to authenticate by using a SASL mechanism.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>com.netscape.sasl.mechanisms</literal></term>
|
||||
<listitem><para>Contains an implementation of the <literal>EXTERNAL</literal> SASL
|
||||
mechanism driver.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>netscape.ldap</literal></term>
|
||||
<listitem><para>Contains the main LDAP Java classes, including classes that
|
||||
allow you to connect to an LDAP server, manipulate entries and attributes,
|
||||
and retrieve search results.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<!--<varlistentry><term><literal>netscape.ldap.beans</literal></term>
|
||||
<listitem><para>Contains LDAP <trademark>JavaBeans
|
||||
</trademark> technology. You can use LDAP JavaBeans
|
||||
classes in a development environment such as Sun Java
|
||||
Studio.</para>
|
||||
</listitem>
|
||||
</varlistentry>-->
|
||||
<varlistentry><term><literal>netscape.ldap.ber.stream</literal></term>
|
||||
<listitem><para>Contains the LDAP Java classes that implement the <firstterm>Basic
|
||||
Encoding Rules</firstterm> (BER) for transfer syntax. For more information
|
||||
about BER, see ISO-IEC 8825 at <ulink url="http://www.iso.ch/" type="url">http://www.iso.ch/
|
||||
</ulink>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>netscape.ldap.controls</literal></term>
|
||||
<listitem><para>Contains the LDAP Java classes that implement specific LDAP
|
||||
v3 controls. The implementations include controls to request server-side sorting
|
||||
and persistent searches.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>netscape.ldap.factory</literal></term>
|
||||
<listitem><para>Contains classes that allow you to create an SSL socket connection
|
||||
to a server.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>netscape.ldap.util</literal></term>
|
||||
<listitem><para>Contains utility classes, such as classes to parse LDIF data
|
||||
and filters that allow regular expression matching.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>Clients typically execute methods in &DirectorySDKForJava; synchronously.
|
||||
All LDAP operations block until the operations are completed, except for the <literal>
|
||||
search</literal> method, which can return information before all the results
|
||||
have been received.</para>
|
||||
<para>An asynchronous interface is also provided for circumstances that require
|
||||
low-level interaction with an LDAP server. The asynchronous interface is discussed
|
||||
more fully in <olink targetptr="asynchronous">Chapter 13, Writing Asynchronous Clients With Directory SDK for Java</olink>.</para></sect1>
|
||||
<sect1 id="understanding-sample"><title>Understanding the Sample Java Client</title>
|
||||
<para>The sample client in this chapter retrieves the full name (<literal>cn</literal>),
|
||||
last name (<literal>sn</literal>), email address (<literal>mail</literal>),
|
||||
and telephone number (<literal>telephoneNumber</literal>) of Barbara Jensen.
|
||||
You can find the program in the <filename>GetAttrs.java</filename> file in
|
||||
the <filename class="directory">examples/java</filename> directory.</para>
|
||||
<orderedlist>
|
||||
<para>The client does the following:</para>
|
||||
<listitem><para>Creates a new <classname>LDAPConnection</classname> object,
|
||||
which represents the connection to the LDAP server</para></listitem>
|
||||
<listitem><para>Connects to the server</para></listitem>
|
||||
<listitem><para>Searches for a single entry, identified by the DN using the
|
||||
following search criteria:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>The base DN, the starting point for the search, is <literal>uid=bjensen,ou=People,dc=example,dc=com
|
||||
</literal>.</para></listitem>
|
||||
<listitem><para>The search scope is <literal>LDAPConnection.SCOPE_BASE</literal>,
|
||||
meaning only the base DN.</para></listitem>
|
||||
<listitem><para>The search filter is <literal>"objectclass=*"</literal>, meaning
|
||||
the filter matches any entry.</para><para>As the scope narrows the search
|
||||
to a single entry, the search filter does not need to be more specific. </para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>To invoke a search on a single entry with these parameters is equivalent
|
||||
to using the <literal>LDAPConnection.read</literal> method.</para>
|
||||
</listitem>
|
||||
<listitem><para>Iterates through the enumerated search results to retrieve
|
||||
and print the values of the <literal>cn</literal>, <literal>sn</literal>, <literal>
|
||||
mail</literal>, and <literal>telephoneNumber</literal> attributes</para><para>This
|
||||
iteration also allows the client to obtain multiple values for a single attribute.
|
||||
</para></listitem>
|
||||
<listitem><para>Disconnects from the server</para></listitem></orderedlist>
|
||||
<para>Before you compile the sample client, make sure that the <filename>packages/ldapjdk.jar
|
||||
</filename> file is in your <envar>CLASSPATH</envar>.</para></sect1>
|
||||
<sect1 id="sample-code"><title>Sample Java Code</title>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import netscape.ldap.util.*;
|
||||
import java.util.*;
|
||||
|
||||
public class GetAttrs {
|
||||
public static void main( String[] args ) {
|
||||
try {
|
||||
UserArgs userArgs = new UserArgs("GetAttrs", args, false);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
|
||||
String ENTRYDN = "uid=bjensen, ou=People, dc=example,dc=com";
|
||||
String[] attrNames = {
|
||||
"cn", // Get canonical name(s) (full name)
|
||||
"sn", // Get surname(s) (last name)
|
||||
"mail", // Get email address(es)
|
||||
"telephonenumber"}; // Get telephone number(s)
|
||||
LDAPSearchResults res =
|
||||
ld.search(ENTRYDN, ld.SCOPE_BASE, "(objectclass=*)",
|
||||
attrNames, false );
|
||||
|
||||
/* Loop on results until finished; only one entry here */
|
||||
while (res.hasMoreElements()) {
|
||||
LDAPEntry findEntry = null;
|
||||
try {
|
||||
findEntry = res.next();
|
||||
} catch (LDAPReferralException e) {
|
||||
System.out.println("Search reference: ");
|
||||
LDAPUrl refUrls[] = e.getURLs();
|
||||
for (int i=0; i < refUrls.length; i++) {
|
||||
System.out.println("\t" + refUrls[i].getUrl());
|
||||
}
|
||||
continue;
|
||||
} catch (LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the attributes of the entry */
|
||||
LDAPAttributeSet findAttrs = findEntry.getAttributeSet();
|
||||
Enumeration enumAttrs = findAttrs.getAttributes();
|
||||
|
||||
/* Loop on attributes */
|
||||
while (enumAttrs.hasMoreElements()) {
|
||||
LDAPAttribute anAttr =
|
||||
(LDAPAttribute)enumAttrs.nextElement();
|
||||
String attrName = anAttr.getName();
|
||||
if (attrName.equals("cn")) {
|
||||
System.out.println("Full name:");
|
||||
} else if (attrName.equals("sn")) {
|
||||
System.out.println("Last name (surname):");
|
||||
} else if (attrName.equals("mail")) {
|
||||
System.out.println("Email address:");
|
||||
} else if (attrName.equals("telephonenumber")) {
|
||||
System.out.println("Telephone number:");
|
||||
}
|
||||
/* Loop on values for this attribute */
|
||||
Enumeration enumVals = anAttr.getStringValues();
|
||||
if (enumVals != null) {
|
||||
while (enumVals.hasMoreElements()) {
|
||||
String aVal = (String)enumVals.nextElement();
|
||||
System.out.println("\t" + aVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ld.disconnect();
|
||||
}
|
||||
catch(LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</sect1>
|
||||
</chapter>
|
||||
338
mozilla/directory/docs/ldapjdk/jdk-sasl.sgm
Normal file
338
mozilla/directory/docs/ldapjdk/jdk-sasl.sgm
Normal file
@@ -0,0 +1,338 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="sasl"><title>SASL Authentication With &DirectorySDKForJava;</title>
|
||||
<highlights>
|
||||
<para>This chapter describes the process of using a SASL mechanism to authenticate
|
||||
an LDAP client to an LDAP server.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="sasl-overview">Understanding SASL and Directory
|
||||
SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="sasl-prepare">Preparing to Use SASL Authentication
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="sasl-client">Using SASL in the Client With
|
||||
Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="sasl-reading">Further Reading About SASL</olink></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="sasl-overview"><title>Understanding SASL and &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>SASL</primary>
|
||||
<secondary>defined</secondary>
|
||||
</indexterm>
|
||||
<para>The Simple Authentication and Security Layer (SASL) is an authentication
|
||||
method. SASL allows you to use mechanisms other than simple passwords and
|
||||
SSL for authenticating over connection-based protocols, such as LDAP.</para>
|
||||
<para>All SASL mechanisms are registered with the Internet Assigned Numbers
|
||||
Authority (IANA). Included among these mechanisms are <literal>KERBEROS_V4</literal>, <literal>
|
||||
GSSAPI</literal>, and several others. The client implements these mechanisms
|
||||
through the use of mechanism drivers. These drivers are classes that contain
|
||||
the code that is required for authenticating over a given mechanism.</para>
|
||||
<para>When a client attempts to authenticate to an LDAP server with the <literal>
|
||||
LDAPConnection.authenticate</literal> method, the client can specify a list
|
||||
of SASL mechanisms to use. If the client does not specify any mechanisms, &DirectorySDKForJava; queries
|
||||
the server to find out which mechanisms the server supports. If &DirectorySDKForJava; and
|
||||
the server have a common mechanism, authentication can occur.</para>
|
||||
<para>If the server supports a requested mechanism, the server responds with
|
||||
one or more challenges. To authenticate, the client must correctly respond
|
||||
to these challenges. Client handling is performed transparently by &DirectorySDKForJava; with
|
||||
a mechanism driver.</para>
|
||||
<para>If the server does not support any of the requested mechanisms, the
|
||||
SDK returns an <classname>AuthenticationNotSupportedException</classname>.</para>
|
||||
<para>If the mechanism driver requires additional authentication data from
|
||||
the client, the driver sends a <classname>Callback</classname> object to the
|
||||
client. To prepare for the callback, the client implements a <classname>CallbackHandler
|
||||
</classname> and passes the handler to &DirectorySDKForJava;. The SASL
|
||||
mechanism might need additional client credentials. The SASL mechanism might
|
||||
also notify the client of errors during the SASL negotiations. For either
|
||||
purpose, the mechanism calls the <classname>CallbackHandler</classname> object
|
||||
with <classname>Callback</classname> objects for each item to be processed.
|
||||
The <classname>CallbackHandler</classname> then determines how to proceed.</para>
|
||||
<para>&DirectorySDKForJava; includes a package, <literal>com.netscape.sasl</literal>,
|
||||
that contains the code necessary to perform all of the steps involved in SASL
|
||||
authentication.</para></sect1>
|
||||
<sect1 id="sasl-prepare"><title>Preparing to Use SASL Authentication With &DirectorySDKForJava;</title>
|
||||
<itemizedlist>
|
||||
<para>Before performing SASL authentication, you must do the following:</para>
|
||||
<listitem><para>Ensure that your LDAP server supports at least one SASL mechanism
|
||||
</para></listitem>
|
||||
<listitem><para>Ensure that your client environment supports at least one
|
||||
SASL mechanism supported by the server</para></listitem>
|
||||
</itemizedlist>
|
||||
<sect2 id="sasl-prepare-server"><title>SASL Support on the Server</title>
|
||||
<indexterm>
|
||||
<primary>SASL</primary>
|
||||
<secondary>server-side requirements</secondary>
|
||||
</indexterm>
|
||||
<para>&cnDirectoryServer; supports a plug-in API that allows you to write
|
||||
your own server plug-in to handle SASL authentication. &cnDirectoryServer; also
|
||||
supports SASL authentication through DIGEST-MD5 and through GSSAPI.</para>
|
||||
<itemizedlist>
|
||||
<para>If you write your own plug-in, your plug-in uses a registered SASL mechanism
|
||||
to do the following:</para>
|
||||
<listitem><para>Get information from a SASL bind request.</para></listitem>
|
||||
<listitem><para>Create and send a SASL bind response back to the client.</para>
|
||||
<para>This response can take the form of a challenge that requires an answer
|
||||
from the client. The response can also take the form of an error message.
|
||||
Finally, the response can take the form of a success message indicating that
|
||||
authentication is complete.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<sect2 id="sasl-prepare-client"><title>SASL Support on the Client</title>
|
||||
<indexterm>
|
||||
<primary>SASL</primary>
|
||||
<secondary>client-side requirements</secondary>
|
||||
</indexterm>
|
||||
<para>To authenticate over SASL, you must have a mechanism in your SASL client
|
||||
package. If you have obtained a <classname>ClientFactory</classname> class
|
||||
that can produce a SASL mechanism that your server supports, you can name
|
||||
its package in your code.</para>
|
||||
<itemizedlist>
|
||||
<para>This option can be performed in one of two ways:</para>
|
||||
<listitem><para>Request a SASL client. Specify the package in the <property>javax.security.sasl.client.pkgs
|
||||
</property> property of its <classname>Hashtable</classname>.</para></listitem>
|
||||
<listitem><para>Set the package as the default factory for the session with
|
||||
the <literal>Sasl.setSaslClientFactory</literal> method.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>For example, you might have a class, <classname>mysecurity.sasl.ClientFactory
|
||||
</classname>, capable of producing a <classname>SaslClient</classname> object
|
||||
for one or more mechanisms. You could then write either of the two following
|
||||
bits of code:</para>
|
||||
<programlisting>Hashtable props = new Hashtable();
|
||||
props.put("javax.security.sasl.client.pkgs", "mysecurity.sasl");
|
||||
ld.authenticate(dn, props, cbh);</programlisting>
|
||||
<programlisting>Sasl.setSaslClientFactory (new mysecurity.sasl.ClientFactory());
|
||||
ld.authenticate(dn, props, cbh);</programlisting>
|
||||
<para>The parameters used have the following descriptions:</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><parameter>dn</parameter></term>
|
||||
<listitem><para>Authentication DN</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><parameter>props</parameter></term>
|
||||
<listitem><para>Optional properties that the mechanism accepts</para>
|
||||
<para>Refer to <olink type="auto-generated" targetptr="sasl-client-external">Using
|
||||
the External Mechanism</olink> for details.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><parameter>cbh</parameter></term>
|
||||
<listitem><para>Instance of <classname>CallbackHandler</classname> that is
|
||||
implemented in your application</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
<sect2 id="sasl-prepare-callback"><title>Implementing <literal>javax.security.auth.callback
|
||||
</literal></title>
|
||||
<indexterm>
|
||||
<primary>authentication</primary>
|
||||
<secondary>implementing SASL callbacks</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>callbacks</primary>
|
||||
<secondary>implementing for SASL</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>SASL</primary>
|
||||
<secondary>implementing callbacks</secondary>
|
||||
</indexterm>
|
||||
<para>Some SASL mechanisms require additional credentials during the authentication
|
||||
process. To provide this additional information, your SASL client might need
|
||||
to implement <classname>Callback</classname> objects and a <classname>CallbackHandler
|
||||
</classname> to list credentials. <classname>Callback</classname> and <classname>
|
||||
CallbackHandler</classname> are part of the <literal>javax.security.auth.callback
|
||||
</literal> package.</para>
|
||||
<para>The following example shows <classname>Callback</classname> and <classname>
|
||||
CallbackHandler</classname> implementations.</para>
|
||||
<programlisting>class SampleCallbackHandler implements CallbackHandler {
|
||||
SampleCallbackHandler(String userName) {
|
||||
userName = userName;
|
||||
}
|
||||
/** Invoke the requested Callback */
|
||||
public void invokeCallback(Callback[] callbacks)
|
||||
throws java.io.IOException,UnsupportedCallbackException {
|
||||
for (int i = 0; i < callbacks.length; i++) {
|
||||
if (callbacks[i] instanceof TextOutputCallback) {
|
||||
// display the message according to the
|
||||
// specified STYLE
|
||||
TextOutputCallback toc =
|
||||
		 (TextOutputCallback)callbacks[i];
|
||||
switch (toc.getStyle()) {
|
||||
case TextOutputCallback.ERROR:
|
||||
System.out.println("ERROR: " + toc.getMessage());
|
||||
break;
|
||||
case TextOutputCallback.INFORMATION:
|
||||
System.out.println(toc.getMessage());
|
||||
break;
|
||||
case TextOutputCallback.WARNING:
|
||||
System.out.println("WARNING: " + toc.getMessage());
|
||||
break;
|
||||
}
|
||||
} else if (callbacks[i] instanceof TextInputCallback){
|
||||
// prompt the user for information
|
||||
TextInputCallback tic = (TextInputCallback)callbacks[i];
|
||||
// display the prompt and a default reply
|
||||
System.err.print(tic.getPrompt() + " [" +
|
||||
tic.getDefaultText() + "]: ");
|
||||
System.err.flush();
|
||||
BufferedReader reader = new
|
||||
BufferedReader(new InputStreamReader(System.in));
|
||||
tic.setText(reader.readLine());
|
||||
} else if (callbacks[i] instanceof NameCallback) {
|
||||
((NameCallback)callbacks[i]).setName(_userName);
|
||||
} else if (callbacks[i] instanceof PasswordCallback){
|
||||
// prompt the user for sensitive information
|
||||
PasswordCallback pc = (PasswordCallback)callbacks[i];
|
||||
System.err.print(pc.getPrompt() + " ");
|
||||
System.err.flush();
|
||||
pc.setPassword(readPassword(System.in));
|
||||
} else if (callbacks[i] instanceof LanguageCallback){
|
||||
// Get the language from the locale
|
||||
LanguageCallback lc = (LanguageCallback)callbacks[i];
|
||||
lc.setLocale(Locale.getDefault());
|
||||
} else {
|
||||
throw new UnsupportedCallbackException(
|
||||
		 callbacks[i], "Unrecognized Callback");
|
||||
}
|
||||
}
|
||||
}
|
||||
/** Reads user password from given input stream. */
|
||||
private char[] readPassword(InputStream in) {
|
||||
// insert code to read a user password from the
|
||||
// input stream
|
||||
}
|
||||
private String _userName = null;
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="sasl-client"><title>Using SASL in the Client With &DirectorySDKForJava;</title>
|
||||
<itemizedlist>
|
||||
<para>You are ready to authenticate when you have done the following:</para>
|
||||
<listitem><para>Determined that at least one SASL mechanism exists in common
|
||||
between the server and your client environment</para></listitem>
|
||||
<listitem><para>Implemented <classname>javax.security.auth.callback.CallbackHandler
|
||||
</classname> if you might need to supply additional credentials during authentication
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>The following example shows how to use SASL in an application:</para>
|
||||
<programlisting>Hashtable props = new Hashtable();
|
||||
props.put("javax.security.sasl.client.pkgs", "mysecurity.sasl");
|
||||
ld.authenticate(dn, props, new SampleCallbackHandler());</programlisting>
|
||||
<sect2 id="sasl-client-external"><title>Using the <literal>External</literal> Mechanism
|
||||
</title>
|
||||
<indexterm>
|
||||
<primary>SASL</primary>
|
||||
<secondary>using the EXTERNAL mechanism with</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>SSL</primary>
|
||||
<secondary>using SASL with</secondary>
|
||||
</indexterm>
|
||||
<para>&DirectorySDKForJava; includes a mechanism called <literal>EXTERNAL</literal>.
|
||||
This mechanism verifies that SSL authentication has already completed before
|
||||
the mechanism allows a client to connect over LDAP.</para>
|
||||
<orderedlist>
|
||||
<para>To use the <literal>EXTERNAL</literal> mechanism, do the following:</para>
|
||||
<listitem><para>Bind to the server, and authenticate using SSL.</para><para>Refer
|
||||
to <olink type="auto-generated" targetptr="ssl-connecting">Connecting to a
|
||||
Server Over SSL With Directory SDK for Java</olink> for details.</para>
|
||||
</listitem>
|
||||
<listitem><para>Call the <literal>LDAPConnection.authenticate</literal> method
|
||||
as follows:</para>
|
||||
<programlisting>ld = new LDAPConnection();
|
||||
ld.authenticate(
|
||||
null, new String[]{"EXTERNAL"}, null, (CallbackHandler)null);</programlisting>
|
||||
<para><literal>LDAPConnection.authenticate</literal> takes the following parameters.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><parameter>dn</parameter></term>
|
||||
<listitem><para>Authentication DN</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><parameter>mechanisms</parameter></term>
|
||||
<listitem><para>List of SASL mechanisms to use for authentication</para>
|
||||
<para>If <literal>null</literal> is specified, &DirectorySDKForJava; queries
|
||||
the server for all available mechanisms.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><parameter>props</parameter></term>
|
||||
<listitem><para>Optional properties that the mechanism accepts, which include
|
||||
the following:</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><property>javax.security.sasl.encryption.minimum</property></term>
|
||||
<listitem><para>The minimum key length to be used during the session.</para>
|
||||
<para>The default value is <literal>0</literal>, no session protection. A
|
||||
value of <literal>1</literal> enables integrity protection only.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><property>javax.security.sasl.encryption.maximum</property></term>
|
||||
<listitem><para>The maximum key length to be used during the session.</para>
|
||||
<para>The default value is <literal>256</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><property>javax.security.sasl.server.authentication</property></term>
|
||||
<listitem><para>A boolean value.</para>
|
||||
<para><literal>true</literal> if a server must authenticate to the client.
|
||||
The default value is <literal>false</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><property>javax.security.sasl.ip.local</property></term>
|
||||
<listitem><para>The client's IP address in dotted decimal format.</para>
|
||||
<para>This value is required for <literal>KERBEROS_V4</literal> authentication.
|
||||
No default value exists.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><property>javax.security.sasl.ip.remote</property></term>
|
||||
<listitem><para>The server's IP address in dotted decimal format.</para>
|
||||
<para>This value is required for <literal>KERBEROS_V4</literal> authentication.
|
||||
No default value exists.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><property>javax.security.sasl.maxbuffer</property></term>
|
||||
<listitem><para>The maximum size of the security layer frames.</para>
|
||||
<para>The default is <literal>0</literal>, meaning that the client does not
|
||||
use the security layer.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><property>javax.security.sasl.client.pkgs</property></term>
|
||||
<listitem><para>A bar-separated list of package names to use when locating
|
||||
a <classname>SaslClientFactory</classname>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><parameter>cbh</parameter></term>
|
||||
<listitem><para>Instance of <classname>CallbackHandler</classname> that is
|
||||
implemented in your application.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</sect2>
|
||||
<sect2 id="sasl-client-other"><title>Other SASL Mechanisms</title>
|
||||
<para>Authentication with a SASL mechanism other than <literal>EXTERNAL</literal> requires
|
||||
you to implement classes for the mechanism in the client and on the server.</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="sasl-reading"><title>Further Reading About SASL</title>
|
||||
<para>SASL is described in <ulink url="http://www.ietf.org/rfc/rfc4422.txt"
|
||||
type="text_url">RFC 4422</ulink>.</para>
|
||||
<para>For a current list of registered SASL mechanisms, see <ulink
|
||||
url="http://www.iana.org/assignments/sasl-mechanisms" type="url">http://www.iana.org/assignments/sasl-mechanisms
|
||||
</ulink>.</para></sect1>
|
||||
</chapter>
|
||||
970
mozilla/directory/docs/ldapjdk/jdk-searching.sgm
Normal file
970
mozilla/directory/docs/ldapjdk/jdk-searching.sgm
Normal file
@@ -0,0 +1,970 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="searching"><title>Searching the Directory With &DirectorySDKForJava;</title>
|
||||
<highlights>
|
||||
<para>This chapter explains how to use the LDAP Java classes to search the
|
||||
directory to retrieve entries. The chapter also describes how to get attributes
|
||||
and attribute values from an entry.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="searching-overview">Searching With the LDAP
|
||||
Java Classes</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="searching-request">Sending a Search Request
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="searching-results">Getting the Search Results
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="searching-sorting">Sorting the Search Results
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="searching-abandoning">Abandoning a Search
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="searching-example">Searching the Directory
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="searching-read">Reading an Entry With Directory
|
||||
SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="searching-child-entries">Listing Child Entries
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="searching-overview"><title>Searching With the LDAP Java Classes</title>
|
||||
<itemizedlist>
|
||||
<para>In &DirectorySDKForJava;, searches are represented by objects of
|
||||
the following classes:</para>
|
||||
<listitem><para>You can send a search request by invoking the <literal>search</literal> method
|
||||
of the <classname>LDAPConnection</classname> object.</para></listitem>
|
||||
<listitem><para>You can specify a set of search constraints by using an <classname>
|
||||
LDAPSearchConstraints</classname> object. The constraints can specify the
|
||||
maximum number of results to return. The constraints can also specify the
|
||||
maximum amount of time that is allowed for a search.</para></listitem>
|
||||
<listitem><para>You can specify different parts of the search criteria in
|
||||
separate arguments. Alternatively, you can construct an <classname>LDAPUrl</classname> object
|
||||
to specify the search criteria.</para></listitem>
|
||||
<listitem><para>You can search for a single entry by invoking the <literal>read</literal> method
|
||||
of the <classname>LDAPConnection</classname> object.</para></listitem>
|
||||
<listitem><para>The server returns the search results to the LDAP Java classes,
|
||||
which represents the results as an <classname>LDAPSearchResults</classname> object.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="searching-request"><title>Sending a Search Request With &DirectorySDKForJava;</title>
|
||||
<para>To search the directory, use the <literal>search</literal> method of
|
||||
the <classname>LDAPConnection</classname> object. The search results are returned
|
||||
in the form of an <classname>LDAPSearchResults</classname> object.</para>
|
||||
<programlisting>public LDAPSearchResults search(String base, int scope,
|
||||
String filter, String attrs[], boolean attrsOnly,
|
||||
LDAPSearchConstraints cons) throws LDAPException</programlisting>
|
||||
<para>You need to specify the following parameters as arguments to the <literal>search
|
||||
</literal> method.</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><parameter>base</parameter></term>
|
||||
<listitem><para>Specifies the base DN, which is the entry on and under which
|
||||
the search is carried out.</para>
|
||||
<para>For example, when searching entries with DNs such as <literal>uid=bjensen,ou=People,dc=example,dc=com
|
||||
</literal>, the <parameter>base</parameter> could be <literal>ou=People,dc=example,dc=com
|
||||
</literal> or <literal>dc=example,dc=com</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><parameter>scope</parameter></term>
|
||||
<listitem><para>Specifies the scope of the search.</para>
|
||||
<para>You can adjust the scope of the search to examine only the entry identified
|
||||
by the <parameter>base</parameter>, only those entries one level down the
|
||||
tree from the <parameter>base</parameter>, or the entire subtree underneath
|
||||
the <parameter>base</parameter>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><parameter>filter</parameter></term>
|
||||
<listitem><para>Specifies what to search for.</para>
|
||||
<para>A search filter specifies what search results to return. The filter
|
||||
meaning can be simple, such as “find entries where the last name is
|
||||
Jensen”. The filter meaning can also be complex, such as “find
|
||||
entries that belong to Dept. #17 and with first names that start with the
|
||||
letter F.”</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><parameter>attrs</parameter></term><term><parameter>attrsOnly
|
||||
</parameter></term>
|
||||
<listitem><para>Specify the entry attributes to retrieve.</para>
|
||||
<para>For example, you can use <parameter>attrs</parameter> to retrieve only
|
||||
email addresses and phone numbers. Alternatively, you can set up a search
|
||||
to return all attributes in an entry. You can also specify to return only
|
||||
the names of attributes, not the values, by setting <parameter>attrsOnly</parameter> to <constant>
|
||||
true</constant>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><parameter>cons</parameter></term>
|
||||
<listitem><para>Specifies constraints to apply to the search when you do not
|
||||
want to use the default constraints.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>The following figure illustrates how search criteria work.</para>
|
||||
<figure id="searching-criteria"><title>Criteria for an LDAP Search</title>
|
||||
<mediaobject>
|
||||
<imageobject><imagedata entityref="hierovrw"></imageobject>
|
||||
<textobject><simpara>How search criteria work</simpara></textobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
<para>You can also specify the criteria in the form of an LDAP URL. An LDAP
|
||||
URL allows you to specify the host name and port number of the LDAP server
|
||||
that you want to search. To search a different LDAP server than the server
|
||||
you are connected to, you can invoke the search method. You then specify an
|
||||
LDAP URL in the form of an <classname>LDAPUrl</classname> object. See <olink
|
||||
targetptr="ldap-urls">Chapter 7, LDAP URLs With Directory SDK for Java</olink> for
|
||||
details.</para>
|
||||
<sect2 id="searching-specify-base"><title>Specifying the Base DN and Scope</title>
|
||||
<indexterm>
|
||||
<primary>base DN</primary>
|
||||
<secondary>explained</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>scope</primary>
|
||||
<secondary>explained</secondary>
|
||||
</indexterm>
|
||||
<para>When sending a search request, you need to specify the base DN and scope
|
||||
of the search to identify the entries that you want searched.</para>
|
||||
<para>The base DN is the DN of the entry that serves as the starting point
|
||||
of the search.</para>
|
||||
<itemizedlist>
|
||||
<para>To specify the scope of the search, you pass one of the following values
|
||||
as the scope parameter:</para>
|
||||
<listitem><para><constant>LDAPv3.SCOPE_SUB</constant> — Search the base
|
||||
entry and all entries at all levels under the base entry.</para>
|
||||
<mediaobject>
|
||||
<imageobject><imagedata entityref="hiersrch"></imageobject>
|
||||
<textobject><simpara>Subtree scope applies to everything below the base DN.</simpara>
|
||||
</textobject>
|
||||
</mediaobject>
|
||||
</listitem>
|
||||
<listitem><para><constant>LDAPv3.SCOPE_ONE</constant> — Search all entries
|
||||
at one level under the base entry.</para>
|
||||
<mediaobject>
|
||||
<imageobject><imagedata entityref="hier1lvl"></imageobject>
|
||||
<textobject><simpara>One level scope applies to all entries just below the
|
||||
base DN.</simpara></textobject>
|
||||
</mediaobject>
|
||||
<para>The base entry is not included in the search. Use this setting if you
|
||||
just want a list of the entries under a given entry.</para></listitem>
|
||||
<listitem><para><constant>LDAPv3.SCOPE_BASE</constant> — Search only
|
||||
the base entry.</para>
|
||||
<mediaobject>
|
||||
<imageobject><imagedata entityref="hierbase"></imageobject>
|
||||
<textobject><simpara>Base scope applies only to the base DN entry.</simpara>
|
||||
</textobject>
|
||||
</mediaobject>
|
||||
<para>Use this setting if you want to read the attributes of only the base
|
||||
entry.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<sect2 id="searching-filter"><title>Specifying a Search Filter</title>
|
||||
<indexterm>
|
||||
<primary>filters</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>search filters</primary>
|
||||
<secondary>specifying</secondary>
|
||||
</indexterm>
|
||||
<para>When you search the directory, you use a search filter to define the
|
||||
search. Here is the basic syntax for a search filter:</para>
|
||||
<programlisting>(<replaceable>attribute</replaceable> <replaceable>operator</replaceable> <replaceable>
|
||||
value</replaceable>)</programlisting>
|
||||
<para>Here is a simple example of a search filter:</para>
|
||||
<programlisting>(cn=Barbara Jensen)</programlisting>
|
||||
<para>In this example, <literal>cn</literal> is the attribute. <literal>=</literal> is
|
||||
the operator. <literal>Barbara Jensen</literal> is the value. The filter finds
|
||||
entries with the common name <literal>Barbara Jensen</literal>.</para>
|
||||
<para>Valid attributes that you can use in your search filter are provided
|
||||
in the documentation for the LDAP server.</para>
|
||||
<para>Following are descriptions of valid operators for search filters, and
|
||||
example filters that use the operators.</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><literal>=</literal></term>
|
||||
<listitem><para>Return entries whose attributes are equal to the value provided.</para>
|
||||
<para>For example, the following filter matches Barbara Jensen's entry:</para>
|
||||
<programlisting>(cn=Barbara Jensen)</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>>=</literal></term>
|
||||
<listitem><para>Return entries whose attributes are greater than or equal
|
||||
to the value provided.</para>
|
||||
<para>For example, the following filter matches Barbara Jensen's entry and
|
||||
entries for people with surnames following Jensen in alphabetic order, such
|
||||
as entries with <literal>sn=Seuss</literal> and <literal>sn=Zhivago</literal>:</para>
|
||||
<programlisting>(sn>=jensen)</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal><=</literal></term>
|
||||
<listitem><para>Return entries whose attributes are less than or equal to
|
||||
the value provided.</para>
|
||||
<para>For example, the following filter matches Barbara Jensen's entry and
|
||||
entries for people with surnames that precede Jensen in alphabetic order,
|
||||
such as entries with <literal>sn=Anderson</literal> and <literal>sn=Cubbins</literal>:
|
||||
</para>
|
||||
<programlisting>(sn<=jensen)</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>=*</literal></term>
|
||||
<listitem><para>Return entries that have a value set for the attribute (presence).
|
||||
</para>
|
||||
<para>For example, the following filter matches all entries that have a value
|
||||
for the surname:</para>
|
||||
<programlisting>(sn=*)</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>~=</literal></term>
|
||||
<listitem><para>Return entries whose attribute value approximately matches
|
||||
the specified value, such as the value sounds like the specified value.</para>
|
||||
<para>For example, the following filter matches all entries with values for
|
||||
surname that sound like Jensen, such as Barbara Jensen's entry, but also Emanuel
|
||||
Johnson's entry:</para>
|
||||
<programlisting>(sn~=jensen)</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>With Boolean operators and with parentheses, you can combine different
|
||||
sets of conditions. Here is the syntax for combining search filters:</para>
|
||||
<programlisting>(<replaceable>boolean</replaceable>(<replaceable>filter1</replaceable>)(<replaceable>
|
||||
filter2</replaceable>)(…))</programlisting>
|
||||
<para>Following are descriptions of the valid boolean operators.</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><literal>&</literal></term>
|
||||
<listitem><para>Return entries that match all specified filters.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>|</literal></term>
|
||||
<listitem><para>Return entries that match one or more of the specified filters.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>!</literal></term>
|
||||
<listitem><para>Return entries that do not match the specified filter.</para>
|
||||
<para>This operator is unary because you can apply the operator only to a
|
||||
single set of results. In other words, to specify “entries that match
|
||||
neither <replaceable>filter1</replaceable> nor <replaceable>filter2</replaceable>,”
|
||||
use the syntax:</para>
|
||||
<programlisting>(!(|(<replaceable>filter1</replaceable>)(<replaceable>filter2</replaceable>)))
|
||||
</programlisting>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>You can also include wildcard characters to search for entries that
|
||||
start with, contain, or end with a given value. For example, you can use the
|
||||
following filter to search for all entries with first names that begin with
|
||||
the letter <literal>F</literal>:</para>
|
||||
<programlisting>(givenName=F*)</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="searching-specify-attrs"><title>Specifying the Attributes to Retrieve</title>
|
||||
<indexterm>
|
||||
<primary>attributes</primary>
|
||||
<secondary>operational</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>attributes</primary>
|
||||
<secondary>retrieving in a search</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>operational attributes</primary>
|
||||
</indexterm>
|
||||
<itemizedlist>
|
||||
<para>With the <parameter>attrs</parameter> parameter, you can retrieve all
|
||||
attributes in entries returned by the search. Alternatively, you can specify
|
||||
the attributes that you want returned in the search results. For example,
|
||||
you can specify to return the attributes in one of the following ways:</para>
|
||||
<listitem><para>To return selected attributes, pass an array of the attribute
|
||||
names as the <parameter>attrs</parameter> parameter. For example, to return
|
||||
only email addresses and phone numbers, pass the array <literal>{"mail", "telephoneNumber"}
|
||||
</literal> as the <parameter>attrs</parameter> parameter.</para></listitem>
|
||||
<listitem><para>To return all attributes in an entry, pass <constant>null</constant> as
|
||||
the <parameter>attrs</parameter> parameter.</para></listitem>
|
||||
<listitem><para>To return no attributes from an entry, pass <constant>LDAPv3.NO_ATTRS
|
||||
</constant> as the <parameter>attrs</parameter> parameter.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>You might plan to sort the results on your client as described in <olink
|
||||
targetptr="searching-sorting">Sorting the Search Results With Directory SDK
|
||||
for Java</olink>. Return the attributes that you plan to use for sorting.
|
||||
For example, if you plan to sort by email address, make sure that the mail
|
||||
attribute is returned in the search results.</para>
|
||||
<para>Some attributes are used by servers for administering the directory.
|
||||
For example, the <literal>creatorsName</literal> attribute specifies the DN
|
||||
of the user who added the entry. These attributes are called <firstterm>operational
|
||||
attributes</firstterm>.</para>
|
||||
<para>Servers do not normally return operational attributes in search results
|
||||
unless you specify the attributes by name. For example, if you pass <constant>null
|
||||
</constant> as the <parameter>attrs</parameter> parameter to retrieve all
|
||||
of the attributes in entries found by the search, the operational attribute <literal>
|
||||
creatorsName</literal> is not returned to your client. You need to explicitly
|
||||
specify the <literal>creatorsName</literal> attribute in the <parameter>attrs</parameter> parameter.
|
||||
</para>
|
||||
<para>To return all attributes in an entry with selected operational attributes,
|
||||
pass a string array containing <constant>LDAPv3.ALL_USER_ATTRS</constant>,
|
||||
and also the names of the operational attributes as the <parameter>attrs</parameter> parameter.
|
||||
Following are a few operational attributes and a description of what each
|
||||
attribute contains.</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><literal>createTimestamp</literal></term>
|
||||
<listitem><para>The time when the entry was added to the directory.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>modifyTimestamp</literal></term>
|
||||
<listitem><para>The time when the entry was last modified.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>creatorsName</literal></term>
|
||||
<listitem><para>Distinguished name (DN) of the user who added the entry to
|
||||
the directory.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>modifiersName</literal></term>
|
||||
<listitem><para>DN of the user who last modified the entry.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>subschemaSubentry</literal></term>
|
||||
<listitem><para>DN of the subschema entry, that controls the schema for this
|
||||
entry.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
<sect2 id="searching-set-prefs"><title>Setting Search Preferences</title>
|
||||
<para>For a given search, you can apply a set of preferences that determine
|
||||
how the search is performed. For example, you can specify the maximum number
|
||||
of results to be returned or the maximum amount of time to wait for a search.</para>
|
||||
<para>The <classname>LDAPSearchConstraints</classname> class represents a
|
||||
set of search constraints. The methods of this class allow you to get and
|
||||
set the constraints.</para>
|
||||
<sect3 id="searching-set-prefs-all"><title>Setting Preferences for All Searches</title>
|
||||
<indexterm>
|
||||
<primary>search results</primary>
|
||||
<secondary>setting preferences</secondary>
|
||||
</indexterm>
|
||||
<para>The <classname>LDAPConnection</classname> object, which represents a
|
||||
connection to the LDAP server, is associated with a default set of search
|
||||
constraints. These constraints apply to all searches that you perform over
|
||||
the connection.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>To get the default set of search constraints for the connection,
|
||||
you can use the <literal>getSearchConstraints</literal> method.</para>
|
||||
</listitem>
|
||||
<listitem><para>To get or set any of the search constraints individually,
|
||||
you can use the <literal>getOption</literal> method and the <literal>setOption</literal> method.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>For example, if you want to specify the maximum number of results returned,
|
||||
you can set this constraint for the connection:</para>
|
||||
<programlisting>LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
|
||||
ld.setOption(LDAPv3.SIZELIMIT, new Integer(100));</programlisting>
|
||||
</sect3>
|
||||
<sect3 id="searching-set-prefs-override"><title>Overriding Preferences for
|
||||
Individual Searches</title>
|
||||
<para>To override the default set of search constraints for a given search
|
||||
request, construct your own <classname>LDAPSearchConstraints</classname> object.
|
||||
Pass the object to the <literal>search</literal> method of the <classname>LDAPConnection
|
||||
</classname> object.</para>
|
||||
<para>You can also modify a copy of the existing search constraints. Pass
|
||||
the modified set of constraints to the <literal>search</literal> method. Invoke
|
||||
the <literal>getSearchConstraints</literal> method of the <classname>LDAPConnection
|
||||
</classname> object to get the default set of constraints for that connection.
|
||||
Then invoke the clone method of the <classname>LDAPSearchConstraints</classname> object
|
||||
to make a copy of the set that you can then modify.</para></sect3>
|
||||
<sect3 id="searching-set-prefs-wait"><title>Configuring the Search to Wait
|
||||
for All Results</title>
|
||||
<indexterm>
|
||||
<primary>search results</primary>
|
||||
<secondary>waiting for all</secondary>
|
||||
</indexterm>
|
||||
<para>By default, the <literal>search</literal> method of the <classname>LDAPConnection
|
||||
</classname> object does not block until all results are received. Instead,
|
||||
the <literal>search</literal> method returns as soon as one of the results
|
||||
has been received.</para>
|
||||
<itemizedlist>
|
||||
<para>If you want the <literal>search</literal> method to block until all
|
||||
results are received, you can do one of the following:</para>
|
||||
<listitem><para>Use the <literal>setOption</literal> method of the <classname>LDAPConnection
|
||||
</classname> object to set the <constant>LDAPv3.BATCHSIZE</constant> preference
|
||||
to <literal>0</literal>.</para></listitem>
|
||||
<listitem><para>Pass a <literal>0</literal> to the <literal>setBatchSize</literal> method
|
||||
of the <classname>LDAPSearchConstraints</classname> object to change the behavior
|
||||
for a particular set of search constraints.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>Whether waiting for one or all results of the <literal>search</literal> method,
|
||||
you still need to invoke the <literal>next</literal> method of the returned <classname>
|
||||
LDAPSearchResults</classname> object to retrieve each individual result.</para>
|
||||
</sect3>
|
||||
<sect3 id="searching-set-prefs-size"><title>Setting Size and Time Limits</title>
|
||||
<indexterm>
|
||||
<primary>search results</primary>
|
||||
<secondary>setting size limits</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>search results</primary>
|
||||
<secondary>setting time limits</secondary>
|
||||
</indexterm>
|
||||
<para>By default, when you search the directory from a client that you built
|
||||
with &DirectorySDKForJava;, the maximum number of entries to return is
|
||||
set to <literal>1000</literal>. No maximum time limit is set for waiting on
|
||||
an operation to complete.</para>
|
||||
<itemizedlist>
|
||||
<para>To change these default values, you can do one of the following:</para>
|
||||
<listitem><para>Use the <literal>setOption</literal> method of the <classname>LDAPConnection
|
||||
</classname> object to set the <constant>LDAPv3.SIZELIMIT</constant> and <constant>
|
||||
LDAPv3.TIMELIMIT</constant> preferences.</para></listitem>
|
||||
<listitem><para>Use the <literal>setMaxResults</literal> method and the <literal>
|
||||
setTimeLimit</literal> method of the <classname>LDAPSearchConstraints</classname> object
|
||||
to change the behavior for a particular set of search constraints.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<para>When you set the size limit or time limit, you might cause an <classname>LDAPException
|
||||
</classname> to be returned. The exception is returned when the limit is exceeded.
|
||||
</para>
|
||||
<listitem><para>If the size limit is exceeded, the server returns an <constant>LDAPException.SIZE_LIMIT_EXCEEDED
|
||||
</constant> result code.</para></listitem>
|
||||
<listitem><para>If the time limit is exceeded, the server returns an <constant>LDAPException.TIME_LIMIT_EXCEEDED
|
||||
</constant> result code.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect3>
|
||||
</sect2>
|
||||
<sect2 id="searching-example-request"><title>Search Request Example</title>
|
||||
<para>The following section of code searches for all entries with surname <literal>
|
||||
Jensen</literal>. The search retrieves the names and values of the <literal>cn</literal>, <literal>
|
||||
mail</literal>, and <literal>telephoneNumber</literal> attributes.</para>
|
||||
<programlisting>LDAPConnection ld = null;
|
||||
try {
|
||||
/* Create a new LDAPConnection object. */
|
||||
ld = new LDAPConnection();
|
||||
|
||||
/* Connect and bind to the server. */
|
||||
String HOSTNAME = "localhost";
|
||||
ld.connect(HOSTNAME, LDAPv3.DEFAULT_PORT, null, null);
|
||||
|
||||
/* Specify the search criteria. */
|
||||
String baseDN = "dc=example,dc=com";
|
||||
int searchScope = LDAPv3.SCOPE_SUB;
|
||||
String searchFilter = "(sn=Jensen)";
|
||||
String getAttrs[] = {"cn", "mail", "telephoneNumber"};
|
||||
|
||||
/* Send the search request. */
|
||||
LDAPSearchResults res = ld.search(baseDN, searchScope,
|
||||
searchFilter, getAttrs, false);
|
||||
} catch(LDAPException e) {
|
||||
System.out.println("Error: " + e.toString);
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="searching-results"><title>Getting the Search Results With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>search results</primary>
|
||||
<secondary>getting</secondary>
|
||||
</indexterm>
|
||||
<para>When you invoke the <literal>search</literal> method of an <classname>LDAPConnection
|
||||
</classname> object to search the directory, the method returns the search
|
||||
results in the form of an <classname>LDAPSearchResults</classname> object.</para>
|
||||
<para>The search results consist of an enumeration of entries, which are represented
|
||||
by <classname>LDAPEntry</classname> objects. The search results can also include
|
||||
smart referrals, also known as <firstterm>search references</firstterm>, and
|
||||
exceptions.</para>
|
||||
<para>Each entry contains a set of attributes, which are represented by <classname>
|
||||
LDAPAttributeSet</classname> objects. Individual attributes are represented
|
||||
by <classname>LDAPAttribute</classname> objects. Each attribute has a set
|
||||
of values that you can get.</para>
|
||||
<para>The following figure illustrates the relationship between entries, attributes,
|
||||
values, and search results.</para>
|
||||
<figure id="searching-result-set"><title>Entries, Attributes, and Values in
|
||||
Search Results</title>
|
||||
<mediaobject>
|
||||
<imageobject><imagedata entityref="entries"></imageobject>
|
||||
<textobject><simpara>Relationship between entries, attributes, values, and
|
||||
search results</simpara></textobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
<sect2 id="searching-results-entries"><title>Getting Entries</title>
|
||||
<indexterm>
|
||||
<primary>entries</primary>
|
||||
<secondary>getting from search results</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>search results</primary>
|
||||
<secondary>getting entries</secondary>
|
||||
</indexterm>
|
||||
<para>The <classname>LDAPSearchResults</classname> object represents the results
|
||||
of the search. These results can include entries found by the search, search
|
||||
references, and result codes. Your LDAP client can receive an <returnvalue>ADMIN_LIMIT_EXCEEDED
|
||||
</returnvalue>, <returnvalue>TIME_LIMIT_EXCEEDED</returnvalue>, or <returnvalue>SIZE_LIMIT_EXCEEDED
|
||||
</returnvalue> result code from the server. When the result code is received, &DirectorySDKForJava; adds
|
||||
an exception for this result code to the search results.</para>
|
||||
<para>To get entries from the <classname>LDAPSearchResults</classname> object,
|
||||
you can either invoke the <literal>next</literal> method or the <literal>nextElement
|
||||
</literal> method.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>When you invoke the <literal>next</literal> method, if the
|
||||
next item in the search results is an entry, the method returns an <classname>LDAPEntry
|
||||
</classname> object.</para>
|
||||
<itemizedlist>
|
||||
<para><indexterm>
|
||||
<primary>referrals</primary>
|
||||
<secondary><classname>LDAPReferralException</classname> and</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>referrals</primary>
|
||||
<secondary>getting from search results</secondary>
|
||||
</indexterm>If the next item is a search reference, one of the following can
|
||||
occur:</para>
|
||||
<listitem><para>If referrals are not followed automatically, an <classname>LDAPReferralException
|
||||
</classname> is returned. The exception is also returned if the referral hop
|
||||
limit is exceeded.</para></listitem>
|
||||
<listitem><para>The LDAP Java classes follow the referral when two conditions
|
||||
are fulfilled. Referrals must be followed automatically, the referral hop
|
||||
limit must not be exceeded. </para></listitem>
|
||||
</itemizedlist>
|
||||
<para>The classes also retrieve the entry for you. The method creates a new
|
||||
connection to the server that is specified in the referral and attempts to
|
||||
retrieve the entry from that server.</para><para>See <olink
|
||||
targetptr="handling-referrals">Handling Referrals With Directory SDK for Java</olink> for
|
||||
more information about referrals and search references.</para><para>If the
|
||||
next item is an LDAP result code such as <returnvalue>ADMIN_LIMIT_EXCEEDED</returnvalue>, <returnvalue>
|
||||
TIME_LIMIT_EXCEEDED</returnvalue>, or <returnvalue>SIZE_LIMIT_EXCEEDED</returnvalue>,
|
||||
the LDAP Java classes return an <classname>LDAPException</classname>.</para>
|
||||
</listitem>
|
||||
<listitem><para>When you invoke the <literal>nextElement</literal> method,
|
||||
the method returns an object that you must cast. The object is an <classname>LDAPEntry
|
||||
</classname> object, an <classname>LDAPReferralException</classname>, or an <classname>
|
||||
LDAPException</classname>.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>As you iterate through the search results, you can invoke the <literal>hasMoreElements
|
||||
</literal> method to determine if you have reached the end of the search results.
|
||||
</para>
|
||||
<programlisting>LDAPConnection ld = null;
|
||||
try {
|
||||
/* Create a new LDAPConnection object. */
|
||||
ld = new LDAPConnection();
|
||||
|
||||
/* Set up parameters for the search request... */
|
||||
|
||||
/* Send the search request. */
|
||||
LDAPSearchResults res = ld.search(baseDN, searchScope,
|
||||
searchFilter, getAttrs, false);
|
||||
|
||||
/* Iterate through the results until finished. */
|
||||
while (res.hasMoreElements()) {
|
||||
|
||||
/* Get the next entry in the results. */
|
||||
LDAPEntry findEntry = null;
|
||||
try {
|
||||
findEntry = res.next();
|
||||
|
||||
/* If it is a referral, print the LDAP URLs. */
|
||||
} catch (LDAPReferralException e) {
|
||||
System.out.println("Search references: ");
|
||||
LDAPUrl refUrls[] = e.getURLs();
|
||||
for (int i=0; i < refUrls.length; i++) {
|
||||
System.out.println("\t" + refUrls[i].getUrl());
|
||||
}
|
||||
continue;
|
||||
} catch (LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
continue;
|
||||
}
|
||||
/* Do something with the entry... */
|
||||
}
|
||||
} catch (LDAPException e) {
|
||||
/* Handle exceptions arising outside the search... */
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="searching-results-dns"><title>Getting Distinguished Names</title>
|
||||
<indexterm>
|
||||
<primary>distinguished names</primary>
|
||||
<secondary>getting from search results</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>search results</primary>
|
||||
<secondary>getting distinguished names</secondary>
|
||||
</indexterm>
|
||||
<para>To get the distinguished name of an <classname>LDAPEntry</classname> object,
|
||||
invoke the <literal>getDN</literal> method. This method returns a <classname>String
|
||||
</classname>.</para>
|
||||
<programlisting>LDAPEntry nextEntry = res.next();
|
||||
String nextDN = nextEntry.getDN();</programlisting>
|
||||
<para>Although the <literal>netscape.ldap</literal> package includes an <classname>
|
||||
LDAPDN</classname> class, you typically do not construct objects of this class
|
||||
to represent DNs. The <classname>LDAPDN</classname> class is mainly a utility
|
||||
class that provides methods for manipulating string DNs.</para></sect2>
|
||||
<sect2 id="searching-results-attrs"><title>Getting Attributes</title>
|
||||
<indexterm>
|
||||
<primary>attributes</primary>
|
||||
<secondary>getting from search results</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>search results</primary>
|
||||
<secondary>getting attributes</secondary>
|
||||
</indexterm>
|
||||
<para>To get the set of attributes in an <classname>LDAPEntry</classname> object,
|
||||
invoke the <literal>getAttributeSet</literal> method. This method returns
|
||||
an <classname>LDAPAttributeSet</classname> object.</para>
|
||||
<programlisting>LDAPEntry nextEntry = res.next();
|
||||
LDAPAttributeSet entryAttrs = nextEntry.getAttributeSet();</programlisting>
|
||||
<para>To get individual attributes from an <classname>LDAPAttributeSet</classname> object,
|
||||
invoke the <literal>getAttributes</literal> method. This method returns an
|
||||
enumeration of attributes. You can then iterate through the elements in this
|
||||
enumeration to retrieve individual <classname>LDAPAttribute</classname> objects.</para>
|
||||
<programlisting>/* Get the set of attributes for an entry. */
|
||||
LDAPAttributeSet entryAttrs = nextEntry.getAttributeSet();
|
||||
|
||||
/* Get an enumeration of those attribute. */
|
||||
Enumeration enumAttrs = entryAttrs.getAttributes();
|
||||
|
||||
/* Loop through the enumeration to get each attribute. */
|
||||
while (enumAttrs.hasMoreElements()) {
|
||||
LDAPAttribute attr = (LDAPAttribute)enumAttrs.nextElement();
|
||||
System.out.println("Attribute type: " + attr.getName());
|
||||
}</programlisting>
|
||||
<para>To determine the number of attributes in the <classname>LDAPAttributeSet</classname> object,
|
||||
invoke the <literal>size</literal> method.</para>
|
||||
<itemizedlist>
|
||||
<para>You can also retrieve a specific attribute from the entry or from the
|
||||
attribute set.</para>
|
||||
<listitem><para>To get a specific attribute from an <classname>LDAPEntry</classname> object,
|
||||
invoke the <literal>getAttribute</literal> method.</para></listitem>
|
||||
<listitem><para>To get a specific attribute from an <classname>LDAPAttributeSet</classname> object,
|
||||
invoke the <literal>getAttribute</literal> method.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>Both methods return an <classname>LDAPAttribute</classname> object.</para>
|
||||
<programlisting>LDAPEntry nextEntry = res.next();
|
||||
LDAPAttribute anAttr = nextEntry.getAttribute("cn");</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="searching-results-attr-types-values"><title>Getting Attribute Types
|
||||
and Values</title>
|
||||
<indexterm>
|
||||
<primary>attributes</primary>
|
||||
<secondary>getting from search results</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>search results</primary>
|
||||
<secondary>getting attribute types</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>search results</primary>
|
||||
<secondary>getting attribute values</secondary>
|
||||
</indexterm>
|
||||
<para>To get the name of an <classname>LDAPAttribute</classname> object, invoke
|
||||
the <literal>getName</literal> method.</para>
|
||||
<programlisting>LDAPAttribute nextAttr = (LDAPAttribute)enumAttrs.nextElement();
|
||||
String attrName = nextAttr.getName();</programlisting>
|
||||
<itemizedlist>
|
||||
<para>To get the values in an <classname>LDAPAttribute</classname> object,
|
||||
you can use the following methods:</para>
|
||||
<listitem><para>To get the <classname>String</classname> values, invoke the <literal>
|
||||
getStringValues</literal> method.</para></listitem>
|
||||
<listitem><para>To get the binary values as byte arrays, invoke the <literal>getByteValues
|
||||
</literal> method.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>Both methods return an enumeration that you can iterate through to retrieve
|
||||
individual results. For example, if an error occurs when you invoke <literal>getStringValues
|
||||
</literal>, although the values are binary data, the methods return <constant>null
|
||||
</constant>.</para>
|
||||
<para>You can also count the number of values in an attribute by invoking
|
||||
the <literal>size</literal> method of the <classname>LDAPAttribute</classname> object.
|
||||
</para>
|
||||
<programlisting>LDAPAttribute nextAttr = (LDAPAttribute)enumAttrs.nextElement();
|
||||
|
||||
/* Get and print the attribute name. */
|
||||
String attrName = nextAttr.getName();
|
||||
System.out.println("\t" + attrName + ":");
|
||||
|
||||
/* Iterate through the attribute's values. */
|
||||
Enumeration enumVals = nextAttr.getStringValues();
|
||||
if (enumVals != null) {
|
||||
while (enumVals.hasMoreElements()) {
|
||||
String nextValue = (String)enumVals.nextElement();
|
||||
System.out.println("\t\t" + nextValue);
|
||||
}
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="searching-sorting"><title>Sorting the Search Results With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>search results</primary>
|
||||
<secondary>sorting</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>sorting search results</primary>
|
||||
</indexterm>
|
||||
<itemizedlist>
|
||||
<para>With &DirectorySDKForJava;, you can sort the search results in two
|
||||
ways.</para>
|
||||
<listitem><para>You can specify that the LDAP server should sort the results
|
||||
before returning the results to your client.</para><para>Send a server-side
|
||||
sort control to the server as described in <olink targetptr="controls">Chapter 10,
|
||||
LDAP Controls With Directory SDK for Java</olink>. Server-side sorting might
|
||||
work best if you specify a filter that uses an indexed attribute.</para>
|
||||
</listitem>
|
||||
<listitem><para>After you receive the results from the server, you can sort
|
||||
the results on your client.</para><para>Specify the names of the attributes
|
||||
that you want to use for sorting. You also need to specify whether or not
|
||||
the sorting is done in ascending or descending order.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>You can sort the results on the client by invoking the sort method of
|
||||
the <classname>LDAPSearchResults</classname> object.</para>
|
||||
<para><indexterm>
|
||||
<primary><classname>LDAPEntryComparator</classname> interface</primary>
|
||||
<secondary>example of</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary><classname>LDAPEntryCompareAttrNames</classname> class</primary>
|
||||
<secondary>example of</secondary>
|
||||
</indexterm>When invoking this method, you need to pass a comparator object,
|
||||
which is an object of a class that implements the <classname>LDAPEntryComparator</classname> interface. &DirectorySDKForJava; includes
|
||||
an <classname>LDAPCompareAttrNames</classname> class that implements this
|
||||
interface. This class specifies how entries are compared with each other and
|
||||
sorted.</para>
|
||||
<para>To construct an <classname>LDAPCompareAttrNames</classname> object,
|
||||
you need to specify the attributes that you want to use for sorting and, optionally,
|
||||
the sort order. When sorting on the client side, the attributes used for sorting
|
||||
must be returned in the search results. If you are returning only a subset
|
||||
of attributes in the search results, include the attributes that you specify
|
||||
in the <classname>LDAPCompareAttrNames</classname> constructor. For example,
|
||||
the following section of code sorts first by surname, <literal>sn</literal>,
|
||||
and then by common name, <literal>cn</literal>, in ascending order:</para>
|
||||
<programlisting>LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect("localhost", LDAPv3.DEFAULT_PORT);
|
||||
LDAPSearchResults res = ld.search("dc=example,dc=com", LDAPv3.SCOPE_SUB,
|
||||
"(objectclass=inetOrgPerson)", null, false);
|
||||
String[] sortAttrs = {"sn", "cn"};
|
||||
boolean[] ascending = {true, true};
|
||||
res.sort(new LDAPCompareAttrNames(sortAttrs, ascending));</programlisting>
|
||||
<para>If all search results have not yet been returned, the <literal>sort</literal> method
|
||||
blocks until all results have been received.</para></sect1>
|
||||
<sect1 id="searching-abandoning"><title>Abandoning a Search With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>abandoning a search</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>searching the directory</primary>
|
||||
<secondary>abandoning a search</secondary>
|
||||
</indexterm>
|
||||
<para>At any point during a search operation, you can send a request to the
|
||||
server to abandon (cancel) the search. To abandon the search, use the <literal>abandon
|
||||
</literal> method of the <classname>LDAPConnection</classname> object. Pass
|
||||
in the <classname>LDAPSearchResults</classname> object that was returned to
|
||||
you when you first invoked the <literal>search</literal> method.</para></sect1>
|
||||
<sect1 id="searching-example"><title>Searching the Directory With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>searching the directory</primary>
|
||||
<secondary>example of</secondary>
|
||||
</indexterm>
|
||||
<para>The following example prints the values of all attributes in the entries
|
||||
returned by a search.</para>
|
||||
<example id="searching-example-code"><title>Searching for a Specific Entry</title>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
|
||||
public class Search {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
UserArgs userArgs = new UserArgs("Search", args, false);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
|
||||
/* search for all entries with surname of Jensen */
|
||||
String MY_FILTER = "sn=Jensen";
|
||||
String MY_SEARCHBASE = "dc=example,dc=com";
|
||||
|
||||
LDAPSearchConstraints cons = ld.getSearchConstraints();
|
||||
/* Setting the batchSize to one will cause the result
|
||||
enumeration below to block on one result at a time,
|
||||
enabling an update of a list or other things as
|
||||
results come in. */
|
||||
/* This could be set to 0 in order to get all
|
||||
results and to block until then. */
|
||||
cons.setBatchSize(1);
|
||||
LDAPSearchResults res = ld.search(MY_SEARCHBASE,
|
||||
LDAPConnection.SCOPE_SUB, MY_FILTER, null, false, cons);
|
||||
|
||||
/* Loop on results until finished */
|
||||
while (res.hasMoreElements()) {
|
||||
LDAPEntry findEntry = null;
|
||||
try {
|
||||
findEntry = res.next();
|
||||
} catch (LDAPReferralException e) {
|
||||
System.out.println("Search reference: ");
|
||||
LDAPUrl refUrls[] = e.getURLs();
|
||||
for (int i=0; i<refUrls.length; i++) {
|
||||
System.out.println("\t" + refUrls[i].getUrl());
|
||||
}
|
||||
continue;
|
||||
} catch (LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
continue;
|
||||
}
|
||||
System.out.println(findEntry.getDN());
|
||||
|
||||
/* Get the attributes of the entry */
|
||||
LDAPAttributeSet findAttrs = findEntry.getAttributeSet();
|
||||
Enumeration enumAttrs = findAttrs.getAttributes();
|
||||
System.out.println("\tAttributes: ");
|
||||
|
||||
/* Loop on attributes */
|
||||
while (enumAttrs.hasMoreElements()) {
|
||||
LDAPAttribute anAttr =
|
||||
(LDAPAttribute)enumAttrs.nextElement();
|
||||
String attrName = anAttr.getName();
|
||||
System.out.println("\t\t" + attrName);
|
||||
|
||||
/* Loop on values for this attribute */
|
||||
Enumeration enumVals = anAttr.getStringValues();
|
||||
if (enumVals != null) {
|
||||
while (enumVals.hasMoreElements()) {
|
||||
String aVal = (String)enumVals.nextElement();
|
||||
System.out.println("\t\t\t" + aVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ld.disconnect();
|
||||
} catch(LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</example>
|
||||
</sect1>
|
||||
<sect1 id="searching-read"><title>Reading an Entry With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>entries</primary>
|
||||
<secondary>reading from directory</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>reading an entry from the directory</primary>
|
||||
</indexterm>
|
||||
<para>To get a single entry from the directory, use the <literal>read</literal> method
|
||||
of the <classname>LDAPConnection</classname> object. You can specify the DN
|
||||
of the entry with the attributes that you want to retrieve, instead of retrieving
|
||||
all attributes of the entry. You can also specify an LDAP URL that identifies
|
||||
the entry that you want to retrieve.</para>
|
||||
<para>To retrieve data from the entry, you can use the same classes with their
|
||||
methods, as described in <olink targetptr="searching-results-attrs">Getting
|
||||
Attributes</olink> and in <olink targetptr="searching-results-attr-types-values">
|
||||
Getting Attribute Types and Values</olink>.</para>
|
||||
<para>The following example retrieves an entry and prints the values of its
|
||||
attributes.</para>
|
||||
<example id="searching-example-code-read"><title>Retrieving a Specific Entry</title>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
|
||||
public class RdEntry {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
UserArgs userArgs = new UserArgs("PasswordPolicy", args, false);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
|
||||
String ENTRYDN = "uid=bjensen, ou=People, dc=example,dc=com";
|
||||
|
||||
/* Read all attributes */
|
||||
LDAPEntry findEntry = ld.read(ENTRYDN);
|
||||
System.out.println(findEntry.getDN());
|
||||
|
||||
/* Get the attributes of the entry */
|
||||
LDAPAttributeSet findAttrs = findEntry.getAttributeSet();
|
||||
Enumeration enumAttrs = findAttrs.getAttributes();
|
||||
System.out.println("\tAttributes: ");
|
||||
|
||||
/* Loop on attributes */
|
||||
while (enumAttrs.hasMoreElements()) {
|
||||
LDAPAttribute anAttr =
|
||||
(LDAPAttribute)enumAttrs.nextElement();
|
||||
String attrName = anAttr.getName();
|
||||
System.out.println("\t\t" + attrName);
|
||||
|
||||
/* Loop on values for this attribute */
|
||||
Enumeration enumVals = anAttr.getStringValues();
|
||||
if (enumVals != null) {
|
||||
while (enumVals.hasMoreElements()) {
|
||||
String aVal = (String)enumVals.nextElement();
|
||||
System.out.println("\t\t\t" + aVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
ld.disconnect();
|
||||
} catch(LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</example>
|
||||
</sect1>
|
||||
<sect1 id="searching-child-entries"><title>Listing Child Entries With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>entries</primary>
|
||||
<secondary>retrieving child entries of</secondary>
|
||||
</indexterm>
|
||||
<para>To retrieve the entries directly beneath a particular entry, set the
|
||||
starting point of the search to the entry. Also, set the scope of the search
|
||||
to <constant>LDAPv3.SCOPE_ONE</constant>.</para>
|
||||
<figure id="EWAUN"><title>Using Scope of One to Retrieve Child Entries</title>
|
||||
<mediaobject>
|
||||
<imageobject><imagedata entityref="hier1lvl" width="100"></imageobject>
|
||||
<textobject><simpara>Search for child entries</simpara></textobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
<para>The following code performs a one-level search:</para>
|
||||
<programlisting>LDAPConnection ld = null;
|
||||
try {
|
||||
ld = new LDAPConnection();
|
||||
ld.connect("localhost", LDAPv3.DEFAULT_PORT);
|
||||
|
||||
LDAPSearchResults res = ld.search("dc=example,dc=com", LDAPv3.SCOPE_ONE,
|
||||
"(objectclass=*)", null, false );
|
||||
|
||||
/* Loop on results until finished */
|
||||
while (res.hasMoreElements()) {
|
||||
LDAPEntry findEntry = null;
|
||||
try {
|
||||
findEntry = res.next();
|
||||
|
||||
/* If the next result is a referral, print the LDAP URLs. */
|
||||
} catch (LDAPReferralException e) {
|
||||
System.out.println("Search references: ");
|
||||
LDAPUrl refUrls[] = e.getURLs();
|
||||
for (int i=0; i < refUrls.length; i++) {
|
||||
System.out.println("\t" + refUrls[i].getUrl());
|
||||
}
|
||||
continue;
|
||||
} catch ( LDAPException e ) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Print the DN of the entry. */
|
||||
System.out.println(findEntry.getDN());
|
||||
|
||||
/* Get the attributes of the entry */
|
||||
LDAPAttributeSet findAttrs = findEntry.getAttributeSet();
|
||||
Enumeration enumAttrs = findAttrs.getAttributes();
|
||||
System.out.println("\tAttributes: ");
|
||||
/* Loop on attributes */
|
||||
while (enumAttrs.hasMoreElements()) {
|
||||
LDAPAttribute anAttr = (LDAPAttribute)enumAttrs.nextElement();
|
||||
String attrName = anAttr.getName();
|
||||
System.out.println("\t\t" + attrName);
|
||||
|
||||
/* Loop on values for this attribute */
|
||||
Enumeration enumVals = anAttr.getStringValues();
|
||||
if (enumVals != null) {
|
||||
while (enumVals.hasMoreElements()) {
|
||||
String aVal = (String)enumVals.nextElement();
|
||||
System.out.println("\t\t\t" + aVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch( LDAPException e ) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}
|
||||
|
||||
/* Done, so disconnect. */
|
||||
if ((ld != null) && ld.isConnected()) {
|
||||
try {
|
||||
ld.disconnect();
|
||||
} catch (LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}</programlisting>
|
||||
</sect1>
|
||||
</chapter>
|
||||
575
mozilla/directory/docs/ldapjdk/jdk-server-info.sgm
Normal file
575
mozilla/directory/docs/ldapjdk/jdk-server-info.sgm
Normal file
@@ -0,0 +1,575 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="server-info"><title>Getting Server Information With &DirectorySDKForJava;
|
||||
</title>
|
||||
<highlights>
|
||||
<para>This chapter explains how to access and modify information about your
|
||||
LDAP server over the LDAP protocol.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="server-info-dse-intro">About DSEs</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="server-info-dse-info">Getting the Root DSE
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="server-info-ldapv3">Checking Support for
|
||||
LDAP v3 With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="server-info-schema">Getting Schema Information
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="server-info-dse-intro"><title>About DSEs</title>
|
||||
<para>The acronym <acronym>DSE</acronym> refers to a <emphasis>DSA-specific
|
||||
entry</emphasis> in the directory. A DSA is a <emphasis>directory system agent</emphasis>,
|
||||
an X.500 term for a directory server. A DSE contains information specific
|
||||
to the server.</para>
|
||||
<para>LDAP v3 uses the concept of the <firstterm>root DSE</firstterm>. In
|
||||
a directory tree, the root of the tree is the root DSE. The root DSE is not
|
||||
part of any naming context. In other words, the entry is superior to <literal>dc=example,dc=com
|
||||
</literal>, <literal>cn=config</literal>, and similar suffixes in the directory
|
||||
tree. Servers that do not support LDAP v3 therefore do not necessarily have
|
||||
a root DSE.</para>
|
||||
<itemizedlist>
|
||||
<para>The root DSE can contain the following information:</para>
|
||||
<listitem><para>The naming contexts the server supports, such as <literal>dc=example,dc=com
|
||||
</literal> or <literal>cn=config</literal></para></listitem>
|
||||
<listitem><para>URLs to alternate servers that can be contacted if the server
|
||||
is unavailable</para></listitem>
|
||||
<listitem><para>The LDAP v3 extended operations the server supports</para>
|
||||
</listitem>
|
||||
<listitem><para>The LDAP v3 controls the server supports</para></listitem>
|
||||
<listitem><para>The SASL mechanisms the server supports</para></listitem>
|
||||
<listitem><para>The versions of LDAP the server supports</para></listitem>
|
||||
<listitem><para>Additional, server-specific information</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="server-info-dse-info"><title>Getting the Root DSE With &DirectorySDKForJava;
|
||||
</title>
|
||||
<indexterm>
|
||||
<primary>DSE</primary>
|
||||
<secondary>root</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>root DSE</primary>
|
||||
</indexterm>
|
||||
<para>The root DSE for an LDAP server specifies information about the server.
|
||||
The attributes of the root DSE and what the attributes provide are shown here.</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><literal>altServer</literal></term>
|
||||
<listitem><para>LDAP URLs that identify other servers to contact when the
|
||||
server is not available.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>namingContexts</literal></term>
|
||||
<listitem><para>Naming contexts, such as <literal>dc=example,dc=com</literal>,
|
||||
supported by the server.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>supportedControl</literal></term>
|
||||
<listitem><para><firstterm>Object identifiers</firstterm> (OIDs) of LDAP v3
|
||||
controls supported by the server.</para>
|
||||
<para>If this attribute is not present, the server does not support LDAP v3
|
||||
controls.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>supportedExtension</literal></term>
|
||||
<listitem><para>Object identifiers (OIDs) of LDAP v3 extended operations supported
|
||||
by the server.</para>
|
||||
<para>If this attribute is not present, the server does not support LDAP v3
|
||||
extended operations.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>supportedLDAPVersion</literal></term>
|
||||
<listitem><para>Versions of LDAP, <literal>2</literal> or <literal>3</literal>,
|
||||
supported by the server.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>supportedSASLMechanisms</literal></term>
|
||||
<listitem><para>Names of SASL mechanisms supported by the server.</para>
|
||||
<para>If this attribute is not present, the server does not support any SASL
|
||||
mechanisms.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<orderedlist>
|
||||
<para>To access the root DSE of an LDAP server, do the following:</para>
|
||||
<listitem><para>Turn off automatic referral handling, and connect to the LDAP
|
||||
server.</para><para>See <olink type="auto-generated" targetptr="prepare-client">Creating
|
||||
a Connection and Setting Preferences With Directory SDK for Java</olink> and <olink type="auto-generated" targetptr="connect-client">Connecting to an LDAP Server
|
||||
With Directory SDK for Java</olink>. See also <olink type="auto-generated" targetptr="handling-referrals">Handling Referrals With Directory SDK for Java</olink> for
|
||||
instructions.</para></listitem>
|
||||
<listitem>
|
||||
<itemizedlist>
|
||||
<para>Search the directory with the following criteria:</para>
|
||||
<listitem><para>Set the search scope to a <literal>base</literal> search.</para>
|
||||
</listitem>
|
||||
<listitem><para>Specify an empty string for the base DN.</para></listitem>
|
||||
<listitem><para>Use the search filter <literal>(objectclass=*)</literal>.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>Refer to <olink type="auto-generated" targetptr="searching">Chapter 4, Searching the Directory With Directory SDK for Java</olink> for instructions.</para>
|
||||
<para>If an <classname>LDAPException</classname> is returned with a result
|
||||
code such as <returnvalue>OPERATION_ERROR</returnvalue>, <returnvalue>PROTOCOL_ERROR
|
||||
</returnvalue>, <returnvalue>REFERRAL</returnvalue>, or <returnvalue>NO_SUCH_OBJECT
|
||||
</returnvalue>, the LDAP server probably does not support LDAP v3.</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>The following code excerpt retrieves the root DSE, and then displays
|
||||
the attributes.</para>
|
||||
<programlisting>/* Create a new connection. */
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
String hostname = "localhost";
|
||||
int portnumber = LDAPv3.DEFAULT_PORT;
|
||||
|
||||
try {
|
||||
/* Connect to the LDAP server. */
|
||||
ld.connect(3, hostname, portnumber);
|
||||
|
||||
int MY_SCOPE = LDAPv3.SCOPE_BASE;
|
||||
String MY_FILTER = "(objectclass=*)";
|
||||
String MY_SEARCHBASE = "";
|
||||
LDAPSearchResults res = ld.search(MY_SEARCHBASE,
|
||||
MY_SCOPE, MY_FILTER, null, false);
|
||||
|
||||
/* There should be only one result (the root DSE). */
|
||||
while (res.hasMoreElements()) {
|
||||
LDAPEntry findEntry = (LDAPEntry)res.nextElement();
|
||||
|
||||
/* Get the attributes of the root DSE. */
|
||||
LDAPAttributeSet findAttrs = findEntry.getAttributeSet();
|
||||
Enumeration enumAttrs = findAttrs.getAttributes();
|
||||
|
||||
/* Iterate through each attribute. */
|
||||
while (enumAttrs.hasMoreElements()) {
|
||||
LDAPAttribute anAttr = (LDAPAttribute)enumAttrs.nextElement();
|
||||
|
||||
/* Get and print the attribute name. */
|
||||
String attrName = anAttr.getName();
|
||||
System.out.println(attrName);
|
||||
|
||||
/* Get the values of the attribute. */
|
||||
Enumeration enumVals = anAttr.getStringValues();
|
||||
|
||||
/* Get and print each value. */
|
||||
if (enumVals == null) {
|
||||
System.out.println("\tNo values found.");
|
||||
continue;
|
||||
}
|
||||
while (enumVals.hasMoreElements()) {
|
||||
String aVal = (String)enumVals.nextElement();
|
||||
System.out.println("\t" + aVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch( LDAPException e ) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}</programlisting>
|
||||
</sect1>
|
||||
<sect1 id="server-info-ldapv3"><title>Checking Support for LDAP v3 With &DirectorySDKForJava;
|
||||
</title>
|
||||
<indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>protocol version supported</secondary>
|
||||
</indexterm>
|
||||
<para>You can determine what version an LDAP server supports by getting the <literal>
|
||||
supportedLDAPVersion</literal> attribute from the root DSE. This attribute
|
||||
should contain the value <literal>3</literal>. The attribute can also contain
|
||||
other values, such as <literal>2</literal>, so iterate through the values
|
||||
of this attribute.</para>
|
||||
<para>You are not required to authenticate or bind before performing a search.
|
||||
Unlike LDAP v2, LDAP v3 states that clients do not need to bind to the server
|
||||
before performing LDAP operations. The following section of code connects
|
||||
to an LDAP server. The code then determines whether the server supports LDAP
|
||||
v3.</para>
|
||||
<programlisting>/* Create a new connection. */
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
String hostname = "localhost";
|
||||
int portnumber = LDAPv3.DEFAULT_PORT;
|
||||
|
||||
boolean supportsV3 = false;
|
||||
|
||||
try {
|
||||
/* Connect to the LDAP server. */
|
||||
ld.connect( 3, hostname, portnumber );
|
||||
|
||||
int MY_SCOPE = LDAPv3.SCOPE_BASE;
|
||||
String MY_FILTER = "(objectclass=*)";
|
||||
String MY_SEARCHBASE = "";
|
||||
LDAPSearchResults res = ld.search(MY_SEARCHBASE,
|
||||
MY_SCOPE, MY_FILTER, null, false);
|
||||
|
||||
/* There should be only one result (the root DSE). */
|
||||
while (res.hasMoreElements()) {
|
||||
LDAPEntry findEntry = (LDAPEntry)res.nextElement();
|
||||
|
||||
/* Get the supportedLDAPVersion attribute values. */
|
||||
LDAPAttribute versionAttr =
|
||||
findEntry.getAttribute("supportedLDAPVersion");
|
||||
|
||||
/* Check for "3". */
|
||||
Enumeration enumVals = versionAttr.getStringValues();
|
||||
if (enumVals == null) {
|
||||
System.out.println("\tNo values found.");
|
||||
continue;
|
||||
}
|
||||
while (enumVals.hasMoreElements()) {
|
||||
String aVal = (String)enumVals.nextElement();
|
||||
if (aVal.equalsIgnoreCase("3")) {
|
||||
supportsV3 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch( LDAPException e ) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}
|
||||
|
||||
if (supportsV3) {
|
||||
System.out.println("This server supports LDAP v3.");
|
||||
} else {
|
||||
System.out.println("This server does not support LDAP v3.");
|
||||
}</programlisting>
|
||||
</sect1>
|
||||
<sect1 id="server-info-schema"><title>Getting Schema Information With &DirectorySDKForJava;
|
||||
</title>
|
||||
<indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>schema</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>schema</primary>
|
||||
</indexterm>
|
||||
<para>In LDAP v3, you can get LDAP schema over LDAP. You can also modify schema
|
||||
over LDAP. This section explains how to carry out such modifications.</para>
|
||||
<sect2 id="server-info-schema-overview"><title>Understanding Schema Over LDAP</title>
|
||||
<para>An entry can specify the schema that defines the object classes, attributes,
|
||||
syntaxes, and matching rules used by the directory. This entry is called the <firstterm>
|
||||
subschema entry</firstterm>.</para>
|
||||
<para>To find the DN of the subschema entry, get the <literal>subschemaSubentry</literal> operational
|
||||
attribute from the root DSE or from any entry. This code excerpt demonstrates
|
||||
how to retrieve the subschema entry DN.</para>
|
||||
<programlisting>LDAPConnection ld = null;
|
||||
try {
|
||||
ld = new LDAPConnection();
|
||||
ld.connect("localhost", LDAPv3.DEFAULT_PORT);
|
||||
|
||||
String [] schemaAttr = {"subschemaSubentry"};
|
||||
LDAPEntry rootDSE = ld.read("", schemaAttr);
|
||||
LDAPAttribute resAttr = rootDSE.getAttribute(schemaAttr[0]);
|
||||
Enumeration enumVals = resAttr.getStringValues();
|
||||
if (enumVals != null) {
|
||||
while (enumVals.hasMoreElements()) {
|
||||
System.out.println(schemaAttr[0] + ": " +
|
||||
(String)enumVals.nextElement());
|
||||
}
|
||||
}
|
||||
ld.disconnect();
|
||||
} catch(LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}</programlisting>
|
||||
<para>The subschema entry can have the following attributes.</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><literal>objectClasses</literal></term>
|
||||
<listitem><para>Specifies the object class definitions in the schema.</para>
|
||||
<para>Each value of this attribute is an object class that is known to the
|
||||
server.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>attributeTypes</literal></term>
|
||||
<listitem><para>Specifies the attribute type definitions in the schema.</para>
|
||||
<para>Each value of this attribute is an attribute type that is known to the
|
||||
server.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>matchingRules</literal></term>
|
||||
<listitem><para>Specifies the matching rule definitions in the schema.</para>
|
||||
<para>Each value of this attribute is a matching rule that is known to the
|
||||
server.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>matchingRuleUse</literal></term>
|
||||
<listitem><para>Specifies the use of a matching rule in the schema.</para>
|
||||
<para>Each value of this attribute is a matching rule use description. A matching
|
||||
rule use description specifies the OIDs of the attributes that can be used
|
||||
with this extensible matching rule.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>syntaxes</literal></term>
|
||||
<listitem><para>Specifies the syntax definitions in the schema.</para>
|
||||
<para>Each value of this attribute is syntax that is known to the server.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>In &DirectorySDKForJava;, the schema and elements in the schema are
|
||||
represented by classes in the <literal>netscape.ldap</literal> package. These
|
||||
classes include the following.</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><classname>LDAPSchema</classname></term>
|
||||
<listitem><para>Schema used by an LDAP server</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><classname>LDAPSchemaElement</classname></term>
|
||||
<listitem><para>Base class that represents a generic element in the schema</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><classname>LDAPObjectClassSchema</classname></term>
|
||||
<listitem><para>Object class description in the schema</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><classname>LDAPAttributeSchema</classname></term>
|
||||
<listitem><para>Attribute type description in the schema</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><classname>LDAPMatchingRuleSchema</classname></term>
|
||||
<listitem><para>Matching rule description in the schema</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><classname>LDAPMatchingRuleUseSchema</classname></term>
|
||||
<listitem><para>Use of a matching rule in the schema</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><classname>LDAPSyntaxSchema</classname></term>
|
||||
<listitem><para>Syntax description in the schema</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>These classes with their methods handle the subschema entry by using
|
||||
standard LDAP operations, such as <literal>search</literal> and <literal>modify</literal>.
|
||||
</para></sect2>
|
||||
<sect2 id="server-info-schema-get"><title>Getting Information About LDAP Schema</title>
|
||||
<para>To get the schema for an LDAP v3 server, construct a new <classname>LDAPSchema
|
||||
</classname> object. Then, invoke the <literal>fetchSchema</literal> method,
|
||||
passing in an <classname>LDAPConnection</classname> object.</para>
|
||||
<programlisting>LDAPConnection ld = new LDAPConnection();
|
||||
/* Construct an LDAPSchema object to hold the schema to retrieve. */
|
||||
LDAPSchema dirSchema = new LDAPSchema();
|
||||
try {
|
||||
ld.connect(hostname, portnumber, bindDN, bindPW);
|
||||
/* Get the schema. Anonymous access is OK. */
|
||||
dirSchema.fetchSchema(ld);
|
||||
/* Use the schema. */
|
||||
} catch (Exception e) {
|
||||
System.err.println(e.toString());
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="server-info-schema-objectclasses"><title>Working With Object Class
|
||||
Descriptions</title>
|
||||
<para>In the LDAP Java classes, the object class descriptions in a schema
|
||||
are represented by objects of the <classname>LDAPObjectClassSchema</classname> class.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<para>To get the object class descriptions from the schema, invoke one of
|
||||
the following methods:</para>
|
||||
<listitem><para>To get an enumeration of <classname>LDAPObjectClassSchema</classname> objects
|
||||
that represent the object classes in the schema, invoke the <literal>getObjectClasses
|
||||
</literal> method.</para></listitem>
|
||||
<listitem><para>To get a specific object class description, invoke the <literal>getObjectClass
|
||||
</literal> method and pass in the name of the object class.</para></listitem>
|
||||
<listitem><para>To get an enumeration of the names of object classes in the
|
||||
schema, invoke the <literal>getObjectClassNames</literal> method.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<para>An object class description consists of the following information, which
|
||||
you can retrieve by invoking methods of the <classname>LDAPObjectClassSchema</classname> object:
|
||||
</para>
|
||||
<listitem><para>An OID that identifies the object class, retrieved by invoking
|
||||
the <literal>getOID</literal> method</para></listitem>
|
||||
<listitem><para>A name that identifies the object class, retrieved by invoking
|
||||
the <literal>getName</literal> method</para></listitem>
|
||||
<listitem><para>A description that identifies the object class, retrieved
|
||||
by invoking the <literal>getDescription</literal> method</para></listitem>
|
||||
<listitem><para>A name that identifies the parent object class, retrieved
|
||||
by invoking the <literal>getSuperior</literal> method</para></listitem>
|
||||
<listitem><para>The list of required attributes, retrieved by invoking the <literal>
|
||||
getRequiredAttributes</literal> method</para></listitem>
|
||||
<listitem><para>The list of optional attributes that are allowed, retrieved
|
||||
by invoking the <literal>getOptionalAttributes</literal> method</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>To add an object class description to the schema, construct a new <classname>
|
||||
LDAPObjectClassSchema</classname> object. You can specify the pieces of information
|
||||
in the object as individual arguments or in a description formatted according
|
||||
to <ulink url="http://www.ietf.org/rfc/rfc4517.txt" type="text_url">RFC 4517</ulink>, <citetitle>
|
||||
Lightweight Directory Access Protocol (LDAP): Syntaxes and Matching Rules</citetitle>.
|
||||
</para>
|
||||
<para>Then, you can either invoke the <literal>add</literal> method of this
|
||||
object or the <literal>addObjectClass</literal> method of the <classname>LDAPSchema
|
||||
</classname> object.</para>
|
||||
<para>To remove an object class description, invoke the <literal>remove</literal> method
|
||||
of this object.</para></sect2>
|
||||
<sect2 id="server-info-schema-attributetypes"><title>Working With Attribute
|
||||
Type Descriptions</title>
|
||||
<para>In the LDAP Java classes, the attribute type descriptions in a schema
|
||||
are represented by objects of the <classname>LDAPAttributeSchema</classname> class.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<para>To get the attribute type descriptions from the schema, invoke one of
|
||||
the following methods:</para>
|
||||
<listitem><para>To get an enumeration of <classname>LDAPAttributeSchema</classname> objects
|
||||
that represent the attribute types in the schema, invoke the <literal>getAttributes
|
||||
</literal> method.</para></listitem>
|
||||
<listitem><para>To get a specific attribute type description, invoke the <literal>
|
||||
getAttribute</literal> method and pass in the name of the attribute type.</para>
|
||||
</listitem>
|
||||
<listitem><para>To get an enumeration of the names of attribute types in the
|
||||
schema, invoke the <literal>getAttributeNames</literal> method.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<para>An attribute type description consists of the following information,
|
||||
which you can retrieve by invoking methods of the <classname>LDAPAttributeSchema</classname> object:
|
||||
</para>
|
||||
<listitem><para>An OID that identifies the attribute type, retrieved by invoking
|
||||
the <literal>getOID</literal> method</para></listitem>
|
||||
<listitem><para>A name that identifies the attribute type, retrieved by invoking
|
||||
the <literal>getName</literal> method</para></listitem>
|
||||
<listitem><para>A description that identifies the attribute type, retrieved
|
||||
by invoking the <literal>getDescription</literal> method</para></listitem>
|
||||
<listitem><para>The syntax used by the attribute type, retrieved by invoking
|
||||
the <literal>getSyntax</literal> method</para></listitem>
|
||||
<listitem><para>An indication whether the attribute type is single-valued
|
||||
or multivalued, retrieved by invoking the <literal>isSingleValued</literal> method
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>To add an attribute type description to the schema, construct a new <classname>
|
||||
LDAPAttributeSchema</classname> object. You can specify the pieces of information
|
||||
in the object as individual arguments or in a description formatted according
|
||||
to <ulink url="http://www.ietf.org/rfc/rfc4517.txt" type="text_url">RFC 4517</ulink>, <citetitle>
|
||||
Lightweight Directory Access Protocol (LDAP): Syntaxes and Matching Rules</citetitle>.
|
||||
</para>
|
||||
<para>Then, you can either invoke the <literal>add</literal> method of this
|
||||
object or the <literal>addAttributeType</literal> method of the <classname>LDAPSchema
|
||||
</classname> object.</para>
|
||||
<para>To remove an <literal>attributeType</literal> description, invoke the <literal>
|
||||
remove</literal> method of this object.</para></sect2>
|
||||
<sect2 id="server-info-schema-matchingrules"><title>Working With Matching
|
||||
Rule Descriptions</title>
|
||||
<para>In the LDAP Java classes, the matching rule and matching rule use descriptions
|
||||
in a schema are represented by objects of the <classname>LDAPMatchingRuleSchema</classname> class.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<para>To get the matching rule descriptions from the schema, invoke one of
|
||||
the following methods:</para>
|
||||
<listitem><para>To get an enumeration of <classname>LDAPMatchingRuleSchema</classname> objects
|
||||
that represent the matching rules in the schema, invoke the <literal>getMatchingRules
|
||||
</literal> method.</para></listitem>
|
||||
<listitem><para>To get a specific matching rule description, invoke the <literal>
|
||||
getMatchingRule</literal> method and pass in the name of the matching rule.</para>
|
||||
</listitem>
|
||||
<listitem><para>To get an enumeration of the names of matching rules in the
|
||||
schema, invoke the <literal>getMatchingRuleNames</literal> method.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<para>A matching rule description consists of the following information, which
|
||||
you can retrieve by invoking methods of the <classname>LDAPMatchingRuleSchema</classname> object:
|
||||
</para>
|
||||
<listitem><para>An OID that identifies the matching rule, retrieved by invoking
|
||||
the <literal>getOID</literal> method</para></listitem>
|
||||
<listitem><para>A name that identifies the matching rule, retrieved by invoking
|
||||
the <literal>getName</literal> method</para></listitem>
|
||||
<listitem><para>A description that identifies the matching rule, retrieved
|
||||
by invoking the <literal>getDescription</literal> method</para></listitem>
|
||||
<listitem><para>The syntax of the matching rule, retrieved by invoking the <literal>
|
||||
getSyntax</literal> method</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>To add a matching rule description to the schema, construct a new <classname>
|
||||
LDAPMatchingSchema</classname> object. You can specify the pieces of information
|
||||
in the object as individual arguments or in a description formatted according
|
||||
to <ulink url="http://www.ietf.org/rfc/rfc4517.txt" type="text_url">RFC 4517</ulink>, <citetitle>Lightweight Directory Access Protocol (LDAP):
|
||||
Syntaxes and Matching Rules</citetitle>.</para>
|
||||
<para>Then, you can either invoke the <literal>add</literal> method of this
|
||||
object or the <literal>addMatchingRule</literal> method of the <classname>LDAPSchema
|
||||
</classname> object.</para>
|
||||
<para>To remove a matching rule description, invoke the <literal>remove</literal> method
|
||||
of this object.</para></sect2>
|
||||
<sect2 id="server-info-schema-example"><title>Example of Working With Schema</title>
|
||||
<para>The following example illustrates how to get the schema and how to add
|
||||
object classes and attribute types.</para>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
|
||||
public class GetSchema {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
UserArgs userArgs = new UserArgs("GetSchema", args, true);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
ld.authenticate(userArgs.getBindDN(), userArgs.getPassword());
|
||||
|
||||
/* Get the schema. */
|
||||
LDAPSchema dirSchema = new LDAPSchema();
|
||||
dirSchema.fetchSchema(ld);
|
||||
|
||||
/* Get and print the inetOrgPerson object class. */
|
||||
LDAPObjectClassSchema objClass =
|
||||
dirSchema.getObjectClass("inetOrgPerson");
|
||||
if (objClass != null)
|
||||
System.out.println("inetOrgPerson := " +
|
||||
objClass.toString());
|
||||
|
||||
/* Get and print the userPassword attribute. */
|
||||
LDAPAttributeSchema attrType =
|
||||
dirSchema.getAttribute("userpassword");
|
||||
if (attrType != null)
|
||||
System.out.println("userPassword := " +
|
||||
attrType.toString());
|
||||
|
||||
/* Add a new object class. Requires write access. */
|
||||
String[] requiredAttrs = {"cn", "mail"};
|
||||
String[] optionalAttrs = {"sn", "telephoneNumber"};
|
||||
LDAPObjectClassSchema newObjClass =
|
||||
new LDAPObjectClassSchema("newInetOrgPerson",
|
||||
"1.2.3.4.5.6.7", "top", "Experiment",
|
||||
requiredAttrs, optionalAttrs);
|
||||
|
||||
/* Add the new object class to the schema. */
|
||||
newObjClass.add(ld);
|
||||
|
||||
/* Create a new attribute type "hairColor". */
|
||||
LDAPAttributeSchema newAttrType =
|
||||
new LDAPAttributeSchema("hairColor",
|
||||
"1.2.3.4.5.4.3.2.1", "Blonde, red, etc",
|
||||
LDAPAttributeSchema.cis, false);
|
||||
|
||||
/* Add the new attribute type to the schema. */
|
||||
newAttrType.add(ld);
|
||||
|
||||
/* Fetch schema again to verify changes */
|
||||
dirSchema.fetchSchema(ld);
|
||||
|
||||
/* Get and print the new attribute type. */
|
||||
newAttrType = dirSchema.getAttribute("hairColor");
|
||||
if (newAttrType != null)
|
||||
System.out.println("hairColor := " +
|
||||
newAttrType.toString());
|
||||
|
||||
/* Get and print the new object class. */
|
||||
newObjClass = dirSchema.getObjectClass("newInetOrgPerson");
|
||||
if (newObjClass != null)
|
||||
System.out.println("newInetOrgPerson := " +
|
||||
newObjClass.toString());
|
||||
|
||||
ld.disconnect();
|
||||
} catch ( Exception e ) {
|
||||
System.err.println(e.toString());
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
||||
209
mozilla/directory/docs/ldapjdk/jdk-ssl.sgm
Normal file
209
mozilla/directory/docs/ldapjdk/jdk-ssl.sgm
Normal file
@@ -0,0 +1,209 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="ssl"><title>SSL Connections With &DirectorySDKForJava;</title>
|
||||
<highlights>
|
||||
<para>This chapter describes the process of enabling an LDAP client to connect
|
||||
to an LDAP server over the Secure Sockets Layer (SSL) protocol. The chapter
|
||||
explains how to connect to an LDAP server with SSL. It also covers SSL authentication.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="ssl-overview">How SSL Works With Directory
|
||||
SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="ssl-prerequisites">Prerequisites for Connecting
|
||||
Over SSL With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="ssl-connecting">Connecting to a Server Over
|
||||
SSL With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="ssl-cert-based-auth">Using Certificate-Based
|
||||
Client Authentication With Directory SDK for Java</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="ssl-overview"><title>How SSL Works With &DirectorySDKForJava;</title>
|
||||
<para>&DirectorySDKForJava; includes classes and methods to enable your
|
||||
application to connect to an LDAP server over a <firstterm>Secure Sockets
|
||||
Layer</firstterm> (SSL).</para>
|
||||
<sect2 id="ssl-overview-overview"><title>Understanding SSL</title>
|
||||
<para>The primary goal of the SSL Protocol is to provide privacy and reliability
|
||||
between two communicating applications. For more information about SSL and <firstterm>
|
||||
Transport Layer Security</firstterm>, refer to <ulink
|
||||
url="http://www.ietf.org/rfc/rfc2246.txt" type="text">RFC 2246</ulink>, <emphasis>
|
||||
The TLS Protocol</emphasis>.</para>
|
||||
<para>The &DirectorySDKForJava; supports SSL 3.0.</para></sect2>
|
||||
<sect2 id="ssl-ldap"><title>SSL and LDAP</title>
|
||||
<para>When an LDAP client connects to an LDAP server over SSL, the LDAP server
|
||||
identifies itself by sending its <firstterm>certificate</firstterm> to the
|
||||
LDAP client. The LDAP client needs to determine whether or not the <firstterm>certificate
|
||||
authority</firstterm> (CA) who issued the certificate is trusted.</para>
|
||||
<para>The LDAP server can also request that the client send a certificate
|
||||
to authenticate. This process is called <firstterm>certificate-based client
|
||||
authentication</firstterm>.</para>
|
||||
<para>After receiving the client's certificate, the LDAP server determines
|
||||
whether or not the CA who issued the certificate is trusted. If the CA is
|
||||
trusted, the server uses the subject name in the certificate. With the subject
|
||||
name, the server determines if the client has access rights to perform the
|
||||
requested operation.</para>
|
||||
<para>To use SSL, you need a <firstterm>certificate database</firstterm> to
|
||||
hold the CA certificate. If certificate-based client authentication is used,
|
||||
you need the client certificate.</para></sect2>
|
||||
<sect2 id="ssl-interfaces-classes"><title>Interfaces and Classes for SSL</title>
|
||||
<para>&DirectorySDKForJava; includes the <classname>LDAPSocketFactory</classname> interface.
|
||||
This interface describes a single method, <literal>makeSocket</literal>, that
|
||||
returns a socket to a given server specified by a host name and port number.
|
||||
To establish an SSL connection, you need to create an object of a class that
|
||||
implements this interface.</para>
|
||||
<para>Classes that implement this interface rely on a separate class that
|
||||
implements SSL sockets. In the constructors for objects that implement <classname>
|
||||
LDAPSocketFactory</classname>, you typically need to specify the name of a
|
||||
class that implements SSL sockets. The following classes implement this interface.
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><classname>LDAPSSLSocketFactory</classname></term>
|
||||
<listitem><para>Use this class if you are using the <classname>netscape.net.SSLSocket
|
||||
</classname> class to implement SSL sockets. You can also use this class if
|
||||
the class that implements SSL sockets extends the <classname>Socket</classname> object.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><classname>LDAPSSLSocketWrapFactory</classname></term>
|
||||
<listitem><para>Use this class if the class that implements SSL sockets does
|
||||
not extend the <classname>Socket</classname> object. The <classname>LDAPSSLSocketWrapFactory
|
||||
</classname> class wraps your SSL socket implementation class in a class that
|
||||
does extend the <classname>Socket</classname> object.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><classname>JSSESocketFactory</classname></term>
|
||||
<listitem><para>Use this class to rely on the standard SSL socket factory
|
||||
code.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>You can construct an object for one of these factory classes. You can
|
||||
pass the factory object to the constructor for the <classname>LDAPConnection</classname> object,
|
||||
to identify the socket factory that is used for the connection.</para></sect2>
|
||||
</sect1>
|
||||
<sect1 id="ssl-prerequisites"><title>Prerequisites for Connecting Over SSL
|
||||
With &DirectorySDKForJava;</title>
|
||||
<itemizedlist>
|
||||
<para>The LDAP Java classes that enable you to connect over SSL assume the
|
||||
following:</para>
|
||||
<listitem><para>Your client has access to a Netscape Security Services (NSS)
|
||||
certificate database.</para><para>If your client runs in a Netscape or Mozilla
|
||||
browser, you can use the browser certificate database. With the browser certificate
|
||||
database, you can determine if you trust the certificate that is sent from
|
||||
the server.</para></listitem>
|
||||
<listitem><para>The database used contains one of the following certificates:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>The certificate of the CA who issued the server certificate</para>
|
||||
</listitem>
|
||||
<listitem><para>If the CAs are organized hierarchically, the certificate of
|
||||
any CA in the hierarchy</para></listitem>
|
||||
<listitem><para>The certificate of the server</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>The CA certificate is marked as <literal>trusted</literal> in
|
||||
the database.</para></listitem>
|
||||
<listitem><para>If you use certificate-based client authentication, you must
|
||||
have the following data:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>A client certificate issued by a CA trusted by the LDAP server</para>
|
||||
<para>This certificate must be in the client certificate database.</para>
|
||||
</listitem>
|
||||
<listitem><para>A public key, private key pair in an NSS key database on the
|
||||
client side</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>When your client sends an initial request to the secure LDAP server,
|
||||
the server sends its certificate back to your client. Your client determines
|
||||
which CA issued the server's certificate. Your client then searches the certificate
|
||||
database for the certificate of the issuing CA.</para>
|
||||
<para>Your client might not find the CA certificate. Your client might also
|
||||
find that the CA certificate is marked as <literal>not trusted</literal>.
|
||||
If either condition occurs, your client refuses to connect to the server.</para>
|
||||
<para>If you are using certificate-based client authentication, your client
|
||||
retrieves its certificate from the certificate database. Your client sends
|
||||
the certificate to the server for authentication. The server determines which
|
||||
CA issued the client certificate. The server then searches its certificate
|
||||
database for the certificate of the issuing CA.</para>
|
||||
<para>The server might not find the CA certificate. The CA certificate might
|
||||
be marked as <literal>not trusted</literal>. If either condition occurs, the
|
||||
server refuses to authenticate your client.</para></sect1>
|
||||
<sect1 id="ssl-connecting"><title>Connecting to a Server Over SSL With &DirectorySDKForJava;</title>
|
||||
<orderedlist>
|
||||
<para>To connect to an LDAP server with SSL, do the following:</para>
|
||||
<listitem><para>Construct a new <classname>LDAPSSLSocketFactory</classname> object
|
||||
or a new <classname>LDAPSSLSocketWrapFactory</classname> object.</para><para>This
|
||||
object represents the SSL socket factory used to create the sockets for establishing
|
||||
connections with the LDAP server.</para><para>The constructors for these classes
|
||||
allow you to specify the name of the class used to create the actual sockets.</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>For the <literal>LDAPSSLSocketFactory</literal> constructor,
|
||||
you should specify a class that implements the <classname>javax.net.ssl.SSLSocket
|
||||
</classname> interface. By default, if you do not specify a class, the <classname>
|
||||
netscape.net.SSLSocket</classname> class is used.</para></listitem>
|
||||
<listitem><para>If the SSL socket class does not extend the <classname>Socket</classname> class,
|
||||
use the <classname>LDAPSSLSocketWrapFactory</classname> constructor.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem><para>Pass the object that you constructed to the <literal>LDAPConnection
|
||||
</literal> constructor.</para><para>When first you establish a connection
|
||||
to the LDAP server, use the <literal>makeSocket</literal> method of the specified
|
||||
object that you used to construct the socket.</para></listitem></orderedlist>
|
||||
</sect1>
|
||||
<sect1 id="ssl-cert-based-auth"><title>Using Certificate-Based Client Authentication
|
||||
With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>authentication</primary>
|
||||
<secondary>certificate-based</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>certificate-based client authentication</primary>
|
||||
</indexterm>
|
||||
<para>Some LDAP servers might be configured to use certificate-based client
|
||||
authentication. A server might request that your client sends a certificate
|
||||
to identify itself.</para>
|
||||
<itemizedlist>
|
||||
<para>With &DirectorySDKForJava;, you can set up your client to perform
|
||||
certificate-based authentication in either of the following situations:</para>
|
||||
<listitem><para>Your client runs as an applet in a Netscape or Mozilla browser</para>
|
||||
</listitem>
|
||||
<listitem><para>Your client uses a class implementing the <classname>LDAPSocketFactory
|
||||
</classname> interface and supporting client-based authentication</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<para>When using certificate-based client authentication, consider the following:
|
||||
</para>
|
||||
<listitem><para>The <classname>LDAPSSLSocketWrapFactory</classname> class
|
||||
does not support certificate-based client authentication.</para></listitem>
|
||||
<listitem><para>The <classname>LDAPSSLSocketFactory</classname> class relies
|
||||
on the browser to support certificate-based client authentication. The class
|
||||
does not support the use of certificates for authentication outside the browser,
|
||||
in stand-alone Java applications.</para></listitem>
|
||||
</itemizedlist>
|
||||
<orderedlist>
|
||||
<para>To enable an applet to use certificate-based client authentication,
|
||||
do the following:</para>
|
||||
<listitem><para>Construct a new <classname>LDAPSSLSocketFactory</classname> object.
|
||||
</para></listitem>
|
||||
<listitem><para>Invoke the <literal>enableClientAuth</literal> method of the
|
||||
object to enable certificate-based client authentication.</para></listitem>
|
||||
<listitem><para>Pass the object that you constructed to the <literal>LDAPConnection
|
||||
</literal> constructor.</para></listitem></orderedlist>
|
||||
</sect1>
|
||||
</chapter>
|
||||
412
mozilla/directory/docs/ldapjdk/jdk-understanding.sgm
Normal file
412
mozilla/directory/docs/ldapjdk/jdk-understanding.sgm
Normal file
@@ -0,0 +1,412 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="understanding-jdk"><title>Understanding the &DirectorySDKForJava;</title>
|
||||
<highlights>
|
||||
<para>This chapter describes the LDAP Java classes and the &DirectorySDKForJava;,
|
||||
including the following sections:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para><olink targetptr="understanding-java-classes">Understanding the LDAP
|
||||
Java Classes</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="getting-started">About &DirectorySDKForJava;</olink></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="understanding-java-classes"><title>Understanding the LDAP Java Classes
|
||||
</title>
|
||||
<indexterm>
|
||||
<primary>packages</primary>
|
||||
<secondary>summary of</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>&DirectorySDKForJava;</primary>
|
||||
<secondary>packages</secondary>
|
||||
</indexterm>
|
||||
<para>The &DirectorySDKForJava; includes the LDAP Java classes, which you use to
|
||||
build LDAP clients. The LDAP Java classes allow you to write client applications that
|
||||
connect to LDAP servers and perform standard LDAP operations. For example, you can
|
||||
search for entries or add, update, or delete entries.</para>
|
||||
<para>The classes are organized in the following packages:</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><literal>com.netscape.sasl</literal></term>
|
||||
<listitem><para>Contains the interfaces and classes that you can use to enable your
|
||||
client to authenticate by using a SASL mechanism.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>com.netscape.sasl.mechanisms</literal></term>
|
||||
<listitem><para>Contains an implementation of the EXTERNAL SASL mechanism driver.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>netscape.ldap</literal></term>
|
||||
<listitem><para>Contains the main LDAP Java classes, including classes that allow
|
||||
you to connect to an LDAP server, manipulate entries and attributes, and retrieve
|
||||
search results</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<!--<varlistentry><term><literal>netscape.ldap.beans</literal></term>
|
||||
<listitem><para>Contains LDAP <trademark>JavaBeans
|
||||
</trademark> technology. You can use LDAP JavaBeans
|
||||
classes in a development environment such as Sun Java
|
||||
Studio.</para>
|
||||
</listitem>
|
||||
</varlistentry>-->
|
||||
<varlistentry><term><literal>netscape.ldap.ber.stream</literal></term>
|
||||
<listitem><para>Contains the LDAP Java classes that implement the <firstterm>Basic
|
||||
Encoding Rules</firstterm> (BER) for transfer syntax. For more information on BER,
|
||||
see ISO/IEC 8825 at <ulink url="http://www.iso.ch/" type="url">http://www.iso.ch/
|
||||
</ulink>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>netscape.ldap.controls</literal></term>
|
||||
<listitem><para>Contains the LDAP Java classes that implement specific LDAP v3 controls.
|
||||
These include controls to request server-side sorting and persistent searches.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>netscape.ldap.factory</literal></term>
|
||||
<listitem><para>Contains classes that allow you to create an SSL socket connection
|
||||
to a server.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><literal>netscape.ldap.util</literal></term>
|
||||
<listitem><para>Contains utility classes, such as classes to parse LDIF data and filters
|
||||
that allow regular expression matching.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>Clients typically execute methods in the &DirectorySDKForJava; synchronously.
|
||||
All LDAP operations block until they are completed, except for the <literal>search
|
||||
</literal> method, which can return information before all the results have been received.
|
||||
</para>
|
||||
<para>An asynchronous interface is also provided for circumstances requiring low-level
|
||||
interaction with an LDAP server. The asynchronous interface is discussed more fully
|
||||
in <olink targetptr="asynchronous">Chapter 33, Writing Asynchronous Clients With Directory SDK for Java</olink>.</para></sect1>
|
||||
<sect1 id="getting-started"><title>About &DirectorySDKForJava;</title>
|
||||
<para>This section covers the following topics:</para>
|
||||
<itemizedlist>
|
||||
<!--<listitem><para><olink targetptr="install-jdk">Getting
|
||||
and Installing the Directory SDK for Java</olink></para>
|
||||
</listitem>-->
|
||||
<listitem><para><olink targetptr="explore-jdk">Exploring the Directory SDK for Java
|
||||
</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="prepare-jdk">Preparing to Use Directory SDK for
|
||||
Java</olink></para></listitem>
|
||||
<!--<listitem><para><olink targetptr="applets-jdk"></olink></para>
|
||||
</listitem><listitem><para><olink targetptr="version-jdk"></olink></para>
|
||||
</listitem><listitem><para><olink targetptr="javabeans-jdk"></olink></para>
|
||||
</listitem><listitem><para><olink targetptr="javascript-jdk"></olink></para>
|
||||
</listitem>-->
|
||||
</itemizedlist>
|
||||
<!--<sect2 id="install-jdk"><title>Getting and Installing
|
||||
the &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>&DirectorySDKForJava;</primary>
|
||||
<secondary>installing</secondary>
|
||||
</indexterm>
|
||||
<para>TODO</para></sect2>-->
|
||||
<sect2 id="explore-jdk"><title>Exploring the &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>&DirectorySDKForJava;</primary>
|
||||
<secondary>contents</secondary>
|
||||
</indexterm>
|
||||
<para>TODO: verify this is all still true</para>
|
||||
<para>The &DirectorySDKForJava; contains the following directories:</para>
|
||||
<variablelist>
|
||||
<!--<varlistentry><term><filename class="directory">beans
|
||||
</filename></term>
|
||||
<listitem><para>This directory contains the LDAP JavaBeans
|
||||
class files from the <literal>netscape.ldap.beans
|
||||
</literal> package.</para>
|
||||
<para>If you are writing applications or applets that
|
||||
use these classes, make sure to provide these classes
|
||||
to your users.</para>
|
||||
<para>This directory also contains a script to create
|
||||
JAR files for the LDAP JavaBeans classes.</para>
|
||||
</listitem>
|
||||
</varlistentry><varlistentry><term><filename class="directory">
|
||||
examples</filename></term>
|
||||
<listitem><para>This directory contains sample source
|
||||
code for LDAP Java applications. The examples are
|
||||
organized in different subdirectories:</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><filename class="directory">java
|
||||
</filename></term>
|
||||
<listitem><para>Contains examples of the standard
|
||||
LDAP operations, such as adding an entry and searching
|
||||
for entries. This directory also contains examples
|
||||
using LDAP controls.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><filename class="directory">java/beans
|
||||
</filename></term>
|
||||
<listitem><para>Contains examples uses of the LDAP
|
||||
JavaBeans classes.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><filename class="directory">java/ldapfilt
|
||||
</filename></term>
|
||||
<listitem><para>Contains an example uses of an LDAP
|
||||
filter configuration file with the LDAP filter classes.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><filename class="directory">js
|
||||
</filename></term>
|
||||
<listitem><para>Contains an example of using LiveConnect
|
||||
to create and manipulate LDAP Java objects from JavaScript.
|
||||
LiveConnect enables communication in a single page
|
||||
between a variety of elements such as JavaScript code,
|
||||
HTML, browser plug-ins, and Java applets.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>-->
|
||||
<varlistentry><term><filename class="directory">packages</filename></term>
|
||||
<listitem><para>This directory contains the following JAR file<!--s-->:</para>
|
||||
<variablelist>
|
||||
<varlistentry><indexterm>
|
||||
<primary>ldapjdk.jar</primary>
|
||||
</indexterm><term><filename>ldapjdk.jar</filename></term>
|
||||
<listitem><para>Contains classes for all packages listed in <olink targetptr="understanding-java-classes">
|
||||
Understanding the LDAP Java Classes</olink><!--, but does not contain the filter classes-->
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<!--<varlistentry><indexterm>
|
||||
<primary>ldapfilt.jar</primary>
|
||||
</indexterm><term><filename>ldapfilt.jar</filename></term>
|
||||
<listitem><para>Contains the filter classes in the <literal>
|
||||
netscape.ldap.util</literal> package, and the underlying
|
||||
regular expression classes needed by the filter classes
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>-->
|
||||
</variablelist>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><filename class="directory">tools</filename></term>
|
||||
<listitem><para>This directory contains Java classes for the <command>LDAPDelete</command>, <command>
|
||||
LDAPModify</command>, and <command>LDAPSearch</command> commands.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
<sect2 id="prepare-jdk"><title>Preparing to Use &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary><envar>CLASSPATH</envar></primary>
|
||||
<secondary>setting</secondary>
|
||||
</indexterm>
|
||||
<para>TODO: is this right?</para>
|
||||
<para>Before compiling applications, add the following to your <envar>CLASSPATH</envar> environment
|
||||
variable:</para>
|
||||
<variablelist>
|
||||
<!--<varlistentry><term><filename>beans/*.jar</filename></term>
|
||||
<listitem><para>Containing the LDAP JavaBeans classes
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>-->
|
||||
<varlistentry><term><filename>packages/ldapjdk.jar</filename></term>
|
||||
<listitem><para>Containing the main LDAP Java classes</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<!--<varlistentry><term><filename>packages/ldapfilt.jar
|
||||
</filename></term>
|
||||
<listitem><para>Containing the LDAP classes for handling
|
||||
search filters</para>
|
||||
</listitem>
|
||||
</varlistentry>-->
|
||||
</variablelist>
|
||||
</sect2>
|
||||
<!--<sect2 id="applets-jdk"><title>Writing Applets with
|
||||
the &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>applets</primary>
|
||||
<secondary>security framework and</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>&DirectorySDKForJava;</primary>
|
||||
<secondary>writing applets for</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>writing applets</secondary>
|
||||
</indexterm>
|
||||
<para>TODO: Get this up to date. None of it seems
|
||||
to work.</para>
|
||||
<para>In <trademark>Netscape</trademark> Communicator,
|
||||
an applet can connect to servers on hosts other than
|
||||
the host that served the applet. This capability is
|
||||
part of the new signed applet security framework.
|
||||
To take advantage of this capability, your applet
|
||||
class, the class making an LDAP connection, must be
|
||||
signed. Your applet class needs to request certain
|
||||
special rights before connecting to other servers.
|
||||
</para>
|
||||
<para>The steps to enable your applet to connect to
|
||||
other LDAP servers are as follows:</para>
|
||||
<orderedlist>
|
||||
<listitem><para>Get a certificate from your organization's
|
||||
certificate authority or from a third-party certificate
|
||||
authority, such as RSA, Verisign, or ATT.</para><para>
|
||||
Users should have the certificate from the certificate
|
||||
authority in the Communicator certificate database.
|
||||
</para></listitem>
|
||||
<listitem><para>Create a JAR file with your classes
|
||||
and have them signed.</para></listitem>
|
||||
<listitem><para>Add the following line to your applet
|
||||
code in the thread where you invoke <literal>LDAPConnection.connect
|
||||
</literal>:</para>
|
||||
<programlisting>PrivilegeManager.enablePrivilege("UniversalConnect");
|
||||
</programlisting>
|
||||
<para>At this point in the code, the user of your
|
||||
applet will be prompted with a dialog box identifying
|
||||
the author of the signed class and asking permission
|
||||
to grant the right to access the LDAP server. The
|
||||
user can either allow access for this time only or
|
||||
forever.</para></listitem></orderedlist>
|
||||
<para>TODO: fix this.</para>
|
||||
<para>If you want to test the ability for your applet
|
||||
to connect to hosts other than the originating one
|
||||
without using object signing and certificates, in
|
||||
case you want to test your applet while waiting for
|
||||
your certificate to be issued for example, you can
|
||||
configure Netscape Communicator to bypass this check.
|
||||
</para>
|
||||
<orderedlist>
|
||||
<listitem><para>Exit Communicator or make sure that
|
||||
it is not running.</para></listitem>
|
||||
<listitem><para>Add the following line to the <filename>
|
||||
prefs.js</filename> file: </para>
|
||||
<programlisting>user_pref("signed.applets.codebase_principal_support", true);
|
||||
</programlisting>
|
||||
</listitem></orderedlist>
|
||||
</sect2><sect2 id="version-jdk"><title>Checking the
|
||||
Version of Classes from an Applet</title>
|
||||
<indexterm>
|
||||
<primary>applets</primary>
|
||||
<secondary>checking version of LDAP classes</secondary>
|
||||
</indexterm>
|
||||
<para>To get the version number, invoke the <literal>
|
||||
LDAPConnection.getProperty</literal> method and pass
|
||||
in the constant <literal>LDAPConnection.LDAP_PROPERTY_SDK
|
||||
</literal>. The version number is a <classname>Float
|
||||
</classname> type. For example:</para>
|
||||
<programlisting>Float sdkVersion = (Float)myConn.getProperty(myConn.LDAP_PROPERTY_SDK);
|
||||
System.out.println("LDAP Java Classes version: " + sdkVersion);
|
||||
</programlisting>
|
||||
</sect2><sect2 id="javabeans-jdk"><title>Working with
|
||||
LDAP JavaBeans Classes</title>
|
||||
<indexterm>
|
||||
<primary>JavaBeans classes</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP JavaBeans classes</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>&DirectorySDKForJava;</primary>
|
||||
<secondary>LDAP JavaBeans classes</secondary>
|
||||
</indexterm>
|
||||
<para>The JavaBeans classes are part of the <literal>
|
||||
netscape.ldap.beans</literal> package. Class files
|
||||
are located in the <filename class="directory">beans
|
||||
</filename> directory. The following JavaBeans classes
|
||||
are included with the &DirectorySDKForJava;:</para>
|
||||
<variablelist>
|
||||
<varlistentry><term><classname>DisplayString</classname></term>
|
||||
<listitem><para>Extends <classname>java.awt.TextArea
|
||||
</classname> to help you display results from some
|
||||
of the JavaBeans classes.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><classname>LDAPBasePropertySupport
|
||||
</classname></term>
|
||||
<listitem><para>Exists as a base class specifying
|
||||
accessor methods inherited by the other LDAP JavaBeans
|
||||
classes.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><classname>LDAPGetEntries</classname></term>
|
||||
<listitem><para>Allows you to search the directory
|
||||
and get an array of the DNs found by the search.</para>
|
||||
<para>You can use the properties of this class to
|
||||
specify the search criteria. The <literal>getEntries
|
||||
</literal> method performs the search and sets the <property>
|
||||
Result</property> property to the array of DNs found.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><classname>LDAPGetProperty</classname></term>
|
||||
<listitem><para>Allows you to find an entry in the
|
||||
directory and get the values of a specified attribute
|
||||
in that entry.</para>
|
||||
<para>You can use the properties of this class to
|
||||
specify the search criteria. The <literal>getProperty
|
||||
</literal> method performs the search and sets the <property>
|
||||
Result</property> property to the array of the string
|
||||
values of the specified attribute.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><classname>LDAPIsMember</classname></term>
|
||||
<listitem><para>Determines whether a user belongs
|
||||
to a group.</para>
|
||||
<para>Both the user and group can be specified as
|
||||
properties of the class. The <literal>isMember</literal> method
|
||||
sets the <property>Result</property> property to the
|
||||
string <literal>Y</literal>or <literal>N</literal> to
|
||||
indicate whether the user is a member.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry><term><classname>LDAPSimpleAuth</classname></term>
|
||||
<listitem><para>Authenticates to an LDAP server.</para>
|
||||
<para>After attempting to authenticate, the <literal>
|
||||
authenticate</literal> method sets the <property>
|
||||
Result</property> property to the string <literal>
|
||||
Y</literal>or <literal>N</literal> to indicate whether
|
||||
the authentication was successful.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>TODO: explain how to set this up with Java Studio
|
||||
or Java Studio Creator</para>
|
||||
<para>The LDAP JavaBeans classes have a <property>
|
||||
Debug</property> property you can set to have debugging
|
||||
information displayed. This information is printed
|
||||
to standard output. TODO: what happens when you use
|
||||
Java Studio or Creator?</para></sect2><sect2 id="javascript-jdk">
|
||||
<title>Using the Classes from <trademark>JavaScript
|
||||
</trademark> Code</title>
|
||||
<indexterm>
|
||||
<primary>JavaScript</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LiveConnect</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP Java classes</primary>
|
||||
<secondary>JavaScript and</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP Java classes</primary>
|
||||
<secondary>LiveConnect and</secondary>
|
||||
</indexterm>
|
||||
<para>TODO: Update all this. The code doesn't appear
|
||||
to work with Mozilla.</para>
|
||||
<para>Using Netscape Communicator's LiveConnect capabilities,
|
||||
you can use the LDAP Java classes from within JavaScript
|
||||
code in an HTML page. LiveConnect enables communication
|
||||
between JavaScript and Java applets in a page and
|
||||
between JavaScript and plug-ins loaded on a page.
|
||||
</para>
|
||||
<para>To see an example of how you can do this, see
|
||||
the sample JavaScript code in the HTML file in the <filename
|
||||
class="directory">examples/js</filename> directory.
|
||||
</para></sect2>-->
|
||||
</sect1>
|
||||
</chapter>
|
||||
361
mozilla/directory/docs/ldapjdk/jdk-writing-client.sgm
Normal file
361
mozilla/directory/docs/ldapjdk/jdk-writing-client.sgm
Normal file
@@ -0,0 +1,361 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="writing-client"><title>Writing an LDAP Client With &DirectorySDKForJava;</title>
|
||||
<highlights>
|
||||
<para>This chapter describes the general process of writing an LDAP client.
|
||||
The chapter covers the procedures for connecting to an LDAP server. It covers
|
||||
authentication, requesting operations, and disconnecting from the server. </para>
|
||||
<itemizedlist>
|
||||
<para>The chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="designing-client">Designing an LDAP Java
|
||||
Client</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="prepare-client">Creating a Connection and
|
||||
Setting Preferences With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="connect-client">Connecting to an LDAP Server
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="bind-client">Binding and Authenticating
|
||||
to an LDAP Server With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="ldapops-client">Performing LDAP Operations
|
||||
With Directory SDK for Java</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="close-client">Closing the Connection to
|
||||
an LDAP Server With Directory SDK for Java</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="designing-client"><title>Designing an LDAP Java Client</title>
|
||||
<para>The following steps outline the typical process of communicating with
|
||||
an LDAP server. Follow these steps when writing your LDAP client.</para>
|
||||
<orderedlist>
|
||||
<listitem><para>Create a new <classname>LDAPConnection</classname> object,
|
||||
and set any preferences that you want applied to all LDAP operations.</para>
|
||||
</listitem>
|
||||
<listitem><para>Connect to an LDAP server.</para></listitem>
|
||||
<listitem><para>If necessary, bind to the LDAP server, specifying the version
|
||||
of LDAP supported by your client.</para></listitem>
|
||||
<listitem><para>Perform the LDAP operations, such as searching the directory
|
||||
or modifying entries in the directory.</para></listitem>
|
||||
<listitem><para>When finished performing operations, disconnect from the LDAP
|
||||
server.</para></listitem>
|
||||
</orderedlist>
|
||||
<para>The following example LDAP client follows these steps to search a directory.
|
||||
The client connects to the LDAP server running on the local host at port <literal>
|
||||
389</literal>. The client then searches the directory for entries with the
|
||||
surname <literal>Jensen</literal>. Finally, the client displays the DNs of
|
||||
matching entries.</para>
|
||||
<programlisting>import netscape.ldap.*;
|
||||
import java.util.*;
|
||||
|
||||
public class Search {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
UserArgs userArgs = new UserArgs("Search", args, false);
|
||||
LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(userArgs.getHost(), userArgs.getPort());
|
||||
|
||||
/* search for all entries with surname of Jensen */
|
||||
String MY_FILTER = "sn=Jensen";
|
||||
String MY_SEARCHBASE = "dc=example,dc=com";
|
||||
|
||||
LDAPSearchConstraints cons = ld.getSearchConstraints();
|
||||
/* Setting the batchSize to one will cause the result
|
||||
enumeration below to block on one result at a time,
|
||||
enabling an update of a list or other things as
|
||||
results come in. */
|
||||
/* This could be set to 0 in order to get all
|
||||
results and to block until then. */
|
||||
cons.setBatchSize(1);
|
||||
LDAPSearchResults res = ld.search(MY_SEARCHBASE,
|
||||
LDAPConnection.SCOPE_SUB, MY_FILTER, null, false, cons);
|
||||
|
||||
/* Loop on results until finished */
|
||||
while (res.hasMoreElements()) {
|
||||
LDAPEntry findEntry = null;
|
||||
try {
|
||||
findEntry = res.next();
|
||||
} catch (LDAPReferralException e) {
|
||||
System.out.println("Search reference: ");
|
||||
LDAPUrl refUrls[] = e.getURLs();
|
||||
for (int i=0; i<refUrls.length; i++) {
|
||||
System.out.println("\t" + refUrls[i].getUrl());
|
||||
}
|
||||
continue;
|
||||
} catch (LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
continue;
|
||||
}
|
||||
System.out.println(findEntry.getDN());
|
||||
|
||||
/* Get the attributes of the entry */
|
||||
LDAPAttributeSet findAttrs = findEntry.getAttributeSet();
|
||||
Enumeration enumAttrs = findAttrs.getAttributes();
|
||||
System.out.println("\tAttributes: ");
|
||||
|
||||
/* Loop on attributes */
|
||||
while (enumAttrs.hasMoreElements()) {
|
||||
LDAPAttribute anAttr =
|
||||
(LDAPAttribute)enumAttrs.nextElement();
|
||||
String attrName = anAttr.getName();
|
||||
System.out.println("\t\t" + attrName);
|
||||
|
||||
/* Loop on values for this attribute */
|
||||
Enumeration enumVals = anAttr.getStringValues();
|
||||
if (enumVals != null) {
|
||||
while (enumVals.hasMoreElements()) {
|
||||
String aVal = (String)enumVals.nextElement();
|
||||
System.out.println("\t\t\t" + aVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ld.disconnect();
|
||||
} catch(LDAPException e) {
|
||||
System.out.println("Error: " + e.toString());
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
</sect1>
|
||||
<sect1 id="prepare-client"><title>Creating a Connection and Setting Preferences
|
||||
With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>connection</primary>
|
||||
<secondary>creating</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>connection</primary>
|
||||
<secondary>setting preferences</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP session</primary>
|
||||
<secondary>setting preferences</secondary>
|
||||
</indexterm>
|
||||
<para>The first step in writing an LDAP client is creating an <classname>LDAPConnection
|
||||
</classname> object. This object represents the connection to an LDAP server.</para>
|
||||
<programlisting>LDAPConnection ld = new LDAPConnection();</programlisting>
|
||||
<note><para>If you plan to connect to the LDAP server over the <firstterm>Secure
|
||||
Sockets Layer</firstterm> (SSL) protocol, you need to specify a class that
|
||||
implements SSL sockets. Refer to <olink type="auto-generated" targetptr="ssl">Chapter 9,
|
||||
SSL Connections With Directory SDK for Java</olink> for details.</para></note>
|
||||
<para>The <classname>LDAPConnection</classname> object also contains preferences
|
||||
for the LDAP session, such as whether referrals are or are not followed automatically.
|
||||
To get or set the value of a preference, invoke the <literal>getOption</literal> method
|
||||
or the <literal>setOption</literal> method as described in the API specification.
|
||||
</para></sect1>
|
||||
<sect1 id="connect-client"><title>Connecting to an LDAP Server With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>connecting to</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>connection to a server</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>connection</primary>
|
||||
<secondary>establishing</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>session</primary>
|
||||
<secondary>starting</secondary>
|
||||
</indexterm>
|
||||
<para>To connect to an LDAP server, use the <literal>connect</literal> method
|
||||
of the <classname>LDAPConnection</classname> object.</para>
|
||||
<programlisting>LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);</programlisting>
|
||||
<para><literal>DEFAULT_PORT</literal> specifies the default LDAP port, port
|
||||
389. You can also specify a list of LDAP servers to attempt to connect to.
|
||||
If the first LDAP server in the list does not respond, the client attempts
|
||||
to connect to the next server in the list.</para>
|
||||
<para><indexterm>
|
||||
<primary>connection</primary>
|
||||
<secondary>specifying multiple LDAP servers</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>failover support</primary>
|
||||
</indexterm>Use a space-delimited list of the host names as the first argument
|
||||
of the connect method. If the server is not using the default LDAP port, specify
|
||||
the port number in <replaceable>hostname</replaceable><literal>:</literal><replaceable>
|
||||
portnumber</replaceable> format.</para>
|
||||
<programlisting>LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect("ldap1.example.com ldap2.example.com:3890
|
||||
ldap3.example.com:3900", LDAPv3.DEFAULT_PORT);</programlisting>
|
||||
</sect1>
|
||||
<sect1 id="bind-client"><title>Binding and Authenticating to an LDAP Server
|
||||
With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>authenticating with LDAP servers</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>authenticating to</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>bind operation</primary>
|
||||
</indexterm>
|
||||
<para>When connecting to the LDAP server, your client might need to send a
|
||||
bind operation request to the server. This operation is also called binding
|
||||
to the server.</para>
|
||||
<itemizedlist>
|
||||
<para>An LDAP bind request contains the following information:</para>
|
||||
<listitem><para>LDAP version of the client</para></listitem>
|
||||
<listitem><para>DN that is used to authenticate</para></listitem>
|
||||
<listitem><para>Authentication method that is requested</para></listitem>
|
||||
<listitem><para>Credentials that are used to authenticate</para></listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<para>The client should send a bind request to the server in the following
|
||||
situations:</para>
|
||||
<listitem><para>You want to authenticate to the server.</para><para>For example,
|
||||
if you want to add or modify entries in the directory, you need to authenticate
|
||||
as a user with access privileges.</para></listitem>
|
||||
<listitem><para>You are connecting to an LDAP v2 server.</para><para>LDAP
|
||||
v2 servers typically require clients to bind before any operations can be
|
||||
performed.</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>An LDAP client can also bind as an anonymous client. For example, the
|
||||
LDAP server might not require authentication if your client is only searching
|
||||
the directory.</para>
|
||||
<para>This section explains how to set up your client to bind to an LDAP server.</para>
|
||||
<sect2 id="simple-auth-client"><title>Using Simple Authentication</title>
|
||||
<para>Simple authentication can be used when security is not a concern. If
|
||||
you plan to use simple authentication, use the <literal>authenticate</literal> method
|
||||
of the <classname>LDAPConnection</classname> object.</para>
|
||||
<programlisting>LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
|
||||
ld.authenticate("uid=bjensen,ou=People,cd=example,dc=com", "hifalutin");</programlisting>
|
||||
<para>The server to which you bind might send back a special control to indicate
|
||||
that your password has expired. The server might also send back a control
|
||||
to indicate that your password is to expire in the near future. Refer to <olink
|
||||
type="auto-generated" targetptr="controls">Chapter 10, LDAP Controls
|
||||
With Directory SDK for Java</olink> for details.</para></sect2>
|
||||
<sect2 id="anonymous-bind-client"><title>Binding Anonymously</title>
|
||||
<indexterm>
|
||||
<primary>anonymous bind</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>binding</primary>
|
||||
<secondary>anonymously</secondary>
|
||||
</indexterm>
|
||||
<para>In some cases, you might not need to authenticate to the LDAP server.
|
||||
For example, the directory that you search might not require special access
|
||||
permissions for searches. Therefore, you might not need to authenticate before
|
||||
performing the search operation. In LDAP v3, the server no longer expects
|
||||
the client to send a bind request in this type of situation. In LDAP v2, the
|
||||
server expects the client to send a bind request, even if the operation does
|
||||
not require the client to authenticate.</para>
|
||||
<para>In this kind of situation, use the <literal>authenticate</literal> method.
|
||||
Specify <literal>null</literal> for the DN and password.</para>
|
||||
<programlisting>LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
|
||||
ld.authenticate(null, null);</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="ldap-version-client"><title>Specifying the LDAP Version</title>
|
||||
<indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>specifying protocol version</secondary>
|
||||
</indexterm>
|
||||
<para>As part of the bind request sent to the server, the client includes
|
||||
the version of the LDAP protocol that the client supports. By default, clients
|
||||
built with the&DirectorySDKForJava; identify themselves as LDAP v2 clients.
|
||||
Therefore, explicitly identify your client as an LDAP v3 client.</para>
|
||||
<itemizedlist>
|
||||
<para>To identify your client as an LDAP v3 client, do one of the following:</para>
|
||||
<listitem><para>Specify version 3 when invoking the <literal>authenticate</literal> method.
|
||||
</para>
|
||||
<programlisting>LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
|
||||
ld.authenticate(3, null, null);</programlisting>
|
||||
</listitem>
|
||||
<listitem><para>Invoke the <literal>setOption</literal> method of the <classname>
|
||||
LDAPConnection</classname> object to set the <literal>LDAPv3.PROTOCOL_VERSION</literal> preference
|
||||
to <literal>3</literal>, then invoke the <literal>authenticate</literal> method.</para>
|
||||
<programlisting>LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
|
||||
ld.setOption(LDAPv3.PROTOCOL_VERSION, 3);
|
||||
ld.authenticate(null, null);</programlisting>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect2>
|
||||
<sect2 id="connect-method-client"><title>Authenticating With the <literal>connect
|
||||
</literal> Method</title>
|
||||
<para>The <literal>connect</literal> method of the <classname>LDAPConnection</classname> object
|
||||
has a signature that allows you to authenticate and specify the LDAP version
|
||||
supported by your client.</para>
|
||||
<para>You can specify all of this information using one method, rather than
|
||||
invoking several methods.</para>
|
||||
<programlisting>LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect(3, "ldap.example.com", LDAPv3.DEFAULT_PORT,
|
||||
"uid=bjensen,ou=People,cd=example,dc=com", "hifalutin");</programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="ldapops-client"><title>Performing LDAP Operations With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>LDAP operations</primary>
|
||||
</indexterm>
|
||||
<para>First, you initialize a session with an LDAP server. Next, you complete
|
||||
the authentication process. After authentication, you can perform LDAP operations.
|
||||
For example, you can search the directory, add new entries, update entries
|
||||
that exist, and remove entries. You can perform the operations provided that
|
||||
the server access control allows you to request the operations.</para>
|
||||
<itemizedlist>
|
||||
<para>To perform LDAP operations, invoke these methods of the <classname>LDAPConnection
|
||||
</classname> object:</para>
|
||||
<listitem><para>To search for entries in the directory, use the <literal>search</literal> method
|
||||
as explained in <olink targetptr="searching">Chapter 4, Searching the
|
||||
Directory With Directory SDK for Java</olink>.</para></listitem>
|
||||
<listitem><para>To retrieve a single entry in the directory, use the <literal>read
|
||||
</literal> method as explained in <olink targetptr="searching">Chapter 4,
|
||||
Searching the Directory With Directory SDK for Java</olink>.</para></listitem>
|
||||
<listitem><para>To determine whether an attribute contains a certain value,
|
||||
use the <literal>compare</literal> method as explained in <olink
|
||||
targetptr="comparing">Chapter 6, Comparing Attribute Values With Directory
|
||||
SDK for Java</olink>.</para></listitem>
|
||||
<listitem><para>To add entries to the directory, use the <literal>add</literal> method
|
||||
as explained in <olink targetptr="adding">Chapter 5, Adding, Updating,
|
||||
and Deleting Entries With Directory SDK for Java</olink>.</para></listitem>
|
||||
<listitem><para>To modify entries in the directory, use the <literal>modify</literal> method
|
||||
as explained in <olink targetptr="adding">Chapter 5, Adding, Updating,
|
||||
and Deleting Entries With Directory SDK for Java</olink>.</para></listitem>
|
||||
<listitem><para>To delete entries from the directory, use the <literal>delete</literal> method
|
||||
as explained in <olink targetptr="adding">Chapter 5, Adding, Updating,
|
||||
and Deleting Entries With Directory SDK for Java</olink>.</para></listitem>
|
||||
<listitem><para>To rename entries in the directory, use the <literal>rename</literal> method
|
||||
as explained in <olink targetptr="adding">Chapter 5, Adding, Updating,
|
||||
and Deleting Entries With Directory SDK for Java</olink>.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="close-client"><title>Closing the Connection to an LDAP Server With &DirectorySDKForJava;</title>
|
||||
<indexterm>
|
||||
<primary>ending an LDAP session</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP session</primary>
|
||||
<secondary>ending</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>closing an LDAP connection</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>closing connection from client</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>closing connection to server</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>connection</primary>
|
||||
<secondary>closing</secondary>
|
||||
</indexterm>
|
||||
<para>When you have finished performing all necessary LDAP operations, close
|
||||
the connection to the LDAP server. Use the <literal>disconnect</literal> method
|
||||
of the <classname>LDAPConnection</classname> object to disconnect from the
|
||||
LDAP server.</para>
|
||||
<programlisting>LDAPConnection ld = new LDAPConnection();
|
||||
ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
|
||||
/*
|
||||
* Authenticate and perform LDAP operations.
|
||||
*/
|
||||
ld.disconnect();</programlisting>
|
||||
</sect1>
|
||||
</chapter>
|
||||
113
mozilla/directory/docs/ldapjdk/legal.sgm
Normal file
113
mozilla/directory/docs/ldapjdk/legal.sgm
Normal file
@@ -0,0 +1,113 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<para>Copyright 2000-2007 Sun Microsystems, Inc., 4150 Network Circle,
|
||||
Santa Clara, California 95054, U.S.A. All rights reserved. Portions
|
||||
copyright 1999 Netscape Communications Corporations. All rights
|
||||
reserved.</para>
|
||||
<para>Sun Microsystems, Inc. has intellectual property rights relating
|
||||
to technology embodied in the product that is described in this
|
||||
document. In particular, and without limitation, these intellectual
|
||||
property rights may include one or more U.S. patents or pending patent
|
||||
applications in the U.S. and in other countries.</para>
|
||||
<para>U.S. Government Rights - Commercial software. Government users
|
||||
are subject to the Sun Microsystems, Inc. standard license agreement
|
||||
and applicable provisions of the FAR and its supplements.</para>
|
||||
<para>This distribution may include materials developed by third
|
||||
parties.</para>
|
||||
<para>Parts of the product may be derived from Berkeley BSD systems,
|
||||
licensed from the University of California. UNIX is a registered
|
||||
trademark in the U.S. and in other countries, exclusively licensed
|
||||
through X/Open Company, Ltd.</para>
|
||||
<para>Sun, Sun Microsystems, the Sun logo, Java, Solaris, JavaBeans,
|
||||
JavaScript and the SunTone Certified logo are trademarks or registered
|
||||
trademarks of Sun Microsystems, Inc. in the U.S. and other
|
||||
countries.</para>
|
||||
<para>All SPARC trademarks are used under license and are trademarks
|
||||
or registered trademarks of SPARC International, Inc. in the U.S. and
|
||||
other countries. Products bearing SPARC trademarks are based upon
|
||||
architecture developed by Sun Microsystems, Inc.</para>
|
||||
<para>Mozilla, Netscape, and Netscape Navigator are trademarks or
|
||||
registered trademarks of Netscape Communications Corporation in the
|
||||
United States and other countries.</para>
|
||||
<para>Products covered by and information contained in this service
|
||||
manual are controlled by U.S. Export Control laws and may be subject
|
||||
to the export or import laws in other countries. Nuclear, missile,
|
||||
chemical biological weapons or nuclear maritime end uses or end users,
|
||||
whether direct or indirect, are strictly prohibited. Export or
|
||||
reexport to countries subject to U.S. embargo or to entities
|
||||
identified on U.S. export exclusion lists, including, but not limited
|
||||
to, the denied persons and specially designated nationals lists is
|
||||
strictly prohibited.</para>
|
||||
<para>DOCUMENTATION IS PROVIDED “AS IS” AND ALL EXPRESS OR
|
||||
IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
|
||||
IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
|
||||
OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH
|
||||
DISCLAIMERS ARE HELD TO BE LEGALLY INVALID.</para>
|
||||
<para>Copyright 2000-2007 Sun Microsystems, Inc., 4150 Network Circle,
|
||||
Santa Clara, California 95054, Etats-Unis. Tous droits
|
||||
réservés. Certaines parties copyright 1999 Netscape
|
||||
Communications Corporations. Tous droits réservés.</para>
|
||||
<para>Sun Microsystems, Inc. détient les droits de
|
||||
propriété intellectuelle relatifs à la
|
||||
technologie incorporée dans le produit qui est décrit
|
||||
dans ce document. En particulier, et ce sans limitation, ces droits de
|
||||
propriété intellectuelle peuvent inclure un ou plusieurs
|
||||
brevets américains ou des applications de brevet en attente aux
|
||||
Etats-Unis et dans d'autres pays.</para>
|
||||
<para>Cette distribution peut comprendre des composants
|
||||
développés par des tierces parties.</para>
|
||||
<para>Des parties de ce produit pourront être
|
||||
dérivées des systèmes Berkeley BSD
|
||||
licenciés par l'Université de Californie. UNIX est une
|
||||
marque déposée aux Etats-Unis et dans d'autres pays et
|
||||
licenciée exclusivement par X/Open Company, Ltd.</para>
|
||||
<para>Sun, Sun Microsystems, le logo Sun, Java, Solaris, JavaBeans,
|
||||
JavaScript et le logo SunTone Certified sont des marques de fabrique
|
||||
ou des marques déposées de Sun Microsystems, Inc. aux
|
||||
Etats-Unis et dans d'autres pays.</para>
|
||||
<para>Toutes les marques SPARC sont utilisées sous licence et
|
||||
sont des marques de fabrique ou des marques déposées de
|
||||
SPARC International, Inc. aux Etats-Unis et dans d'autres pays. Les
|
||||
produits portant les marques SPARC sont basés sur une
|
||||
architecture développée par Sun Microsystems,
|
||||
Inc.</para>
|
||||
<para>Mozilla, Netscape, et Netscape Navigator sont des marques de
|
||||
Netscape Communications Corporation aux Etats-Unis et dans d'autres
|
||||
pays.</para>
|
||||
<para>Les produits qui font l'objet de ce manuel d'entretien et les
|
||||
informations qu'il contient sont regis par la legislation americaine
|
||||
en matiere de controle des exportations et peuvent etre soumis au
|
||||
droit d'autres pays dans le domaine des exportations et
|
||||
importations. Les utilisations finales, ou utilisateurs finaux, pour
|
||||
des armes nucleaires, des missiles, des armes biologiques et chimiques
|
||||
ou du nucleaire maritime, directement ou indirectement, sont
|
||||
strictement interdites. Les exportations ou reexportations vers des
|
||||
pays sous embargo des Etats-Unis, ou vers des entites figurant sur les
|
||||
listes d'exclusion d'exportation americaines, y compris, mais de
|
||||
maniere non exclusive, la liste de personnes qui font objet d'un ordre
|
||||
de ne pas participer, d'une facon directe ou indirecte, aux
|
||||
exportations des produits ou des services qui sont regi par la
|
||||
legislation americaine en matiere de controle des exportations et la
|
||||
liste de ressortissants specifiquement designes, sont rigoureusement
|
||||
interdites.</para>
|
||||
<para>LA DOCUMENTATION EST FOURNIE “EN L'ETAT” ET TOUTES
|
||||
AUTRES CONDITIONS, DECLARATIONS ET GARANTIES EXPRESSES OU TACITES SONT
|
||||
FORMELLEMENT EXCLUES, DANS LA MESURE AUTORISEE PAR LA LOI APPLICABLE,
|
||||
Y COMPRIS NOTAMMENT TOUTE GARANTIE IMPLICITE RELATIVE A LA QUALITE
|
||||
MARCHANDE, A L'APTITUDE A UNE UTILISATION PARTICULIERE OU A L'ABSENCE
|
||||
DE CONTREFACON. </para>
|
||||
226
mozilla/directory/docs/ldapjdk/license.txt
Normal file
226
mozilla/directory/docs/ldapjdk/license.txt
Normal file
@@ -0,0 +1,226 @@
|
||||
Attribution-ShareAlike 2.5
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL
|
||||
SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT
|
||||
RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS.
|
||||
CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND
|
||||
DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE.
|
||||
|
||||
License
|
||||
|
||||
THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS
|
||||
PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR
|
||||
OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS
|
||||
LICENSE OR COPYRIGHT LAW IS PROHIBITED.
|
||||
|
||||
BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE
|
||||
BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED
|
||||
HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS.
|
||||
|
||||
1. Definitions
|
||||
|
||||
1. "Collective Work" means a work, such as a periodical issue, anthology or
|
||||
encyclopedia, in which the Work in its entirety in unmodified form, along with a
|
||||
number of other contributions, constituting separate and independent works in
|
||||
themselves, are assembled into a collective whole. A work that constitutes a
|
||||
Collective Work will not be considered a Derivative Work (as defined below) for
|
||||
the purposes of this License.
|
||||
2. "Derivative Work" means a work based upon the Work or upon the Work and
|
||||
other pre-existing works, such as a translation, musical arrangement,
|
||||
dramatization, fictionalization, motion picture version, sound recording, art
|
||||
reproduction, abridgment, condensation, or any other form in which the Work may
|
||||
be recast, transformed, or adapted, except that a work that constitutes a
|
||||
Collective Work will not be considered a Derivative Work for the purpose of this
|
||||
License. For the avoidance of doubt, where the Work is a musical composition or
|
||||
sound recording, the synchronization of the Work in timed-relation with a moving
|
||||
image ("synching") will be considered a Derivative Work for the purpose of this
|
||||
License.
|
||||
3. "Licensor" means the individual or entity that offers the Work under the
|
||||
terms of this License.
|
||||
4. "Original Author" means the individual or entity who created the Work.
|
||||
5. "Work" means the copyrightable work of authorship offered under the terms
|
||||
of this License.
|
||||
6. "You" means an individual or entity exercising rights under this License
|
||||
who has not previously violated the terms of this License with respect to the
|
||||
Work, or who has received express permission from the Licensor to exercise
|
||||
rights under this License despite a previous violation.
|
||||
7. "License Elements" means the following high-level license attributes as
|
||||
selected by Licensor and indicated in the title of this License: Attribution,
|
||||
ShareAlike.
|
||||
|
||||
2. Fair Use Rights. Nothing in this license is intended to reduce, limit, or
|
||||
restrict any rights arising from fair use, first sale or other limitations on
|
||||
the exclusive rights of the copyright owner under copyright law or other
|
||||
applicable laws.
|
||||
|
||||
3. License Grant. Subject to the terms and conditions of this License, Licensor
|
||||
hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the
|
||||
duration of the applicable copyright) license to exercise the rights in the Work
|
||||
as stated below:
|
||||
|
||||
1. to reproduce the Work, to incorporate the Work into one or more Collective
|
||||
Works, and to reproduce the Work as incorporated in the Collective Works;
|
||||
2. to create and reproduce Derivative Works;
|
||||
3. to distribute copies or phonorecords of, display publicly, perform
|
||||
publicly, and perform publicly by means of a digital audio transmission the Work
|
||||
including as incorporated in Collective Works;
|
||||
4. to distribute copies or phonorecords of, display publicly, perform
|
||||
publicly, and perform publicly by means of a digital audio transmission
|
||||
Derivative Works.
|
||||
5.
|
||||
|
||||
For the avoidance of doubt, where the work is a musical composition:
|
||||
1. Performance Royalties Under Blanket Licenses. Licensor waives the
|
||||
exclusive right to collect, whether individually or via a performance rights
|
||||
society (e.g. ASCAP, BMI, SESAC), royalties for the public performance or public
|
||||
digital performance (e.g. webcast) of the Work.
|
||||
2. Mechanical Rights and Statutory Royalties. Licensor waives the
|
||||
exclusive right to collect, whether individually or via a music rights society
|
||||
or designated agent (e.g. Harry Fox Agency), royalties for any phonorecord You
|
||||
create from the Work ("cover version") and distribute, subject to the compulsory
|
||||
license created by 17 USC Section 115 of the US Copyright Act (or the equivalent
|
||||
in other jurisdictions).
|
||||
6. Webcasting Rights and Statutory Royalties. For the avoidance of doubt,
|
||||
where the Work is a sound recording, Licensor waives the exclusive right to
|
||||
collect, whether individually or via a performance-rights society (e.g.
|
||||
SoundExchange), royalties for the public digital performance (e.g. webcast) of
|
||||
the Work, subject to the compulsory license created by 17 USC Section 114 of the
|
||||
US Copyright Act (or the equivalent in other jurisdictions).
|
||||
|
||||
The above rights may be exercised in all media and formats whether now known or
|
||||
hereafter devised. The above rights include the right to make such modifications
|
||||
as are technically necessary to exercise the rights in other media and formats.
|
||||
All rights not expressly granted by Licensor are hereby reserved.
|
||||
|
||||
4. Restrictions.The license granted in Section 3 above is expressly made subject
|
||||
to and limited by the following restrictions:
|
||||
|
||||
1. You may distribute, publicly display, publicly perform, or publicly
|
||||
digitally perform the Work only under the terms of this License, and You must
|
||||
include a copy of, or the Uniform Resource Identifier for, this License with
|
||||
every copy or phonorecord of the Work You distribute, publicly display, publicly
|
||||
perform, or publicly digitally perform. You may not offer or impose any terms on
|
||||
the Work that alter or restrict the terms of this License or the recipients'
|
||||
exercise of the rights granted hereunder. You may not sublicense the Work. You
|
||||
must keep intact all notices that refer to this License and to the disclaimer of
|
||||
warranties. You may not distribute, publicly display, publicly perform, or
|
||||
publicly digitally perform the Work with any technological measures that control
|
||||
access or use of the Work in a manner inconsistent with the terms of this
|
||||
License Agreement. The above applies to the Work as incorporated in a Collective
|
||||
Work, but this does not require the Collective Work apart from the Work itself
|
||||
to be made subject to the terms of this License. If You create a Collective
|
||||
Work, upon notice from any Licensor You must, to the extent practicable, remove
|
||||
from the Collective Work any credit as required by clause 4(c), as requested. If
|
||||
You create a Derivative Work, upon notice from any Licensor You must, to the
|
||||
extent practicable, remove from the Derivative Work any credit as required by
|
||||
clause 4(c), as requested.
|
||||
2. You may distribute, publicly display, publicly perform, or publicly
|
||||
digitally perform a Derivative Work only under the terms of this License, a
|
||||
later version of this License with the same License Elements as this License, or
|
||||
a Creative Commons iCommons license that contains the same License Elements as
|
||||
this License (e.g. Attribution-ShareAlike 2.5 Japan). You must include a copy
|
||||
of, or the Uniform Resource Identifier for, this License or other license
|
||||
specified in the previous sentence with every copy or phonorecord of each
|
||||
Derivative Work You distribute, publicly display, publicly perform, or publicly
|
||||
digitally perform. You may not offer or impose any terms on the Derivative Works
|
||||
that alter or restrict the terms of this License or the recipients' exercise of
|
||||
the rights granted hereunder, and You must keep intact all notices that refer to
|
||||
this License and to the disclaimer of warranties. You may not distribute,
|
||||
publicly display, publicly perform, or publicly digitally perform the Derivative
|
||||
Work with any technological measures that control access or use of the Work in a
|
||||
manner inconsistent with the terms of this License Agreement. The above applies
|
||||
to the Derivative Work as incorporated in a Collective Work, but this does not
|
||||
require the Collective Work apart from the Derivative Work itself to be made
|
||||
subject to the terms of this License.
|
||||
3. If you distribute, publicly display, publicly perform, or publicly
|
||||
digitally perform the Work or any Derivative Works or Collective Works, You must
|
||||
keep intact all copyright notices for the Work and provide, reasonable to the
|
||||
medium or means You are utilizing: (i) the name of the Original Author (or
|
||||
pseudonym, if applicable) if supplied, and/or (ii) if the Original Author and/or
|
||||
Licensor designate another party or parties (e.g. a sponsor institute,
|
||||
publishing entity, journal) for attribution in Licensor's copyright notice,
|
||||
terms of service or by other reasonable means, the name of such party or
|
||||
parties; the title of the Work if supplied; to the extent reasonably
|
||||
practicable, the Uniform Resource Identifier, if any, that Licensor specifies to
|
||||
be associated with the Work, unless such URI does not refer to the copyright
|
||||
notice or licensing information for the Work; and in the case of a Derivative
|
||||
Work, a credit identifying the use of the Work in the Derivative Work (e.g.,
|
||||
"French translation of the Work by Original Author," or "Screenplay based on
|
||||
original Work by Original Author"). Such credit may be implemented in any
|
||||
reasonable manner; provided, however, that in the case of a Derivative Work or
|
||||
Collective Work, at a minimum such credit will appear where any other comparable
|
||||
authorship credit appears and in a manner at least as prominent as such other
|
||||
comparable authorship credit.
|
||||
|
||||
5. Representations, Warranties and Disclaimer
|
||||
|
||||
UNLESS OTHERWISE AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK
|
||||
AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE
|
||||
MATERIALS, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT
|
||||
LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY,
|
||||
OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME
|
||||
JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH
|
||||
EXCLUSION MAY NOT APPLY TO YOU.
|
||||
|
||||
6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN
|
||||
NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL,
|
||||
INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS
|
||||
LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
7. Termination
|
||||
|
||||
1. This License and the rights granted hereunder will terminate automatically
|
||||
upon any breach by You of the terms of this License. Individuals or entities who
|
||||
have received Derivative Works or Collective Works from You under this License,
|
||||
however, will not have their licenses terminated provided such individuals or
|
||||
entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7,
|
||||
and 8 will survive any termination of this License.
|
||||
2. Subject to the above terms and conditions, the license granted here is
|
||||
perpetual (for the duration of the applicable copyright in the Work).
|
||||
Notwithstanding the above, Licensor reserves the right to release the Work under
|
||||
different license terms or to stop distributing the Work at any time; provided,
|
||||
however that any such election will not serve to withdraw this License (or any
|
||||
other license that has been, or is required to be, granted under the terms of
|
||||
this License), and this License will continue in full force and effect unless
|
||||
terminated as stated above.
|
||||
|
||||
8. Miscellaneous
|
||||
|
||||
1. Each time You distribute or publicly digitally perform the Work or a
|
||||
Collective Work, the Licensor offers to the recipient a license to the Work on
|
||||
the same terms and conditions as the license granted to You under this License.
|
||||
2. Each time You distribute or publicly digitally perform a Derivative Work,
|
||||
Licensor offers to the recipient a license to the original Work on the same
|
||||
terms and conditions as the license granted to You under this License.
|
||||
3. If any provision of this License is invalid or unenforceable under
|
||||
applicable law, it shall not affect the validity or enforceability of the
|
||||
remainder of the terms of this License, and without further action by the
|
||||
parties to this agreement, such provision shall be reformed to the minimum
|
||||
extent necessary to make such provision valid and enforceable.
|
||||
4. No term or provision of this License shall be deemed waived and no breach
|
||||
consented to unless such waiver or consent shall be in writing and signed by the
|
||||
party to be charged with such waiver or consent.
|
||||
5. This License constitutes the entire agreement between the parties with
|
||||
respect to the Work licensed here. There are no understandings, agreements or
|
||||
representations with respect to the Work not specified here. Licensor shall not
|
||||
be bound by any additional provisions that may appear in any communication from
|
||||
You. This License may not be modified without the mutual written agreement of
|
||||
the Licensor and You.
|
||||
|
||||
Creative Commons is not a party to this License, and makes no warranty
|
||||
whatsoever in connection with the Work. Creative Commons will not be liable to
|
||||
You or any party on any legal theory for any damages whatsoever, including
|
||||
without limitation any general, special, incidental or consequential damages
|
||||
arising in connection to this license. Notwithstanding the foregoing two (2)
|
||||
sentences, if Creative Commons has expressly identified itself as the Licensor
|
||||
hereunder, it shall have all rights and obligations of Licensor.
|
||||
|
||||
Except for the limited purpose of indicating to the public that the Work is
|
||||
licensed under the CCPL, neither party will use the trademark "Creative Commons"
|
||||
or any related trademark or logo of Creative Commons without the prior written
|
||||
consent of Creative Commons. Any permitted use will be in compliance with
|
||||
Creative Commons' then-current trademark usage guidelines, as may be published
|
||||
on its website or otherwise made available upon request from time to time.
|
||||
|
||||
Creative Commons may be contacted at http://creativecommons.org/.
|
||||
349
mozilla/directory/docs/ldapjdk/preface.sgm
Normal file
349
mozilla/directory/docs/ldapjdk/preface.sgm
Normal file
@@ -0,0 +1,349 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<preface id="preface"><title>Preface</title>
|
||||
<highlights>&abstract;
|
||||
</highlights>
|
||||
<sect1 id="who-should-read"><title>Who Should Use This Book</title>
|
||||
<para>This guide is intended for developers creating directory client applications.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<para>Before using this guide, you must be familiar with the following:</para>
|
||||
<listitem><para>&cnDirectoryServer; functionality</para></listitem>
|
||||
<listitem><para>Developing programs in the <trademark>Java</trademark> programming
|
||||
language</para></listitem>
|
||||
<listitem><para>Specifications for LDAP and related protocols, such as DSML
|
||||
v2</para></listitem>
|
||||
<listitem><para>Internet and World Wide Web technologies</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="before-you-read"><title>Before You Read This Book</title>
|
||||
<para>Before developing directory client applications, install &DirectorySDKForJava;.
|
||||
</para>
|
||||
<!-- TODO: Need an XREF to installation instructions -->
|
||||
</sect1>
|
||||
<sect1 id="reading-for-developers"><title>Additional Recommended Reading</title>
|
||||
<itemizedlist>
|
||||
<para>Directory client application developers might benefit from reading the
|
||||
following books:</para>
|
||||
<listitem><para><citetitle>LDAP Programming with Java</citetitle> by Weltman
|
||||
and Dabhura (ISBN 0-201-65758-96)</para></listitem>
|
||||
<listitem><para><citetitle>LDAP Programming, Management and Integration</citetitle> by
|
||||
Donley (ISBN 1930110405)</para></listitem>
|
||||
<listitem><para><citetitle>LDAP: Programming Directory-Enabled Applications
|
||||
with Lightweight Directory Access Protocol</citetitle> by Howes and Smith
|
||||
(ISBN 1-57870-000-00)</para></listitem>
|
||||
<listitem><para><citetitle>Understanding and Deploying LDAP Directory Services</citetitle> by
|
||||
Howes, et al. (ISBN 1-57870-070-10)</para></listitem>
|
||||
</itemizedlist>
|
||||
<itemizedlist>
|
||||
<para>In addition, keep bookmarks to the following IETF documents:</para>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2251.txt" type="text_url">
|
||||
RFC 2251</ulink>, <citetitle>Lightweight Directory Access Protocol (v3)</citetitle></para>
|
||||
</listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2252.txt" type="text_url">
|
||||
RFC 2252</ulink>, <citetitle>Lightweight Directory Access Protocol (v3): Attribute
|
||||
Syntax Definitions</citetitle></para></listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2253.txt" type="text_url">
|
||||
RFC 2253</ulink>, <citetitle>Lightweight Directory Access Protocol (v3): UTF-8
|
||||
String Representation of Distinguished Names</citetitle></para></listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2254.txt" type="text_url">
|
||||
RFC 2254</ulink>, <citetitle>The String Representation of LDAP Search Filters</citetitle></para>
|
||||
</listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2255.txt" type="text_url">
|
||||
RFC 2255</ulink>, <citetitle>The LDAP URL Format</citetitle></para></listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2256.txt" type="text_url">
|
||||
RFC 2256</ulink>, <citetitle>A Summary of the X.500(96) User Schema for use
|
||||
with LDAPv3</citetitle></para></listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2829.txt" type="text_url">
|
||||
RFC 2829</ulink>, <citetitle>Authentication Methods for LDAP</citetitle></para>
|
||||
</listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2830.txt" type="text_url">
|
||||
RFC 2830</ulink>, <citetitle>Lightweight Directory Access Protocol (v3): Extension
|
||||
for Transport Layer Security</citetitle></para></listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc2849.txt" type="text_url">
|
||||
RFC 2849</ulink>, <citetitle>The LDAP Data Interchange Format (LDIF) - Technical
|
||||
Specification</citetitle></para></listitem>
|
||||
<listitem><para><ulink url="http://www.ietf.org/rfc/rfc3377.txt" type="text_url">
|
||||
RFC 3377</ulink>, <citetitle>Lightweight Directory Access Protocol (v3): Technical
|
||||
Specification</citetitle></para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="organization"><title>How This Book Is Organized</title>
|
||||
<itemizedlist>
|
||||
<para>This guide includes the following chapters.</para>
|
||||
<listitem><para><olink targetptr="understanding-ldap">Chapter 1, Understanding LDAP</olink> describes LDAP and directory concepts.</para></listitem>
|
||||
<listitem><para><olink targetptr="best-practices-choose">Chapter 2, Choosing a Client SDK</olink> covers what to consider when choosing a software development kit for building directory client applications.</para></listitem>
|
||||
<listitem><para><olink targetptr="best-practices-overview">Chapter 3,
|
||||
Best Practices for Writing Client Applications</olink> reviews what and what
|
||||
not to do when building directory client applications.</para></listitem>
|
||||
<listitem><para><olink targetptr="quickstart-jdk">Chapter 1, Getting
|
||||
Started With Directory SDK for Java</olink> gets you started using &DirectorySDKForJava;</para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="writing-client">Chapter 2, Writing an LDAP Client With Directory SDK for Java</olink> covers the basics of writing
|
||||
a directory client application</para></listitem>
|
||||
<listitem><para><olink targetptr="common-classes">Chapter 3, Using the LDAP Java Classes</olink> provides a look how &DirectorySDKForJava; is
|
||||
structured</para></listitem>
|
||||
<listitem><para><olink targetptr="searching">Chapter 4, Searching the Directory With Directory SDK for Java</olink> shows you how to write client
|
||||
application code for searching a directory</para></listitem>
|
||||
<!--<listitem><para><olink targetptr="filter-conf"></olink> shows you
|
||||
how to write client application code for searching
|
||||
a directory using filter configuration files</para>
|
||||
</listitem>-->
|
||||
<listitem><para><olink targetptr="adding">Chapter 5, Adding, Updating, and Deleting Entries With Directory SDK for Java</olink> shows you how to
|
||||
write client application code for changing directory entries</para></listitem>
|
||||
<listitem><para><olink targetptr="comparing">Chapter 6, Comparing Attribute Values With Directory SDK for Java</olink> shows you how to comparing attribute
|
||||
values in a directory with known values</para></listitem>
|
||||
<listitem><para><olink targetptr="ldap-urls">Chapter 7, LDAP URLs With Directory SDK for Java</olink> shows you how to handle LDAP URLs</para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="server-info">Chapter 8, Getting Server Information With Directory SDK for Java</olink> shows you how to retrieve
|
||||
information about the directory and directory service</para></listitem>
|
||||
<listitem><para><olink targetptr="ssl">Chapter 9, SSL Connections With Directory SDK for Java</olink> shows you how to write client application code
|
||||
that connects to the directory over SSL</para></listitem>
|
||||
<listitem><para><olink targetptr="controls">Chapter 10, LDAP Controls With Directory SDK for Java</olink> shows you how to handle supported LDAP
|
||||
controls</para></listitem>
|
||||
<listitem><para><olink targetptr="sasl">Chapter 11, SASL Authentication With Directory SDK for Java</olink> shows you how to connect to the directory
|
||||
by using SASL</para></listitem>
|
||||
<listitem><para><olink targetptr="extended-ops">Chapter 12, Extended Operations With Directory SDK for Java</olink> shows you how to write client
|
||||
application code for handling LDAP v3 extended operations</para></listitem>
|
||||
<listitem><para><olink targetptr="asynchronous">Chapter 13, Writing Asynchronous Clients With Directory SDK for Java</olink> shows you how to write applications
|
||||
that do not block waiting for results</para></listitem>
|
||||
<listitem><para><olink targetptr="share-alike">Appendix A, Creative Commons Attribution-ShareAlike 2.5</olink> provides the full text of the license governing this guide</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
<sect1 id="related-reading"><title>Related Reading</title>
|
||||
<para><indexterm>
|
||||
<primary>SLAMD Distributed Load Generation Engine</primary>
|
||||
</indexterm>The SLAMD Distributed Load Generation Engine (SLAMD) is a <trademark>
|
||||
Java</trademark> application that is designed to stress test and analyze the
|
||||
performance of network-based applications. It was originally developed by
|
||||
Sun Microsystems, Inc. to benchmark and analyze the performance of LDAP directory
|
||||
servers. SLAMD is available as an open source application under the Sun Public
|
||||
License, an OSI-approved open source license. To obtain information about
|
||||
SLAMD, go to <ulink url="http://www.slamd.com/" type="url"></ulink>. SLAMD
|
||||
is also available as a java.net project. See <ulink
|
||||
url="https://slamd.dev.java.net/" type="url"></ulink>.</para>
|
||||
<para><indexterm>
|
||||
<primary>Java Naming and Directory Interface</primary>
|
||||
</indexterm>Java Naming and Directory Interface (JNDI) technology supports
|
||||
accessing the Directory Server using LDAP and DSML v2 from Java applications.
|
||||
For information about JNDI, see <ulink url="http://java.sun.com/products/jndi/"
|
||||
type="url"></ulink>. The <citetitle>JNDI Tutorial</citetitle> contains detailed
|
||||
descriptions and examples of how to use JNDI. This tutorial is at <ulink
|
||||
url="http://java.sun.com/products/jndi/tutorial/" type="url"></ulink>.</para>
|
||||
</sect1>
|
||||
<sect1 id="FWBKX"><title>Typographic Conventions</title>
|
||||
<para>The following table describes the typographic changes that are used
|
||||
in this book.</para>
|
||||
<table frame="topbot" id="FWBTE"><title>Typographic Conventions</title>
|
||||
<tgroup cols="3" colsep="0" rowsep="0"><colspec colwidth="15*"><colspec
|
||||
colwidth="40*"><colspec colwidth="45*">
|
||||
<thead>
|
||||
<row rowsep="1">
|
||||
<entry align="left">
|
||||
<para>Typeface</para></entry>
|
||||
<entry align="left">
|
||||
<para>Meaning</para></entry>
|
||||
<entry align="left">
|
||||
<para>Example</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>AaBbCc123</literal></para></entry>
|
||||
<entry>
|
||||
<para>The names of commands, files, and directories, and onscreen computer
|
||||
output</para></entry>
|
||||
<entry>
|
||||
<para>Edit your <filename>.login</filename> file.</para>
|
||||
<para>Use <command>ls <option>a</option></command> to list all files.</para>
|
||||
<para><computeroutput>machine_name% you have mail.</computeroutput></para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><userinput>AaBbCc123</userinput></para></entry>
|
||||
<entry>
|
||||
<para>What you type, contrasted with onscreen computer output</para></entry>
|
||||
<entry>
|
||||
<para><computeroutput>machine_name%</computeroutput> <userinput>su</userinput></para>
|
||||
<para><computeroutput>Password:</computeroutput></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><replaceable>AaBbCc123</replaceable></para></entry>
|
||||
<entry>
|
||||
<para>A placeholder to be replaced with a real name or value</para></entry>
|
||||
<entry>
|
||||
<para>The command to remove a file is <command>rm</command> <replaceable>filename
|
||||
</replaceable>.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><emphasis>AaBbCc123</emphasis></para></entry>
|
||||
<entry>
|
||||
<para>Book titles, new terms, and terms to be emphasized (note that some emphasized
|
||||
items appear bold online)</para></entry>
|
||||
<entry>
|
||||
<para>Read Chapter 6 in the <citetitle>User's Guide</citetitle>.</para>
|
||||
<para>A <emphasis>cache</emphasis> is a copy that is stored locally.</para>
|
||||
<para>Do <emphasis>not</emphasis> save the file.</para></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect1>
|
||||
<sect1 id="FWBMK"><title>Shell Prompts in Command Examples</title>
|
||||
<para>The following table shows default system prompts and superuser prompts.</para>
|
||||
<table frame="topbot" id="GCTTT"><title>Shell Prompts</title>
|
||||
<tgroup cols="2" colsep="0" rowsep="0"><colspec colwidth="75*"><colspec
|
||||
colwidth="25*">
|
||||
<thead>
|
||||
<row rowsep="1">
|
||||
<entry>
|
||||
<para>Shell</para></entry>
|
||||
<entry>
|
||||
<para>Prompt</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para>C shell on UNIX and Linux systems</para></entry>
|
||||
<entry>
|
||||
<para><literal>machine_name%</literal></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>C shell superuser on UNIX and Linux systems</para></entry>
|
||||
<entry>
|
||||
<para><literal>machine_name#</literal></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Bourne shell and Korn shell on UNIX and Linux systems</para></entry>
|
||||
<entry>
|
||||
<para><literal>$</literal></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Bourne shell and Korn shell superuser on UNIX and Linux systems</para>
|
||||
</entry>
|
||||
<entry>
|
||||
<para><literal>#</literal></para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>Microsoft Windows command line</para></entry>
|
||||
<entry>
|
||||
<para><literal>C:\</literal></para></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect1>
|
||||
<sect1 id="FQUVC"><title>Symbol Conventions</title>
|
||||
<para>The following table explains symbols that might be used in this book.</para>
|
||||
<table frame="topbot" id="FQUVR"><title>Symbol Conventions</title>
|
||||
<tgroup cols="4" colsep="0" rowsep="0"><colspec colnum="1" colwidth="8*"
|
||||
align="center"><colspec colnum="2" colwidth="28*"><colspec colnum="3"
|
||||
colwidth="28*"><colspec colnum="4" colwidth="36*">
|
||||
<thead>
|
||||
<row rowsep="1">
|
||||
<entry>
|
||||
<para>Symbol</para></entry>
|
||||
<entry>
|
||||
<para>Description</para></entry>
|
||||
<entry>
|
||||
<para>Example</para></entry>
|
||||
<entry>
|
||||
<para>Meaning</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>[ ]</literal></para></entry>
|
||||
<entry>
|
||||
<para>Contains optional arguments and command options.</para></entry>
|
||||
<entry>
|
||||
<para><literal>ls [-l]</literal></para></entry>
|
||||
<entry>
|
||||
<para>The <literal>-l</literal> option is not required.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>{ | }</literal></para></entry>
|
||||
<entry>
|
||||
<para>Contains a set of choices for a required command option.</para></entry>
|
||||
<entry>
|
||||
<para><literal>-d {y|n}</literal></para></entry>
|
||||
<entry>
|
||||
<para>The <literal>-d</literal> option requires that you use either the <literal>
|
||||
y</literal> argument or the <literal>n</literal> argument.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para><literal>${ }</literal></para></entry>
|
||||
<entry>
|
||||
<para>Indicates a variable reference.</para></entry>
|
||||
<entry>
|
||||
<para><literal>${com.sun.javaRoot}</literal></para></entry>
|
||||
<entry>
|
||||
<para>References the value of the <literal>com.sun.javaRoot</literal> variable.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>-</para></entry>
|
||||
<entry>
|
||||
<para>Joins simultaneous multiple keystrokes.</para></entry>
|
||||
<entry>
|
||||
<para>Control-A</para></entry>
|
||||
<entry>
|
||||
<para>Press the Control key while you press the A key.</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>+</para></entry>
|
||||
<entry>
|
||||
<para>Joins consecutive multiple keystrokes.</para></entry>
|
||||
<entry>
|
||||
<para>Ctrl+A+N</para></entry>
|
||||
<entry>
|
||||
<para>Press the Control key, release it, and then press the subsequent keys.</para>
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<para>→</para></entry>
|
||||
<entry>
|
||||
<para>Indicates menu item selection in a graphical user interface.</para>
|
||||
</entry>
|
||||
<entry>
|
||||
<para>File → New → Templates</para></entry>
|
||||
<entry>
|
||||
<para>From the File menu, choose New. From the New submenu, choose Templates.</para>
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
</sect1>
|
||||
</preface>
|
||||
274
mozilla/directory/docs/ldapjdk/understanding-ldap.sgm
Normal file
274
mozilla/directory/docs/ldapjdk/understanding-ldap.sgm
Normal file
@@ -0,0 +1,274 @@
|
||||
<!--
|
||||
|
||||
Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
Portions copyright 1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
The contents of this document are subject to the terms of the
|
||||
Creative Commons Attribution-ShareAlike 2.5 license or any later
|
||||
version (the "License"). You may not use this document except in
|
||||
compliance with the License.
|
||||
|
||||
See the License for the specific language governing
|
||||
permissions and limitations under the License. You can obtain
|
||||
a copy of the License at
|
||||
http://creativecommons.org/licenses/by-sa/2.5/legalcode.
|
||||
|
||||
-->
|
||||
<chapter id="understanding-ldap"><title>Understanding LDAP</title>
|
||||
<indexterm>
|
||||
<primary>LDAP</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>Lightweight Directory Access Protocol</primary>
|
||||
<see>LDAP</see></indexterm><highlights>
|
||||
<para><firstterm>Lightweight Directory Access Protocol</firstterm> (LDAP)
|
||||
is the Internet directory protocol. Developed at the University of Michigan
|
||||
at Ann Arbor in conjunction with the Internet Engineering Task Force, LDAP
|
||||
is a protocol for accessing and managing directory services.</para>
|
||||
<itemizedlist>
|
||||
<para>This chapter explains the LDAP protocol, and the concepts behind LDAP.
|
||||
This chapter covers the following topics:</para>
|
||||
<listitem><para><olink targetptr="how-ds-works">How Directory Services Work</olink></para>
|
||||
</listitem>
|
||||
<listitem><para><olink targetptr="how-ds-organizes-data">How LDAP Servers
|
||||
Organize Directories</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="how-ldap-clients-servers-work">How LDAP
|
||||
Clients and Servers Work</olink></para></listitem>
|
||||
<listitem><para><olink targetptr="understanding-ldapv3">Understanding LDAP
|
||||
v3</olink></para></listitem>
|
||||
</itemizedlist>
|
||||
</highlights>
|
||||
<sect1 id="how-ds-works"><title>How Directory Services Work</title>
|
||||
<indexterm>
|
||||
<primary>directory</primary>
|
||||
<secondary>definition of</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>entries</primary>
|
||||
<secondary>definition of</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>attributes</primary>
|
||||
<secondary>definition of</secondary>
|
||||
</indexterm>
|
||||
<para>A <firstterm>directory</firstterm> consists of <firstterm>entries</firstterm> that
|
||||
contain descriptive information. For example, a directory might contain entries
|
||||
that describe people or network resources, such as printers or fax machines.</para>
|
||||
<para>The descriptive information is stored in the <firstterm>attributes</firstterm> of
|
||||
the entry. Each attribute describes a specific type of information. For example,
|
||||
attributes that describe a person might include her name, also referred to
|
||||
as her common name (CN), telephone number, and email address.</para>
|
||||
<para><indexterm>
|
||||
<primary>entries</primary>
|
||||
<secondary>example of</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>attributes</primary>
|
||||
<secondary>example of</secondary>
|
||||
</indexterm>The entry for <literal>Barbara Jensen</literal> might have the
|
||||
following attributes:</para>
|
||||
<programlisting>cn: Barbara Jensen
|
||||
mail: babs@example.com
|
||||
telephoneNumber: 555-1212
|
||||
roomNumber: 3995</programlisting>
|
||||
<para>An attribute can have more than one value. For example, a person might
|
||||
have two common names, both a formal name and also a nickname:</para>
|
||||
<programlisting>cn: Barbara Jensen
|
||||
cn: Babs Jensen
|
||||
mail: babs@example.com
|
||||
telephoneNumber: 555-1212
|
||||
roomNumber: 3995</programlisting>
|
||||
<para>Attributes can also contain binary data. For example, a person's attributes
|
||||
might include her photo in JPEG format, a recording of her voice as an audio
|
||||
file, or her SSL certificate.</para>
|
||||
<para><indexterm>
|
||||
<primary>directory service</primary>
|
||||
<secondary>definition of</secondary>
|
||||
</indexterm>A <firstterm>directory service</firstterm> is a distributed database
|
||||
application for managing the entries and attributes in a directory. A directory
|
||||
service also makes the entries and attributes available to users and other
|
||||
applications.</para>
|
||||
<para>&cnDirectoryServer; is an example of a directory service. For example,
|
||||
a user might use the directory service to look up someone's telephone number.
|
||||
Another application might use the directory service to retrieve a list of
|
||||
email addresses.</para>
|
||||
<para><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
</indexterm>LDAP is a protocol that defines a directory service and access
|
||||
to that service. LDAP is based on a client-server model. LDAP servers provide
|
||||
the directory service. LDAP clients use the directory service to access entries
|
||||
and attributes.</para>
|
||||
<para><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>example of</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>example of</secondary>
|
||||
</indexterm>&cnDirectoryServer; is an example of an LDAP server that manages
|
||||
and provides information about users and organizational structures. Examples
|
||||
of LDAP clients include Identity Manager, Access Manager, <trademark>Solaris</trademark> naming
|
||||
services, Messaging Server, Portal Server, NameFinder, and the Mozilla mail
|
||||
client. Such clients use &cnDirectoryServer; to find, update, and add information
|
||||
about users.</para></sect1>
|
||||
<sect1 id="how-ds-organizes-data"><title>How LDAP Servers Organize Directories</title>
|
||||
<indexterm>
|
||||
<primary>LDAP</primary>
|
||||
<secondary>organization of data</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>entries</primary>
|
||||
<secondary>organization in LDAP</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>how data is organized</secondary>
|
||||
</indexterm>
|
||||
<para>Because LDAP is intended to be a global directory service, data is organized
|
||||
hierarchically, starting at a root and branching down into individual entries.</para>
|
||||
<para>At the top level of the hierarchy, entries represent larger organizations.
|
||||
Under larger organizations in the hierarchy, you might find entries for smaller
|
||||
organizations. The hierarchy might end with entries for individual people,
|
||||
or resources, as shown in the following figure.</para>
|
||||
<figure id="hierarchy-in-ldap"><title>Hierarchy of Entries in a Directory</title>
|
||||
<mediaobject>
|
||||
<imageobject><imagedata entityref="hierovrw"></imageobject>
|
||||
<textobject><simpara>Simple directory information tree with two organizational
|
||||
unit entries and two user entries</simpara></textobject>
|
||||
</mediaobject>
|
||||
</figure>
|
||||
<para><indexterm>
|
||||
<primary>relative distinguished names (RDNs)</primary>
|
||||
<secondary>definition of</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>RDNs</primary>
|
||||
<see>relative distinguished names (RDNs)</see></indexterm><indexterm>
|
||||
<primary>distinguished names (DNs)</primary>
|
||||
<secondary>definition of </secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>CNs</primary>
|
||||
<see>common names (CNs)</see></indexterm><indexterm>
|
||||
<primary>DNs</primary>
|
||||
<see>distinguished names (DNs)</see></indexterm><indexterm>
|
||||
<primary>common names (CNs)</primary>
|
||||
</indexterm>Each entry is uniquely identified by a <firstterm>distinguished
|
||||
name</firstterm> (DN). A DN includes a relative distinguished name (RDN),
|
||||
that uniquely identifies the entry at that hierarchical level. For example, <literal>
|
||||
bjensen</literal> and <literal>kjensen</literal> are different user IDs that
|
||||
identify different entries at the same level. Following the RDN is a path
|
||||
of names that trace the entry back to the root of the tree, such as <literal>ou=People,dc=example,dc=com
|
||||
</literal>. <literal>DC</literal> is short for domain component. The full
|
||||
DN for this example would be <literal>uid=bjensen,ou=People,dc=example,dc=com</literal>.
|
||||
Here, <literal>uid</literal> is the user ID of the entry. <literal>ou</literal> is
|
||||
short for organizational unit.</para>
|
||||
<para><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>how data is distributed</secondary>
|
||||
</indexterm>The data stored in a directory can be distributed among several
|
||||
LDAP servers. For example, one LDAP server at <literal>Example.com</literal> might
|
||||
contain entries representing North American organizational units and employees,
|
||||
while another LDAP server might contain entries representing European organizational
|
||||
units and employees.</para>
|
||||
<para><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>how referrals work</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>referrals</primary>
|
||||
</indexterm>Some LDAP servers are set up to refer requests to other LDAP servers.
|
||||
For example, if the LDAP server at <literal>Example.com</literal> receives
|
||||
a request for information about an employee in a Pacific Rim branch, that
|
||||
server can refer the request to the LDAP server at the Pacific Rim branch.
|
||||
In this way, LDAP servers can appear to be a single source of directory information.
|
||||
Even if an LDAP server does not contain the information you request, the server
|
||||
can refer you to another server that does contain the information.</para>
|
||||
</sect1>
|
||||
<sect1 id="how-ldap-clients-servers-work"><title>How LDAP Clients and Servers
|
||||
Work</title>
|
||||
<indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>LDAP clients and</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>LDAP servers and</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>operations performed by</secondary>
|
||||
</indexterm>
|
||||
<para>In the LDAP client-server model, LDAP servers such as &cnDirectoryServer;
|
||||
make information about people, organizations, and resources accessible to
|
||||
LDAP clients. LDAP defines operations that clients use to search and update
|
||||
the directory.</para>
|
||||
<itemizedlist>
|
||||
<para>An LDAP client can perform these operations, among others:</para>
|
||||
<listitem><para>Search for and retrieve entries from the directory</para>
|
||||
</listitem>
|
||||
<listitem><para>Add new entries to the directory</para></listitem>
|
||||
<listitem><para>Update entries in the directory</para></listitem>
|
||||
<listitem><para>Delete entries from the directory</para></listitem>
|
||||
<listitem><para>Rename entries in the directory</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>For example, to update an entry, an LDAP client submits the distinguished
|
||||
name of the entry with updated attribute information to the LDAP server. The
|
||||
LDAP server uses the distinguished name to find the entry. The server then
|
||||
performs a modify operation to update the entry in the directory.</para>
|
||||
<para><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>connecting with LDAP clients</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>connecting with LDAP servers</secondary>
|
||||
</indexterm>To perform any of these LDAP operations, an LDAP client needs
|
||||
to establish a connection with an LDAP server. The LDAP protocol specifies
|
||||
the use of TCP/IP port number 389, although servers can run on other ports.</para>
|
||||
<para><indexterm>
|
||||
<primary>LDAP servers</primary>
|
||||
<secondary>authentication</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>LDAP clients</primary>
|
||||
<secondary>authentication</secondary>
|
||||
</indexterm>The LDAP protocol also defines a simple method for authentication.
|
||||
LDAP servers can be set up to restrict permissions to the directory. Before
|
||||
an LDAP client can perform an operation on an LDAP server, the client must
|
||||
authenticate to the server. Clients typically authenticate by supplying a
|
||||
distinguished name and password. If the user identified by the distinguished
|
||||
name does not have permission to perform the operation, the server does not
|
||||
execute the operation.</para></sect1>
|
||||
<sect1 id="understanding-ldapv3"><title>Understanding LDAP v3</title>
|
||||
<indexterm>
|
||||
<primary>LDAP</primary>
|
||||
<secondary>version 3</secondary>
|
||||
</indexterm>
|
||||
<para><ulink url="http://www.ietf.org/rfc/rfc4511.txt" type="text_url">RFC
|
||||
4511</ulink> specifies LDAP version 3. Use this version of the protocol when
|
||||
writing new client applications.</para>
|
||||
<para>Many LDAP servers continue to support LDAP version 2 for use with legacy
|
||||
clients. This version of the protocol is specified in <ulink
|
||||
url="http://www.ietf.org/rfc/rfc1777.txt" type="text_url">RFC 1777</ulink>.</para>
|
||||
<itemizedlist>
|
||||
<para>LDAP v3 includes new features not present in version 2:</para>
|
||||
<listitem><para>Clients and servers can specify <firstterm>controls</firstterm> that
|
||||
extend the functionality of an LDAP operation.</para></listitem>
|
||||
<listitem><para>Clients can request that the server perform <firstterm>extended
|
||||
operations</firstterm>, operations not included in the list of standard LDAP
|
||||
operations.</para></listitem>
|
||||
<listitem><para>Clients can use <firstterm>Simple Authentication and Security
|
||||
Layer</firstterm> (SASL) mechanisms to authenticate to the directory. SASL
|
||||
is specified in <ulink url="http://www.ietf.org/rfc/rfc4422.txt" type="text_url">
|
||||
RFC 4422</ulink>.</para></listitem><?Pub Caret>
|
||||
<listitem><para>Servers, known as <firstterm>Directory System Agents</firstterm> (DSAs),
|
||||
have <firstterm>DSA-specific entries</firstterm> (DSEs). DSEs provide information
|
||||
about the versions of the LDAP protocol that the server supports. DSEs also
|
||||
provide a list of the controls, extended operations, and SASL mechanisms supported
|
||||
by the server. Finally, DSEs specify the naming contexts of the server. Naming
|
||||
contexts are portions of the directory information tree managed by the server.</para>
|
||||
</listitem>
|
||||
<listitem><para>Servers make their <firstterm>schemas</firstterm>, which define
|
||||
the object classes, attributes, syntaxes, and matching rules enforced by the
|
||||
directory, available to clients through the root DSE.</para></listitem>
|
||||
<listitem><para><indexterm>
|
||||
<primary>UTF-8</primary>
|
||||
<secondary>support of</secondary>
|
||||
</indexterm>Both client and server applications can support data in UTF-8. <firstterm>
|
||||
UTF-8</firstterm> is a transformation format of the Universal Character Set
|
||||
standard. UTF-8 is specified in <ulink url="http://www.ietf.org/rfc/rfc3269.txt"
|
||||
type="text_url">RFC 3269</ulink>. With UTF-8, clients can request and receive
|
||||
data that is tagged with language information.</para></listitem>
|
||||
</itemizedlist>
|
||||
</sect1>
|
||||
</chapter>
|
||||
Reference in New Issue
Block a user