diff --git a/mozilla/directory/docs/Readme.txt b/mozilla/directory/docs/Readme.txt
new file mode 100644
index 00000000000..de942b20735
--- /dev/null
+++ b/mozilla/directory/docs/Readme.txt
@@ -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
diff --git a/mozilla/directory/docs/ldapcsdk/00-Programmers-Guide.book b/mozilla/directory/docs/ldapcsdk/00-Programmers-Guide.book
new file mode 100644
index 00000000000..377b7e0270b
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/00-Programmers-Guide.book
@@ -0,0 +1,114 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]>
+
+LDAP C SDK Programmer's Guide
+
+MarkCraig
+
+June 2007
+
+Sun Microsystems, Inc.
+
+4150 Network Circle
+Santa ClaraCA95054
+U.S.A.
+
+2000-2007Sun Microsystems, Inc. All Rights Reserved.
+License -
+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. The full text of the
+License is provided at the end of this
+document.&legal;
+
+&abstract;
+
+&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;
+
+Creative Commons Attribution-ShareAlike 2.5
+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.
+See the License for the specific language governing permissions
+and limitations under the License. The full text of the License is as
+follows.
+&license;
+
+Index
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/abstract.sgm b/mozilla/directory/docs/ldapcsdk/abstract.sgm
new file mode 100644
index 00000000000..273b411e7ae
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/abstract.sgm
@@ -0,0 +1,20 @@
+
+This &BookTitle; 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.
diff --git a/mozilla/directory/docs/ldapcsdk/best-practices.sgm b/mozilla/directory/docs/ldapcsdk/best-practices.sgm
new file mode 100644
index 00000000000..8f96271f1d6
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/best-practices.sgm
@@ -0,0 +1,378 @@
+
+Best Practices for
+Writing Client Applications
+
+
+This chapter includes best practices for developing client applications
+and cover the following topics:
+Creating Your Application
+
+Troubleshooting Problems
+
+
+
+Creating Your Application
+
+This section identifies practices to observe when creating directory
+client applications.
+Specify LDAP v3
+
+Authenticate Correctly
+
+Limit Connection Overhead
+
+Handle Potential
+Inactivity Timeouts
+Retrieve Entries Intelligently
+
+Write Simple, Conforming LDAP
+Filters
+Performing Specific Modifications
+
+Trust Result Codes
+
+Limit Dealings With Groups
+and Roles
+Read the DSE
+
+Use Resource-Intensive Features Sparingly
+Avoid Hard Coding Certain Information
+
+Define Schemas Only When Necessary
+
+Handle Referrals
+
+Treat a Directory as a Directory
+
+
+Specify LDAP v3
+
+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.
+With JNDI, you could use LDAP v3 as shown here.
+import java.util.Hashtable;
+import javax.naming.ldap.InitialLdapContext;
+
+Hashtable env = new Hashtable();
+env.put("java.naming.ldap.version", "3");
+InitialLdapContext ctx = new InitialLdapContext(env, null);
+
+With &DirectorySDKForC;, you could use LDAP v3 as shown
+here.
+#include "ldap.h"
+
+int version = LDAP_VERSION3;
+ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version );
+&DirectorySDKForC; uses LDAP v3 by default.
+With &DirectorySDKForJava;, you could use LDAP v3 as shown
+here.
+import netscape.ldap.LDAPConnection;
+
+LDAPConnection ld = new LDAPConnection();
+ld.setOption(LDAPv3.PROTOCOL_VERSION, new Integer(3));
+
+
+
+
+
+Authenticate Correctly
+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.
+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).
+If your application needs to authenticate, obtain a regular account
+to authenticate with the directory, rather than using the directory superuser
+account such as cn=Directory Manager. When you authenticate
+as directory superuser, you often bypass normal access control mechanisms.
+Bypassing normal access control renders auditing directory access more difficult.
+
+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.
+
+Limit Connection Overhead
+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.
+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.
+When finished with a connection, your application should perform an
+unbind.
+Handle Potential Inactivity Timeouts
+Most network equipment can use timeouts to drop stale connections, ensuring
+the equipment keeps a maximum number of connections that are available.
+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.
+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.
+
+Retrieve Entries Intelligently
+&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.
+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.
+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 USAGE, which is directoryOperation
+ or dsaOperation.
+When retrieving entries and attributes, recognize that you might not
+have access to all the attributes that exist.
+Write Simple, Conforming LDAP Filters
+
+LDAP filters
+writing
+
+The best filters use attributes that are indexed according to the way
+the attributes are indexed. For example, if employeeNumber is
+indexed for equality, your filter should be an equality filter such as (employeeNumber=123456)
+. Do not use a substring filter instead.
+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 not
+, !, only with and, &
+, for example (&(cn=Barbara)(!(sn=Jensen))).
+When you use not with or in a filter,
+the directory must construct a candidate list of everything except what your
+filter specifies.
+Performing Specific Modifications
+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.
+Moreover, when you have large values to store in an attribute, store
+a reference to the data instead of storing the data object.
+Trust Result Codes
+
+result codes
+trust
+
+&cnDirectoryServer; trades tight consistency across replica servers
+for very high performance, availability, and scalability. By allowing
+loose consistency 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.
+
+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.
+
+Limit Dealings With Groups and Roles
+
+groups
+working with
+
+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.
+
+For dynamic groups, do the following:
+Read the URL from the group definition.
+Examine the host, DN, and scope of the URL.
+Apply the filter part of the URL to the entry for the account.
+
+
+
+roles
+working with
+For roles, compare the DN of the role to the
+nsRole attribute of the entry for the account, such as (nsrole=cn=management,ou=people,dc=example,dc=com)
+. You can then retrieve all the values of the nsRole attribute
+for the account.
+Read the DSE
+
+DSE, root
+reading
+
+The root DSE is the entry that is retrieved by ldapsearch -b
+"" -s base "(objectclass=*)". 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.
+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.
+Use Resource-Intensive Features Sparingly
+Directories offer powerful features that can nevertheless place a heavy
+load on the server. Two such features are persistent search, and server-side
+sorting.
+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.
+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.
+
+Avoid Hard Coding Certain Information
+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.
+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.
+Be aware as well that object class and attribute type identifiers are
+not case-sensitive in LDAP. Your application should therefore recognize
+that inetOrgPerson and inetorgperson are
+equivalent, as are isMemberOf and ismemberof.
+
+Define Schemas Only When Necessary
+
+schema
+defining
+
+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.
+
+When you must define your own schema objects, follow these guidelines:
+Extend existing object classes by using AUXILIARY classes.
+
+Create new attributes rather than redefining existing attributes.
+Other applications might depend on existing attributes to keep
+their existing semantics.
+Obtain new object identifiers for the schema elements you
+define, rather than reusing existing object identifiers.
+Obtain new names for the schema elements you define, rather
+than reusing existing names.
+Update &cnDirectoryServer; schema over LDAP if you can.
+
+
+
+Handle Referrals
+
+referrals
+following
+
+LDAP v3 allows directories that are unable to handle your request to
+refer your application to other directories. Your application should follow
+those referrals.
+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.
+Treat a Directory as a Directory
+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.
+
+Troubleshooting Problems
+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.
+Check Result Codes
+
+troubleshooting
+result codes
+
+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.
+
+1
+LDAP operations error. The server encountered an error while
+processing your request.
+
+
+32
+No such object. The entry is not present on the server. Also,
+no referral is defined for the entry.
+
+
+49
+Invalid credentials. Your application failed to authenticate
+properly.
+
+
+53
+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.
+
+
+65
+Object class violation. Your write request would cause an
+entry to no longer conform to the schema defined for the directory.
+
+
+68
+Already exists. Your application is requesting to add an entry
+that has the same DN as an entry already present in the directory.
+
+
+
+RFC 4511 defines
+LDAP error codes, as does Chapter 22, Directory
+SDK for C Result Codes.
+Check Server Log Files
+
+troubleshooting
+log files
+
+&cnDirectoryServer; logs messages related to server operation in its
+logs/errors file. If you have access to this file, you might find
+useful troubleshooting information there.
+When debugging your application against &cnDirectoryServer;, you can
+adjust the log level, as well. See the server documentation for instructions.
+
+Inspect Network Packets
+
+troubleshooting
+decoding packets
+
+Although LDAP is not a textual protocol, tools such as
+snoop1M,
+ethereal, and tcpdump can decode the packets,
+sometimes providing you with important debugging information.
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/choose-api.sgm b/mozilla/directory/docs/ldapcsdk/choose-api.sgm
new file mode 100644
index 00000000000..9db9908e1ee
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/choose-api.sgm
@@ -0,0 +1,98 @@
+
+Choosing a Client
+SDK
+
+This chapter discusses software development kits to help you select
+the appropriate directory SDK for your particular situation.
+
+This chapter covers the following topics:
+Java Naming and Directory Interface
+
+Directory SDK for Java
+
+Directory SDK for C
+
+Operating System libldap Library
+Support for Other Programming
+Languages
+
+
+Java Naming and Directory Interface
+
+Java Naming and Directory Interface
+
+JNDI
+Java Naming and Directory Interface
+Java Naming and Directory Interface (JNDI) technology supports directory
+access through LDAP and DSML v2 from Java 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.
+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.
+For information about JNDI, see . The JNDI
+Tutorial contains descriptions and examples of how to use JNDI.
+The tutorial is at .
+&DirectorySDKForC;
+&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.
+&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;.
+
+This document demonstrates how to use &DirectorySDKForC;. &DirectorySDKForC; code
+is published in open source form as part of the Mozilla Directory SDK project.
+
+&DirectorySDKForJava;
+&DirectorySDKForJava; lets you access LDAP directories from Java
+applications, but it is not part of the Java platform.
+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.
+This document demonstrates how to use &DirectorySDKForJava;. &DirectorySDKForJava; code
+is published in open source form as part of the Mozilla Directory SDK project.
+
+Operating System libldap Library
+
+
+libraries
+libldap
+
+libldap
+
+The native LDAP library on Solaris systems provides
+essentially the same API as &DirectorySDKForC;. Many &DirectorySDKForC; need
+only be recompiled to work with libldap.
+The LDAP library is sometimes not compatible with libldap on
+many GNU/Linux distributions. Many GNU/Linux distributions provide OpenLDAP
+support by default.
+Support for Other Programming Languages
+Support for directory access is available in a number of contexts where
+you do not choose to use the C or Java languages.
+For example, Perl has the PerLDAP module and the Net::LDAP collection
+of modules. Python has the python-ldap 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.
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-api.sgm b/mozilla/directory/docs/ldapcsdk/csdk-api.sgm
new file mode 100644
index 00000000000..ee927171e6e
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-api.sgm
@@ -0,0 +1,1465 @@
+
+Using the LDAP C API
+
+This chapter covers features of the LDAP C API to use when writing
+an LDAP client application with &DirectorySDKForC;.
+
+This chapter covers the following topics:
+Synchronous and Asynchronous Functions
+
+Retrieving SDK Information
+
+Managing Memory
+
+Reporting Errors
+
+Handling Referrals With Directory
+SDK for C
+Creating an In-Memory Cache
+
+Handling Failover
+
+
+
+APIsCC API
+Synchronous and Asynchronous Functions
+You can perform most operations with synchronous or
+with asynchronous functions. For example, to search
+the directory, you can call either the synchronous ldap_search_ext_s function
+or the asynchronous ldap_search_ext function. In general,
+all synchronous functions have names that end with _s.
+The difference between the synchronous and asynchronous functions is
+the calling convention. The LDAP exchanges are identical.
+Calling Synchronous Functions
+
+C SDK
+synchronous functions
+
+When you call a synchronous function, your client
+waits for the operation to complete before executing any subsequent lines
+of code. Synchronous functions return LDAP_SUCCESS when
+they are successful. Synchronous functions return an LDAP error code when
+they are not successful. The following example deletes the entry in the directory.
+
+Calling Synchronous ldap_delete_ext_s
+ to Delete an Entry
+#include <stdio.h>
+#include "ldap.h"
+...
+LDAP *ld;
+char *matched_msg = NULL, *error_msg = NULL;
+int rc;
+...
+/* Perform an LDAP delete operation. */
+rc = ldap_delete_ext_s( ld, DELETE_DN, NULL, NULL );
+if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_delete_ext_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 the server cannot find an entry with the specified DN,
+ it may send back the portion of the DN that matches 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 );
+ }
+} else {
+ printf( "%s deleted successfully.\n", DELETE_DN );
+}
+...
+
+To see other sample programs that call synchronous functions, view the
+source files in the examples/ directory.
+Calling Asynchronous Functions
+
+C SDK
+asynchronous functions
+
+When you call an asynchronous function, your client
+does not need to wait for the operation to complete. The client can continue
+performing other tasks, such as initiating other LDAP operations, while the
+asynchronous operation is executing. An asynchronous function passes back
+a unique message ID to identify the operation being performed. You can pass
+this message ID to the ldap_result function to check
+the status of the operation. The following sections explain how to call an
+asynchronous function and how to check the results of the operation. To see
+other sample programs that call asynchronous functions, view the source files
+in the examples/ directory.
+Verifying that an LDAP Request Was Sent
+Asynchronous functions return an LDAP result code indicating whether
+or not the LDAP request was successfully sent to the server. If the function
+returns LDAP_SUCCESS, the function has successfully
+sent the request to the server. The following example sends an LDAP delete
+request to the server and checks if the result was sent successfully. The
+example uses the asynchronous ldap_delete_ext function.
+Calling Asynchronous ldap_delete_ext
+ and Sending a Verification
+#include <stdio.h>
+#include "ldap.h"
+...
+/* Change these as needed. */
+#define DELETE_DN "uid=wjensen,ou=People,dc=example,dc=com"
+...
+LDAP *ld;
+int rc, msgid;
+...
+/* Send an LDAP delete request to the server. */
+rc = ldap_delete_ext( ld, DELETE_DN, NULL, NULL, &msgid );
+if ( rc != LDAP_SUCCESS ) {
+ /* If the request was not sent successfully,
+ print an error message and return. */
+ fprintf( stderr, "ldap_delete_ext: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+}
+...
+
+
+Retrieving the Server Response
+If the request was sent successfully, the function passes the message
+ID of the LDAP operation back to the client. Use the message ID to determine
+if the server has sent back results for this operation. Call ldap_result
+, passing the message ID as a parameter.
+
+The function then returns one of the following values:
+-1 indicates that an error occurred.
+
+0 indicates that the time—out period
+has been exceeded and that the server has not yet sent a response back to
+your client.
+Any other value indicates that the server has sent a response
+for the requested operation back to your client. The ldap_result parameter
+passes back a pointer to an LDAPMessage structure.
+
+This structure contains the server’s response, which can include
+the following information:
+An LDAP result code that specifies the result of the operation
+you requestedSee Reporting Errors for
+details.
+An additional error message sent back from the server
+This information is optional.
+If the server cannot find the entry specified by a DN, the
+portion that identifies an existing entry.See Receiving the Matching Portion of a DN for details.
+
+A set of referrals, if the server’s directory does not
+contain the requested entriesThe server must be configured to
+return referralsSee Handling Referrals
+With Directory SDK for C for details.
+A set of server response controls that apply to the operation
+you requestedSee Chapter 16,
+LDAP Controls With Directory SDK for C for information about controls.
+
+
+
+
+You can specify a timeout period to wait for results from the server.
+Polling Loop
+You can set up a loop to poll for results while doing other work. The
+following example defines a function that does other work while waiting for
+the server to send a response back to your client
+Polling for Results
+int global_counter = 0;
+void do_other_work()
+{
+ global_counter++;
+}
+
+
+while Loop
+This example sets up a while loop to call your function
+when you are not checking for the server’s response.
+Using a while Loop
+to Handle Results
+#include <stdio.h>
+#include "ldap.h"
+...
+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 an LDAP delete request to the server. */
+rc = ldap_delete_ext( ld, DELETE_DN, NULL, NULL, &msgid );
+...
+/* Poll the server for the results of the LDAP operation. */
+while ( !finished ) {
+ rc = ldap_result( ld, msgid, 0, &zerotime, &res );
+
+ /* Check to see if a result was received. */
+ switch ( rc ) {
+ case -1:
+ .../* An error occurred. */...
+ case 0:
+ /* The timeout period specified by zerotime was exceeded, meaning
+ the server has still not yet sent the results of the delete
+ operation back to the client. Break out of this switch statement,
+ and continue calling ldap_result() to poll for results. */
+ default:
+ finished = 1;
+ .../* Your client received a response from the server. */...
+ }
+
+ /* Do other work while waiting. This is called if ldap_result()
+ returns 0 (before you continue to top of the loop and call
+ ldap_result() again). */
+ if ( !finished ) {
+ do_other_work();
+ }
+ ...
+}
+...
+
+
+
+Getting Information From a Server Response
+To get information from the server response, call ldap_parse_result
+ as shown here.
+The ldap_parse_result Function
+
+LDAP_API(int) LDAP_CALL
+ldap_parse_result( LDAP *ld, LDAPMessage *res, int *errcodep,
+ char **matcheddnp, char **errmsgp, char ***referralsp,
+ LDAPControl ***serverctrlsp, int freeit );
+
+
+You can get the following information from parameters of the ldap_parse_result
+:
+errcodep holds the LDAP result code of
+the operation that the server finished processing.See Reporting Errors for details.
+errmsgp is an additional error message
+that the server can send to your client.
+matcheddnp is the portion of the DN that
+matches an existing entry. The portion of the DN is used when the server is
+not able to find an entry for the DN that you specified.See Receiving the Matching Portion of a DN for details.
+
+referralsp is a set of referrals sent back
+to your client. The set of referrals is sent if you requested an entry that
+is not part of the DIT managed by the server. The server must be configured
+to refer clients to other LDAP servers.See
+Handling Referrals With Directory SDK for C for details.
+
+serverctrlsp is a set of server response
+controls that apply to the operation.See Chapter 16, LDAP Controls With Directory SDK
+for C for details.
+
+When processing LDAP search operations, the server can send back individual
+entries, individual search references, chains of entries, and chains of search
+references.
+The following example retrieves error information from an LDAPMessage
+ structure returned by ldap_result.
+Retrieving Error Information
+From an LDAPMessage Structure
+#include <stdio.h>
+#include "ldap.h"
+...
+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;
+...
+rc = ldap_result( ld, msgid, 0, &zerotime, &res );
+
+/* Check to see if a result was received. */
+switch ( rc ) {
+case -1:
+ ...
+case 0:
+ ...
+default:
+ ...
+ /* Call ldap_parse_result() to get information from the results
+ received from the server. */
+ parse_rc = ldap_parse_result( ld, res, &rc, &matched_msg,
+ &error_msg, &referrals, &serverctrls, 1 );
+
+ /* Make sure the results were parsed successfully. */
+ 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 operation. */
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf(stderr, "Error: %s\n", ldap_err2string(rc));
+ if ( error_msg != NULL & *error_msg != '\0' ) {
+ fprintf( stderr, "%s\n", error_msg );
+ }
+ /* If the server returned the portion of the DN
+ that identifies an existing entry, print it out. */
+ if ( matched_msg != NULL && *matched_msg != '\0' ) {
+ fprintf( stderr,
+ "Part of the DN that matches an existing entry: %s\n",
+ matched_msg );
+ }
+ } else {
+ printf( "Operation completed successfully" );
+ }
+}
+...
+
+
+Freeing an LDAPMessage Structure
+
+When you are done, call ldap_msgfree to free the
+LDAPMessage structure unless the structure is part of a chain
+of results. The result code returned by this function is not the same as the
+result code of the operation, errcodep. This operation
+returns a result code that indicates the type of operation to which the freed
+LDAPMessage structure is a response.
+If you pass a non-zero value for the freeit parameter
+of ldap_result, the structure is automatically freed
+after the information is retrieved.
+Canceling an Operation in Progress
+If you need to cancel an LDAP operation, call ldap_abandon_ext.
+The function returns LDAP_SUCCESS if successful, or an
+LDAP result code if an error occurs. After you cancel an operation, you cannot
+retrieve the results of that operation. Thus, calling ldap_result does
+not return any results.
+Sample Code to Call an Asynchronous Function
+
+example programs
+asynchronous deletion of an entry
+
+The following example calls ldap_delete_ext to
+delete an entry in the directory, and ldap_result within
+a loop to poll the results of the delete.
+Performing Asynchronous Deletion
+of an Entry
+#include <stdio.h>
+#include "ldap.h"
+...
+void do_other_work();
+int global_counter = 0;
+...
+/* Change these as needed. */
+#define DELETE_DN "uid=wjensen,ou=People,dc=example,dc=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 an LDAP delete request to the server. */
+rc = ldap_delete_ext( ld, DELETE_DN, NULL, NULL, &msgid );
+if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_delete_ext: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+}
+
+/* Poll the server for the results of the delete operation. */
+while ( !finished ) {
+ /* Call ldap_result() to get the results of the delete operation.
+ ldap_result() blocks for the time specified by the timeout argument
+ (set to zerotime here) while waiting for the result from the server. */
+ rc = ldap_result( ld, msgid, 0, &zerotime, &res );
+
+ /* Check to see if a result was received. */
+ switch ( rc ) {
+ case -1:
+ /* If ldap_result() returned -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, meaning
+ the server has still not yet sent the results of the delete
+ operation back to the client. Break out of this switch statement,
+ and continue calling ldap_result() to poll for results. */
+ break;
+
+ default:
+ /* ldap_result() got the results of the delete operation
+ from the server. No need to keep polling. */
+ finished = 1;
+
+ /* Call ldap_parse_result() to get information from the results
+ received from the server. Note the last argument is a non-zero
+ value. This means after the function retrieves information from
+ the LDAPMessage structure, the structure is freed.
+ (You do not need to call ldap_msgfree() to free the structure.)*/
+ 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 delete operation. */
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf(stderr, "ldap_delete_ext: %s\n", ldap_err2string(rc));
+ if ( error_msg != NULL & *error_msg != '\0' ) {
+ fprintf( stderr, "%s\n", error_msg );
+ }
+ /* Print the portion of a specified DN that matches an
+ existing entry, if returned by the server. */
+ if ( matched_msg != NULL && *matched_msg != '\0' ) {
+ fprintf( stderr,
+ "Part of the DN that matches an existing entry: %s\n",
+ matched_msg );
+ }
+ } else {
+ printf( "%s deleted successfully.\n"
+ "Counted to %d while waiting for the delete operation.\n",
+ DELETE_DN, global_counter );
+ }
+ }
+
+ /* Do other work while waiting for the results of the
+ delete operation. */
+ if ( !finished ) {
+ do_other_work();
+ }
+}
+ldap_unbind( ld );
+return 0;
+...
+
+/* Perform other work while polling for results. */
+void
+do_other_work()
+{
+ global_counter++;
+}
+...
+
+
+
+
+Retrieving SDK Information
+
+C SDK
+retrieving SDK information
+
+You can get information about the particular version of &DirectorySDKForC;
+that you are using by calling the ldap_get_option function:
+ldap_get_option(..., LDAP_OPT_API_INFO, ...);
+The retrieved information can include the version of the SDK or the
+highest version of the LDAP that the SDK supports. This example shows how
+to use this function to retrieve version information.
+Retrieving the SDK Version Using
+ldap_get_option
+
+example programs
+retrieving SDK version
+
+#include <stdio.h>
+#include "ldap.h"
+
+main()
+{
+
+LDAPAPIInfo ldapi;
+LDAPAPIFeatureInfo fi;
+int i;
+int rc;
+LDAP *ld;
+
+memset( &ldapi, 0, sizeof(ldapi));
+ldapi.ldapai_info_version = LDAP_API_INFO_VERSION;
+
+if ((rc = ldap_get_option( ld, LDAP_OPT_API_INFO, &ldapi)) != 0) {
+ printf("Error: ldap_get_option (rc: %d)\n", rc);
+ exit(0);
+}
+
+printf("LDAP Library Information -\n"
+ " Highest supported protocol version: %d\n"
+ " LDAP API revision: %d\n"
+ " API vendor name: %s\n"
+ " Vendor-specific version: %.2f\n",
+ ldapi.ldapai_protocol_version, ldapi.ldapai_api_version,
+ ldapi.ldapai_vendor_name,
+ (float)ldapi.ldapai_vendor_version / 100.0 );
+
+if ( ldapi.ldapai_extensions != NULL ) {
+ printf(" LDAP API Extensions:\n");
+
+ for ( i = 0; ldapi.ldapai_extensions[i] != NULL; i++ ) {
+ printf(" %s", ldapi.ldapai_extensions[i] );
+ fi.ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
+ fi.ldapaif_name = ldapi.ldapai_extensions[i];
+ fi.ldapaif_version = 0;
+
+ if ( ldap_get_option( NULL, LDAP_OPT_API_FEATURE_INFO, &fi )
+ != 0 ) {
+ printf("Error: ldap_get_option( NULL,"
+ " LDAP_OPT_API_FEATURE_INFO, ... ) for %s failed"
+ " (Feature Info version: %d)\n",
+ fi.ldapaif_name, fi.ldapaif_info_version );
+ } else {
+ printf(" (revision %d)\n", fi.ldapaif_version);
+ }
+ }
+ }
+ printf("\n");
+}
+
+
+Managing Memory
+
+C SDK
+managing memory
+
+memory management
+
+Several of the SDK functions allocate memory when called. When you have
+finished working with data allocated by these functions, you should free the
+memory. The following shows some of the functions that allocate memory and
+the corresponding functions you use to free the memory when done.
+
SDK Functions to Allocate
+and Free Memory
+
+
+
+
+Function to Free Memory
+
+Type of Memory Freed
+
+
+
+
+
+ldap_unbind, ldap_unbind_s
+
+
+Frees LDAP structures allocated by ldap_init
+ or prldap_init.
+
+
+
+ldap_msgfree
+
+Frees LDAPMessage structures allocated by
+ldap_result or ldap_search_ext_s.
+
+
+
+ldap_ber_free
+
+Frees BerElement structures allocated by
+ldap_first_attribute.
+
+
+
+ldap_value_free
+
+Frees char ** arrays and structures allocated by
+ldap_get_values.
+
+
+
+ldap_value_free_len
+
+Frees arrays of berval structures allocated
+by ldap_get_values_len.
+
+
+
+ber_bvfree
+
+Frees berval structures allocated by ldap_extended_operation_s
+, ldap_parse_extended_result, ldap_parse_sasl_bind_result
+, and ldap_sasl_bind_s.
+
+
+
+ldap_free_friendlymap
+
+Frees FriendlyMap structures allocated by
+ldap_friendly_name.
+
+
+
+ldap_free_urldesc
+
+Frees LDAPURLDesc structures allocated by
+ldap_url_parse.
+
+
+
+ldap_getfilter_free
+
+Frees LDAPFiltDesc structures allocated by
+ldap_init_getfilter or ldap_init_getfilter_buf.
+
+
+
+
+ldap_mods_free
+
+Frees LDAPMod** arrays and
+structures allocated by functions that you call when you add or modify entries.
+
+
+
+
+ldap_free_sort_keylist
+
+Frees LDAPsortkey** arrays
+that you allocate by calling ldap_create_sort_keylist.
+
+
+
+
+ldap_control_free
+
+Frees LDAPControl structures that you allocate
+by calling ldap_create_sort_control or ldap_create_persistentsearch_control
+.
+
+
+
+ldap_controls_free
+
+Frees LDAPControl** arrays
+and structures that you allocate by calling ldap_get_entry_controls,
+ldap_parse_result, or ldap_parse_reference.
+
+
+
+
+ldap_memfree
+
+Frees any other types of memory that you allocate. This function is
+a general function for freeing memory.
+
+
+
+
+
+Reporting Errors
+
+C SDK
+reporting errors
+
+errors
+reporting
+
+In LDAP, the success or failure of an operation is specified by a
+result code sent back to the client. A result code of zero (
+0) normally indicates that the operation was successful, whereas
+a nonzero result code usually indicates that an error occurred. For a detailed
+list of result codes, see Chapter 22, Directory
+SDK for C Result Codes.
+Setting Error Codes
+
+C SDK
+setting error codes
+
+error codes
+setting
+
+When an LDAP operation is performed, the error information from the
+operation is specified in the LDAP structure. If
+you want to set error codes and error information in the LDAP structure,
+call the ldap_set_lderrno function. This example sets
+the LDAP_PARAM_ERROR error code in an LDAP structure.
+
+Setting an Error Code
+#include "ldap.h"
+...
+LDAP *ld;
+char *errmsg = "Invalid parameter";
+...
+if ( ldap_my_function() != LDAP_SUCCESS ) {
+ ldap_set_lderrno( ld, LDAP_PARAM_ERROR, NULL, errmsg );
+ return( 1 );
+}
+...
+
+
+Getting Information About an Error
+
+C SDK
+retrieving error information
+
+When an error occurs in an LDAP operation, the server sends an LDAP
+result code for the error back to the client. The server also sends a message
+with any additional information about the error.
+
+You can get this information back from the server in two ways:
+If you are calling asynchronous functions, you can get the
+information from the LDAPMessage structure that represents
+the result the server returns.For details, see Getting Information From an LDAPMessage Structure.
+
+Sometimes, you do not have an LDAPMessage structure.
+For example, you might be calling functions that do not interact with the
+server. When you do not have a message ID, get error information from the
+LDAP connection handle.For details, see Getting Information From an LDAP Structure.
+
+
+Getting Information From an LDAPMessage Structure
+
+If you have requested the operation through an asynchronous function,
+get the result by calling the ldap_result function. This
+function passes the result as an LDAPMessage structure.
+You can get information from this structure by calling the ldap_parse_result
+ function whose prototype is shown here
+The ldap_parse_result
+ Function
+LDAP_API(int) LDAP_CALL ldap_parse_result( LDAP *ld,
+ LDAPMessage *res, int *errcodep, char **matcheddnp,
+ char **errmsgp, char ***referralsp,
+ LDAPControl ***serverctrlsp, int freeit );
+
+
+Different types of information are returned in the parameters of this
+function.
+The LDAP result code is the errcodep argument.
+
+Additional information from the server is passed back as the
+errmsgp argument.
+When the server cannot find an entry from a DN, the portion
+of the DN that identifies an entry is passed as the matcheddnp argument.
+See Receiving the Matching Portion of
+a DN for details.
+
+You can also get the error message that describes the LDAP result code
+by using the ldap_err2string function. See Getting the Error Message From an Error Code for
+details.
+The following example gets and prints information about an error returned
+from the server.
+Getting and Printing Error
+Information From an LDAPMessage Structure
+
+example programs
+printing error information
+
+#include <stdio.h>
+#include "ldap.h"
+...
+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;
+...
+while ( !finished ) {
+ /* Check to see if the server returned a result. */
+ rc = ldap_result( ld, msgid, 0, &zerotime, &res );
+ switch ( rc ) {
+ ...
+ default:
+ /* The client has received the result of the LDAP operation. */
+ finished = 1;
+
+ /* Parse this result to determine if the operation was successful. */
+ parse_rc = ldap_parse_result( ld, res, &rc, &matched_msg,
+ &error_msg, &referrals, &serverctrls, 1 );
+
+ /* Verify that the result was parsed correctly. */
+ if ( parse_rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_parse_result error: %s\n",
+ ldap_err2string( parse_rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+
+ /* Check the results of the operation. */
+ if ( rc != LDAP_SUCCESS ) {
+
+ /* Print the error message corresponding to the result code. */
+ fprintf( stderr, "Error: %s\n",
+ ldap_err2string( rc ) );
+
+ /* If the server sent an additional message, print it out. */
+ if ( error_msg != NULL && *error_msg != '\0' ) {
+ fprintf( stderr, "%s\n", error_msg );
+ }
+
+ /* If the server cannot find an entry with the specified DN,
+ it may send back the portion of the DN that matches
+ 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 );
+ }
+
+ /* Disconnect and return. */
+ ldap_unbind( ld );
+ return( 1 );
+ }
+...
+
+
+Getting Information From an LDAP Structure
+
+Sometimes, you do not get an LDAPMessage structure.
+For example, when you call functions that do not interact with the server,
+get error information from the connection handle. You can get information
+about the last error that has occurred by calling the ldap_get_lerrno function
+whose prototype is shown here.
+The ldap_get_lderrno Function
+
+LDAP_API(int) LDAP_CALL ldap_get_lderrno(LDAP *ld,
+char **m, char **s);
+
+
+The different types of information to retrieve are returned in the following
+ways:
+The LDAP result code is returned by this function.
+
+Additional information from the server is passed back as the
+s argument.
+When the server cannot find an entry from a DN, the portion
+of the DN that identifies an entry is passed as the m argument.
+See Receiving the Matching Portion of
+a DN for details.
+
+If you do not need to use the parameters returned by the ldap_get_lerrno
+ function, set the parameters to NULL:
+ldap_get_lderrno( ld, NULL, NULL );
+The following example gets and prints information about an error from
+an LDAP structure.
+Getting and Printing an Error
+Message From an LDAP Structure
+#include <stdio.h>
+#include "ldap.h"
+...
+LDAP *ld;
+char* *error_msg = NULL, *matched_msg = NULL;
+int rc;
+...
+rc = ldap_get_lderrno( ld, &matched_msg, &error_msg );
+fprintf( stderr, "ldap_result error: %s\n", ldap_err2string( rc ) );
+if ( error_msg != NULL && *error_msg != '\0' ) {
+ fprintf( stderr, "%s\n", error_msg );
+}
+
+/* If the server cannot find an entry with the specified DN,
+ it may send back the portion of the DN that matches
+ 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 );
+}
+...
+
+
+Getting the Error Message From an Error Code
+If you have an error code, you can retrieve its corresponding error
+message using the ldap_err2string function. The function
+returns a pointer to the error message. The pointer returned by this function
+is a pointer to static data. Do not free this string.
+Retrieving an Error
+Message From an Error Code
+#include <stdio.h>
+#include "ldap.h"
+...
+int rc;
+...
+if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "Error: %s\n", ldap_err2string( rc ) );
+}
+...
+
+
+
+Receiving the Matching Portion of a DN
+
+distinguished names (DNs)
+return portion of
+
+If the server cannot find an entry specified by a DN, the server can
+return the portion of the DN that identifies an existing entry. According
+to LDAP v3, if a server returns an LDAP_NO_SUCH_OBJECT,
+LDAP_ALIAS_PROBLEM, LDAP_INVALID_DN_SYNTAX,
+or LDAP_ALIAS_DEREF_PROBLEM result code, the LDAP server
+should also send back the portion of the DN that matches an entry that is
+closest to the requested entry.
+For example, suppose that the LDAP server processes a request to modify
+the entry with the DN uid=bjensen,ou=Contractors,dc=example,dc=com but
+that entry does not exist in the directory. If ou=Contractors,dc=example,dc=com
+ does exist, the server sends this portion of the DN with the result
+code LDAP_NO_SUCH_OBJECT. If ou=Contractors,dc=example,dc=com
+ does not exist, but dc=example,dc=com does,
+the server sends dc=example,dc=com back to the client.
+The server also returns the result code LDAP_NO_SUCH_OBJECT.
+Basically, the server removes one DN component at a time, until the server
+can find a DN that identifies an existing entry.
+Printing Error Messages
+
+error messages
+printing
+
+To print the error message that describes the last error that occurred,
+call the ldap_get_lerrno function. The following prints
+a message if a function fails to delete an entry in the server.
+Printing Error Messages
+From Error Codes
+#include "ldap.h"
+...
+int lderr;
+char * errmsg;
+LDAP *ld;
+char *dn = "uid=bjensen,ou=People,dc=example,dc=com";
+...
+if ( ldap_delete_s( ld, dn ) != LDAP_SUCCESS ) {
+ lderr = ldap_get_lderrno (ld, NULL, &errmsg);
+ if ( errmsg, != NULL ) {
+ fprintf(stderr, "ldap_delete_s: %s\n", errmsg );
+ ldap_memfree( errmsg );
+ }
+ return( 1 );
+}
+...
+
+The client also prints the following message if the client does not
+have access permissions to delete the entry:
+ldap_delete_s: Insufficient access
+
+
+Handling Referrals With Directory SDK for C
+
+C SDK
+handling referrals
+
+referrals
+handling with C SDK
+
+When a server receives a request for a DN, that DN might not be in its
+directory tree. The server can refer clients to another server that might
+contain the DN. The reference that the client receives is called a referral
+.
+Consider an LDAP server that has a directory that starts under dc=example,dc=com
+.
+
+Your client sends the server a request to modify the entry with the
+DN uid=bjensen,ou=People,dc=exampleWest,dc=com, that is,
+the entry is not under dc=example,dc=com. One of the following
+can occur:
+If the server is not configured to send a referral, the server
+sends back an LDAP_NO_SUCH_OBJECT result code.
+
+If the server is configured to refer you to another LDAP server,
+the server sends a referral back to your client. The referral consists of
+the result code, LDAP_PARTIAL_RESULTS for LDAP v2 clients,
+or LDAP_REFERRAL for LDAP v3 clients, and one or more
+LDAP URLs. For LDAP v2 clients, the URLs are included in the error message
+that the server sends to the client. For LDAP v3 clients, the URLs are included
+in a separate section of the result.
+
+
+Depending on how your LDAP client is configured, one of the following
+can occur:
+If your client handles referrals automatically, the client
+connects to the LDAP server specified in the referral. The client then requests
+the operation from that server. The client binds anonymously to that server.
+
+If your client does not handle referrals automatically, your
+client returns the result code sent from the server, LDAP_PARTIAL_RESULTS
+ or LDAP_REFERRAL. You can get the LDAP
+URLs from the result by calling the ldap_parse_result function.
+
+
+By default, clients built with &DirectorySDKForC; follow referrals
+automatically.
+Searching References and Referrals
+
+C SDK
+search references
+
+A concept that is similar to a referral is a search reference. A
+search reference is an entry with the object class referral.
+The ref attribute of this object class contains an LDAP
+URL that identifies another LDAP server. When your client searches a subtree
+of a directory that contains search references, the server returns a mix of
+matching entries and search references.
+
+As your client retrieves search references from the server, one of the
+following occurs:
+If your client handles referrals automatically, &DirectorySDKForC;
+retrieves each search reference, binds to the server identified in the reference,
+and then retrieves the entry.
+If your client does not handle referrals automatically, &DirectorySDKForC;
+adds the search reference to the chain of search results. The search reference
+is a message of the type LDAP_RES_SEARCH_REFERENCE. You
+can get the search references from a chain of results by calling the ldap_first_reference
+ and ldap_next_reference functions. You can
+also call the ldap_first_message and ldap_next_message
+ functions to get each message in the search results, and then
+call the ldap_msgtype function to determine if the message
+is of the type LDAP_RES_SEARCH_REFERENCE.
+
+See ldap_ssl.h Header File for information
+about specifying a DN and password for binding to a server for a referral.
+
+Enabling or Disabling Referral Handling With &DirectorySDKForC;
+
+
+referrals
+handling with C SDK
+
+By default, clients built with &DirectorySDKForC; automatically follow
+referrals to other servers. To change the way referrals are handled, call
+the ldap_set_option function and pass LDAP_OPT_REFERRALS
+ as the value of the option parameter.
+
+To prevent the client from automatically following referrals,
+set the optdata parameter to LDAP_OPT_OFF.
+
+If you want the client to automatically follow referrals again,
+set the optdata parameter to LDAP_OPT_ON.
+Both LDAP_OPT_OFF and LDAP_OPT_ON are
+cast to (void *). You can pass these parameters directly
+to the function as shown in the following example. The parameter prevents
+the client from automatically following referrals to other LDAP servers.
+
+
+Disabling Referrals
+#include <stdio.h>
+#include "ldap.h"
+...
+LDAP *ld;
+int rc;
+char *host = "localhost";
+...
+/* Initialize a session with the LDAP server ldap.example.com:389. */
+/* Use prldap_init() for IPv6 support. */
+if ( ( ld = ldap_init( host, LDAP_PORT ) ) == NULL ) {
+ perror( "ldap_init" );
+ return( 1 );
+}
+
+/* Never follow referrals. */
+if ( ldap_set_option( ld,
+ LDAP_OPT_REFERRALS,
+ LDAP_OPT_OFF) !=
+ LDAP_SUCCESS ) {
+ rc = ldap_get_lderrno( ld, NULL, NULL );
+ fprintf( stderr, "ldap_set_option: %s\n",
+ ldap_err2string( rc );
+ return( 1 );
+}
+...
+
+
+Limiting Referral Hops With &DirectorySDKForC;
+
+C SDK
+referral hop limit
+
+You can specify the maximum number of referral hops that should be followed
+in a sequence of referrals. The maximum setting is called the referral
+hop limit. You can specify the limit as a preference for the connection.
+You can also specify the limit as a search constraint for a specific search
+operation. For example, LDAP server 1 refers your client to server 2, server
+2 to server 3, and then server 3 to server 4. Your client is being referred
+three times. With a limit of two referral hops, your client would not follow
+the referral to server 4, as the third referral exceeds the limit. If the
+referral hop limit is exceeded, the client returns the result code LDAP_REFERRAL_LIMIT_EXCEEDED
+.
+To set the referral hop limit, pass LDAP_OPT_REFERRAL_HOP_LIMIT as
+the value of the option parameter. Also, pass the maximum
+number of hops as the value of the optdata parameter. By
+default, the maximum number of hops is 5.
+Binding for Referrals
+
+C SDK
+binding for referrals
+
+referrals
+binding for
+
+If the session setup specifies that the client always follows referrals,
+the LDAP server that the client connects to can refer the client to another
+server. By default, the client binds anonymously when following referrals.
+No user name or password is specified. The following sections explain how
+to set up your client to authenticate with a DN and with corresponding credentials.
+
+How Referral Binding Works
+To authenticate to the referred LDAP server, define a rebind function
+of the type LDAP_REBINDPROC_CALLBACK. The rebind
+function gets the DN and password to be used for authentication. Then, you
+specify that your function should be used if binding to other servers when
+following referrals.
+
+Referral handling proceeds as follows:
+The LDAP server sends a referral back to the client.
+The referral contains an LDAP URL that identifies another LDAP server.
+
+The client calls the rebind function, specified by the LDAP_OPT_REBIND_FN
+ option, passing 0 as the freeit argument.
+
+The rebind function sets the dnp,
+passwdp, and authmethodp arguments.
+
+The dnp argument points to the DN used
+to authenticate to the new LDAP server.
+The passwdp argument points to the
+credentials for this DN.
+The authmethodp argument points to
+the method of authentication that is used, such as LDAP_AUTH_SIMPLE.
+
+
+
+If successful, the rebind function returns LDAP_SUCCESS
+, and referral processing continues.If any other
+value is returned, referral processing stops, and that value is returned as
+the result code for the original LDAP request.
+The client gets the DN, the credentials, and the authentication
+method from the arguments of the rebind function. The client uses this information
+to authenticate to the new LDAP server.
+The client calls the rebind function again, passing 1 as
+the freeit argument.
+The rebind function frees any memory that was allocated earlier
+to specify the DN and credentials.
+
+
+Defining the Rebind Function
+
+You need to define a rebind function that does the following:
+ If freeit is 0,
+do the following:
+
+Set dnp to point to the DN to be used
+for authentication.
+Set passwdp to point to the credentials
+to be used for authentication.
+Set authmethodp to point to the method
+of authentication to be used, such as LDAP_AUTH_SIMPLE.
+
+Alternatively, you can also make use of the arg argument,
+a pointer to the argument specified in the ldap_set_rebind_proc function.
+If successful, the function returns LDAP_SUCCESS. Otherwise,
+the function returns the appropriate LDAP error code.
+
+
+If freeit is 1,
+free any memory that you allocated to create the DN and credentials.
+The following code defines the rebind function. The table defines the
+parameters of the rebind function. LDAP_CALL and
+LDAP_CALLBACK set up calling conventions. The structures are
+defined in the lber.h header file.
+
+Rebind Function Definition
+int LDAP_CALL LDAP_CALLBACK rebindproc( LDAP *ld, char **dnp,
+ char **passwdp, int *authmethodp, int freeit, void *arg );
+
+
+LDAP_CALL and LDAP_CALLBACK Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to the connection handle to the LDAP server.
+
+
+
+dnp
+
+Pointer to the DN of the user or entity who wants to perform the LDAP
+operations. Your function needs to set this value.
+
+
+
+passwdp
+
+Pointer to the user password. Your function needs to set this value.
+
+
+
+
+authmethodp
+
+Pointer to the method of authentication. Your function needs to set
+this value.
+
+
+
+freeit
+
+Specifies whether or not to free the memory allocated by the previous
+rebindproc function call in the event that this function is called
+more than once. If freeit is set to a nonzero value,
+your function should free the memory allocated by the previous call.
+
+
+
+
+arg
+
+Pointer to data that can be passed to your function.
+
+
+
+
+
+Registering the Rebind Function
+
+After you define a rebind function, you must register the function.
+You can register the function in one of the following ways:
+Call ldap_set_rebind_proc, specifying
+your function and any data that you want passed as an argument.
+
+Call ldap_set_option to set the LDAP_OPT_REBIND_FN
+ option to your function. Use the LDAP_OPT_REBIND_ARG option
+to specify any arguments to pass to your rebind function.
+
+
+
+
+Creating an In-Memory Cache
+
+C SDK
+setting up in-memory cache
+
+cache
+setting up
+
+&DirectorySDKForC; includes functions that allow you to create an
+in-memory cache of search results for your client. Then, when sending a search
+request and receiving results, the results would be cached. The next time
+your client issues the same search request, the results are read from the
+cache. To set up a cache for your connection, complete the following procedure.
+To Set Up an In-Memory Cache
+
+Call the ldap_memcache_init function to create
+a new LDAPMemCache structure.The structure
+is the cache. Pass the pointer to this structure for subsequent operations.
+
+Call the ldap_memcache_set function to associate
+the cache with an LDAP structure, which is a connection
+handle.When a search request is cached, the search criteria are
+used as the key to the item in the cache. If you run the same search again,
+the results are read from the cache. If you alter the criteria, your client
+gets the results from the server rather than the cache. For example, you can
+specify to return all attributes instead of just the uid attribute,
+The cache periodically checks for expired items. The cache mechanism
+removes expired items from the cache.
+When you write a multithreaded application, set up a separate
+thread to keep the cache up to date. To keep the cache updated,
+call the ldap_memcache_update function.
+If you want to remove items from the cache or flush the cache,
+call the ldap_memcache_flush function.
+When you are done working with the cache, call the ldap_memcache_destroy
+ function.
+
+
+Setting Up an In-Memory Cache
+#include "ldap.h"
+...
+#define HOSTNAME "localhost"
+#define PORTNUMBER LDAP_PORT
+...
+LDAP *ld;
+LDAPMemCache *dircache;
+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 );
+}
+...
+/* Create an in-memory cache. */
+rc = ldap_memcache_init( 0, 0, NULL, NULL, &dircache );
+if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_memcache_init: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+}
+
+/* Associate the cache with the connection. */
+rc = ldap_memcache_set( ld, dircache );
+if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_memcache_set: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+}
+...
+
+
+
+Handling Failover
+
+C SDK
+handling failover
+
+failover handling
+C SDK
+
+While performing an LDAP operation, if the LDAP client loses the connection
+with the server, the SDK returns an LDAP_SERVER_DOWN or
+LDAP_CONNECT_ERROR result code.
+
+To reconnect to the server, you can do one of the following:
+Free the current connection handle. Then create a new connection
+handle.See Creating a New Connection
+Handle for details.
+Use the reconnect option, LDAP_OPT_RECONNECT
+, to connect to the server again with the same connection handle.
+See Using the Reconnect Option for
+details.You can use this option if you do not want to free the
+connection handle, for example, if multiple threads are sharing the same connection
+handle.
+
+Creating a New Connection Handle
+Call the ldap_unbind or ldap_unbind_s function
+to free the existing connection handle, which is an LDAP structure.
+Then call ldap_init or prldap_init to
+initialize a new connection as shown in the following example.
+The disadvantage of this approach is the need to free the connection
+handle, which can make sharing connection handles between threads difficult.
+Initializing a New Connection Handle
+#include "ldap.h"
+...
+LDAP *ld;
+int tries = 0, rc = 0;
+...
+do {
+ /* Call a function that performs an LDAP operation
+ (my_ldap_request_function() can be any of these functions,
+ such as ldap_search_ext_s()) */
+ rc = my_ldap_request_function( ld );
+
+ /* Check to see if the connection was lost. */
+ if ( rc != LDAP_SERVER_DOWN && rc != LDAP_CONNECT_ERROR ) {
+ return( rc ); /* Return result code. */
+ }
+
+ /* If the connection was lost, free the handle. */
+ ldap_unbind( ld );
+
+ /* Create a new connection handle and attempt to bind again. */
+ /* Use prldap_init() for IPv6 support. */
+ if (( ld = ldap_init( hostlist, port )) != NULL ) {
+ ldap_simple_bind_s();
+
+ /* Perform any other initialization
+ work on the connection handle. */
+ }
+} while ( ld != NULL && ++tries < 2 );
+...
+
+
+Using the Reconnect Option
+To reconnect to the server without freeing the connection handle, for
+example, if multiple threads need to share the same connection handle, call
+the ldap_set_option function to set the LDAP_OPT_RECONNECT
+ option to LDAP_OPT_ON. Call this function immediately
+after calling ldap_init or prldap_init as
+shown in the following example:
+Reconnecting to an Existing
+Connection Handle
+#include "ldap.h"
+...
+#define HOSTNAME "localhost"
+#define PORTNUMBER LDAP_PORT
+...
+LDAP *ld;
+...
+/* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
+if ( (ld = ldap_init( HOSTNAME, PORTNUMBER )) == NULL ) {
+ perror( "ldap_init" );
+ return( 1 );
+}
+
+/* Set the reconnect option. */
+if ( ldap_set_option( ld, LDAP_OPT_RECONNECT, LDAP_OPT_ON ) == 0 ) {
+ /* success */
+ } else {
+ /* failure */
+}
+...
+
+If after setting this option, the connection to the server has been
+lost, the SDK returns an LDAP_CONNECT_ERROR or
+LDAP_SERVER_DOWN result code to your client. When you receive
+this result code, call the ldap_simple_bind_s function.
+This function reestablishes a connection to one of the hosts specified in
+the ldap_init or prldap_init function
+call. If your client is able to reconnect with the server, ldap_simple_bind_s
+ issues a bind request to the server and returns the result. The
+following example attempts to reconnect to the server if the client is disconnected.
+
+Reconnecting to a Server
+After Disconnect
+#include "ldap.h"
+...
+LDAP *ld;
+int tries = 0, rc = 0;
+...
+do {
+ /* Call a function that performs an LDAP operation
+ (my_ldap_request_function() can be any of these functions,
+ such as ldap_search_ext_s()) */
+ rc = my_ldap_request_function( ld );
+
+ /* Check to see if the connection was lost. */
+ if ( rc != LDAP_SERVER_DOWN && rc != LDAP_CONNECT_ERROR ) {
+ return( rc ); /* Return the result code. */
+ }
+
+ /* If the connection was lost, call
+ ldap_simple_bind_s() to reconnect. */
+ if ( ldap_simple_bind_s( ld, dn, passwd ) != LDAP_SUCCESS ) {
+ /* failure -- could not reconnect */
+ /* remember that ld as bad */
+ return( rc );
+ }
+} while ( ++tries < 2 );
+
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-client.sgm b/mozilla/directory/docs/ldapcsdk/csdk-client.sgm
new file mode 100644
index 00000000000..4b9985d4c79
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-client.sgm
@@ -0,0 +1,768 @@
+
+Writing an LDAP Client With &DirectorySDKForC;
+
+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.
+
+This chapter covers the following topics:
+Designing an LDAP Client With Directory
+SDK for C
+Initializing an LDAP Session With
+Directory SDK for C
+Binding and Authenticating to an
+LDAP Server With Directory SDK for C
+Performing LDAP Operations With Directory
+SDK for C
+Closing the Connection to an LDAP
+Server With Directory SDK for C
+
+
+Designing an LDAP Client With &DirectorySDKForC;
+
+C SDK
+designing LDAP client
+
+LDAP clients
+designing with C SDK
+
+The following procedure outlines a typical process for communicating
+with an LDAP server.
+To Communicate With an LDAP Server
+
+Initialize an LDAP session.See
+Initializing an LDAP Session With Directory SDK for C for details.
+
+Bind to the LDAP server, if necessary.See Binding and Authenticating to an LDAP Server With Directory
+SDK for C for details.
+Perform LDAP operations, such as searching the directory or modifying
+entries in the directory.See Performing
+LDAP Operations With Directory SDK for C for details.
+Close the connection to the LDAP server when finished.See Closing the Connection to an LDAP Server With Directory
+SDK for C for details.
+
+
+Performing an LDAP Search
+
+example programs
+LDAP search
+
+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
+389. The client searches the directory for entries with the last
+name Jensen (sn=Jensen), and prints
+the distinguished name (DN) of any matching entry.
+#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 );
+}
+...
+
+
+
+Initializing an LDAP Session With &DirectorySDKForC;
+
+C SDK
+initializing an LDAP session
+
+LDAP session
+initializing
+
+Before connecting to an LDAP server, you must initialize a session.
+As part of this process, you create an LDAP structure
+that contains information about the LDAP server and session. You then pass
+this LDAP 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 Example Session Initialization.
+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 Chapter 15, SSL Connections
+With Directory SDK for C.
+Specifying a Single LDAP Server
+To initialize an LDAP session, call ldap_init,
+or prldap_init for IPv6 support, with the host name and
+port number of the LDAP server. If the server is using the default port
+389 for the LDAP server, pass LDAP_PORT as the
+value for the defport parameter as shown here.
+Passing an LDAP Server With the Default
+LDAP Port
+...
+LDAP *ld
+...
+ld = ldap_init( "directory.example.com", LDAP_PORT );
+
+If successful, ldap_init, or prldap_init,
+returns a connection handle to the LDAP server. A connection handle is
+a pointer to the LDAP 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.
+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.
+
+Specifying a List of LDAP Servers
+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 ldap_init or
+prldap_init function. In the following example, the LDAP client
+attempts to connect to the LDAP server on ld1.example.com,
+port 389. If that server does not respond, the client attempts
+to connect to the LDAP server on ld2.example2.com, port
+389. If that server does not respond, the client uses the server
+on ld3.example.com, port 389.
+Passing Multiple LDAP Servers
+With the Default LDAP Port
+...
+LDAP *ld
+...
+ld = ldap_init( "ld1.example.com ld2.example2.com
+ ld3.example.com", LDAP_PORT );
+
+If any servers do not use the default LDAP port, use the host
+:port format to specify the server name
+and port number. In the following example, that means ld1.example.com,
+port 389. If that server does not respond, the client attempts
+to connect to the LDAP server on ld2.example.com, port
+1389.
+Passing Non-Default LDAP Ports
+...
+LDAP *ld
+...
+ld = ldap_init( "ld1.example.com ld2.example.com:1389",
+ LDAP_PORT );
+
+
+Example Session Initialization
+
+example programs
+initializing an LDAP session
+
+The following example initializes a session with an LDAP server, specifying
+a list of LDAP servers to try: ldap.example.com:389 and
+directory.example.com:1389. The example also sets a session preference
+that identifies the client as an LDAP v3 client. This session initialization
+code uses the prldap_init function, which works on IPv6
+networks. Notice that prldap_init does not connect to
+the LDAP server right away.
+After you initialize a session with an LDAP server, you can set session
+preferences. For information, seeSetting Session
+Preferences With Directory SDK for C.
+Initializing an LDAP Session
+#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. */
+
+...
+
+
+Setting Session Preferences With &DirectorySDKForC;
+
+C SDK
+setting LDAP session preferences
+
+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 ldap_get_option or ldap_set_option functions
+respectively.
+
+Both functions pass two parameters in addition to the ld parameter,
+which represents the connection to the server:
+The option parameter identifies the
+option that you want to get or set.
+The value parameter is either a pointer
+to a place to put the value to get, or a pointer to the value to set.
+
+
+You can set a preference for all connections by passing NULL as
+the first argument, not an LDAP structure that specifies
+the connection.
+Reconnecting Automatically
+If communication with the LDAP server is interrupted, the server returns
+LDAP_SERVER_DOWN. If you want your client to continue to attempt
+communication with the server, you can set the LDAP_OPT_RECONNECT preference
+for the session. Once set, if your connection is lost, the client attempts
+another bind with the same authentication to reestablish the connection.
+The following example shows that to set the reconnect preference, call
+the ldap_set_option function and pass LDAP_OPT_RECONNECT
+ as the value of the option parameter. To
+resume LDAP I/O operations automatically, set the optdata parameter
+to LDAP_OPT_ON. This setting specifies the same connection
+handle that can be used to reconnect to the server.
+Passing Restart Preferences
+ldap_set_option( ld, LDAP_OPT_RECONNECT, LDAP_OPT_ON );
+
+To avoid resuming I/O operations, you would set the optdata parameter
+to LDAP_OPT_OFF. This setting specifies that you want to
+create a new connection handle to connect to the server. By default, the
+optdata parameter is set to LDAP_OPT_OFF. Both
+LDAP_OPT_OFF and LDAP_OPT_ON are cast to (void
+*).
+Specifying the LDAP Version of Your Client
+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.
+To specify the LDAP version supported by your client, call the ldap_set_option
+ function and set the LDAP_OPT_PROTOCOL_VERSION option
+to the value 3.
+Passing the LDAP Protocol Version Number
+...
+version = LDAP_VERSION3;
+ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
+...
+
+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.
+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.
+
+Setting Connection Timeout
+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 LDAP_X_OPT_CONNECT_TIMEOUT option, you can
+adjust how long to wait for a connection.
+You specify the timeout as an int number of milliseconds,
+then call the ldap_set_option function, passing the
+LDAP_X_OPT_CONNECT_TIMEOUT option.
+Passing Connection Timeout Preferences
+The following example sets the connection timeout to one second.
+int timeout = 1000; /* 1000 milliseconds == 1 second */
+ldap_set_option( ld, LDAP_X_OPT_CONNECT_TIMEOUT, &timeout );
+
+
+The LDAP_X_OPT_CONNECT_TIMEOUT option can be set
+using the following values as well:
+LDAP_X_IO_TIMEOUT_NO_WAITReturn
+immediately if the server cannot be reached.
+LDAP_X_IO_TIMEOUT_NO_TIMEOUTWait
+indefinitely for the server to connect.
+
+By passing NULL as the first parameter to the
+ldap_set_option function, you can set the default timeout for all
+connections used by your application.
+
+
+Binding and Authenticating to an LDAP Server With &DirectorySDKForC;
+
+C SDK
+binding and authenticating
+
+binding
+with C SDK
+
+When connecting to the LDAP server, your client might need to send a
+bind request.
+
+A bind request should be sent if either of the following are true.
+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.
+You are connecting to an LDAP v2 server. LDAP v2 servers typically
+require clients to bind before any operations can be performed.
+
+
+
+The bind request should contain the following information:
+ LDAP version of the client
+ Method of authentication to use
+ DN that the client is attempting to authenticate as
+
+ Credentials to be used for authentication
+
+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.
+Using Simple Authentication With &DirectorySDKForC;
+
+C SDK
+methods of authentication
+simple authentication
+
+authentication
+C SDK
+simple
+
+
+If you plan to use simple authentication, call one of the following
+functions:
+ldap_simple_bind_s is a synchronous function
+for use if you want to wait for the bind operation to complete before the
+function returns.See Performing a Synchronous
+Authentication Operation
+ldap_simple_bind 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.See Performing
+an Asynchronous Authentication Operation
+
+For more information about the differences between the types of functions,
+see Synchronous and Asynchronous Functions.
+Performing a Synchronous Authentication Operation
+If you want to wait for the bind operation to complete before continuing,
+call ldap_simple_bind_s. This function returns LDAP_SUCCESS
+ if the operation completed successfully, or an LDAP result code
+if a problem occurred. See ldap_simple_bind_s in ldap_simple_bind_s for a list of result codes returned.
+
+If you specify a DN but no password, your client binds to the server
+anonymously. If you want a NULL password to be rejected
+as incorrect, you must write code to perform the check before you call
+ldap_simple_bind_s.
+The following example uses the synchronous ldap_simple_bind_s function
+to authenticate user Barbara Jensen to the LDAP server.
+Performing Synchronous Authentication
+
+#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 );
+...
+
+
+Performing an Asynchronous Authentication Operation
+If you want to perform other work in parallel while waiting for the
+bind operation to complete, call ldap_simple_bind. 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 ldap_result function
+with the message ID. If your client has received the results, ldap_result
+ passes back the information in an LDAPMessage structure.
+To retrieve error information from LDAPMessage, you
+can pass the message ID to the ldap_parse_result function.
+ldap_parse_result 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.
+If you specify a DN but no password, your client binds to the server
+anonymously. If you want a NULL password to be rejected
+as incorrect, you need to write code to perform the check before you call
+ldap_simple_bind.
+The following example uses the asynchronous ldap_simple_bind function
+to authenticate user Barbara Jensen to the LDAP server.
+Performing Asynchronous Authentication
+
+
+example programs
+asynchronous authentication
+
+#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++;
+}
+...
+
+
+
+Binding Anonymously With &DirectorySDKForC;
+
+C SDK
+methods of authentication
+anonymous authentication
+
+authentication
+C SDK
+anonymous
+
+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 ldap_simple_bind or ldap_simple_bind_s,
+and pass NULL values for the who and
+passwd parameters.
+rc = ldap_simple_bind_s( ld, NULL, NULL );
+
+
+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.
+
+Performing LDAP Operations With &DirectorySDKForC;
+
+C SDK
+LDAP operations
+
+LDAP operations
+with C SDK
+
+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.
+
Functions for Performing
+LDAP Operations
+
+
+
+
+To Perform This Operation
+
+Call This API Function
+
+
+
+
+
+Search for entries
+
+ldap_search_ext
+ldap_search_ext_s
+
+
+
+Determine an attribute’s value
+
+ldap_compare_ext
+ldap_compare_ext_s
+
+
+
+Add entries
+
+ldap_add_ext
+ldap_add_ext_s
+
+
+
+Modify entries
+
+ldap_modify_ext
+ldap_modify_ext_s
+
+
+
+Delete entries
+
+ldap_delete_ext
+ldap_delete_ext_s
+
+
+
+Change DN of entries
+
+ldap_rename_ext
+ldap_rename_ext_s
+
+
+
+
+Most LDAP operations can be performed synchronously or asynchronously.
+The functions with names that end in _s are synchronous.
+The remaining ones are asynchronous. For more information about the distinction
+between the functions, see Synchronous and Asynchronous
+Operations.
+Closing the Connection to an LDAP Server With &DirectorySDKForC;
+
+C SDK
+closing an LDAP server connection
+
+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 LDAP structure because
+the structure is freed from memory.
+
+To close a connection to an LDAP server, call one of the following functions:
+
+ldap_unbind
+ldap_unbind_s
+ldap_unbind_ext
+
+Both ldap_unbind and ldap_unbind_s are
+identical synchronous functions. These functions use different names so that
+each function has a corresponding authentication function, ldap_simple_bind
+ and ldap_simple_bind_s, to close the server
+connection.
+The ldap_unbind_ext 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.
+The following example closes the current connection with the LDAP server.
+Closing an LDAP Server Connection
+#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 ) );
+}
+...
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-compare.sgm b/mozilla/directory/docs/ldapcsdk/csdk-compare.sgm
new file mode 100644
index 00000000000..c60374fba7d
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-compare.sgm
@@ -0,0 +1,438 @@
+
+Comparing Attribute Values
+With &DirectorySDKForC;
+
+C SDK
+comparing attribute values
+
+This chapter describes how to compare the value of an attribute in an
+entry against a specified value.
+
+This chapter covers the following topics:
+Functions for Comparing Attribute
+Values With Directory SDK for C
+Performing Synchronous Comparison
+Operations With Directory SDK for C
+Performing Asynchronous Comparison
+Operations With Directory SDK for C
+
+
+Functions for Comparing Attribute Values With Directory
+SDK for C
+&DirectorySDKForC; has functions to determine if an attribute contains
+a certain string or binary value.
+
+To determine if an attribute contains a certain string value,
+call either of the following functions:
+The synchronous ldap_compare_s function
+
+The asynchronous ldap_compare function
+
+
+
+To determine if an attribute contains a certain binary value,
+call either of the following functions:
+The synchronous ldap_compare_ext_s function
+
+The asynchronous ldap_compare_ext function
+
+
+
+Performing Synchronous Comparison Operations With
+Directory SDK for C
+
+synchronous functions
+comparison operation
+
+You can wait for the results of the compare operation to complete before
+continuing. Call the synchronous ldap_compare_ext_s function
+to compare values in berval structures or the synchronous
+ldap_compare_s 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.
+
+Both functions return one of the following values after the compare
+operation completes:
+LDAP_COMPARE_TRUE indicates that the
+attribute contains the specified value.
+LDAP_COMPARE_FALSE indicates that the
+attribute does not contain the specified value.
+
+An error code indicates that a problem has occurred during the operation.
+The following example calls the synchronous ldap_compare_s function
+to determine if an entry has the value bjensen@example.com in
+the mail attribute.
+Performing a Synchronous Compare
+Operation
+#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 );
+...
+
+The following sample program calls the synchronous ldap_compare_s
+ function. The sample program uses this function to determine if
+a user entry has the value bjensen@example.com in the
+mail attribute.
+Sample Synchronous Compare
+Program
+#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;
+}
+
+
+Performing Asynchronous Comparison Operations With
+Directory SDK for C
+
+asynchronous functions
+comparison operation
+
+You can perform other work in parallel while waiting for the comparison
+to complete. Call the asynchronous ldap_compare_ext function
+to compare values in berval structures or the asynchronous
+ldap_compare function to compare string values. These functions
+send a compare request to the server and return an LDAP_SUCCESS result
+code if the request was successfully sent, or an LDAP result code if an error
+occurred.
+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 ldap_result function and pass in the
+message ID. The ldap_result function uses the message
+ID to determine if the server sent the results of the compare operation. The
+ldap_result function passes back the results in an LDAPMessage
+ structure. You can call the ldap_parse_result function
+to parse the LDAPMessage structure to determine if
+the operation was successful.
+
+The result code should be one of the following:
+LDAP_COMPARE_TRUE indicates that the
+attribute contains the specified value.
+LDAP_COMPARE_FALSE indicates that the
+attribute does not contain the specified value.
+
+An error code indicates that a problem occurred during the operation.
+The following example calls the asynchronous ldap_compare function
+to determine if an entry has the value bjensen@example.com in
+the mail attribute.
+Performing an Asynchronous Compare
+Operation
+#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;
+ }
+ }
+}
+...
+
+The following sample program calls the asynchronous ldap_compare function.
+The sample program uses this function to determine if a user entry has the
+value bjensen@example.com in the mail attribute.
+
+Sample Asynchronous Compare
+Program
+#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++;
+}
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-controls.sgm b/mozilla/directory/docs/ldapcsdk/csdk-controls.sgm
new file mode 100644
index 00000000000..dc704af333d
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-controls.sgm
@@ -0,0 +1,2028 @@
+
+LDAP Controls With &DirectorySDKForC;
+
+C SDK
+LDAP controls
+
+This chapter explains how LDAP controls work and how to use them.
+
+This chapter covers the following topics:
+How LDAP Controls Work With Directory
+SDK for C
+Using Controls in the LDAP API
+
+Determining the Controls Supported
+by the Server With Directory SDK for C
+Using the Server-Side Sorting Control
+With Directory SDK for C
+Using the Persistent Search Control
+With Directory SDK for C
+Using the Entry Change Notification
+Control With Directory SDK for C
+Using the Virtual List View Control
+With Directory SDK for C
+Using the Manage DSA IT Control With
+Directory SDK for C
+Using Password Policy Controls With
+Directory SDK for C
+Using the Proxied Authorization Control
+With Directory SDK for C
+Using the Authorization
+Identity Bind Request Control With Directory SDK for C
+Using the
+Get Effective Rights Request Control With Directory SDK for C
+
+Using the Real
+Attributes Only Request Control With Directory SDK for C
+
+Using the Virtual
+Attributes Only Request Control With Directory SDK for C
+
+
+
+How LDAP Controls Work With Directory SDK for C
+LDAP v3, as documented in RFC 4511, 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.
+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.
+Servers can also send controls back to clients. For example, &cnDirectoryServer; can
+send a control back to a client to indicate that the client password has expired,
+or that the password is going to expire.
+
+A control specifies the following information:
+A unique object identifier (OID) as defined by the creator
+of the controlThe OID identifies the control. Table 16–1 names common OIDs.
+
+An indication of whether or not the control is critical to
+the operation
+Optional data related to the controlFor example,
+the server-side sort control needs the attributes that would be used for sorting
+search results.
+
+
+When your client includes a control in a request for an LDAP operation,
+the server can respond in one of the following ways:
+If the server supports the control, and if the control is
+appropriate, the server should make use of the control when performing the
+operation.
+
+
+If the server does not support the control type, and the control is
+not appropriate, the server should do one of the following:
+If the control is marked as critical to the operation, the
+server should not perform the operation. Instead, the server should return
+the result code LDAP_UNAVAILABLE_CRITICAL_EXTENSION.
+
+If the control is not marked as critical to the operation,
+the server should ignore the control and perform the operation.
+
+
+
+
+If you plan to use a control, make sure that the server supports the
+control. See Determining the Controls Supported by
+the Server With Directory SDK for C for details.
+Using Controls in the LDAP API
+
+&DirectorySDKForC; supports two types of controls:
+Server controls can be included in requests sent by clients
+and in responses sent by servers.
+Client controls affect the behavior of the SDK only and are
+never sent to the server.
+
+In the SDK, a control is represented by an LDAPControl structure.
+
+
+The fields in this structure represent the data in a control.
+ldctl_oid specifies the OID of the control.
+
+ldctl_value contains a berval structure
+that contains data that is associated with the control.
+ldctl_iscritical specifies whether or not
+the control is critical to the operation. LDAP_OPT_ON indicates
+that the control is critical. LDAP_OPT_OFF indicates that
+the control is not critical.
+
+The following shows the LDAPControl structure
+definition.
+LDAPControl Structure
+
+typedef struct ldapcontrol {
+ char *ldctl_oid;
+ struct berval ldctl_value;
+ char ldctl_iscritical;
+} LDAPControl;
+
+You can allocate space for the control, then create the control yourself.
+You can also call a function to create the control. For example, you can call
+the ldap_create_sort_control function to create a server-side
+sorting control. To include a control in a request, call one of the LDAP v3
+API functions, which are functions with names that end with _ext and
+_ext_s. These functions allow you to pass in an array of server
+controls and an array of client controls.
+You can also include controls in a request by specifying the array of
+controls in the LDAP_OPT_SERVER_CONTROLS option. However,
+these controls are sent to the server with every request. If the control is
+specific to a certain type of operation, you should use functions with names
+that end with _ext and _ext_s instead.
+To retrieve any controls included in a server’s response, call
+the ldap_parse_result function. You can then retrieve
+data from the returned controls yourself by checking the fields of the
+LDAPControl structure or by calling additional functions such
+as ldap_parse_sort_control.
+After working with a control, or with an array of controls, free the
+controls from memory. Call ldap_control_free or ldap_controls_free
+ function.
+Determining the Controls Supported by the Server
+With &DirectorySDKForC;
+According to LDAP v3, servers should list any controls that the server
+supports in the supportedControl attribute in the root
+DSE, which is described in Chapter 14,
+Getting Server Information With Directory SDK for C.
+The following table shows OIDs for server controls that might be referenced
+in the supportedControl attribute.
+
LDAP v3 Server
+Controls for Directory SDK for C
+
+
+
+
+OID
+
+Name in ldap.h
+
+Instructions
+
+
+
+
+
+1.2.840.113556.1.4.473, 1.2.840.113556.1.4.474
+
+
+LDAP_CONTROL_SORTREQUEST, LDAP_CONTROL_SORTRESPONSE
+
+
+Using the Server-Side Sorting Control With
+Directory SDK for C
+
+
+
+1.3.6.1.4.1.42.2.27.8.5.1
+
+LDAP_CONTROL_PASSWD_POLICY
+
+Using Password Policy Controls With Directory
+SDK for C
+
+
+
+1.3.6.1.4.1.42.2.27.9.5.2
+
+LDAP_CONTROL_GETEFFECTIVERIGHTS_REQUEST
+
+Using the Get Effective
+Rights Request Control With Directory SDK for C
+
+
+
+1.3.6.1.4.1.42.2.27.9.5.8
+
+LDAP_CONTROL_ACCOUNT_USABLE
+
+Using Password Policy Controls With Directory
+SDK for C
+
+
+
+2.16.840.1.113730.3.4.2
+
+LDAP_CONTROL_MANAGEDSAIT
+
+Using the Manage DSA IT Control With Directory
+SDK for C
+
+
+
+
+2.16.840.1.113730.3.4.3
+
+LDAP_CONTROL_PERSISTENTSEARCH
+
+Using the Persistent Search Control With Directory
+SDK for C
+
+
+
+2.16.840.1.113730.3.4.7
+
+LDAP_CONTROL_ENTRYCHANGE
+
+Using the Entry Change Notification Control
+With Directory SDK for C
+
+
+
+2.16.840.1.113730.3.4.4
+
+LDAP_CONTROL_PWEXPIRED
+
+Using Password Policy Controls With Directory
+SDK for C
+
+
+
+2.16.840.1.113730.3.4.5
+
+LDAP_CONTROL_PWEXPIRING
+
+Using Password Policy Controls With Directory
+SDK for C
+
+
+
+2.16.840.1.113730.3.4.9, 2.16.840.1.113730.3.4.10
+
+
+LDAP_CONTROL_VLVREQUEST, >>
+LDAP_CONTROL_VLVRESPONSE
+
+Using the Virtual List View Control With Directory
+SDK for C
+
+
+
+2.16.840.1.113730.3.4.12, 2.16.840.1.113730.3.4.18
+
+
+LDAP_CONTROL_PROXYAUTH,
+LDAP_CONTROL_PROXIEDAUTH
+
+Using the Proxied Authorization Control With
+Directory SDK for C
+
+
+
+2.16.840.1.113730.3.4.15, 2.16.840.1.113730.3.4.16
+
+
+LDAP_CONTROL_AUTHZID_RES, LDAP_CONTROL_AUTHZID_REQ
+
+Also known as LDAP_CONTROL_AUTH_RESPONSE, LDAP_CONTROL_AUTH_REQUEST
+
+
+Using the Authorization Identity
+Bind Request Control With Directory SDK for C
+
+
+
+2.16.840.1.113730.3.4.17
+
+LDAP_CONTROL_REAL_ATTRS_ONLY
+
+Using the Real Attributes
+Only Request Control With Directory SDK for C
+
+
+
+2.16.840.1.113730.3.4.19
+
+LDAP_CONTROL_VIRTUAL_ATTRS_ONLY
+
+Using the Virtual Attributes
+Only Request Control With Directory SDK for C
+
+
+
+
+The following sample command-line program searches for the root DSE.
+The program then prints the values of the supportedControl attribute.
+
+Searching for Supported
+Controls
+#include "ldap.h"
+static char *usage = "Usage: listctrl -h hostname -p portnumber\n";
+
+/* Associate OIDs of known controls with descriptions. */
+struct oid2desc {
+ char *oid;
+ char *desc;
+};
+static struct oid2desc oidmap[] = {
+ {LDAP_CONTROL_ACCOUNT_USABLE, "Account availability control"}
+ {LDAP_CONTROL_AUTH_REQUEST, "Authorization bind identity request"}
+ {LDAP_CONTROL_AUTH_RESPONSE, "Authorization bind identity response"}
+ {LDAP_CONTROL_ENTRYCHANGE, "Entry change notification control"}
+ {LDAP_CONTROL_GETEFFECTIVERIGHTS_REQUEST, "Get effective rights control"}
+ {LDAP_CONTROL_MANAGEDSAIT, "Manage DSA IT control"}
+ {LDAP_CONTROL_PASSWD_POLICY, "Password policy control"}
+ {LDAP_CONTROL_PERSISTENTSEARCH, "Persistent search control"}
+ {LDAP_CONTROL_PROXIEDAUTH, "Proxied authorization (version 2) control"}
+ {LDAP_CONTROL_PROXYAUTH, "Proxied authorization (version 1) control"}
+ {LDAP_CONTROL_PWEXPIRED, "Password expired control"}
+ {LDAP_CONTROL_PWEXPIRING, "Password expiring control"}
+ {LDAP_CONTROL_REAL_ATTRS_ONLY, "Real attributes only control"}
+ {LDAP_CONTROL_SORTREQUEST, "Server-side sort request control"}
+ {LDAP_CONTROL_SORTRESPONSE, "Server-side sort response control"}
+ {LDAP_CONTROL_VIRTUAL_ATTRS_ONLY, "Virtual attributes only control"}
+ {LDAP_CONTROL_VLVREQUEST, "Virtual list view request control"}
+ {LDAP_CONTROL_VLVRESPONSE, "Virtual list view response control"}
+ {NULL, NULL}
+};
+
+int
+main( int argc, char **argv )
+{
+ LDAP *ld;
+ LDAPMessage *result, *e;
+ char *hostname = NULL;
+ char **vals;
+ char *attrs[2];
+ int i, j, c, portnumber = LDAP_PORT, rc;
+ LDAPControl **serverctrls = NULL, **clntctrls = NULL;
+ /* Parse the command line arguments. */
+ while ( ( c = getopt( argc, argv, "h:p:" ) ) != -1 ) {
+ switch ( c ) {
+ case 'h':
+ hostname = strdup( optarg );
+ break;
+ case 'p':
+ portnumber = atoi( optarg );
+ break;
+ default:
+ printf( "Unsupported option: %c\n", c );
+ printf( usage );
+ exit( 1 );
+ }
+ }
+ /* By default, connect to localhost at port 389. */
+ if ( hostname == NULL || hostname[0] == NULL ) {
+ hostname = "localhost";
+ }
+ /* Initialize the connection. Use prldap_init() for IPv6. */
+ if ( (ld = ldap_init( hostname, portnumber )) == 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 retrieve only the
+ supportedControl attribute. */
+ attrs[ 0 ] = "supportedControl";
+ attrs[ 1 ] = NULL;
+ rc = ldap_search_ext_s( ld, "", LDAP_SCOPE_BASE, "(objectclass=*)",
+ attrs, 0, serverctrls, clntctrls, NULL, NULL, &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 %s:%d returned result code %d (%s).\n"
+ "This server does not support the LDAPv3 protocol.\n",
+ hostname, portnumber, rc, ldap_err2string( rc ) );
+ return( 1 );
+ break;
+ /* If any other value is returned, an error must have occurred. */
+ default:
+ ldap_perror( ld, "ldap_search_ext_s" );
+ return( 1 );
+ break;
+ }
+ /* Get the root DSE from the results.
+ Since there is only one root DSE, there
+ should be only one entry in the results. */
+ e = ldap_first_entry( ld, result );
+ /* Get and print the values of the supportedControl attribute. */
+ if (e != NULL &&
+ (vals = ldap_get_values(ld, e, "supportedControl")) != NULL ) {
+ printf( "\nControls Supported by %s:%d\n", hostname, portnumber );
+ printf( "==================================================\n" );
+ for ( i = 0; vals[i] != NULL; i++ ) {
+ printf( "%s\n", vals[i] );
+ for ( j = 0; oidmap[j].oid != NULL; j++ ) {
+ if ( !strcmp( vals[i], oidmap[j].oid )) {
+ printf( "\t%s\n", oidmap[j].desc );
+ }
+ }
+ }
+ /* Free the values allocated by ldap_get_values(). */
+ ldap_value_free( vals );
+ printf( "\n" );
+ }
+ /* Free memory allocated by ldap_search_ext_s(). */
+ ldap_msgfree( result );
+ ldap_unbind( ld );
+ return( 0 );
+}
+
+
+Using the Server-Side Sorting Control With &DirectorySDKForC;
+
+C SDK
+LDAP controls
+server-side sorting
+
+The control with OID 1.2.840.113556.1.4.473, or
+LDAP_CONTROL_SORTREQUEST as defined in the ldap.h header
+file, is a server-side sorting control. When you send a search request with
+this control to the server, the server should sort the results before sending
+the results back to you.
+The server-side sorting control is described in RFC 2891.
+Specifying the Sort Order With &DirectorySDKForC;
+To specify the sort order of the results, call the ldap_create_sort_keylist
+ function to create a sort key list from a string in the following
+format:
+[-]attr-name[:matching-rule-oid
+] …
+
+attr-name is the name of the attribute
+to sort by.You can specify a space-delimited list of attribute
+names.
+matching-rule-oid is the optional
+OID of a matching rule that you want to use for sorting.
+sn -givenname
+
+The minus sign indicates that the results should be sorted
+in reverse order for that attribute. For example, the following string specifies
+that results should be sorted by last name, sn, first in
+ascending order. If multiple entries have the same last name, these entries
+are sorted by first name, givenname, in descending order:
+
+
+Pass this string to ldap_create_sort_keylist to
+create a sort key list, which is an array of LDAPsortkey structures.
+You can use this technique to create the server-side sorting control.
+
+Creating the Server-Side Sorting Control With &DirectorySDKForC;
+Next, to create the server-side sorting control, you pass the sort key
+list, the array of LDAPsortkey structures, to the
+ldap_create_sort_control function. The function passes back a newly
+created sort control, an LDAPControlstructure that
+you can include in a search request.
+You can specify whether or not the control is critical to the search
+operation. If the control is marked as critical, but the server cannot sort
+the results, the server should not send back any entries. See Interpreting the Results of Sorting With Directory SDK for
+C for more information about the ramifications of marking the control
+as critical.
+After you call the ldap_create_sort_control function
+and create the control, free the array of LDAPsortkey structures
+by calling ldap_free_sort_keylist. When you are done
+receiving sorted results from the server, free the LDAPControl structure
+by calling ldap_control_free.
+Performing a Search With &DirectorySDKForC;
+For the server to sort the results, add the newly created server-side
+sorting control to a NULL terminated array of LDAPControl
+ structures. Pass this array to the ldap_search_ext function
+or the ldap_search_ext_s function. The server returns
+a result for the search operation. The server also returns a response control.
+The response control indicates the success or failure
+of the sort. To determine if sort was successful, use the following procedure.
+To Search With a Sort Request for Directory SDK for C
+
+Call ldap_parse_result to parse the result
+of the search operation. The function retrieves any response
+controls sent back from the server.Response controls are passed
+back in a NULL terminated array of LDAPControl structures.
+
+Pass this array of structures as an argument to ldap_parse_sort_control
+ to retrieve the LDAP result code for the sorting operation.
+If the sorting operation fails, the server can also return the name
+of the attribute that caused the failure. The ldap_parse_sort_control function
+also retrieves this name, if available.
+Free the array by calling the ldap_controls_free function
+when you are done parsing the array of response controls.The
+server can return the following result codes.
+
+LDAP_SUCCESS
+The results were sorted successfully.
+
+
+LDAP_OPERATION_ERROR
+An internal server error occurred.
+
+
+LDAP_TIMELIMIT_EXCEEDED
+The maximum time allowed for a search was exceeded before
+the server finished sorting the results.
+
+
+LDAP_STRONG_AUTH_REQUIRED
+The server refused to send back the sorted search results
+because the server requires you to use a stronger authentication method.
+
+
+LDAP_ADMINLIMIT_EXCEEDED
+The server retrieved too many entries to sort.
+
+
+LDAP_NO_SUCH_ATTRIBUTE
+The sort key list specifies an attribute that does not exist.
+
+
+LDAP_INAPPROPRIATE_MATCHING
+The sort key list specifies a matching rule that is not recognized
+or appropriate.
+
+
+LDAP_INSUFFICIENT_ACCESS
+The server did not send the sorted results because the client
+has insufficient access rights.
+
+
+LDAP_BUSY
+The server is too busy to sort the results.
+
+
+LDAP_UNWILLING_TO_PERFORM
+The server is unable to sort the results.
+
+
+LDAP_OTHER
+This general result code indicates that the server failed
+to sort the results for a reason other than the ones listed previously.
+
+
+
+
+
+
+
+Interpreting the Results of Sorting With &DirectorySDKForC;
+The following table shows the kinds of results to expect from the LDAP
+server under different situations.
+
Server
+Responses to Sorting Controls
+
+
+
+
+Does the server support the sort control?
+
+Is the sort control marked as critical?
+
+Other Conditions
+
+Results From LDAP Server
+
+
+
+
+
+Server does not support the sort control.
+
+Control is marked as critical.
+
+Not applicable
+
+The server does not send back any entries.
+
+
+
+
+Control is not marked as critical.
+
+
+The server ignores the sorting control. Instead, the server returns
+the entries unsorted.
+
+
+
+Server does support the sort control.
+
+Control is marked as critical.
+
+The server cannot sort the results by using the specified sort key list.
+
+
+The server does not send back any entries. 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.
+
+
+
+
+
+Control is not marked as critical.
+
+
+The server returns the entries unsorted. 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.
+
+
+
+
+Not applicable, might or might not be marked as critical.
+
+The server successfully sorted the entries.
+
+The server sends back the sorted entries. The server sends back the
+sorting response control. The response control specifies the result code of
+the sort attempt, LDAP_SUCCESS.
+
+
+
+
+
+The search failed for any reason.
+
+The server sends back a result code for the search operation. The server
+does not send back the sorting response control.
+
+
+
+
+
+Server-Side Sorting Control Sample Program for Directory
+SDK for C
+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.
+Applying Server—Side
+Sorting Control for Direcory SDK for C
+#include <stdio.h>
+#include "ldap.h"
+/* Change these as needed. */
+#define HOSTNAME "localhost"
+#define PORTNUMBER 389
+int
+main( int argc, char **argv )
+{
+ LDAP *ld;
+ LDAPMessage *result, *e;
+ char *attrfail, *matched = NULL, *errmsg = NULL;
+ char **vals, **referrals;
+ int rc, parse_rc, version;
+ unsigned long rcode;
+ LDAPControl *sortctrl = NULL;
+ LDAPControl *requestctrls[ 2 ];
+ LDAPControl **resultctrls = NULL;
+ LDAPsortkey **sortkeylist;
+ /* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
+ if ( (ld = ldap_init( HOSTNAME, PORTNUMBER ) ) == NULL ) {
+ perror( "ldap_init" );
+ return( 1 );
+ }
+ version = LDAP_VERSION3;
+ ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
+ /* Create a sort key list that specifies the sort order of the results.
+ Sort the results by last name first, then by first name. */
+ ldap_create_sort_keylist( &sortkeylist, "sn -givenname" );
+ /* Create the sort control. */
+ rc = ldap_create_sort_control( ld, sortkeylist, 1, &sortctrl );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr,
+ "ldap_create_sort_control: %s\n",
+ ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+ requestctrls[ 0 ] = sortctrl;
+ requestctrls[ 1 ] = NULL;
+ /* Search for all entries in Sunnyvale */
+ rc = ldap_search_ext_s( ld, "dc=example,dc=com", LDAP_SCOPE_SUBTREE,
+ "(mail=*example.com*)", NULL, 0, requestctrls,
+ NULL, NULL, 0, &result );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+ parse_rc = ldap_parse_result( ld, result, &rc, &matched,
+ &errmsg, &referrals, &resultctrls, 0 );
+ if ( parse_rc != LDAP_SUCCESS ) {
+ fprintf( stderr,
+ "ldap_parse_result: %s\n",
+ ldap_err2string( parse_rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) );
+ if ( errmsg != NULL && *errmsg != '\0' ) {
+ fprintf( stderr, "%s\n", errmsg );
+ }
+ ldap_unbind( ld );
+ return( 1 );
+ }
+ parse_rc =
+ ldap_parse_sort_control( ld, resultctrls, &rcode, &attrfail );
+ if ( parse_rc != LDAP_SUCCESS ) {
+ fprintf( stderr,
+ "ldap_parse_sort_control: %s\n",
+ ldap_err2string( parse_rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+
+ if ( rcode != LDAP_SUCCESS ) {
+ fprintf( stderr, "Sort error: %s\n", ldap_err2string( rcode ) );
+ if ( attrfail != NULL && *attrfail != '\0' ) {
+ fprintf( stderr, "Bad attribute: %s\n", attrfail );
+ }
+ ldap_unbind( ld );
+ return( 1 );
+ }
+ /* for each entry print out name + all attrs and values */
+ for ( e = ldap_first_entry( ld, result ); e != NULL;
+ e = ldap_next_entry( ld, e ) ) {
+ if ((vals = ldap_get_values( ld, e, "sn")) != NULL ) {
+ if ( vals[0] != NULL ) {
+ printf( "%s", vals[0] );
+ }
+ ldap_value_free( vals );
+ }
+ if ((vals = ldap_get_values( ld, e, "givenname")) != NULL ) {
+ if ( vals[0] != NULL ) {
+ printf( "\t%s", vals[0] );
+ }
+ ldap_value_free( vals );
+ }
+ printf( "\n" );
+ }
+ ldap_msgfree( result );
+ ldap_free_sort_keylist( sortkeylist );
+ ldap_control_free( sortctrl );
+ ldap_controls_free( resultctrls );
+ ldap_unbind( ld );
+ return( 0 );
+}
+
+
+
+Using the Persistent Search Control With &DirectorySDKForC;
+
+C SDK
+LDAP controls
+persistent search
+
+The control OID 2.16.840.1.113730.3.4.3, LDAP_CONTROL_PERSISTENTSEARCH
+ as defined in the ldap.h header file, is the
+persistent search control. A persistent search is an
+ongoing search operation that allows your LDAP client to get notification
+of changes to the directory.
+The persistent search control is described in the Internet Draft
+Persistent Search: A Simple LDAP Change Notification Mechanism.
+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. When an entry in the directory
+changes, 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 these conditions are true, the server sends
+the entry to your client.
+To create a persistent search control, call ldap_create_persistentsearch_control
+ as shown here.
+ldap_create_persistentsearch_control
+ Prototype for Directory SDK for C
+int ldap_create_persistentsearch_control( LDAP *ld,
+ int changetypes, int changesonly, int return_echg_ctls,
+ char ctl_iscritical, LDAPControl **ctrlp );
+
+
+You can specify the following information:
+changetypes specifies 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 operator, |.
+LDAP_CHANGETYPE_ADD indicates that you
+want to track added entries.
+LDAP_CHANGETYPE_DELETE indicates that you
+want to track deleted entries.
+LDAP_CHANGETYPE_MODIFY indicates that you
+want to track modified entries.
+LDAP_CHANGETYPE_MODDN indicates that you
+want to track renamed entries.
+LDAP_CHANGETYPE_ANY indicates that you
+want to track all changes to entries.
+
+
+changesonly indicates whether or not you
+want the server to return all entries that initially matched the search criteria.
+Use 0 to return all entries, or non zero to return only
+the entries that change.
+return_echg_ctls indicates whether or not
+you want entry change notification controls included with every modified entry
+returned by the server. Use a non zero value to return entry change notification
+controls.
+
+You can use this control in conjunction with an entry change notification
+control. See Using the Entry Change Notification
+Control With Directory SDK for C for details.
+The ldap_create_persistentsearch_control function
+passes back an LDAPControl structure that represents
+the control in the ctrlp parameter. You can add the newly
+created control to a NULL terminated array of LDAPControl
+ structures. Pass this array to the ldap_search_ext function.
+
+To end the persistent search, call the ldap_abandon_ext function.
+Alternatively, call the ldap_unbind function to disconnect
+from the server.
+The example provided in examples/psearch.c shows
+how to perform a persistent search.
+Using the Entry Change Notification Control With &DirectorySDKForC;
+
+C SDK
+LDAP controls
+entry change notification
+
+The control with OID 2.16.840.1.113730.3.4.7, LDAP_CONTROL_ENTRYCHANGE
+ as defined in the ldap.h header file, is the
+entry change notification control. This control contains additional information
+about the change to the entry. The information includes the type of change,
+and the change number, which corresponds to an item in the server’s
+change log. If the entry was renamed, the control also contains the old DN
+of the entry in the change log.
+You use this control in conjunction with a persistent search control.
+You can specify the preference for returning entry change notification controls.
+The server then includes an entry change notification control with each entry
+found by the search. To retrieve and parse an entry change notification control
+included with an entry, follow this procedure.
+To Use Entry Change Notification With Directory SDK for C
+
+Pass the LDAPMessage structure that represents
+an entry to the ldap_get_entry_controls function.
+
+Pass the entry change notification control to the ldap_parse_entrychange_control
+ function.For more information, see Using the Persistent Search Control With Directory SDK for
+C.
+
+
+
+Using the Virtual List View Control With &DirectorySDKForC;
+
+C SDK
+LDAP controls
+virtual list view
+
+The control with OID 2.16.840.1.113730.3.4.9, LDAP_CONTROL_VLVREQUEST
+ as defined in the ldap.h header file, is a virtual
+list view control. When you send a search request with this control and a
+server-side sorting control, the server should sort the results. The server
+should then return the specified subset of entries back to your client.
+The virtual list view control is described in the Internet Draft,
+LDAP Extensions for Scrolling View Browsing of Search Results.
+
+Using the Manage DSA IT Control With &DirectorySDKForC;
+
+C SDK
+LDAP controls
+manage DSA IT
+
+The control with OID 2.16.840.1.113730.3.4.2, LDAP_CONTROL_MANAGEDSAIT
+ as defined in the ldap.h header file, is the
+manage DSA IT control. You can use this control to manage search references
+in the directory. To create this control, create an LDAPControl structure
+and set the ldctl_oid field to 2.16.840.1.113730.3.4.2
+.
+When you add this control to the array of LDAPControl structures
+for ldap_search_ext or ldap_modify_ext,
+the server treats search references as ordinary entries. 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.
+The manage DSA IT control is described in RFC 2891.
+
+Using Password Policy Controls With &DirectorySDKForC;
+&cnDirectoryServer; offers three password policy response controls sent
+back to a client that performs a bind operation. The server also offers an
+account availability control that does not require a bind to return status
+about a client account.
+Using Password Policy Expiration Controls With
+Directory SDK for C
+
+&cnDirectoryServer; uses two server response controls to send information
+back to a client after an LDAP bind operation.
+The control with OID 2.16.840.1.113730.3.4.4,
+LDAP_CONTROL_PWEXPIRED, is the expired password control.This
+control serves when the server requires users to change passwords when first
+logging in, and after password reset. After the first login, and after password
+reset, the server sends this control to indicate that the client needs to
+change the password immediately. At this point, the only operation that the
+client can perform is to change the user’s password. If the client requests
+any other operation, the server sends back an LDAP_UNWILLING_TO_PERFORM
+ result code with an expired password control.
+The control with OID 2.16.840.1.113730.3.4.5,
+LDAP_CONTROL_PWEXPIRING, is the password expiration warning control.
+This control is used if the server is configured to expire user passwords
+after a certain amount of time. The server sends this control back to the
+client if the client binds with a password that is to expire soon . The
+ldctl_value field of the LDAPControl structure
+specifies the number of seconds before the password expires.
+
+To Use Password Policy Expiration Controls With Directory SDK
+for C
+
+C SDK
+LDAP controls
+password policy
+
+
+Call ldap_simple_bind to send a request for
+an asynchronous bind operation.
+Call ldap_result to get the results of the
+operation.
+Call ldap_parse_result to parse the result.
+The function retrieves the server response controls from the result
+as an array of LDAPControl structures.
+Check the ldctl_oid field to determine
+the OID of the control and the ldctl_value field
+for any data that is included in the control.
+
+
+
+Using the Account Availability Control
+With Directory SDK for C
+&cnDirectoryServer; offers an account availability control that does
+not require a bind to return status about a client account. The account availability
+control is assigned OID 1.3.6.1.4.1.42.2.27.9.5.8, LDAP_CONTROL_ACCOUNT_USABLE
+. This control allows the client to read information about an account
+without having to bind as the user having that account.
+To Use the Account Availability Control
+With Directory SDK for C
+
+C SDK
+LDAP controls
+account status
+
+
+Allocate an LDAPuserstatus structure
+to hold the values for the account status.
+Create an account status control with ldap_create_userstatus_control
+.
+Read the entry for which you want account status, passing in the
+control as part of the search.
+Get the controls on the entry that the search returns.
+Pass the LDAPuserstatus structure to
+ldap_parse_userstatus_control to fill the structure.
+Read account status information from the LDAPuserstatus structure.
+
+
+
+Checking Account Status With Directory SDK for C
+This example displays status for Barbara Jensen's account.
+/*
+ * Get account status using the account status control.
+ */
+
+#include "examples.h"
+
+int
+main( int argc, char **argv )
+{
+ LDAPuserstatus *status;
+ int version;
+ LDAP *ld;
+ int rc;
+ LDAPControl *status_ctrl = NULL;
+ LDAPControl *requestctrls[ 2 ];
+ LDAPMessage *result;
+ char *matched = NULL;
+ char *errmsg = NULL;
+ char **referrals;
+ LDAPControl **resultctrls = NULL;
+ LDAPMessage *msg;
+ LDAPControl **ectrls = NULL;
+
+ /* Allocate the LDAPuserstatus structure. */
+ if ( !( status = (LDAPuserstatus*)malloc(sizeof(LDAPuserstatus)) ) ) {
+ perror("malloc");
+ 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 );
+ }
+
+ /* Create an account status control. */
+ rc = ldap_create_userstatus_control( ld, 1, &status_ctrl );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_create_userstatus_control: %s\n",
+ ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+ requestctrls[ 0 ] = status_ctrl;
+ requestctrls[ 1 ] = NULL;
+
+ /* Authenticate to the directory as a user. */
+ if ( ldap_simple_bind_s( ld, USER_DN, USER_PW ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_simple_bind_s" );
+ return( 1 );
+ }
+
+ /* Read the account entry using the control. */
+ rc = ldap_search_ext_s( ld, ENTRYDN, LDAP_SCOPE_BASE,
+ "(objectclass=*)", NULL, 0, requestctrls, NULL, NULL, 0, &result );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+
+ /* Show the account status. */
+ rc = ldap_parse_result( ld, result, &rc, &matched, &errmsg,
+ &referrals, &resultctrls, 0 );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_parse_result: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+
+ for ( msg = ldap_first_message( ld, result );
+ msg != NULL;
+ msg = ldap_next_message ( ld, msg) ) {
+ if ( ldap_msgtype( msg ) != LDAP_RES_SEARCH_ENTRY ) continue;
+ if ( ldap_get_entry_controls( ld, msg, &ectrls ) != LDAP_SUCCESS ) {
+ ldap_perror ( ld, "ldap_get_entry_controls" );
+ } else {
+ rc = ldap_parse_userstatus_control( ld, ectrls, status );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr,
+ "ldap_parse_userstatus_control: %s\n",
+ ldap_err2string( rc ) );
+ } else {
+ printf( "DN: %s\n", ENTRYDN );
+ if ( LDAP_US_ACCOUNT_USABLE == status->us_available ) {
+ printf( " Account is usable:\tY\n" );
+ } else {
+ printf( " Account is usable:\tN\n" );
+ }
+ printf( " Password expires in:\t%ld s\n",
+ status->us_expire );
+ if ( LDAP_US_ACCOUNT_INACTIVE == status->us_inactive ) {
+ printf( " Account is locked:\tY\n" );
+ } else {
+ printf( " Account is locked:\tN\n" );
+ }
+ if ( LDAP_US_ACCOUNT_RESET == status->us_reset ) {
+ printf( " Password was reset:\tY\n" );
+ } else {
+ printf( " Password was reset:\tN\n" );
+ }
+ if ( LDAP_US_ACCOUNT_EXPIRED == status->us_expired ) {
+ printf( " Password has expired:\tY\n" );
+ } else {
+ printf( " Password has expired:\tN\n" );
+ }
+ printf( " Grace logins left:\t%d\n",
+ status->us_remaining );
+ printf( " Account unlocks in:\t%d s\n",
+ status->us_seconds );
+ }
+ }
+ }
+
+ ldap_msgfree( result );
+ ldap_control_free( status_ctrl );
+ ldap_controls_free( resultctrls );
+ ldap_unbind( ld );
+ return( 0 );
+}
+
+
+
+Using the Password Policy Control With
+Directory SDK for C
+&cnDirectoryServer; offers a password policy control to retrieve information
+about the password policy that applies to the account used to bind to the
+server. The password policy control is assigned OID 1.3.6.1.4.1.42.2.27.8.5.1
+, LDAP_CONTROL_PASSWD_POLICY.
+To Use the Password Policy Control
+With Directory SDK for C
+
+C SDK
+LDAP controls
+password policy
+
+
+Allocate an LDAPpwdpolicy structure to
+hold the values for the account status.
+Create a password policy control with ldap_create_pwdpolicy_control
+.
+Bind sending the password policy control.
+Perform a bind, a modify, an add, a compare, or an extended operation,
+getting the result controls.
+Pass the LDAPpwdpolicy structure to
+ldap_parse_pwdpolicy_control to fill the structure.
+Read password policy information from the LDAPpwdpolicy structure.
+
+
+
+Checking Password Policy for Directory SDK for C
+This example displays the password policy that governs Barbara Jensen's
+account retrieved during the bind operation.
+/*
+ * Get password policy information using the password policy control.
+ */
+
+#include "examples.h"
+
+int
+main( int argc, char **argv )
+{
+ LDAPpwdpolicy *policy;
+ int version;
+ LDAP *ld;
+ int rc;
+ LDAPControl *pwpctrl = NULL;
+ LDAPControl *requestctrls[ 2 ];
+ int msgid;
+ LDAPMessage *result;
+ int parse_rc;
+ char *matched = NULL;
+ char *errmsg = NULL;
+ char **referrals;
+ LDAPControl **resultctrls = NULL;
+
+ /* Allocate the LDAPpwdpolicy structure. */
+ if ( !( policy = (LDAPpwdpolicy*)malloc(sizeof(LDAPpwdpolicy) ) ) ) {
+ perror("malloc");
+ 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 );
+ }
+
+ /* Create a password policy control. */
+ rc = ldap_create_pwdpolicy_control( ld, 1, &pwpctrl);
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_create_pwdpolicy_control: %s\n",
+ ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+ requestctrls[ 0 ] = pwpctrl;
+ requestctrls[ 1 ] = NULL;
+
+ /* Use the password policy control for the bind. */
+ rc = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, &pwpctrl );
+ if ( rc != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_set_option" );
+ return ( 1 );
+ }
+
+ /* Authenticate to the directory, checking for result controls. */
+ msgid = ldap_simple_bind( ld, ENTRYDN, ENTRYPW );
+ if ( msgid < 0 ) {
+ fprintf( stderr, "ldap_simple_bind: %s\n", ldap_err2string( rc ) );
+ if ( errmsg != NULL && errmsg != '\0' ) {
+ fprintf( stderr, "%s\n", errmsg );
+ }
+ ldap_unbind( ld );
+ return ( 1 );
+ }
+
+ rc = ldap_result( ld, msgid, LDAP_MSG_ALL, NULL, &result );
+ if ( rc < 0 ) {
+ rc = ldap_get_lderrno( ld, NULL, NULL );
+ fprintf( stderr, "ldap_result: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return ( 1 );
+ }
+
+ parse_rc = ldap_parse_result( ld, result, &rc, &matched, &errmsg,
+ &referrals, &resultctrls, 0 );
+ if ( parse_rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_parse_result: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return ( 1 );
+ }
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_simple_bind: %s\n", ldap_err2string( rc ) );
+ if ( errmsg != NULL && errmsg != '\0' ) {
+ fprintf( stderr, "%s\n", errmsg );
+ }
+ }
+ if ( resultctrls == NULL ) {
+ fprintf( stderr, "No pwp result control from server.\n" );
+ ldap_unbind( ld );
+ return ( 1 );
+ }
+
+ /* Show the password policy information. */
+ parse_rc = ldap_parse_pwdpolicy_control( ld, resultctrls, policy );
+ if ( parse_rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_parse_pwdpolicy_control: %s\n",
+ ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return ( 1 );
+ }
+
+ printf( "DN: %s\n", ENTRYDN );
+ switch ( policy->pp_warning ) {
+ case LDAP_PP_WARNING_NONE:
+ printf( " No warnings\n" );
+ break;
+ case LDAP_PP_WARNING_EXP:
+ printf( " Password expires in: %d s\n", policy->pp_warning_info );
+ break;
+ case LDAP_PP_WARNING_GRACE:
+ printf( " Grace logins left: %d", policy->pp_warning_info );
+ break;
+ default: printf( " Unrecognized password policy warning\n" ); break;
+ }
+ switch ( policy->pp_error ) {
+ case LDAP_PP_ERROR_NONE:
+ printf( " No errors\n" );
+ break;
+ case LDAP_PP_ERROR_EXPIRED:
+ printf( " Password has expired, and must be reset.\n" );
+ break;
+ case LDAP_PP_ERROR_LOCKED:
+ printf( " Account is locked.\n" );
+ break;
+ case LDAP_PP_ERROR_MUSTCHANGE:
+ printf( " Password has been reset, and must be changed.\n" );
+ break;
+ case LDAP_PP_ERROR_NOTMOD:
+ printf( " This user may not change the password.\n" );
+ break;
+ case LDAP_PP_ERROR_OLDPASSWD:
+ printf( " Old password must be supplied for this operation.\n" );
+ break;
+ case LDAP_PP_ERROR_NOQUALITY:
+ printf( " Password does not pass quality check.\n" );
+ break;
+ case LDAP_PP_ERROR_TOOSHORT:
+ printf( " Password is too short.\n" );
+ break;
+ case LDAP_PP_ERROR_MINAGE:
+ printf( " Password is too new to be modified already.\n" );
+ break;
+ case LDAP_PP_ERROR_INHISTORY:
+ printf( " Password has already been used.\n" );
+ break;
+ default: printf( " Unrecognized password policy error\n" ); break;
+ }
+
+ ldap_msgfree( result );
+ ldap_control_free( pwpctrl );
+ ldap_controls_free( resultctrls );
+ ldap_unbind( ld );
+ return( 0 );
+}
+
+
+
+
+Using the Proxied Authorization Control With &DirectorySDKForC;
+
+C SDK
+LDAP controls
+proxied authorization control
+
+Proxied authorization is an extension to LDAP v3 that allows a bound
+client to assume the identity of another directory entity without rebinding.
+The rebind allows the client to perform operations as if it were bound as
+the proxied directory entity. All directory access, including read, write,
+search, compare, delete, and add operations, is supported by proxied authorization.
+For example, suppose a client is bound as uid=bjensen,ou=Engineering,dc=example,dc=com
+. The user bjensen does not have the right to
+search the ou=Marketing,dc=example,dc=com tree. However,
+uid=lboyd,ou=Marketing,dc=example,dc=com does have rights to search
+the Marketing tree, and lboyd grants proxy rights to
+bjensen. In this case, bjensen can bind as herself,
+assume the identity of lboyd, and then search the Marketing
+tree.
+This feature is intended as a performance and administrative benefit
+for certain types of directory usage. Specifically, applications that allow
+many clients to access directory data without rebinding as another directory
+entity might use this feature.
+Proxy Right for Directory SDK for C
+Proxied authorization adds an additional access right: proxy.
+If an entry grants the proxy right, then the entity to which that right is
+granted can assume the identity of the granting entity. For example, to allow
+uid=bjensen the right to proxy as uid=lboyd,
+add the Proxy Right access control instruction (ACI) as shown in the following
+example. This ACI allows bjensen to assume the identity
+of lboyd for all directory operations. The ACI gives
+bjensen permission to do to the directory whatever lboyd has
+permission to do.
+Proxy Right ACI
+aci: (target = "ldap:///uid=lboyd,ou=Marketing,dc=example,dc=com")
+ (targetattr=*)
+ (version 3.0; aci "grant bjensen the right to proxy as lboyd";
+ allow(proxy)
+ userdn="ldap:///uid=bjensen,ou=Engineering,dc=example,dc=com";)
+
+
+Proxy Authorization Control With Directory SDK for
+C
+To support proxy authorization, an extension to LDAP v3, the proxy authorization
+control has been added to &DirectorySDKForC; in the form of the ldap_create_proxyauth_control
+ function. You use this function to create the control that allows
+a bound entity to assume the identity of another directory entry.
+Proxy authorization is an optional LDAP server feature. Proxy authorization
+might not be supported on all LDAP servers. You should call the proxy authorization
+control function only when interacting with LDAP servers that support this
+LDAP v3 extension. You can check on the support of this control by looking
+at the root DSE supportedControl attribute. For example,
+the following command uses the ldapsearch utility to display
+the root DSE:
+$ ldapsearch -h localhost -p 389 -b "" -s base "(objectclass=*)"
+For the control to work, the server to connect to must support the server
+control for Proxy Authorization, OID 2.16.840.1.113730.3.4.12.
+This control is LDAP_CONTROL_PROXYAUTH as defined in the
+ldap.h header file.
+Proxy Authorization Sample Program for Directory
+SDK for C
+The following sample program creates an LDAP connection, sets the Proxy
+Authorization control, binds to the directory, and then performs a search
+operation using the Proxy Authorization control.
+Program to use Proxy Authorization
+Control With Directory SDK for C
+#include "ldap.h"
+
+int version;
+LDAP *ld;
+LDAPControl *requestctrls[ 2 ];
+LDAPControl *pactrl = NULL;
+
+/* Customize the following host and bind information for your site. */
+int port=389;
+char *host="directory.example.com";
+char *baseDN="dc=example,dc=com";
+
+/* Proxied auth specific information.
+ proxyDN is the entity that will be proxied.
+ bindDN and bindpw is for the bind entity that will use the proxyDN. */
+char *proxyDN = "uid=lboyd,ou=marketing,dc=example,dc=com";
+char *bindDN = "uid=bjensen,ou=engineering,dc=example,dc=com";
+char *bindpw = "password";
+
+/* Do general LDAP init stuff */
+/* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
+if ( (ld = ldap_init( host, port ) ) == NULL ) {
+ printf("ldap_init did not return a conn handle.\n");
+ return;
+ }
+/* set version to ldap version 3 */
+version = LDAP_VERSION3;
+ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
+
+/* authenticate to the directory */
+if ( ldap_simple_bind_s( ld, bindDN, bindpw ) != LDAP_SUCCESS ) {
+ printf("ldap_simple_bind_s failed");
+ return (-1);
+}
+
+/* create the Proxy Authorization control */
+if ( ldap_create_proxyauth_control( ld, proxyDN, 1, &pactrl ) ) {
+ printf("ldap_create_proxyauth_control failed.\n");
+ if ( ldap_unbind( ld ) != LDAP_SUCCESS ) {
+ printf("ldap_unbind failed\n");
+ }
+ return(-1);
+}
+
+requestctrls[ 0 ] = pactrl;
+requestctrls[ 1 ] = NULL;
+
+/* Perform the search using the control */
+printf("Searching for %s with the proxy auth control.\n", proxyDN);
+if ( ldap_search_ext_s( ld, proxyDN, LDAP_SCOPE_SUBTREE, "(objectclass=*)",
+ NULL, 0, requestctrls, NULL, NULL, LDAP_NO_LIMIT, &results ) !=
+ LDAP_SUCCESS ) {
+ printf("ldap_search_ext failed.\n");
+ printf("Something is wrong with proxied auth.\n");
+} else {
+ print_search_results(ld, results);
+}
+
+
+
+Using the Authorization Identity Bind
+Request Control With &DirectorySDKForC;
+
+C SDK
+LDAP controls
+authorization identity
+
+The control with OID 2.16.840.1.113730.3.4.16,
+LDAP_CONTROL_AUTHZID_REQ, is the authorization identity bind request
+control. This control lets you request the authorization ID when binding to
+the server.
+To Retrieve the Authorization ID
+
+&cnDirectoryServer; supports the authorization identity bind request
+and response controls defined in RFC 3829. The server also allows you to retrieve the authorization
+identity value as a string.
+
+Create an authorization identity request control using the
+ldap_create_authzid_control function.
+Bind sending the authorization identity request control.
+
+Read the authorization identity from the response control using
+the ldap_parse_authzid_control function.
+
+
+Retrieving the Authorization ID
+This example gets the authorization ID for Barbara Jensen
+/*
+ * Get the authorization ID for an operation.
+ */
+
+#include "examples.h"
+
+int
+main( int argc, char **argv )
+{
+ int version;
+ LDAP *ld;
+ int rc;
+ LDAPControl *authzidctrl = NULL;
+ LDAPControl *requestctrls[ 2 ];
+ int msgid;
+ LDAPMessage *result;
+ int parse_rc;
+ char *matched = NULL;
+ char *errmsg = NULL;
+ char **referrals;
+ LDAPControl **resultctrls = NULL;
+ 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 );
+ }
+
+ /* Create a authorization ID control. */
+ rc = ldap_create_authzid_control( ld, 1, &authzidctrl );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_create_authzid_control: %s\n",
+ ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+ requestctrls[ 0 ] = authzidctrl;
+ requestctrls[ 1 ] = NULL;
+
+ /* Use the authorization ID control for the bind. */
+ rc = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, &authzidctrl );
+ if ( rc != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_set_option" );
+ return ( 1 );
+ }
+
+ /* Authenticate to the directory, checking for result controls. */
+ msgid = ldap_simple_bind( ld, ENTRYDN, ENTRYPW );
+ if ( msgid < 0 ) {
+ fprintf( stderr, "ldap_simple_bind: %s\n", ldap_err2string( rc ) );
+ if ( errmsg != NULL && errmsg != '\0' ) {
+ fprintf( stderr, "%s\n", errmsg );
+ }
+ ldap_unbind( ld );
+ return ( 1 );
+ }
+
+ rc = ldap_result( ld, msgid, LDAP_MSG_ALL, NULL, &result );
+ if ( rc < 0 ) {
+ rc = ldap_get_lderrno( ld, NULL, NULL );
+ fprintf( stderr, "ldap_result: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return ( 1 );
+ }
+
+ parse_rc = ldap_parse_result( ld, result, &rc, &matched, &errmsg,
+ &referrals, &resultctrls, 0 );
+ if ( parse_rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_parse_result: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return ( 1 );
+ }
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_simple_bind: %s\n", ldap_err2string( rc ) );
+ if ( errmsg != NULL && errmsg != '\0' ) {
+ fprintf( stderr, "%s\n", errmsg );
+ }
+ }
+ if ( resultctrls == NULL ) {
+ fprintf( stderr, "No result control from server.\n" );
+ ldap_unbind( ld );
+ return ( 1 );
+ }
+
+ /* Show the authorization ID. */
+ parse_rc = ldap_parse_authzid_control( ld, resultctrls, &authzid );
+ if ( parse_rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_parse_authzid_control: %s\n",
+ ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return ( 1 );
+ }
+
+ printf( "DN: %s\n", ENTRYDN );
+ printf( "Authz ID: %s\n", authzid );
+
+ ldap_msgfree( result );
+ ldap_control_free( authzidctrl );
+ ldap_controls_free( resultctrls );
+ ldap_unbind( ld );
+ return( 0 );
+}
+
+
+
+Using the Get Effective Rights
+Request Control With &DirectorySDKForC;
+
+C SDK
+LDAP controls
+get effective rights
+
+The control with OID 1.3.6.1.4.1.42.2.27.9.5.2,
+LDAP_CONTROL_GETEFFECTIVERIGHTS_REQUEST, is the get effective rights
+request control. This control lets you request information about the effective
+access rights a user has, by performing a search for the aclRights and
+aclRightsInfo attributes.
+To Get Effective Rights
+
+Create a get effective rights request control using the ldap_create_geteffectiveRights_control
+ function.
+Perform a search with the control, requesting the aclRights and
+aclRightsInfo attributes.
+Read the values of the attributes for the effective rights information.
+
+
+
+Getting Effective Rights
+This example gets effective rights for Kirsten Vaughan.
+/*
+ * Get effective rights for another user.
+ */
+
+#include "examples.h"
+
+int
+main( int argc, char **argv )
+{
+ int version;
+ LDAP *ld;
+ int rc;
+ LDAPControl *gerctrl = NULL;
+ LDAPControl *requestctrls[ 2 ];
+ char *authzid;
+ char **attrlist;
+ LDAPMessage *result;
+ LDAPMessage *entry;
+ char *attr;
+ BerElement *ber;
+ char **vals;
+ int i;
+
+ /* 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 as a user. */
+ if ( ldap_simple_bind_s( ld, USER_DN, USER_PW ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_simple_bind_s" );
+ return( 1 );
+ }
+
+ /* Create a get effective rights control. */
+ authzid = "dn: uid=kvaughan,ou=people,dc=example,dc=com";
+ if ( !( attrlist = (char**)malloc(sizeof(char * [ 2 ]) ) ) ) {
+ perror( "malloc" );
+ ldap_unbind( ld );
+ return ( 1 );
+ }
+ attrlist[ 0 ] = "aclRights";
+ attrlist[ 1 ] = NULL;
+ rc = ldap_create_geteffectiveRights_control( ld, authzid,
+ (const char **)&attrlist, 1, &gerctrl );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_create_geteffectiveRights_control: %s\n",
+ ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+ requestctrls[ 0 ] = gerctrl;
+ requestctrls[ 1 ] = NULL;
+
+ /* Read an entry using the control. */
+ rc = ldap_search_ext_s( ld, ENTRYDN, LDAP_SCOPE_BASE,
+ "(objectclass=*)", attrlist, 0, requestctrls,
+ NULL, NULL, 0, &result );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+
+ /* Examine the entry for effective rights. */
+ printf( "Bind DN: %s\n", ENTRYDN );
+ printf( "Authz ID: %s\n", authzid );
+ printf( "***Rights***\n" );
+ for ( entry = ldap_first_entry( ld, result );
+ entry != NULL;
+ entry = ldap_next_entry( ld, entry ) ) {
+ for ( attr = ldap_first_attribute( ld, entry, &ber );
+ attr != NULL;
+ attr = ldap_next_attribute ( ld, entry, ber) ) {
+ if ( (vals = ldap_get_values( ld, entry, attr ) ) != NULL) {
+ for ( i = 0; vals[i] != NULL; ++i ) {
+ printf( "%s: %s\n", attr, vals[i] );
+ }
+ ldap_value_free( vals );
+ }
+ ldap_memfree( attr );
+ }
+ if ( ber != NULL ) {
+ ber_free( ber, 0 );
+ }
+ }
+ printf( "\n" );
+
+ ldap_msgfree( result );
+ ldap_control_free( gerctrl );
+ ldap_unbind( ld );
+ return( 0 );
+}
+
+
+When you compile and run this sample program against &cnDirectoryServer; with
+a suffix that contains data from Example.ldif, the server
+produces output similar to the following. Lines are wrapped for readability.
+Bind DN: uid=bjensen, ou=People, dc=example,dc=com
+Authz ID: dn: uid=kvaughan,ou=people,dc=example,dc=com
+***Rights***
+aclRights;entryLevel: add:1,delete:1,read:1,write:1,proxy:0
+aclRights;attributeLevel;: search:1,read:1,compare:1,write:1,
+ selfwrite_add:1,selfwrite_delete:1,proxy:0
+aclRights;attributeLevel;dn: uid=kvaughan,ou=people,dc=example,dc=com:
+ search:1,read:1,compare:1,write:1,selfwrite_add:1,selfwrite_delete:1,
+ proxy:0
+aclRights;attributeLevel;@c : search:1,read:1,compare:1,write:1,
+ selfwrite_add:1,selfwrite_delete:1,proxy:0
+See your server documentation for information about aclRights
+ and aclRightsInfo values.
+
+
+Using the Real Attributes Only
+Request Control With &DirectorySDKForC;
+
+C SDK
+LDAP controls
+real attributes only
+
+The control with OID 2.16.840.1.113730.3.4.17,
+LDAP_CONTROL_REAL_ATTRS_ONLY, is the real attributes only request
+control. This control lets you convey to the server to return only real attributes,
+attributes that are stored by the directory, during a search.
+To retrieve only virtual attributes, see Using the Virtual Attributes Only
+Request Control With Directory SDK for C.
+To Retrieve Only Real Attributes
+
+Create an LDAPControl structure with
+the OID defined using LDAP_CONTROL_REAL_ATTRS_ONLY.
+
+Pass the control in to the server with the search request.
+
+Free the control when finished.
+
+
+Retrieving Only Real Attributes
+This example relies on sample data from Example-roles.ldif.
+
+/*
+ * Use the control to get only real attributes.
+ * First load suffix data from Example-roles.ldif.
+ */
+
+#include "examples.h"
+
+int
+main( int argc, char **argv )
+{
+ LDAPControl *ctrl = NULL;
+ LDAPControl *requestctrls[ 2 ];
+ char **attrlist;
+ int version;
+ LDAP *ld;
+ char *target;
+ int rc;
+ LDAPMessage *result;
+ LDAPMessage *entry;
+ char *dn;
+ char *attr;
+ BerElement *ber;
+ char **vals;
+ int i;
+
+ /* Prepare a real attributes only request control. */
+ if ( !(ctrl = (LDAPControl *)malloc(sizeof(LDAPControl))) ) {
+ perror( "malloc" );
+ return( 1 );
+ }
+ ctrl->ldctl_oid = strdup( LDAP_CONTROL_REAL_ATTRS_ONLY );
+ ctrl->ldctl_iscritical = 1;
+ requestctrls[ 0 ] = ctrl;
+ requestctrls[ 1 ] = NULL;
+
+ /* Create a list of attributes to retrieve. */
+ if ( !( attrlist = (char**)malloc(sizeof(char * [ 3 ]) ) ) ) {
+ perror( "malloc" );
+ return ( 1 );
+ }
+ attrlist[ 0 ] = "cn"; /* Real attribute */
+ attrlist[ 1 ] = "nsrole"; /* Virtual attribute */
+ attrlist[ 2 ] = NULL;
+
+ /* 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 to read an entry. */
+ if ( ldap_simple_bind_s( ld, USER_DN, USER_PW ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_simple_bind_s" );
+ return( 1 );
+ }
+
+ /* Read an entry using the control. */
+ target = "uid=kvaughan,ou=people,dc=example,dc=com";
+ rc = ldap_search_ext_s( ld, target, LDAP_SCOPE_BASE, "(objectclass=*)",
+ attrlist, 0, requestctrls, NULL, NULL, 0, &result );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+
+ /* Examine the results. */
+ for ( entry = ldap_first_entry( ld, result );
+ entry != NULL;
+ entry = ldap_next_entry( ld, entry ) ) {
+ if ( (dn = ldap_get_dn( ld, entry )) != NULL ) {
+ printf( "dn: %s\n", dn );
+ ldap_memfree( dn );
+ }
+ for ( attr = ldap_first_attribute( ld, entry, &ber );
+ attr != NULL;
+ attr = ldap_next_attribute ( ld, entry, ber) ) {
+ if ( (vals = ldap_get_values( ld, entry, attr ) ) != NULL) {
+ for ( i = 0; vals[i] != NULL; ++i ) {
+ printf( "%s: %s\n", attr, vals[i] );
+ }
+ ldap_value_free( vals );
+ }
+ ldap_memfree( attr );
+ }
+ if ( ber != NULL ) {
+ ber_free( ber, 0 );
+ }
+ }
+ printf( "\n" );
+
+ ldap_msgfree( result );
+ ldap_control_free( ctrl );
+ ldap_unbind( ld );
+ return( 0 );
+}
+When you compile and run this sample program against &cnDirectoryServer; with
+a suffix that contains data from Example-roles.ldif,
+the server produces output similar to this:
+dn: uid=kvaughan, ou=People, dc=example,dc=com
+cn: Kirsten Vaughan
+
+
+
+Using the Virtual Attributes
+Only Request Control With &DirectorySDKForC;
+
+C SDK
+LDAP controls
+virtual attributes only
+
+The control with OID 2.16.840.1.113730.3.4.19,
+LDAP_CONTROL_VIRTUAL_ATTRS_ONLY, is the virtual attributes only
+request control. This control lets you convey to the server to return only
+virtual attributes during a search. Virtual attribute values are not stored
+by the directory, but instead are generated on request.
+To retrieve only real attributes, see Using the Real Attributes Only Request
+Control With Directory SDK for C.
+To Retrieve Only Virtual Attributes
+
+Create an LDAPControl structure with
+the OID defined using LDAP_CONTROL_VIRTUAL_ATTRS_ONLY.
+
+Pass the control in to the server with the search request.
+
+Free the control when finished.
+
+
+Retrieving Only Virtual Attributes
+This example relies on sample data from Example-roles.ldif.
+
+/*
+ * Use the control to get only virtual attributes.
+ * First load suffix data from Example-roles.ldif.
+ */
+
+#include "examples.h"
+
+int
+main( int argc, char **argv )
+{
+ LDAPControl *ctrl = NULL;
+ LDAPControl *requestctrls[ 2 ];
+ char **attrlist;
+ int version;
+ LDAP *ld;
+ char *target;
+ int rc;
+ LDAPMessage *result;
+ LDAPMessage *entry;
+ char *dn;
+ char *attr;
+ BerElement *ber;
+ char **vals;
+ int i;
+
+ /* Prepare a virtual attributes only request control. */
+ if ( !(ctrl = (LDAPControl *)malloc(sizeof(LDAPControl))) ) {
+ perror( "malloc" );
+ return( 1 );
+ }
+ ctrl->ldctl_oid = strdup( LDAP_CONTROL_VIRTUAL_ATTRS_ONLY );
+ ctrl->ldctl_iscritical = 1;
+ requestctrls[ 0 ] = ctrl;
+ requestctrls[ 1 ] = NULL;
+
+ /* Create a list of attributes to retrieve. */
+ if ( !( attrlist = (char**)malloc(sizeof(char * [ 3 ]) ) ) ) {
+ perror( "malloc" );
+ return ( 1 );
+ }
+ attrlist[ 0 ] = "cn"; /* Real attribute */
+ attrlist[ 1 ] = "nsrole"; /* Virtual attribute */
+ attrlist[ 2 ] = NULL;
+
+ /* 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 to read an entry. */
+ if ( ldap_simple_bind_s( ld, USER_DN, USER_PW ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_simple_bind_s" );
+ return( 1 );
+ }
+
+ /* Read an entry using the control. */
+ target = "uid=kvaughan,ou=people,dc=example,dc=com";
+ rc = ldap_search_ext_s( ld, target, LDAP_SCOPE_BASE, "(objectclass=*)",
+ attrlist, 0, requestctrls, NULL, NULL, 0, &result );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+
+ /* Examine the results. */
+ for ( entry = ldap_first_entry( ld, result );
+ entry != NULL;
+ entry = ldap_next_entry( ld, entry ) ) {
+ if ( (dn = ldap_get_dn( ld, entry )) != NULL ) {
+ printf( "dn: %s\n", dn );
+ ldap_memfree( dn );
+ }
+ for ( attr = ldap_first_attribute( ld, entry, &ber );
+ attr != NULL;
+ attr = ldap_next_attribute ( ld, entry, ber) ) {
+ if ( (vals = ldap_get_values( ld, entry, attr ) ) != NULL) {
+ for ( i = 0; vals[i] != NULL; ++i ) {
+ printf( "%s: %s\n", attr, vals[i] );
+ }
+ ldap_value_free( vals );
+ }
+ ldap_memfree( attr );
+ }
+ if ( ber != NULL ) {
+ ber_free( ber, 0 );
+ }
+ }
+ printf( "\n" );
+
+ ldap_msgfree( result );
+ ldap_control_free( ctrl );
+ ldap_unbind( ld );
+ return( 0 );
+}
+When you compile and run this sample program against &cnDirectoryServer; with
+a suffix that contains data from Example-roles.ldif,
+the server produces output similar to this:
+dn: uid=kvaughan, ou=People, dc=example,dc=com
+nsrole: cn=directory administrators,dc=example,dc=com
+nsrole: cn=hr managers,dc=example,dc=com
+
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-datatypes.sgm b/mozilla/directory/docs/ldapcsdk/csdk-datatypes.sgm
new file mode 100644
index 00000000000..5f4e44efb46
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-datatypes.sgm
@@ -0,0 +1,3580 @@
+
+&DirectorySDKForC; Data Type Reference
+
+C SDK data types
+
+data types
+C SDK data types
+This chapter contains reference material for the public data types and
+structures of &DirectorySDKForC;. The first sections detail the data types
+of the grouped into task categories. The last section is an alphabetical listing
+of the same information. The chapter contains the following sections:
+
+Conventions
+Structure Summary by Task
+
+Structures Alphabetically
+
+
+
+Conventions
+The following sections detail certain conventions and concepts used
+in &DirectorySDKForC;.
+Typographical Conventions
+
+C SDK data types
+typographical conventions
+
+Table 20–1 lists
+the typographical conventions used in the names of data types and structures.
+
Typographical Conventions
+in Data Types and Structures
+
+
+
+
+Convention
+
+Description of Use
+
+
+
+
+
+LeadingCaps
+
+Data structures needed to pass values to and from functions of &DirectorySDKForC;.
+For consistency, use this typedef name for these structures,
+not their literal struct name.
+
+
+
+ALL_CAPS
+
+Names of callback function prototypes which you can implement for extended
+functionality in your client application.
+
+
+
+fns suffix
+
+Structures which hold the function pointers for callback functions,
+grouped by task.
+
+
+
+
+
+Deprecated Structures
+
+C SDK data types
+deprecated
+
+A deprecated API is one you should no longer use for new development,
+and should begin to phase out for applications you maintain. Deprecated interfaces
+may disappear in the major version following their deprecation.
+
+Structure Summary by Task
+
+C SDK data types
+summary by task
+
+In the following sections the structures defined by &DirectorySDKForC;
+are grouped into task categories.
+BER Structures
+The structures listed in Table 20–2
+ represent data encoded using the Basic Encoding Rules (BER). The
+lber.h header file contains many other type definitions; the ones
+listed here are those likely to be handled directly. All others are used internally
+by the various functions of &DirectorySDKForC;.
+
BER Structures
+
+
+
+
+Structure
+
+Description
+
+
+
+
+
+berval
+
+berval represents binary data encoded
+using BER.
+
+
+
+BerElement
+
+BerElement indicates the current position
+during a traversal of an attribute list.
+
+
+
+
+
+Structures for the Core API
+
+C SDK data types
+summary by task
+
+The structures listed in Table
+20–3 are used by the core functions of &DirectorySDKForC;.
+These structures are used directly as argument or return types by functions
+that provide the core functionality.
+
Core API Structures
+
+
+
+
+Structure
+
+Description
+
+
+
+
+
+LDAP
+
+LDAP represents a connection handle
+to the LDAP server.
+
+
+
+LDAPMessage
+
+LDAPMessage represents the results
+of an LDAP operation, a chain of search results, an entry in the search results,
+or a search reference in the search results.
+
+
+
+LDAPMod
+
+LDAPMod specifies changes to an attribute
+in an directory entry.
+
+
+
+LDAPControl
+
+LDAPControl represents a client or
+server control associated with an LDAP operation.
+
+
+
+LDAPAPIInfo
+
+LDAPAPIInfo represents information
+about the version of &DirectorySDKForC; being implemented
+
+
+
+LDAPAPIFeatureInfo
+
+LDAPAPIFeatureInfo represents information
+about the extended features.
+
+
+
+
+
+Structures for API Extensions
+The structures listed in Table
+20–4 are needed for extensions to the standard API within &DirectorySDKForC;.
+These structures are used directly as arguments or return types by the functions
+that provide the extended functionality.
+
API Extension Structures
+
+
+
+
+
+Structure
+
+Description
+
+
+
+
+
+LDAPsortkey
+
+LDAPsortkey represents a server control
+used to specify that the server should sort the search results before sending
+them back to the client.
+
+
+
+LDAPVirtualList
+
+LDAPVirtualList specifies the information
+that can be used to create a virtual list view control.
+
+
+
+LDAPURLDesc
+
+LDAPURLDesc represents the components
+of an LDAP URL.
+
+
+
+LDAPFiltInfo
+
+LDAPFiltInfo represents information
+about a filter in a filter configuration file.
+
+
+
+LDAPFiltDesc
+
+LDAPFiltDesc is a type of structure
+returned when you call ldap_init_getfilter to
+load a filter configuration file.
+
+
+
+FriendlyMap
+
+FriendlyMap represents the mapping
+between a list of standard attribute names and their user friendly counterparts.
+
+
+
+
+LDAPMemCache
+
+LDAPMemCache represents an in-memory,
+client-side cache.
+
+
+
+LDAPpwdpolicy
+
+LDAPpwdpolicy represents password
+policy information concerning an entry.
+
+
+
+LDAPuserstatus
+
+LDAPuserstatus represents
+account availability information.
+
+
+
+
+Many other types, especially prototypes for callback functions,
+are associated with controls. These are listed separately in the subsequent
+sections of this chapter.
+
+Referral Binding Callback
+This prototype for a callback function retrieves authentication information
+when automatically following referrals to other servers.
+
Referral Binding Data Type
+
+
+
+
+Data Type
+
+Description
+
+
+
+
+
+LDAP_REBINDPROC_CALLBACK
+
+Retrieves authentication information when following referrals to other
+servers.
+
+
+
+
+
+Client-Side Sorting Callbacks
+The prototype structures listed in Table 20–6 are extensions
+to &DirectorySDKForC; that implement client side sorting of entries.
+
Client-side Sorting
+Structures
+
+
+
+
+Data Type
+
+Description
+
+
+
+
+
+LDAP_KEYGEN_CALLBACK
+
+Function prototype that generates the sorting key for each entry to
+be sorted, usually by extracting a value out of an entry.
+
+
+
+LDAP_KEYCMP_CALLBACK
+
+Function prototype to compare 2 keys (for ordering).
+
+
+
+
+LDAP_KEYFREE_CALLBACK
+
+Function prototype that frees the memory allocated during the KEYGEN
+ callback.
+
+
+
+LDAP_CMP_CALLBACK
+
+Function prototype to sort a specified set of entries.
+
+
+
+LDAP_VALCMP_CALLBACK
+
+Function prototype to sort a specified set of values.
+
+
+
+
+
+Extended I/O Control
+Table 20–7 lists
+the prototypes and structures used in the extended I/O control, an extension
+to the standard API.
+
Structures and Prototypes
+for Extended I/O Functionality
+
+
+
+
+Data Type
+
+Description
+
+
+
+
+
+ldap_x_ext_io_fns
+
+This structure holds extended I/O function pointers.
+
+
+
+LDAP_X_PollFD
+
+An LDAP file descriptor similar to that of poll.
+
+
+
+
+LDAP_X_EXTIOF_CONNECT_CALLBACK
+
+
+Function prototype for a callback that opens a socket connection.
+
+
+
+
+LDAP_X_EXTIOF_CLOSE_CALLBACK
+
+
+Function prototype for a callback that closes a socket connection.
+
+
+
+
+LDAP_X_EXTIOF_POLL_CALLBACK
+
+
+Function prototype for a callback that surveys a server about a particular
+event.
+
+
+
+LDAP_X_EXTIOF_NEWHANDLE_CALLBACK
+
+
+Function prototype for a callback that defines a new session handle.
+
+
+
+
+LDAP_X_EXTIOF_DISPOSEHANDLE_CALLBACK
+
+
+Function prototype for a callback that disposes of a session handle.
+
+
+
+
+ldap_x_hostlist_status
+
+This structure holds utility functions for parsing space-separated host
+lists.
+
+
+
+
+
+Memory Management Control
+The prototypes and structures listed in Table 20–8 are used in
+memory management control, an extension to the standard API. They allow developers
+to specify their own memory allocation mechanisms and functions.
+
Memory Management
+Data Types
+
+
+
+
+Data Type
+
+Description
+
+
+
+
+
+ldap_memalloc_fns
+
+This structure holds the memory allocation callback functions.
+
+
+
+
+LDAP_MALLOC_CALLBACKLDAP_CALLOC_CALLBACKLDAP_REALLOC_CALLBACK
+LDAP_FREE_CALLBACK
+
+These callbacks allow developers to specify their own memory allocation
+mechanisms.
+
+
+
+
+
+Thread Signaling Controls
+The prototypes and structures listed in Table 20–9 are used
+in the thread signaling control, an extension to the standard API.
+
Thread Signaling
+Control Data Types
+
+
+
+
+Data Type
+
+Description
+
+
+
+
+
+ldap_thread_fns
+
+Structure that contains a set of pointers to functions you want to use
+when writing a multithreaded client.
+
+
+
+LDAP_TF_MUTEX_ALLOC_CALLBACK
+
+
+Function prototype for allocating a mutex.
+
+
+
+LDAP_TF_MUTEX_FREE_CALLBACK
+
+
+Function prototype freeing a mutex.
+
+
+
+LDAP_TF_MUTEX_LOCK_CALLBACK
+
+
+Function prototype for locking critical sections of code.
+
+
+
+LDAP_TF_MUTEX_UNLOCK_CALLBACK
+
+
+Function prototype for unlocking critical sections of code.
+
+
+
+LDAP_TF_GET_ERRNO_CALLBACK
+
+Function prototype for getting the value of the errno variable.
+
+
+
+
+LDAP_TF_SET_ERRNO_CALLBACK
+
+Function prototype for setting the value of the errno variable.
+
+
+
+
+LDAP_TF_GET_LDERRNO_CALLBACK
+
+
+Function prototype for getting error values from calls to functions
+in the libldap library.
+
+
+
+LDAP_TF_SET_LDERRNO_CALLBACK
+
+
+Function prototype for setting error values from calls to functions
+in the libldap library.
+
+
+
+ldap_extra_thread_fns
+
+Structure that contains a set of pointers to additional functions you
+want to use when writing a multithreaded client.
+
+
+
+LDAP_TF_MUTEX_TRYLOCK_CALLBACK
+
+
+Function prototype for attempting to lock a mutex.
+
+
+
+LDAP_TF_SEMA_ALLOC_CALLBACK
+
+
+Function prototype for allocating a semaphore.
+
+
+
+LDAP_TF_SEMA_FREE_CALLBACK
+
+Function prototype for freeing a semaphore.
+
+
+
+LDAP_TF_SEMA_WAIT_CALLBACK
+
+Function prototype for waiting for the value of a semaphore to be greater
+than 0.
+
+
+
+LDAP_TF_SEMA_POST_CALLBACK
+
+Function prototype for incrementing the value of a semaphore.
+
+
+
+
+LDAP_TF_THREADID_CALLBACK
+
+Function prototype to return an identifier that is unique to the calling
+thread.
+
+
+
+
+
+Deprecated and Outdated Types
+Deprecated types are those being dropped from the standard or from the
+extensions to &DirectorySDKForC;. They are not guaranteed to be defined
+in future versions of the API. However, all of these types are still defined
+in this version for backwards compatibility. Table 20–10 lists the deprecated
+prototypes.
+
Deprecated Data Types
+and Their Replacements
+
+
+
+
+Data Type
+
+Replacement
+
+
+
+
+
+LDAP_CANCELPROC_CALLBACK
+
+Provides a way to be cancel a process, for example, by a user or because
+some other condition occurs.
+
+
+
+ldap_cache_fnsLDAP_CF_BIND_CALLBACK
+LDAP_CF_UNBIND_CALLBACKLDAP_CF_SEARCH_CALLBACKLDAP_CF_COMPARE_CALLBACK
+LDAP_CF_ADD_CALLBACKLDAP_CF_DELETE_CALLBACKLDAP_CF_MODIFY_CALLBACK
+LDAP_CF_MODRDN_CALLBACKLDAP_CF_RESULT_CALLBACKLDAP_CF_FLUSH_CALLBACK
+
+
+ldap_cache_fns is a deprecated structure
+and the typedef declarations associated with it have also
+been deprecated.
+
+
+
+LDAPVersion
+
+Replaced by the LDAPAPIInfo type which
+is returned by the ldap_get_option function
+using the LDAP_OPT_API_INFO option.
+
+
+
+
+While not officially deprecated, other data types are outdated because
+they have superseded by new types. Outdated types may become deprecated in
+future releases of &DirectorySDKForC;. Table
+20–11 lists the outdated types and the newer types which implement
+the same functionality.
+
Outdated Types and Their
+New Equivalents
+
+
+
+
+Old Data Type
+
+New, Equivalent Data Type
+
+
+
+
+
+LDAPHostEntLDAP_DNSFN_GETHOSTBYNAMELDAP_DNSFN_GETHOSTBYADDRldap_dns_fns
+
+The DNS resolver callbacks are an outdated extension to the API. The
+new way of specifying host information is through the LDAP_X_EXTIOF_CONNECT_CALLBACK
+ prototype.
+
+
+
+LDAP_IOF_CLOSE_CALLBACKLDAP_IOF_CONNECT_CALLBACKLDAP_IOF_IOCTL_CALLBACK
+LDAP_IOF_READ_CALLBACKLDAP_IOF_SELECT_CALLBACKLDAP_IOF_SOCKET_CALLBACK
+LDAP_IOF_SSL_ENABLE_CALLBACKLDAP_IOF_WRITE_CALLBACKldap_io_fns
+
+Replaced by the types for extended I/O functionality detailed in Table 20–7.
+
+
+
+
+
+
+Structures Alphabetically
+
+C SDK data types
+alphabetically
+
+The following sections detail the structures and controls of &DirectorySDKForC;
+in alphabetical order.
+berval
+
+C SDK data types
+berval
+
+berval
+
+berval is a structure that represents binary data
+encoded using simplified Basic Encoding Rules (BER).
+Description
+Use a berval structure when working with attributes
+that contain binary data (such as a graphic or audio file). The data and the
+size of the data are both included in a berval structure.
+berval Definition
+typedef struct berval {
+ unsigned long bv_len;
+ char *bv_val;
+};
+
+
berval Field
+Descriptions
+
+
+
+
+Field
+
+What It Contains
+
+
+
+
+
+bv_len
+
+The length of the data in bytes.
+
+
+
+bv_val
+
+A pointer to the binary data itself.
+
+
+
+
+
+
+BerElement
+
+C SDK data types
+BerElement
+
+BerElement
+
+The BerElement structure represents data encoded
+using the Basic Encoding Rules (BER).
+Description
+You use this opaque data type to keep track of the current attribute
+during the traversal of an attribute list. Calling the ldap_first_attribute
+ function allocates memory for a BerElement structure
+and initializes it to select the values of the first attribute in the entry.
+Subsequently, ldap_next_attribute is called
+to obtain the name of each remaining attribute and set BerElement to
+select their values. Once BerElement has been set to select
+an attribute's values, ldap_get_values can
+be used to obtain all of them from the buffer. When you are done reading the
+attributes, you need to free the BerElement structure
+from memory by calling the ldap_ber_free function.
+(A BerElement structure can also be allocated by calling
+the ber_alloc_t or the
+ber_init function. In these cases, free the memory allocated to the
+BerElement structure by using the ber_free function.)
+
+The BerElement definition is not completely
+exposed in lber.h because the fields within the structure
+are not intended to be accessible to clients.
+
+
+FriendlyMap
+FriendlyMap represents the mapping between a list
+of standard attribute names and their user-friendly counterparts. For example,
+you can represent the list of two-letter state codes (CA, IA) with their corresponding
+state names (California, Iowa), or map Country ISO codes to the full country
+names, in a FriendlyMap structure.
+FriendlyMap is not completely defined in
+ldap-extension.h because the fields within the structure are not
+intended to be accessible to clients.
+Related Functions
+
+ldap_friendly_name allocates
+a FriendlyMap structure and reads a list of standard attribute
+names and their user friendly counterparts from a file.
+ldap_free_friendlymap frees
+the memory allocated for a FriendlyMap structure.
+
+
+
+
+LDAP
+
+C SDK data types
+LDAP
+
+LDAP data type
+
+LDAP is an opaque data type representing a connection
+with the LDAP server. It is initialized through a call to either the ldap_init or ldapssl_init function.
+ LDAP maintains the state of an LDAP session for the duration
+of the connection. When you call functions that perform LDAP operations on
+an LDAP server (for example, ldap_search_ext to
+search the directory or ldap_modify_ext to
+update an entry), you need to pass a pointer to this connection handle. With
+the LDAP structure, you can also:
+
+Call the ldap_get_option and ldap_set_option functions to view or modify the
+properties of the connection.
+Call the ldap_unbind or ldap_unbind_s function to close the connection and
+free the LDAP structure.
+
+LDAP is not completely defined in ldap-standard.h
+ because the fields within the structure are not intended to be
+accessible to clients.
+
+LDAPAPIFeatureInfo
+
+C SDK data types
+LDAPAPIFeatureInfo
+
+LDAPAPIFeatureInfo
+
+LDAPAPIFeatureInfo is a structure that represents
+information about the extended features of &DirectorySDKForC;.
+LDAPAPIFeatureInfo Definition
+
+#define LDAP_FEATURE_INFO_VERSION
+typedef struct ldap_apifeature_info {
+ int ldapaif_info_version; /* version of this struct (1) */
+ char *ldapaif_name; /* name of supported feature */
+ int ldapaif_version; /* revision of supported feature */
+} LDAPAPIFeatureInfo;
+
+The LDAPAPIFeatureInfo structure can be retrieved
+by using a sequence like the one displayed in Example 20–3.
+Sequence to Retrieve LDAPAPIFeatureInfo
+
+LDAPAPIFeatureInfo ldfi;
+ ldfi.ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
+ ldfi.ldapaif_name = "VIRTUAL_LIST_VIEW";
+ if ( ldap_get_option( NULL, LDAP_OPT_API_FEATURE_INFO, &ldfi ) == 0 )
+
+Parameters
+
LDAPAPIFeatureInfo Structure
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ldapaif_info_version
+
+Specifies the version number of the LDAPAPIFeatureInfo structure.
+This must be set to LDAP_FEATURE_INFO_VERSION before call
+to ldap_get_option is performed.
+
+
+
+ldapaif_name
+
+Pointer to NULL terminated string that specifies
+the name of the supported feature.
+
+
+
+ldapaif_version
+
+Specifies the version number of the supported feature.
+
+
+
+
+
+
+LDAPAPIInfo
+
+C SDK data types
+LDAPAPIInfo
+
+LDAPAPIInfo
+
+LDAPAPIInfo is a structure that represents information
+about the API and supported extensions.
+LDAPAPIInfo Definition
+#define LDAP_API_INFO_VERSION
+typedef struct ldapapiinfo {
+ int ldapai_info_version; /* version of LDAPAPIInfo (1) */
+ int ldapai_api_version; /* revision of API supported */
+ int ldapai_protocol_version; /* highest LDAP version supported */
+ char **ldapai_extensions; /* names of API extensions */
+ char *ldapi_vendor_name; /* name of supplier */
+ int ldapai_vendor_version; /* supplier-specific version x 100 */
+ } LDAPAPIInfo;
+
+The LDAPAPIInfo structure can be retrieved by using
+a sequence like the one displayed in Example
+20–5.
+Sequence to Retrieve LDAPAPIInfo
+
+LDAPAPIInfo ldai;
+ ldai.ldapai_info_version = LDAP_API_INFO_VERSION;
+ if ( ldap_get_option( NULL, LDAP_OPT_API_INFO, &ldia ) == 0 ) ...
+
+Parameters
+
LDAPAPIInfo Structure
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ldapai_info_version
+
+Specifies the version number of the LDAPAPIInfo structure.
+This must be set to LDAP_API_INFO_VERSION before a call
+to ldap_get_option is performed.
+
+
+
+ldapai_api_version
+
+Specifies the version number of the API that is supported.
+
+
+
+ldapai_protocol_version
+
+Specifies the latest LDAP version supported by the LDAP library.
+
+
+
+
+ldapai_extensions
+
+Points to a NULL terminated array of character strings
+that names the supported LDAP extensions. If none are supported, this field
+is set to NULL. The application is responsible for freeing
+this memory by calling the ldap_value_free function.
+
+
+
+
+ldapai_vendor_name
+
+Pointer to a NULL-terminated string that contains the vendor's name.
+Call the ldap_memfree function to free the
+memory.
+
+
+
+ldapai_vendor_version
+
+Specifies the vendor’s version of the LDAP libraries.
+
+
+
+
+
+
+ldap_cache_fns
+
+C SDK data types
+ldap_cache_fns
+
+ldap_cache_fns
+
+ldap_cache_fns is a deprecated structure. The following
+are also deprecated:
+
+LDAP_CF_ADD_CALLBACK
+
+LDAP_CF_BIND_CALLBACK
+
+LDAP_CF_COMPARE_CALLBACK
+
+LDAP_CF_DELETE_CALLBACK
+
+LDAP_CF_FLUSH_CALLBACK
+
+LDAP_CF_MODIFY_CALLBACK
+
+LDAP_CF_MODRDN_CALLBACK
+
+LDAP_CF_RESULT_CALLBACK
+
+LDAP_CF_SEARCH_CALLBACK
+
+LDAP_CF_UNBIND_CALLBACK
+
+
+See Also
+Please see the ldap_memcache_* functions for current
+usage.
+
+LDAP_CALLOC_CALLBACK
+
+C SDK data types
+LDAP_CALLOC_CALLBACK
+
+LDAP_CALLOC_CALLBACK
+
+This callback function prototype of ldap_memalloc_fns
+ represents memory allocation.
+See Also
+ldap_memalloc_fns
+
+LDAP_CANCELPROC_CALLBACK
+
+C SDK data types
+LDAP_CANCELPROC_CALLBACK
+
+LDAP_CANCELPROC_CALLBACK
+
+This callback function prototype is deprecated.
+See Also
+ldap_ufn_search_c, ldap_ufn_search_ct
+
+LDAP_CF_ADD_CALLBACK
+
+C SDK data types
+LDAP_CF_ADD_CALLBACK
+
+LDAP_CF_ADD_CALLBACK
+
+This callback function prototype of ldap_cache_fns
+ is deprecated.
+LDAP_CF_BIND_CALLBACK
+
+C SDK data types
+LDAP_CF_BIND_CALLBACK
+
+LDAP_CF_BIND_CALLBACK
+
+This callback function prototype of ldap_cache_fns
+ is deprecated.
+LDAP_CF_COMPARE_CALLBACK
+
+C SDK data types
+LDAP_CF_COMPARE_CALLBACK
+
+LDAP_CF_COMPARE_CALLBACK
+
+This callback function prototype of ldap_cache_fns
+ is deprecated.
+LDAP_CF_DELETE_CALLBACK
+
+C SDK data types
+LDAP_CF_DELETE_CALLBACK
+
+LDAP_CF_DELETE_CALLBACK
+
+This callback function prototype of ldap_cache_fns
+ is deprecated.
+LDAP_CF_FLUSH_CALLBACK
+
+C SDK data types
+LDAP_CF_FLUSH_CALLBACK
+
+LDAP_CF_FLUSH_CALLBACK
+
+This callback function prototype of ldap_cache_fns
+ is deprecated.
+LDAP_CF_MODIFY_CALLBACK
+
+C SDK data types
+LDAP_CF_MODIFY_CALLBACK
+
+LDAP_CF_MODIFY_CALLBACK
+
+This callback function prototype of ldap_cache_fns
+ is deprecated.
+LDAP_CF_MODRDN_CALLBACK
+
+C SDK data types
+LDAP_CF_MODRDN_CALLBACK
+
+LDAP_CF_MODRDN_CALLBACK
+
+This callback function prototype of ldap_cache_fns
+ is deprecated.
+LDAP_CF_RESULT_CALLBACK
+
+C SDK data types
+LDAP_CF_RESULT_CALLBACK
+
+LDAP_CF_RESULT_CALLBACK
+
+This callback function prototype of ldap_cache_fns
+ is deprecated.
+LDAP_CF_SEARCH_CALLBACK
+
+C SDK data types
+LDAP_CF_SEARCH_CALLBACK
+
+LDAP_CF_SEARCH_CALLBACK
+
+This callback function prototype of ldap_cache_fns
+ is deprecated.
+LDAP_CF_UNBIND_CALLBACK
+
+C SDK data types
+LDAP_CF_UNBIND_CALLBACK
+
+LDAP_CF_UNBIND_CALLBACK
+
+This callback function prototype of ldap_cache_fns
+ is deprecated.
+LDAP_CMP_CALLBACK
+
+C SDK data types
+LDAP_CMP_CALLBACK
+
+LDAP_CMP_CALLBACK
+
+LDAP_CMP_CALLBACK specifies the prototype for a comparison
+callback function used when sorting values. If you define a function with
+this prototype and specify it when calling ldap_sort_entries
+ or ldap_multisort_entries, it will
+be called by your LDAP client to sort a specified set of entries.
+LDAP_CMP_CALLBACK Prototype
+typedef int (LDAP_C LDAP_CALLBACK
+ LDAP_CMP_CALLBACK)(const char*, const char*);
+
+See Also
+ldap_sort_entries, ldap_multisort_entries.
+
+LDAPControl
+
+C SDK data types
+LDAPControl
+
+LDAPControl
+
+LDAPControl represents a client or server control
+associated with an LDAP operation. If set as a server control, it is sent
+to the server along with operation requests; if set as a client control, it
+is interpreted locally by the client.
+Controls are part of the LDAP v3. You can use a control to extend the
+functionality of an LDAP operation. There are two basic types of controls
+described in the LDAP v3:
+
+Server controls are controls that are
+sent from the client to the server along with an LDAP request. (In some cases,
+a server can include a control in the response it sends back to the client.)
+For example, you can include a server control in a search request to specify
+that you want the server to sort the search results before sending them back.
+
+Client controls are controls that can
+extend the client but are never sent to the server. As a general example,
+you might be able to pass a client control to an LDAP API function, which
+might parse the control and use the data that you’ve specified in the
+control.&DirectorySDKForC; does not currently support any
+client controls.
+
+Definition of LDAPControl
+typedef struct ldapcontrol {
+ char *ldctl_oid;
+ struct berval ldctl_value;
+ char ldctl_iscritical;
+} LDAPControl;
+
+
LDAPControl Field
+Descriptions
+
+
+
+
+Field
+
+What It Contains
+
+
+
+
+
+ldctl_oid
+
+Object identifier (OID) of the control.
+
+
+
+ldctl_value
+
+berval structure containing data associated
+with the control. If you want to specify a zero-length value, set ldctl_value.bv_len
+ to 0 and ldctl_value.bv_val to
+a zero-length string. To indicate that no data is associated with the control,
+set ldctl_value.bv_val to NULL.
+
+
+
+
+ldctl_iscritical
+
+Specifies whether or not the control is critical to the operation. This
+field can have one of the following values:
+
+A non-zero value specifies that the control is critical to
+the operation.
+0 specifies that the control is not critical
+to the operation.
+
+
+
+
+
+
+
+LDAP_DNSFN_GETHOSTBYADDR
+
+C SDK data types
+LDAP_DNSFN_GETHOSTBYADDR
+
+LDAP_DNSFN_GETHOSTBYADDR
+
+LDAP_DNSFN_GETHOSTBYADDR specifies the prototype
+for a callback function equivalent to the gethostbyaddr_r() function
+available on some UNIX platforms.
+While not officially deprecated, the functionality of this callback
+prototype is superseded by the extended I/O functions. The new way of specifying
+host information is through the LDAP_X_EXTIOF_CONNECT_CALLBACK
+ prototype.
+Description
+If you define a function with this prototype and set it in the ldap_dns_fns structure, your function will be called
+by the SDK on behalf of your LDAP client if it needs to get the host name
+of the LDAP server to which it is connected.
+In this version of &DirectorySDKForC;, the functions of the
+API never call this function, and your implementation will never be executed.
+Therefore, its implementation is optional.
+LDAP_DNSFN_GETHOSTBYADDR Prototype
+
+typedef LDAPHostEnt * (LDAP_C LDAP_CALLBACK
+LDAP_DNSFN_GETHOSTBYADDR)( const char *addr, int length, int type,
+ LDAPHostEnt *result, char *buffer, int buflen, int *statusp,
+ void *extradata );
+
+
+
+LDAP_DNSFN_GETHOSTBYNAME
+
+C SDK data types
+LDAP_DNSFN_GETHOSTBYNAME
+
+LDAP_DNSFN_GETHOSTBYNAME
+
+LDAP_DNSFN_GETHOSTBYNAME specifies the prototype
+for a callback function equivalent to the gethostbyname_r() function
+available on some UNIX platforms.
+While not officially deprecated, the functionality of this callback
+prototype is superseded by the extended I/O functions. The new way of specifying
+host information is through the LDAP_X_EXTIOF_CONNECT_CALLBACK
+ prototype.
+Description
+If you define a function with this prototype and set it in the ldap_dns_fns
+ structure, your function will be called by &DirectorySDKForC;
+on behalf of your LDAP client to get the host entry for the LDAP server when
+connecting to the server.
+LDAP_DNSFN_GETHOSTBYNAME Prototype
+
+typedef LDAPHostEnt * (LDAP_C LDAP_CALLBACK
+LDAP_DNSFN_GETHOSTBYADDR)( const char *addr, int length, int type,
+ LDAPHostEnt *result, char *buffer, int buflen, int *statusp,
+ void *extradata );
+
+
+
+ldap_dns_fns
+
+C SDK data types
+ldap_dns_fns
+
+ldap_dns_fns
+
+ldap_dns_fns contains a set of pointers to DNS functions
+and is equivalent to the gethostbyname_r() and gethostbyaddr_r()
+ functions available on some UNIX platforms.
+While not officially deprecated, the functionality of this structure
+is superseded by the extended I/O functions. The new way of specifying host
+information is through the LDAP_X_EXTIOF_CONNECT_CALLBACK
+ prototype.
+Description
+You can use this structure if you want &DirectorySDKForC; to call
+these functions when looking up the host name or IP address for the LDAP server.
+For example, you could use this to call versions of the DNS functions that
+are safe for use in a multithreaded application. The function must have the
+prototype specified by LDAP_DNSFN_GETHOSTBYADDR.
+If NULL, the standard built-in OS routine is used.
+After you set the fields in this structure, you can register the functions
+for use by calling the ldap_set_option function
+and setting the LDAP_OPT_DNS_FN_PTRS option to this structure.
+
+ldap_dns_fns Definition
+struct ldap_dns_fns {
+ void *lddnsfn_extradata;
+ int lddnsfn_bufsize;
+ LDAP_DNSFN_GETHOSTBYNAME *lddnsfn_gethostbyname;
+ LDAP_DNSFN_GETHOSTBYADDR *lddnsfn_gethostbyaddr;
+};
+
+
ldap_dns_fns Field
+Descriptions
+
+
+
+
+Field
+
+What It Contains
+
+
+
+
+
+lddnsfn_extradata
+
+Value passed in the extradata argument of the LDAP_DNSFN_GETHOSTBYADDR and LDAP_DNSFN_GETHOSTBYNAME
+ function calls.
+
+
+
+lddnsfn_bufsize
+
+Specifies the size of the buffer that you want passed to your DNS callback
+function. Your LDAP client passes this value as the buflen argument
+of the LDAP_DNSFN_GETHOSTBYADDR and LDAP_DNSFN_GETHOSTBYNAME function calls.
+
+
+
+
+lddnsfn_gethostbyname
+
+Function pointer for getting the host entry for the LDAP server. This
+function is called by the client when connecting to the server if the function
+pointer is not NULL. The function must have the prototype
+specified by LDAP_DNSFN_GETHOSTBYNAME. If
+NULL, the standard built-in OS routine is used.
+
+
+
+lddnsfn_gethostbyaddr
+
+Function pointer for getting the host name of the LDAP server. This
+function is called by the client when needed if the function pointer is not
+NULL.
+
+
+
+
+
+
+ldap_extra_thread_fns
+
+C SDK data types
+ldap_extra_thread_fns
+
+ldap_extra_thread_fns
+
+The ldap_extra_thread_fns structure contains a set
+of pointers to additional functions that you can use when writing a multithreaded
+client. Your client calls these functions when getting results from the LDAP structure.
+&DirectorySDKForC; ignores all the elements in this structure
+except for the ltf_threadid_fn function. Calling ltf_threadid_fn
+ will, in some cases, enhance the performance of a multithreaded
+program.
+After you set the fields in this structure, you can register the functions
+for use by calling the ldap_set_option function
+and setting the LDAP_OPT_EXTRA_THREAD_FN_PTRS option to
+this structure.
+ldap_extra_thread_fns Definition
+
+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;
+};
+
+
ldap_extra_thread_fns Field
+Descriptions
+
+
+
+
+Field
+
+What It Contains
+
+
+
+
+
+ltf_mutex_trylock
+
+Function pointer for attempting to lock a mutex. This function is called
+by the client when needed if the function pointer is not NULL.
+The function must have the prototype specified by LDAP_TF_MUTEX_TRYLOCK_CALLBACK
+ .
+
+
+
+ltf_sema_alloc
+
+Function pointer for allocating a semaphore. This finction is called
+by the client if needed when the function pointer is not NULL.
+The function must have the prototype specified by LDAP_TF_SEMA_ALLOC_CALLBACK
+ .
+
+
+
+ltf_sema_free
+
+Function pointer for freeing a semaphore. This function is called by
+the client when needed if the function pointer is not NULL.
+The function must have the prototype specified by LDAP_TF_SEMA_FREE_CALLBACK
+ .
+
+
+
+ltf_sema_wait
+
+Function pointer for waiting for the value of a semaphore to be greater
+than 0. This function is called by the client when needed if the function
+pointer is not NULL. The function must have the prototype
+specified by LDAP_TF_SEMA_WAIT_CALLBACK.
+
+
+
+
+ltf_sema_post
+
+Function pointer for incrementing the value of a semaphore. This function
+is called by the client when needed if the function pointer is not NULL.
+The function must have the prototype specified by LDAP_TF_SEMA_POST_CALLBACK
+ .
+
+
+
+ltf_threadid_fn
+
+Function pointer that is called to retrieve the unique identifier for
+the calling thread. If this is NULL, it is not used. An
+example of a similar function in the POSIX threads standard is pthread_self()
+. The function must have the prototype specified by LDAP_TF_THREADID_CALLBACK .
+
+
+
+
+
+LDAPFiltDesc
+
+C SDK data types
+LDAPFiltDesc
+
+LDAPFiltDesc
+
+LDAPFiltDesc is a structure that is returned when
+you call ldap_init_getfilter to load a filter
+configuration file.
+The LDAPFiltDesc definition is not completely
+exposed in ldap-extension.h because the fields within the
+structure are not intended to be accessible to clients.
+Description
+After calling the ldap_init_getfilter function,
+use the pointer to the returned LDAPFiltDesc structure
+in subsequent calls to get information about filters in the filter configuration
+file.
+
+LDAPFiltInfo
+
+C SDK data types
+LDAPFiltInfo
+
+LDAPFiltInfo
+
+LDAPFiltInfo represents information about a filter
+in the filter configuration file.
+Description
+When you call the ldap_getfirstfilter or ldap_getnextfilter functions to get a filter from
+the filter configuration file, they return a pointer to an LDAPFiltInfo structure
+containing the information about the filter.
+LDAPFiltInfo Definition
+typedef struct ldap_filt_info {
+ char *lfi_filter;
+ char *lfi_desc;
+ int lfi_scope;
+ int lfi_isexact;
+ struct ldap_filt_info *lfi_next;
+} LDAPFiltInfo;
+
+
LDAPFilterInfo Field
+Descriptions
+
+
+
+
+Field
+
+What It Contains
+
+
+
+
+
+lfi_filter
+
+The filter, for example (cn=d*).
+
+
+
+lfi_desc
+
+Description of the filter, also the fifth field in the filter configuration
+file.
+
+
+
+lfi_scope
+
+The scope of the filter, also the sixth field in the filter configuration
+file, which can be one of the following values:
+
+LDAP_SCOPE_BASE specifies that the search
+will be restricted to the current DN.
+LDAP_SCOPE_ONELEVEL specifies that the
+search will be restricted to the entries at the level beneath the current
+DN.
+LDAP_SCOPE_SUBTREE specifies that the search
+will encompass entries at all levels beneath the current DN.If
+the scope of the filter is not specified in the filter configuration file,
+the scope is LDAP_SCOPE_SUBTREE by default.
+
+
+
+
+
+
+lfi_isexact
+
+Specifies whether or not the filter is an exact filter, where an exact
+filter contains no wildcard characters and does not match words that sound
+alike:
+
+0 specifies that the filter is not an exact
+filter.
+1 specifies that the filter is an exact
+filter.
+
+
+
+
+
+lfi_next
+
+Pointer to the LDAPFiltInfo structure representing
+the next filter in the filter list.
+
+
+
+
+Example 20–13 prints
+out information about a filter.
+Sample LDAPFiltInfo Code
+
+LDAPFiltInfo *lfip;
+/* Print out the filter */
+printf( "Filter:\t%s\n", lfdp->lfd_filter );
+printf( "Description:\t%s\n", lfdp->lfd_desc );
+
+For example, in the filter configuration file, if the first filter that
+applies to the value @ is:
+"@" " " "(mail=%v)" "email address is" "onelevel"
+The code prints out:
+Filter: (mail=@)
+Description: email address is
+
+
+LDAP_FREE_CALLBACK
+
+C SDK data types
+LDAP_FREE_CALLBACK
+
+LDAP_FREE_CALLBACK
+
+This callback function prototype of ldap_memalloc_fns
+ is used to free allocated memory.
+See Also
+ldap_memalloc_fns
+
+LDAPHostEnt
+
+C SDK data types
+LDAPHostEnt
+
+LDAPHostEnt
+
+The LDAPHostEnt structure represents an entry for
+a host found by a domain name server.
+While not officially deprecated, the functionality of this callback
+prototype is superseded by the extended I/O functions. The new way of specifying
+host information is through the LDAP_X_EXTIOF_CONNECT_CALLBACK
+ prototype.
+Description
+This type is similar to the hostent structure returned
+by functions such as gethostbyname_r() on UNIX systems.
+If you are writing your own DNS functions for use by the client, they should
+return the host entry in this type of structure.
+The fields in this structure should point to addresses within the buffer
+that is passed to the DNS callback (referenced in the LDAP callback function).
+This buffer contains the host data. The pointers in the hostent structure
+returned by the function point to the data in this buffer.
+LDAPHostEnt Definition
+typedef struct LDAPHostEnt {
+ char *ldaphe_name;
+ char **ldaphe_aliases;
+ int ldaphe_addrtype;
+ int ldaphe_length;
+ char **ldaphe_addr_list;
+} LDAPHostEnt;
+
+
LDAPHostEnt Field
+Descriptions
+
+
+
+
+Field
+
+What It Contains
+
+
+
+
+
+ldaphe_name
+
+Canonical name of the host
+
+
+
+ldaphe_aliases
+
+List of aliases for this host
+
+
+
+ldaphe_addrtype
+
+Address type of the host
+
+
+
+ldaphe_length
+
+Length of the address
+
+
+
+ldaphe_addr_list
+
+List of addresses for this host as returned by the name server
+
+
+
+
+
+
+See Also
+LDAP_DNSFN_GETHOSTBYADDR, LDAP_DNSFN_GETHOSTBYNAME
+
+LDAP_IOF_CLOSE_CALLBACK
+
+C SDK data types
+LDAP_IOF_CLOSE_CALLBACK
+
+LDAP_IOF_CLOSE_CALLBACK
+
+LDAP_IOF_CLOSE_CONNECT_CALLBACK specifies the prototype
+for a callback function equivalent to the standard close system
+call.
+Description
+If you define a function with this prototype and set it in the ldap_io_fns structure, the function will be called
+by your LDAP client.
+LDAP_IOF_CLOSE_CONNECT_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK
+ LDAP_IOF_CLOSE_CALLBACK )( LBER_SOCKET );
+
+
+
+LDAP_IOF_CONNECT_CALLBACK
+
+C SDK data types
+LDAP_IOF_CONNECT_CALLBACK
+
+LDAP_IOF_CONNECT_CALLBACK
+
+LDAP_IOF_CONNECT_CALLBACK specifies the prototype
+for a callback function equivalent to the standard connect network
+I/O function.
+Description
+If you define a function with this prototype and set it in the ldap_io_fns structure, the function will be called
+by your LDAP client.
+LDAP_IOF_CONNECT_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK
+ LDAP_IOF_CONNECT_CALLBACK )( LBER_SOCKET,
+ struct sockaddr *, int );
+
+
+
+LDAP_IOF_IOCTL_CALLBACK
+
+C SDK data types
+LDAP_IOF_IOCTL_CALLBACK
+
+LDAP_IOF_IOCTL_CALLBACK
+
+LDAP_IOF_IOCTL_CALLBACK specifies the prototype for
+a callback function equivalent to the standard ioctl system
+call.
+Description
+If you define a function with this prototype and set it in the ldap_io_fns structure, the function will be called
+by your LDAP client.
+LDAP_IOF_IOCTL_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK
+ LDAP_IOF_IOCTL_CALLBACK)( LBER_SOCKET, int, ... );
+
+
+
+LDAP_IOF_READ_CALLBACK
+
+C SDK data types
+LDAP_IOF_READ_CALLBACK
+
+LDAP_IOF_READ_CALLBACK
+
+LDAP_IOF_READ_CALLBACK specifies the prototype for
+a callback function equivalent to the standard read I/O
+function.
+Description
+If you define a function with this prototype and set it in the ldap_io_fns structure, the function will be called
+by your LDAP client.
+LDAP_IOF_READ_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK
+ LDAP_IOF_READ_CALLBACK)( LBER_SOCKET, void *, int );
+
+
+
+LDAP_IOF_SELECT_CALLBACK
+
+C SDK data types
+LDAP_IOF_SELECT_CALLBACK
+
+LDAP_IOF_SELECT_CALLBACK
+
+LDAP_IOF_SELECT_CALLBACK specifies the prototype
+for a callback function equivalent to the standard select I/O
+function.
+Description
+If you define a function with this prototype and set it in the ldap_io_fns structure, the function will be called
+by your LDAP client.
+LDAP_IOF_SELECT_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK
+LDAP_IOF_SELECT_CALLBACK)( int, fd_set *, fd_set *,
+ fd_set *, struct timeval * );
+
+
+
+LDAP_IOF_SOCKET_CALLBACK
+
+C SDK data types
+LDAP_IOF_SOCKET_CALLBACK
+
+LDAP_IOF_SOCKET_CALLBACK
+
+LDAP_IOF_SOCKET_CALLBACK specifies the prototype
+for a callback function equivalent to the standard socket network
+I/O function.
+Description
+If you define a function with this prototype and set it in the ldap_io_fns structure, the function will be called
+by your LDAP client.
+LDAP_IOF_SOCKET_CALLBACK Prototype
+
+typedef LBER_SOCKET (LDAP_C LDAP_CALLBACK
+ LDAP_IOF_SOCKET_CALLBACK)( int, int, int );
+
+
+
+LDAP_IOF_SSL_ENABLE_CALLBACK
+
+C SDK data types
+LDAP_IOF_SSL_ENABLE_CALLBACK
+
+LDAP_IOF_SSL_ENABLE_CALLBACK
+
+LDAP_IOF_SSL_ENABLE_CALLBACK specifies the prototype
+for a callback function equivalent to the ssl_enable function.
+
+Description
+If you define a function with this prototype and set it in the ldap_io_fns structure, the function will be called
+by your LDAP client.
+LDAP_IOF_SSL_ENABLE_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK
+ LDAP_IOF_SSL_ENABLE_CALLBACK )( LBER_SOCKET );
+
+
+
+LDAP_IOF_WRITE_CALLBACK
+
+C SDK data types
+LDAP_IOF_WRITE_CALLBACK
+
+LDAP_IOF_WRITE_CALLBACK
+
+LDAP_IOF_WRITE_CALLBACK specifies the prototype for
+a callback function equivalent to the standard write I/O
+function.
+Description
+If you define a function with this prototype and set it in the ldap_io_fns structure, the function will be called
+by your LDAP client.
+LDAP_IOF_WRITE_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK LDAP_IOF_WRITE_CALLBACK)
+ ( LBER_SOCKET, const void *, int );
+
+
+
+ldap_io_fns
+
+C SDK data types
+ldap_io_fns
+
+ldap_io_fns
+
+The ldap_io_fns structure contains a set of pointers
+to input/output functions that you want used with SDK. You need to set up
+this structure if you want to connect to the LDAP server using a Secure Sockets
+Layer (SSL).
+ldap_io_fns Structure
+struct ldap_io_fns {
+ LDAP_IOF_READ_CALLBACK *liof_read;
+ LDAP_IOF_WRITE_CALLBACK *liof_write;
+ LDAP_IOF_SELECT_CALLBACK *liof_select;
+ LDAP_IOF_SOCKET_CALLBACK *liof_socket;
+ LDAP_IOF_IOCTL_CALLBACK *liof_ioctl;
+ LDAP_IOF_CONNECT_CALLBACK *liof_connect;
+ LDAP_IOF_CLOSE_CALLBACK *liof_close;
+ LDAP_IOF_SSL_ENABLE_CALLBACK *liof_ssl_enable;
+};
+
+
ldap_io_fns Field
+Descriptions
+
+
+
+
+Field
+
+What It Contains
+
+
+
+
+
+liof_read
+
+Function pointer to the equivalent of the standard read() I/O
+function. The function must have the prototype specified by LDAP_IOF_READ_CALLBACK.
+
+
+
+liof_write
+
+Function pointer to the equivalent of the standard write() I/O
+function. The function must have the prototype specified by LDAP_IOF_WRITE_CALLBACK.
+
+
+
+liof_select
+
+Function pointer to the equivalent of the standard select() I/O
+function. The function must have the prototype specified by LDAP_IOF_SELECT_CALLBACK.
+
+
+
+liof_socket
+
+Function pointer to the equivalent of the standard socket() network
+I/O function. The function must have the prototype specified by LDAP_IOF_SOCKET_CALLBACK.
+
+
+
+liof_ioctl
+
+Function pointer to the equivalent of the standard ioctl() system
+call. The function must have the prototype specified by
+LDAP_IOF_IOCTL_CALLBACK.
+
+
+
+liof_connect
+
+Function pointer to the equivalent of the standard connect() network
+I/O function. The function must have the prototype specified by LDAP_IOF_CONNECT_CALLBACK.
+
+
+
+liof_close
+
+Function pointer to the equivalent of the standard close() system
+call. The function must have the prototype specified by
+LDAP_IOF_CLOSE_CALLBACK.
+
+
+
+liof_ssl_enable
+
+Function pointer to the equivalent of the ssl_enable() function.
+The function must have the prototype specified by LDAP_IOF_SSL_ENABLE_CALLBACK
+ .
+
+
+
+
+LDAP_KEYCMP_CALLBACK
+
+C SDK data types
+LDAP_KEYCMP_CALLBACK
+
+LDAP_KEYCMP__CALLBACK
+
+LDAP_KEYCMP_CALLBACK specifies the prototype for
+a callback function to sort a specified set of entries.
+Definition
+If you define a function with this prototype and specify it when calling ldap_keysort_entries, the function will be called
+by your LDAP client to sort a specified set of entries.
+See Also
+ldap_keysort_entries
+
+LDAP_KEYFREE_CALLBACK
+
+C SDK data types
+LDAP_KEYFREE_CALLBACK
+
+LDAP_KEYFREE__CALLBACK
+
+LDAP_KEYFREE_CALLBACK specifies the prototype for
+a callback function that frees a sorting key.
+Description
+ldap_keysort_entries requires a function
+pointer that matches the signature defined by this type.
+
+LDAP_KEYGEN_CALLBACK
+
+C SDK data types
+LDAP_KEYGEN_CALLBACK
+
+LDAP_KEYGEN__CALLBACK
+
+LDAP_KEYGEN_CALLBACK specifies the prototype for
+a callback function that generates a key for sorting.
+Description
+ldap_keysort_entries requires a function
+pointer that matches the signature defined by this type.
+
+LDAP_MALLOC_CALLBACK
+
+C SDK data types
+LDAP_MALLOC_CALLBACK
+
+LDAP_MALLOC__CALLBACK
+
+This callback function prototype of ldap_memalloc_fns
+ represents memory allocation.
+See Also
+ldap_memalloc_fns
+
+ldap_memalloc_fns
+
+C SDK data types
+ldap_memalloc_fns
+
+ldap_memalloc_fns
+
+ldap_memalloc_fns is a structure representing callback
+functions for memory allocation. These are global and can not be set on a
+per-LDAP session handle basis. Install your own functions by making a call
+similar to the one detailed in Example
+20–24.
+Installing ldap_memalloc_fns
+
+ldap_set_option(NULL, LDAP_OPT_MEMALLOC_FN_PTRS, &memalloc_fns);
+
+
+See Also
+
+LDAP_MALLOC_CALLBACK
+
+LDAP_CALLOC_CALLBACK
+
+LDAP_REALLOC_CALLBACK
+
+LDAP_FREE_CALLBACK
+
+
+
+
+LDAPMemCache
+
+C SDK data types
+LDAPMemCache
+
+LDAPMemCache
+
+LDAPMemCache is a type of structure representing
+an in-memory, client-side cache. You can create a cache and specify the following
+information:
+
+The maximum size of the cache.
+The maximum amount of time to keep an item in the cache.
+
+A set of base DNs for the search requests that you want to
+cache (optional).
+A set of functions to ensure the thread-safety of the cache.
+To use a cache, you need to associate it with a connection handle (and LDAP structure). Before a search request is sent
+to the server, the cache is checked to determine if the same request was made
+before. If an earlier request was cached, the search results are retrieved
+from the cache.
+
+The cache uses the search criteria as the key to cached items.
+Search requests with different criteria are cached as separate items. For
+example, suppose you send a search request specifying that you just want to
+retrieve the uid attribute. Your client caches the result
+of that search. If you send a similar search request specifying that you want
+to retrieve all attributes instead of just the uid, the
+result cached from the previous search are not used.
+The cache uses a combination of the following information as the key
+to a cached item:
+
+The host name and port number of the LDAP server that you
+are searching.
+The DN to which you are currently authenticated.From
+the search criteria, the base DN, scope, filter, attributes to be returned,
+and an indication of whether to return attribute types only or attribute types
+and values.
+
+Related Functions
+Table 20–21 lists
+functions related to the LDAPMemCache structure.
+
Functions for
+LDAPMemCache Structure
+
+
+
+
+Function
+
+Description
+
+
+
+
+
+ldap_memcache_init
+
+Creates an LDAPMemCache structure and initialize
+the caching mechanism.
+
+
+
+ldap_memcache_set
+
+Associates an LDAPMemCache structure with a connection
+handle (an LDAP structure).
+
+
+
+ldap_memcache_get
+
+Returns the LDAPMemCache structure that is associated
+with a connection handle (an LDAP structure).
+
+
+
+ldap_memcache_update
+
+Forces the cache to remove expired items.
+
+
+
+ldap_memcache_flush
+
+Removes entries from the cache.
+
+
+
+ldap_memcache_destroy
+
+Frees the memory used by the cache and frees the LDAPMemCache structure.
+
+
+
+
+
+
+LDAPMessage
+
+C SDK data types
+LDAPMessage
+
+LDAPMessage
+
+LDAPMessage is a structure representing the results
+of an LDAP operation such as a chain of search results, an entry in the search
+results, or a search reference in the search results.
+LDAPMessage is not completely defined in
+ldap.h because the fields within the structure are not intended
+to be directly accessible to clients.
+
+Description
+Calling the ldap_search_ext_s or ldap_search_ext followed by the ldap_result function creates an LDAPMessage structure
+to represent the chain of results from the search. Calling the ldap_first_entry or ldap_next_entry
+ function creates an LDAPMessage structure to
+represent an entry in the search results. Calling ldap_first_reference
+ or ldap_next_reference creates an
+LDAPMessage structure to represent a search reference in the search
+results. To free the LDAPMessage structure, call the ldap_msgfree routine.
+
+LDAPMod
+
+C SDK data types
+LDAPMod
+
+LDAPMod
+
+LDAPMod is a structure that you use to specify changes
+to an attribute in a directory entry.
+Description
+Before you call the ldap_add_ext, ldap_add_ext_s, ldap_modify_ext
+ , or ldap_modify_ext_s functions
+to add or modify an entry in the directory, you need to fill LDAPMod structures
+with the attribute values that you intend to add or change.
+LDAPMod Definition
+typedef struct ldapmod {
+ int mod_op;
+ char *mod_type;
+ union {
+ char **modv_strvals;
+ struct berval **modv_bvals;
+ } mod_vals;
+#define mod_values mod_vals.modv_strvals
+#define mod_bvalues mod_vals.modv_bvals
+} LDAPMod;
+
+
LDAPMod Field
+Descriptions
+
+
+
+
+Field
+
+What It Contains
+
+
+
+
+
+mod_op
+
+The operation to be performed on the attribute and the type of data
+specified as the attribute values. This field can have one of the following
+values:
+
+LDAP_MOD_ADD adds a value to the attribute.
+
+LDAP_MOD_DELETE removes the value from
+the attribute.
+LDAP_MOD_REPLACE replaces all existing
+values of the attribute.In addition, if you are specifying binary
+values in the mod_bvalues field, you should use the bitwise
+OR operator ( | ) to combine LDAP_MOD_BVALUES
+ with the operation type. For example:mod->mod_op
+= LDAP_MOD_ADD | LDAP_MOD_BVALUESNote the following
+caveats when defining :
+If you specify LDAP_MOD_DELETE and remove
+all values in an attribute, the attribute is removed from the entry.
+
+If you specify LDAP_MOD_DELETE and NULL
+ in the mod_values field, the attribute is removed
+from the entry.
+If you specify LDAP_MOD_REPLACE and NULL
+ in the mod_values field, the attribute is removed
+from the entry.
+If you specify LDAP_MOD_REPLACE and the
+attribute does not exist in the entry, the attribute is added to the entry.
+
+If you specify LDAP_MOD_ADD and the attribute
+does not exist in the entry, the attribute is added to the entry.Also,
+if you are using the structure to add a new entry, you can specify 0 for
+the mod_op field, unless you are adding binary values and
+need to specify LDAP_MOD_BVALUES.
+
+
+
+
+
+mod_type
+
+The attribute type that you want to add, delete, or replace the values
+of such as sn or telephoneNumber.
+
+
+
+
+mod_values
+
+A pointer to a NULL terminated array of string values
+for the attribute.
+
+
+
+mod_bvalues
+
+A pointer to a NULL terminated array of berval structures for the attribute.
+
+
+
+
+If you’ve allocated memory for the structures yourself, you should
+free them when finished by calling the ldap_mods_free function.
+
+Example
+Example 20–26 sets up
+an LDAPMod structure to change the email address of a user’s
+entry to bjensen@example.com.
+Setting Up an LDAPMod Structure
+
+LDAP *ld;
+LDAPMod attribute1;
+LDAPMod *list_of_attrs[2];
+char *mail_values[] = { "bjensen@example.com", NULL };
+char *dn;
+...
+/* Identify the entry that you want changed */
+char *dn = "uid=bjensen,ou=People,dc=example,dc=com";
+
+/* Specify that you want to replace the value of an attribute */
+attribute1.mod_op = LDAP_MOD_REPLACE;
+
+/* Specify that you want to change the value of the mail attribute */
+attribute1.mod_type = "mail";
+
+/* Specify the new value of the mail attribute */
+attribute1.mod_values = mail_values;
+
+/* Add the change to the list of attributes that you want changed */
+list_of_attrs[0] = &attribute_change;
+list_of_attrs[1] = NULL;
+
+/* Update the entry with the change */
+if ( ldap_modify_s( ld, dn, list_of_attrs ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_modify_s" );
+ return( 1 );
+}
+...
+
+
+
+LDAPpwdpolicy
+
+C SDK data types
+LDAPpwdpolicy
+
+LDAPpwdpolicy
+
+An LDAPpwdpolicy structure holds values concerning
+the password policy governing a user account.
+You fill this structure by passing it to the ldap_parse_pwdpolicy_control function.
+
+LDAPpwdpolicy Description
+An LDAPpwdpolicy structure has the following
+definition:
+typedef struct LDAPpwdpolicy { /* password policy */
+ unsigned int pp_warning; /* warning status */
+#define LDAP_PP_WARNING_NONE 0x00
+#define LDAP_PP_WARNING_EXP 0x01
+#define LDAP_PP_WARNING_GRACE 0x02
+ int pp_warning_info; /* warning information */
+ int pp_error; /* error information */
+#define LDAP_PP_ERROR_NONE -1 /* no error */
+#define LDAP_PP_ERROR_EXPIRED 0 /* password expired */
+#define LDAP_PP_ERROR_LOCKED 1 /* account locked */
+#define LDAP_PP_ERROR_MUSTCHANGE 2 /* paasword has to be changed */
+#define LDAP_PP_ERROR_NOTMOD 3 /* modification not allowed */
+#define LDAP_PP_ERROR_OLDPASSWD 4 /* must provide old password */
+#define LDAP_PP_ERROR_NOQUALITY 5 /* insufficient password quality */
+#define LDAP_PP_ERROR_TOOSHORT 6 /* password too short */
+#define LDAP_PP_ERROR_MINAGE 7 /* min age still in effect */
+#define LDAP_PP_ERROR_INHISTORY 8 /* password in history */
+} LDAPpwdpolicy;
+
LDAPpwdpolicy Field
+Descriptions
+
+
+
+
+Field
+
+What It Contains
+
+
+
+
+
+pp_warning
+
+Warning code
+
+
+
+pp_warning_info
+
+If pp_warning is LDAP_PP_WARNING_EXP,
+this holds the number of seconds before the password expires.
+If pp_warning is LDAP_PP_WARNING_GRACE,
+this holds the number of grace logins remaining.
+
+
+
+pp_error
+
+One of the following error codes:
+
+LDAP_PP_ERROR_NONE, meaning no errors
+
+LDAP_PP_ERROR_EXPIRED, meaning the password
+has expired, and must be reset
+LDAP_PP_ERROR_LOCKED, meaning the account
+is locked
+LDAP_PP_ERROR_MUSTCHANGE, meaning the password
+has been reset, and must be changed
+LDAP_PP_ERROR_NOTMOD, meaning the user
+may not change the password
+LDAP_PP_ERROR_OLDPASSWD, meaning the old
+password must be supplied for this operation
+LDAP_PP_ERROR_NOQUALITY, meaning the password
+does not pass the server's password quality check
+LDAP_PP_ERROR_TOOSHORT, meaning the password
+is too short
+LDAP_PP_ERROR_MINAGE, meaning the password
+is too new to be modified, yet
+LDAP_PP_ERROR_INHISTORY, meaning the password
+matches a password stored in the password history, and thus cannot be reused
+
+
+
+
+
+
+
+
+Memory Concerns
+You allocate and free space for the LDAPpwdpolicy structure.
+
+
+LDAP_REALLOC_CALLBACK
+
+C SDK data types
+LDAP_REALLOC_CALLBACK
+
+LDAP_REALLOC_CALLBACK
+
+This callback function prototype of ldap_memalloc_fns
+ represents memory allocation.
+See Also
+ldap_memalloc_fns
+
+LDAP_REBINDPROC_CALLBACK
+
+C SDK data types
+LDAP_REBINDPROC_CALLBACK
+
+LDAP_REBINDPROC_CALLBACK
+
+LDAP_REBINDPROC_CALLBACK specifies the prototype
+for a callback function that retrieves authentication information when automatically
+following referrals to other servers.
+Description
+If you define a function with this prototype and specify it when calling
+the ldap_set_rebind_proc function, the function
+will be called by your LDAP client.
+LDAP_REBINDPROC_CALLBACK Prototype
+
+typedef int (LDAP_CALL LDAP_CALLBACK
+ LDAP_REBINDPROC_CALLBACK)( LDAP *ld, char **dnp, char **passwdp,
+ int *authmethodp, int freeit, void *arg);
+
+
+See Also
+ldap_set_rebind_proc
+
+LDAPsortkey
+
+C SDK data types
+LDAPsortkey
+
+LDAPsortkey
+
+LDAPsortkey represents the criteria to be used by
+a server control to sort search results before sending the results back to
+the client.
+Controls are part of the LDAP v3 and are used to extend the functionality
+of an LDAP operation. The two types of controls described in the LDAP v3 are:
+
+Server controls are controls that are
+sent from the client to the server along with an LDAP request. (In some cases,
+a server can include a control in the response it sends back to the client.)
+For example, you can include a server control in a search request to specify
+that you want the server to sort the search results before sending them back.
+
+Client controls are controls that can
+extend the client but that are never sent to the server. As a general example,
+you might be able to pass a client control to an LDAP API function, which
+might parse the control and use the data that you’ve specified in the
+control. &DirectorySDKForC; does not currently support any client controls.
+
+
+
+Description
+LDAPsortkey Definition
+typedef struct LDAPsortkey {
+ char *sk_attrtype;
+ char *sk_matchruleoid;
+ int sk_reverseorder;
+} LDAPsortkey;
+
+
LDAPsortkey Field
+Descriptions
+
+
+
+
+Field
+
+What It Contains
+
+
+
+
+
+sk_attrtype
+
+Pointer to a NULL terminated string that specifies
+the name of the attribute that you want to use for sorting.
+
+
+
+sk_matchruleoid
+
+Pointer to a NULL terminated string that specifies
+the object identifier (OID) of the matching rule that you want to use for
+sorting.
+
+
+
+sk_reverseorder
+
+Specifies whether or not the results are sorted in reverse order. This
+field can have one of the following values:
+
+A non-zero value specifies that the results should be sorted
+in reverse order.
+0 specifies that the results should be
+sorted in normal (forward) order.
+
+
+
+
+
+
+As an example, you can use LDAPsortkey to specify
+that you want the server to sort search results by the roomNumber attribute.
+To create an array of LDAPsortkey structures, you can call
+the ldap_create_sort_keylist function. To
+free an array of LDAPsortkey structures, you can call
+the ldap_free_sort_keylist function.
+
+
+LDAP_TF_GET_ERRNO_CALLBACK
+
+C SDK data types
+LDAP_TF_GET_ERRNO_CALLBACK
+
+LDAP_TF_GET_ERRNO_CALLBACK
+
+LDAP_TF_GET_ERRNO_CALLBACK specifies the prototype
+for a callback function to get the value of the errno variable
+for a thread.
+For more details on the errno variable, see ldap_thread_fns.
+Description
+LDAP_TF_GET_ERRNO_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK
+ LDAP_TF_GET_ERRNO_CALLBACK) ( void );
+
+
+
+LDAP_TF_GET_LDERRNO_CALLBACK
+
+C SDK data types
+LDAP_TF_GET_LDERRNO_CALLBACK
+
+LDAP_TF_GET_LDERRNO_CALLBACK
+
+LDAP_TF_GET_LDERRNO_CALLBACK specifies the prototype
+for a callback function to retrieve the LDAP result code for an operation.
+Description
+If you define a function with this prototype and set it in the ldap_thread_fns structure, your callback function
+is called when the ldap_get_lderrno function
+is called. The arguments of ldap_get_lderrno are
+passed to your function, and the value returned by your function is returned
+by ldap_get_lderrno .
+For more details on the arguments and return values that your
+function must use, see ldap_get_lderrno.
+
+LDAP_TF_GET_LDERRNO_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK
+ LDAP_TF_GET_LDERRNO_CALLBACK)( char **, char **, void * );
+
+
+
+LDAP_TF_SET_ERRNO_CALLBACK
+
+C SDK data types
+LDAP_TF_SET_ERRNO_CALLBACK
+
+LDAP_TF_SET_ERRNO_CALLBACK
+
+LDAP_TF_SET_ERRNO_CALLBACK specifies the prototype
+for a callback function to set the value of the errno variable
+for a thread.
+For more details on the errno variable, see ldap_thread_fns.
+Description
+LDAP_TF_SET_ERRNO_CALLBACK Prototype
+
+typedef void (LDAP_C LDAP_CALLBACK
+ LDAP_TF_SET_ERRNO_CALLBACK)( int );
+
+
+
+LDAP_TF_SET_LDERRNO_CALLBACK
+
+C SDK data types
+LDAP_TF_SET_LDERRNO_CALLBACK
+
+LDAP_TF_SET_LDERRNO_CALLBACK
+
+LDAP_TF_SET_LDERRNO_CALLBACK specifies the prototype
+for a callback function to set the LDAP result code for an operation.
+For more details on the arguments that your function must use,
+see ldap_set_lderrno.
+Description
+If you define a function with this prototype and set it in the ldap_thread_fns structure, your callback function
+is called when the ldap_set_lderrno function
+is called. The arguments of ldap_set_lderrno are
+passed to your function.
+LDAP_TF_SET_LDERRNO_CALLBACK Prototype
+
+typedef void (LDAP_C LDAP_CALLBACK
+ LDAP_TF_SET_LDERRNO_CALLBACK)( int, char *, char *, void * );
+
+
+
+LDAP_TF_MUTEX_ALLOC_CALLBACK
+
+C SDK data types
+LDAP_TF_MUTEX_ALLOC_CALLBACK
+
+LDAP_TF_MUTEX_ALLOC_CALLBACK
+
+LDAP_TF_MUTEX_ALLOC_CALLBACK specifies the prototype
+for a callback function to allocate a mutex.
+Description
+LDAP_TF_MUTEX_ALLOC_CALLBACK Prototype
+
+typedef void *(LDAP_C LDAP_CALLBACK
+ LDAP_TF_MUTEX_ALLOC_CALLBACK)( void );
+
+
+See Also
+ldap_thread_fns
+
+LDAP_TF_MUTEX_FREE_CALLBACK
+
+C SDK data types
+LDAP_TF_MUTEX_FREE_CALLBACK
+
+LDAP_TF_MUTEX_FREE_CALLBACK
+
+LDAP_TF_MUTEX_FREE_CALLBACK specifies the prototype
+for a callback function to free a mutex.
+Description
+LDAP_TF_MUTEX_FREE_CALLBACK Prototype
+
+typedef void (LDAP_C LDAP_CALLBACK
+ LDAP_TF_MUTEX_FREE_CALLBACK)( void * );
+
+
+See Also
+ldap_thread_fns
+
+LDAP_TF_MUTEX_LOCK_CALLBACK
+
+C SDK data types
+LDAP_TF_MUTEX_LOCK_CALLBACK
+
+LDAP_TF_MUTEX_LOCK_CALLBACK
+
+LDAP_TF_MUTEX_LOCK_CALLBACK specifies the prototype
+for a callback function to lock a mutex.
+Description
+LDAP_TF_MUTEX_LOCK_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK
+ LDAP_TF_MUTEX_LOCK_CALLBACK)( void * );
+
+
+See Also
+ldap_thread_fns
+
+LDAP_TF_MUTEX_TRYLOCK_CALLBACK
+
+C SDK data types
+LDAP_TF_MUTEX_TRYLOCK_CALLBACK
+
+LDAP_TF_MUTEX_TRYLOCK_CALLBACK
+
+This function prototype is not supported in this release of &DirectorySDKForC;.
+
+LDAP_TF_MUTEX_UNLOCK_CALLBACK
+
+C SDK data types
+LDAP_TF_MUTEX_UNLOCK_CALLBACK
+
+LDAP_TF_MUTEX_UNLOCK_CALLBACK
+
+LDAP_TF_MUTEX_UNLOCK_CALLBACK specifies the prototype
+for a callback function to unlock a mutex.
+Description
+LDAP_TF_MUTEX_UNLOCK_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK
+ LDAP_TF_MUTEX_UNLOCK_CALLBACK)( void * );
+
+
+See Also
+ldap_thread_fns
+
+LDAP_TF_SEMA_ALLOC_CALLBACK
+
+C SDK data types
+LDAP_TF_SEMA_ALLOC_CALLBACK
+
+LDAP_TF_SEMA_ALLOC_CALLBACK
+
+This function prototype is not supported in this release of &DirectorySDKForC;.
+
+LDAP_TF_SEMA_FREE_CALLBACK
+
+C SDK data types
+LDAP_TF_SEMA_FREE_CALLBACK
+
+LDAP_TF_SEMA_FREE_CALLBACK
+
+This function prototype is not supported in this release of &DirectorySDKForC;.
+
+
+LDAP_TF_SEMA_POST_CALLBACK
+
+C SDK data types
+LDAP_TF_SEMA_POST_CALLBACK
+
+LDAP_TF_SEMA_POST_CALLBACK
+
+This function prototype is not supported in this release of &DirectorySDKForC;.
+
+LDAP_TF_SEMA_WAIT_CALLBACK
+
+C SDK data types
+LDAP_TF_SEMA_WAIT_CALLBACK
+
+LDAP_TF_SEMA_WAIT_CALLBACK
+
+This function prototype is not supported in this release of &DirectorySDKForC;.
+
+
+LDAP_TF_THREADID_CALLBACK
+
+C SDK data types
+LDAP_TF_THREADID_CALLBACK
+
+LDAP_TF_THREADID_CALLBACK
+
+LDAP_TF_THREADID_CALLBACK specifies the prototype
+for a callback function to return an identifier that is unique to the calling
+thread, much like the POSIX pthread_self function does.
+Description
+LDAP_TF_THREADID_CALLBACK Prototype
+
+typedef void *(LDAP_C LDAP_CALLBACK
+ LDAP_TF_THREADID_CALLBACK)( void );
+
+
+See Also
+ldap_thread_fns
+
+ldap_thread_fns
+
+C SDK data types
+ldap_thread_fns
+
+ldap_thread_fns
+
+The ldap_thread_fns structure contains a set of pointers
+to functions that you want to use when write a multithreaded client.
+Description
+ldap_thread_fns Structure
+Definition
+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;
+};
+
+
ldap_thread_fns Field
+Descriptions
+
+
+
+
+Field
+
+What It Contains
+
+
+
+
+
+ltf_mutex_alloc
+
+Function pointer for allocating a mutex. This function is called by
+the client when needed if the function pointer is not NULL.
+The function must have the prototype specified by LDAP_TF_MUTEX_ALLOC_CALLBACK
+ .
+
+
+
+ltf_mutex_free
+
+Function pointer for freeing a mutex. This function is called by the
+client when needed if the function pointer is not NULL.
+The function must have the prototype specified by LDAP_TF_MUTEX_FREE_CALLBACK
+ .
+
+
+
+ltf_mutex_lock
+
+Function pointer for locking critical sections of code. This function
+is called by the client when needed if the function pointer is not NULL.
+The function must have the prototype specified by LDAP_TF_MUTEX_LOCK_CALLBACK
+ .
+
+
+
+ltf_mutex_unlock
+
+Function pointer for unlocking critical sections of code. This function
+is called by the client when needed if the function pointer is not NULL.
+The function must have the prototype specified by LDAP_TF_MUTEX_UNLOCK_CALLBACK
+ .
+
+
+
+ltf_get_errno
+
+Function pointer for getting the value of the errno variable.
+This function is called by the client when needed if the function pointer
+is not NULL.
+In a threaded environment, errno is typically redefined
+at compile time so that it has a value for each thread, rather than a global
+value for the entire process. Because the libldap library
+does not know what method your code and threading environment will use to
+get the value of errno for each thread, it calls this function
+to obtain the value. The function must have the prototype specified by LDAP_TF_GET_ERRNO_CALLBACK.
+
+
+
+ltf_set_errno
+
+Function pointer for setting the value of the errno variable.
+This function is called by the client when needed if the function pointer
+is not NULL.
+In a threaded environment, errno is typically redefined
+at compile time so that it has a value for each thread, rather than a global
+value for the entire process. Because the libldap library
+does not know what method your code and threading environment will use to
+get the value of errno for each thread, it calls this function
+to obtain the value. The function must have the prototype specified by LDAP_TF_SET_ERRNO_CALLBACK.
+
+
+
+ltf_get_lderrno
+
+Function pointer for getting error values from calls to functions in
+the libldap library. This function is called by the client
+as needed if the function pointer isn’t NULL. If
+this function pointer is not set, the libldap library records
+these errors in fields in the LDAP structure.
+The function must have the prototype specified by LDAP_TF_GET_LDERRNO_CALLBACK
+ .
+
+
+
+ltf_set_lderrno
+
+Function pointer for setting error values from calls to functions in
+the libldap library. This function is called by the client
+as needed if the function pointer is not NULL. If this
+function pointer is not set, the libldap library records
+these errors in fields in the LDAP structure.
+The function must have the prototype specified by LDAP_TF_SET_LDERRNO_CALLBACK
+ .
+
+
+
+ltf_lderrno_arg
+
+Additional parameter passed to the functions for getting and setting
+error values from calls to functions in the libldap library.
+(*ltf_get_lderrno) and (*ltf_set_lderrno) identify
+these functions.
+
+
+
+
+
+
+LDAPURLDesc
+
+C SDK data types
+LDAPURLDesc
+
+LDAPURLDesc
+
+LDAPURLDesc is a structure that represents the components
+of an LDAP URL.
+Description
+LDAP URLs have the following syntax:
+ldap://host:port/
+dn?attributes?
+scope?(
+filter)
+Where, for example:
+ldap://ldap.example.com/c=US?o,description?one?(o=Sales)
+Calling the ldap_url_parse function
+creates an LDAPURLDesc structure with the components of
+the URL.
+LDAPURLDesc Definition
+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
+
+
LDAPURLDesc Field
+Descriptions
+
+
+
+
+Field
+
+What It Contains
+
+
+
+
+
+lud_host
+
+Name of the host in the URL.
+
+
+
+lud_port
+
+Number of the port in the URL.
+
+
+
+lud_dn
+
+Distinguished name in the URL. This base entry DN
+identifies the starting point of the search.
+
+
+
+lud_attrs
+
+Pointer to a NULL terminated list of the attributes
+specified in the URL.
+
+
+
+lud_scope
+
+Integer representing the scope of the search specified in the URL:
+
+LDAP_SCOPE_BASE specifies a search of the
+base entry.
+LDAP_SCOPE_ONELEVEL specifies a search
+of all entries one level under the base entry (not including the base entry).
+
+LDAP_SCOPE_SUBTREE specified a search of
+all entries at all levels under the base entry (including the base entry).
+
+
+
+
+
+
+lud_filter
+
+Search filter included in the URL.
+
+
+
+lud_options
+
+Options; if LDAP_URL_OPT_SECURE, indicates that the
+protocol is ldaps:// instead of ldap://.
+
+
+
+
+
+For example, suppose you pass the following URL to the ldap_url_parse function:
+ldap://ldap.example.com:5000/dc=example,dc=com?cn,mail, \
+ telephoneNumber?sub?(sn=Jensen)
+The resulting LDAPURLDesc structure-ludpp,
+in this example-will contain the values in Table 20–27.
+
+To free the LDAPURLDesc structure, call the ldap_free_urldesc routine.
+
+LDAPuserstatus
+
+C SDK data types
+LDAPuserstatus
+
+LDAPuserstatus
+
+An LDAPuserstatus structure holds the values
+concerning the status of a user account.
+You fill this structure by passing it to the ldap_parse_userstatus_control function.
+
+LDAPuserstatus Description
+An LDAPuserstatus structure has the following
+definition:
+typedef struct LDAPuserstatus { /* user account availability */
+ unsigned int us_available; /* availability status */
+#define LDAP_US_ACCOUNT_USABLE 0
+#define LDAP_US_ACCOUNT_NOT_USABLE 1
+ int us_expire; /* will expire in seconds */
+ int us_inactive; /* boolean inactivation status */
+#define LDAP_US_ACCOUNT_ACTIVE 0
+#define LDAP_US_ACCOUNT_INACTIVE 1
+ int us_reset; /* boolean password reset */
+#define LDAP_US_ACCOUNT_NOT_RESET 0
+#define LDAP_US_ACCOUNT_RESET 1
+ int us_expired; /* boolean password expired */
+#define LDAP_US_ACCOUNT_NOT_EXPIRED 0
+#define LDAP_US_ACCOUNT_EXPIRED 1
+ int us_remaining; /* remaining logins */
+ int us_seconds; /* will unlock in seconds */
+} LDAPuserstatus;
+
LDAPuserstatus Field
+Descriptions
+
+
+
+
+Field
+
+What It Contains
+
+
+
+
+
+us_available
+
+Whether the account is currently usable
+
+
+
+us_expire
+
+Number of seconds before the password expires
+-1 means the password is not set to expire at all.
+
+
+
+
+us_inactive
+
+Whether the account is locked
+
+
+
+us_reset
+
+Whether the password has been reset
+
+
+
+us_expired
+
+Whether the password has expired
+
+
+
+us_remaining
+
+Number of remaining grace logins
+
+
+
+us_seconds
+
+Number of seconds before the server unlocks the account
+
+
+
+
+
+Memory Concerns
+You allocate and free space for the LDAPuserstatus structure.
+
+
+LDAP_VALCMP_CALLBACK
+
+C SDK data types
+LDAP_VALCMP_CALLBACK
+
+LDAP_VALCMP_CALLBACK
+
+LDAP_VALCMP_CALLBACK specifies the prototype for
+a callback function to sort a specified set of values.
+Description
+If you define a function with this prototype and specify it when calling
+the ldap_sort_strcasecmp function, the function
+will be called by your LDAP client.
+LDAP_VALCMP_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK
+ LDAP_VALCMP_CALLBACK)(const char**, const char**);
+
+ldap_sort_values requires a function
+pointer that matches the signature defined by this type.
+ldap_sort_strcasecmp is a value comparison function defined using
+this type which can therefore be passed to ldap_sort_values
+.
+See Also
+ldap_sort_values, ldap_sort_strcasecmp
+
+LDAPVersion
+
+C SDK data types
+LDAPVersion
+
+LDAPVersion
+
+The LDAPVersion structure contains version information
+about &DirectorySDKForC;.
+The LDAPVersion type is deprecated; it is documented
+here only for backward compatibility. Instead, use the ldap_get_option
+ function with the LDAP_OPT_API_INFO option and
+retrieve an LDAPAPIInfo structure.
+
+Description
+Call the ldap_version function to return
+a pointer to an LDAPVersion structure containing version
+information.
+LDAPVersion Definition
+typedef struct _LDAPVersion {
+ int sdk_version;
+ int protocol_version;
+ int SSL_version;
+ int security_level;
+} LDAPVersion;
+
+
LDAPVersion Field
+Definitions
+
+
+
+
+Field
+
+What It Contains
+
+
+
+
+
+sdk_version
+
+Version number of &DirectorySDKForC; multiplied by 100. For example,
+the value 600 in this field represents version 6.0.
+
+
+
+protocol_version
+
+Highest supported LDAP protocol version multiplied by 100. For example,
+the value 300 in this field represents LDAP v3.
+
+
+
+SSL_version
+
+Supported SSL version multiplied by 100. For example, the value 300
+in this field represents SSL 3.0).
+
+
+
+security_level
+
+Level of encryption supported in bits. For example, 128 for US domestic
+or 40 for export.
+If SSL is not enabled, the value of this field is LDAP_SECURITY_NONE
+ .
+
+
+
+
+
+
+LDAPVirtualList
+
+C SDK data types
+LDAPVirtualList
+
+LDAPVirtualList
+
+LDAPVirtualList specifies the information that can
+be used to create a virtual list view control.
+Description
+A virtual list view control is a LDAP v3 control
+designed to allow the client to retrieve subsets of search results to display
+in a virtual list box. A virtual list box is
+typically a graphical user interface that displays a long list of entries
+with a few entries visible. To display the list, the client usually does not
+retrieve the entire list of entries from the server. Instead, the client just
+retrieves the subset of entries to be displayed.
+After you create an LDAPVirtualList structure and
+specify values for its fields, you can create the virtual list view control
+by calling the function ldap_create_virtuallist_control.
+You can pass this control and a server-side sorting control-created by calling
+the ldap_create_sort_keylist function and
+the ldap_create_sort_control function-to
+the ldap_search_ext or
+ldap_search_ext_s function. To get the virtual list view response
+control sent back from the server, call the ldap_parse_result
+ function to get the list of controls returned by the server, then
+call the ldap_parse_virtuallist_control
+function to retrieve information from the control. End users can display different
+sections of the list by scrolling up or down.
+The object identifier (OID) for this control is OID 2.16.840.1.113730.3.4.9
+ , or LDAP_CONTROL_VLVREQUEST as defined in
+ldap.h. It is supported by &cnDirectoryServer;.
+The virtual list view control provides the means for your client to
+request and retrieve certain subsets of a long, sorted list of entries. The
+control specifies the following information:
+
+The entry in the list that is currently selected.
+
+The number of entries to be displayed in the list before the
+selected item.
+The number of entries to be displayed in the list after the
+selected entry.The currently selected entry can be identified
+in one of the following ways:
+By the index of the entry in the entire list in which case,
+the control specifies both the offset of the entry and the total number of
+entries in the list.
+By the value of the entry in which case, the control specifies
+that value.For example, a virtual list view control might specify
+that you want to retrieve entries 15 through 24 in a list of 100 results with
+entry 20 being the selected entry. The control uses the following information
+to specify this:
+The selected entry is the 20th entry from the top—in
+other words, the index or offset of the entry is 20—of a list of 100.
+
+Get 5 entries before the selected entry in the list (entries
+15 - 19).
+Get 4 entries after the selected entry in the list (entries
+21 - 24).As another example, a virtual list view control might
+specify that you want to retrieve a subset of entries that start with the
+letter c or a later letter in the alphabet. The control
+might specify the following information:
+The selected entry is the first entry that starts with the
+letter c. The size of the list is not relevant in determining
+the selected entry in this case.
+Get 5 entries before the selected entry in the list.
+
+Get 4 entries after the selected entry in the list.
+
+
+LDAPVirtualList Definition
+typedef struct ldapvirtuallist {
+ unsigned long ldvlist_before_count;
+ unsigned long ldvlist_after_count;
+ char *ldvlist_attrvalue;
+ unsigned long ldvlist_index;
+ unsigned long ldvlist_size;
+ void *ldvlist_extradata;
+} LDAPVirtualList;
+
+
LDAPVirtualList Field
+Descriptions
+
+
+
+
+Field
+
+What It Contains
+
+
+
+
+
+ldvlist_before_count
+
+Number of entries before the selected entry that you want to retrieve.
+
+
+
+
+ldvlist_after_count
+
+Number of entries after the selected entry that you want to retrieve.
+
+
+
+
+ldvlist_attrvalue
+
+Specifies the value that you want to find in the list. The selected
+entry in the list is the first entry that is greater than or equal to this
+value. If this field is NULL, the ldvlist_index and
+ldvlist_size fields are used to determine the selected entry instead.
+
+
+
+
+ldvlist_index
+
+If the ldvlist_attrvalue field is NULL,
+specifies the offset or index of the selected entry in the list. This field
+is used in conjunction with the ldvlist_size field to identify
+the selected entry.
+
+
+
+ldvlist_size
+
+If the ldvlist_attrvalue field is NULL,
+specifies the total number items in the list. This field is used in conjunction
+with the ldvlist_index field to identify the selected entry.
+
+
+
+
+ldvlist_extradata
+
+Reserved for application-specific use. This data is not used in the
+virtual list view control.
+
+
+
+
+
+
+LDAP_X_EXTIOF_CLOSE_CALLBACK
+This specifies the prototype for an extended I/O callback function to
+close a socket connection.
+Description
+LDAP_X_EXTIOF_CLOSE_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_CLOSE_CALLBACK )(
+ int s, void *arg );
+
+
+See Also
+ldap_x_ext_io_fns
+
+LDAP_X_EXTIOF_CONNECT_CALLBACK
+This specifies the prototype for an extended I/O callback function to
+open a socket connection.
+Description
+LDAP_X_EXTIOF_CONNECT_CALLBACK takes a timeout parameter
+whose value in milliseconds can be set by calling ldap_set_option
+ .
+LDAP_X_EXTIOF_CONNECT_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_CONNECT_CALLBACK )(
+ int s, LDAP_X_SockAddr *saddr, int saddr_len,
+ int timeout /* milliseconds */, void *arg );
+
+
+See Also
+ldap_x_ext_io_fns
+
+LDAP_X_EXTIOF_DISPOSEHANDLE_CALLBACK
+This specifies the prototype for an extended I/O callback function to
+dispose of a session handle.
+Description
+LDAP_X_EXTIOF_DISPOSEHANDLE_CALLBACK is called right
+before the LDAP session handle and its contents are destroyed during ldap_unbind. The value of the arg parameter
+passed to the callback is always the default one.
+LDAP_X_EXTIOF_DISPOSEHANDLE_CALLBACK Prototype
+
+typedef void (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_DISPOSEHANDLE_CALLBACK)(
+ LDAP *ld, void *arg );
+
+
+See Also
+ldap_x_ext_io_fns
+
+LDAP_X_EXTIOF_NEWHANDLE_CALLBACK
+This specifies the prototype for an extended I/O callback function to
+define a new session handle.
+Description
+LDAP_X_EXTIOF_NEWHANDLE_CALLBACK is called right
+after the LDAP session handle is created during ldap_init
+. The value of the arg parameter passed to the
+callback is always the default one. If the callback returns anything other
+than LDAP_SUCCESS, the session handle allocation fails.
+LDAP_X_EXTIOF_NEWHANDLE_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_NEWHANDLE_CALLBACK)(
+ LDAP *ld, void *arg );
+
+
+See Also
+ldap_x_ext_io_fns
+
+ldap_x_ext_io_fns
+This is a structure to hold extended I/O function pointers.
+ldap_x_ext_io_fns Definition
+struct ldap_x_ext_io_fns {
+ /* lextiof_size should always be set to LDAP_X_EXTIO_FNS_SIZE */
+ int lextiof_size;
+ LDAP_X_EXTIOF_CONNECT_CALLBACK *lextiof_connect;
+ LDAP_X_EXTIOF_CLOSE_CALLBACK *lextiof_close;
+ LDAP_X_EXTIOF_READ_CALLBACK *lextiof_read;
+ LDAP_X_EXTIOF_WRITE_CALLBACK *lextiof_write;
+ LDAP_X_EXTIOF_POLL_CALLBACK *lextiof_poll;
+ LDAP_X_EXTIOF_NEWHANDLE_CALLBACK *lextiof_newhandle;
+ LDAP_X_EXTIOF_DISPOSEHANDLE_CALLBACK *lextiof_disposehandle;
+ void *lextiof_session_arg;
+ LDAP_X_EXTIOF_WRITEV_CALLBACK *lextiof_writev;
+};
+#define LDAP_X_EXTIO_FNS_SIZE sizeof(struct ldap_x_ext_io_fns)
+
+
+LDAP_X_EXTIOF_POLL_CALLBACK
+This specifies the prototype for an extended I/O callback function to
+close a socket connection.
+Description
+The LDAP_X_EXTIOF_POLL_CALLBACK interface is provided
+instead of a standard select interface. The time out
+is in milliseconds. The value of the arg parameter
+passed to the callback is always the default one.
+LDAP_X_EXTIOF_POLL_CALLBACK Prototype
+
+typedef int (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_POLL_CALLBACK)(
+ LDAP_X_PollFD fds[], int nfds, int timeout /* milliseconds */,
+ void *arg );
+
+
+See Also
+ldap_x_ext_io_fns, LDAP_X_PollFD
+
+ldap_x_hostlist_status
+This structure contains utility functions for parsing space-separated
+host lists.
+Description
+ldap_x_hostlist_status Definition
+
+struct ldap_x_hostlist_status;
+LDAP_API(int) LDAP_CALL ldap_x_hostlist_first( const char *hostlist,
+ int defport, char **hostp, int *portp /* host byte order */,
+ struct ldap_x_hostlist_status **statusp );
+LDAP_API(int) LDAP_CALL ldap_x_hostlist_next( char **hostp,
+ int *portp /* host byte order */,
+ struct ldap_x_hostlist_status *status
+);
+LDAP_API(void) LDAP_CALL ldap_x_hostlist_statusfree(
+ struct ldap_x_hostlist_status *status );
+
+
+
+LDAP_X_PollFD
+This is a structure to hold the set of file descriptors
+that will be surveyed for I/O by the LDAP_X_EXTIOF_POLL_CALLBACK
+.
+Description
+LDAP_X_PollFD Structure
+Definition
+typedef struct ldap_x_pollfd { /* used by LDAP_X_EXTIOF_POLL_CALLBACK */
+ int lpoll_fd; /* integer file descriptor / socket */
+ void *lpoll_arg; /* pointer socket and for use by application */
+ short lpoll_events; /* requested event */
+ short lpoll_revents; /* returned event */
+} LDAP_X_PollFD;
+
+
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-extendop.sgm b/mozilla/directory/docs/ldapcsdk/csdk-extendop.sgm
new file mode 100644
index 00000000000..ce540227aee
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-extendop.sgm
@@ -0,0 +1,389 @@
+
+Extended Operations With &DirectorySDKForC;
+
+C SDK
+extended operations
+
+This chapter explains LDAP v3 extended operations. It also explains
+how to use the extended operations supported by your LDAP server.
+
+This chapter covers the following topics:
+How Extended Operations Work With
+Directory SDK for C
+Determining the Extended Operations
+Supported With Directory SDK for C
+Performing an Extended Operation
+With Directory SDK for C
+Performing an LDAP Password
+Modify Extended Operation With Directory SDK for C
+Using Start TLS With
+Directory SDK for C
+Performing a Who Am I?
+Extended Operation With Directory SDK for C
+
+
+How Extended Operations Work With Directory SDK for
+C
+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.
+
+Within the request, the client specifies the following:
+The OID of the extended operation that should be performed
+
+Data specific to the extended operation
+
+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.
+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.
+
+Determining the Extended Operations Supported With &DirectorySDKForC;
+To determine the extended operations supported by the server, get the
+root DSE of the server, and check the supportedExtension 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 supportedExtension attribute,
+the server does not support any extended operations. See
+To Get the Root DSE for instructions on reading that entry.
+
+Performing an Extended Operation With &DirectorySDKForC;
+
+To perform an extended operation, for which no specialized API exists,
+call one of the following functions:
+The synchronous ldap_extended_operation_s function
+
+The asynchronous ldap_extended_operation function
+
+
+Both of these functions allow you to specify the OID of the extended
+operation and the data that you want applied to the operation.
+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 LDAP_NOT_SUPPORTED result code is returned. For
+details, see Specifying the LDAP Version of Your
+Client.
+Synchronous Extended Operation
+If you want to wait for the results of an LDAP extended operation to
+complete before continuing, call the synchronous ldap_extended_operation_s
+ 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.
+ldap_extended_operation_s returns LDAP_SUCCESS
+ if the operation completed successfully, or an error code if
+a problem occurred. See the documentation for the ldap_extended_operation_s
+ function for a list of the possible result codes.
+Asynchronous Extended Operation
+If you want to perform other work in parallel while waiting for an LDAP
+extended operation to complete, perform the following procedure.
+To Perform an Asynchronous Extended Operation
+
+Call the asynchronous ldap_extended_operation function
+to send an LDAP extended operation request.This function returns
+an LDAP_SUCCESS 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 msgidp 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 ldap_result
+ function and pass in this message ID. The function passes back
+the response in an LDAPMessage structure.
+Call the ldap_parse_extended_result function
+to parse the LDAPMessage structure and retrieve information
+from the server’s response.If the server sent an OID of
+an extended operation to your client, the OID is passed back as the retoidp
+ argument. If the server sent data to your client, the data is specified
+in the berval structure passed back as the retdatap
+ argument.
+Call the ldap_get_lderrno function to get
+the LDAP result code for the operation.The function returns an
+LDAP_SUCCESS result code if the extended operation was performed
+successfully, or an LDAP error code if a problem occurred. See the documentation
+for the ldap_extended_operation function
+for a list of result codes that the server can return for this operation.
+
+
+
+Perform an Asynchronous Extended Operation
+This example client requests an asynchronous extended operation from
+the server with OID 1.2.3.4.
+#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;
+}
+
+
+
+
+Performing an LDAP Password Modify Extended
+Operation With &DirectorySDKForC;
+
+C SDK
+extended operations
+password modify
+
+RFC
+3062, LDAP Password Modify Extended Operation,
+describes the extended operation, which is particularly useful for changing
+expired passwords.
+To Perform an LDAP Password Modify Extended Operation
+
+Get a connection to the directory that uses LDAP version 3.
+
+Authenticate to the directory.
+
+As an administrator, to be able to reset an expired user password
+if you do not have the old password
+Anonymously to reset an expired password if you have the old password
+
+As the user herself to change the password that has not yet expired
+
+
+Modify the password with the synchronous function ldap_passwd_s
+ or the asynchronous function ldap_passwd and
+use ldap_parse_passwd or ldap_parse_passwd_result to
+examine the results.
+
+
+Performing an LDAP Password Modify Extended Operation
+This example changes a password using ldap_passwd_s.
+/*
+ * 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 );
+When you compile and run this sample program against &cnDirectoryServer; with
+a suffix that contains data from Example.ldif, the server
+produces output similar to this:
+Successfully changed password for uid=bjensen, ou=People, dc=example,dc=com
+
+
+
+
+Using Start TLS With &DirectorySDKForC;
+
+C SDK
+extended operations
+start TLS
+
+RFC
+4513, Lightweight Directory Access Protocol (LDAP): Authentication
+Methods and Security Mechanisms, describes the extended operation.
+Start TLS allows you to connect on a non secure port, and then request transport
+layer security.
+See Starting Transport Layer Security
+With Directory SDK for C for an example of how to use Start TLS.
+
+Performing a Who Am I? Extended Operation
+With &DirectorySDKForC;
+
+C SDK
+extended operations
+Who Am I?
+
+The “Who am I?” extended operation allows you to retrieve
+the authorization identity that is associated with a connection.
+This method can involve less code than the standard authorization identity
+controls that are described in Using the
+Authorization Identity Bind Request Control With Directory SDK for C.
+To Perform a Who Am I? Extended Operation
+
+Get a connection to the directory that uses LDAP version 3.
+
+Use ldap_whoami and ldap_parse_whoami_result
+, or use ldap_whoami_s, to retrieve the authorization
+identity.
+
+
+Getting Authorization Identity
+This example retrieves authorization identity by using ldap_whoami_s
+.
+/*
+ * 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 );
+}
+When you compile and run this sample program against &cnDirectoryServer; with a suffix that contains data from Example.ldif,
+the server produces output similar to this:
+Authorization ID: dn:uid=bjensen,ou=people,dc=example,dc=com
+
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-filter-conf.sgm b/mozilla/directory/docs/ldapcsdk/csdk-filter-conf.sgm
new file mode 100644
index 00000000000..a2d20ff8b79
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-filter-conf.sgm
@@ -0,0 +1,375 @@
+
+Using Filter Configuration Files With &DirectorySDKForC;
+
+C SDK
+filter configuration files
+
+This chapter explains how to use LDAP C API functions to work with filter
+configuration files.
+
+This chapter covers the following topics:
+Understanding Filter Configuration Files for Directory SDK for C
+Loading Filter Configuration Files With Directory SDK for C
+
+Filter Prefixes and Suffixes for Directory SDK for C
+
+Freeing Filters From Memory With Directory SDK for C
+
+Creating Filters Programmatically With Directory SDK for C
+
+
+
+Understanding Filter Configuration Files for Directory
+SDK for C
+Filter configuration files can help simplify the process of selecting
+the appropriate filter for a search request. A filter configuration
+file 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.
+For example, if the user wants to search for the email address bjensen@example.com
+, you might want to use this search filter:
+(mail=bjensen@example.com)
+Similarly, suppose the search term entered by the user contains numbers,
+as in 555-1212. In this case, you might want to use this
+search filter:
+(telephoneNumber=555-1212)
+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, @.
+Section of Filter Configuration File
+"people"
+ "^[0-9][0-9-]*$" " "
+ "(telephoneNumber=*%v))" "phone number ends with"
+ "@" " " "(mail=%v)" "email address is"
+ "(mail=%v*)" "email address starts with"
+
+You should specify the filters in the order that you want the filters
+to be used. For example, if you want to apply the (mail=%v) filter
+before the (mail=%v*) filter, make sure that the filters
+appear in that order.
+Syntax for Filter Configuration Files
+
+filter configuration files
+syntax
+
+A filter configuration file has the following format. The variables
+are discussed in the following sections.
+Syntax for a Filter Configuration
+File
+tag
+ pattern1delimiters
+filter1-1desc1-1 [scope]
+ filter1-2desc1-2 [
+scope]
+ pattern2delimiters
+filter2-1desc2-1 [scope]
+…
+
+Tag for Filter Groups
+A tag 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.
+"people"
+ … (filters for searching "person" entries) …
+"organization"
+ … (filters for "organization" entries) …
+
+When you call functions like ldap_getfirstfilter 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.
+
+Patterns to Select Filters
+pattern1 and pattern2 are
+regular expressions used to determine which filter is selected, based on the
+search criteria. For example, if you specify "^[0-9]" as
+the pattern for a filter, the filter is selected for all search criteria that
+begin with a number.
+"people"
+ "^[0-9]" …
+
+Delimiters for Fields
+Delimiters 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.
+Filter Lists
+filter1-1, filter1-2,
+and filter2-1 are filters. Use %v to
+represent the search criteria. For example, to search email addresses, use
+the filter (mail=%v). During runtime, if the search criteria
+bjensen@example.com is entered, the filter becomes (mail=bjensen@example.com)
+.
+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
+Jensen, Barbara. Use %v1, %v2, …, %vn to
+represent the different fields within the search criteria as shown here:
+"people"
+ "^[A-Z]*," "," (&(sn=%v1)(givenName=%v2))
+In this example, the delimiter is a comma. The word before the delimiter
+replaces %v1 in the filter. The word after the delimiter
+replaces %v2 in the filter. If the user searches for
+Jensen, Barbara , the resulting filter is as follows:
+(&(sn=Jensen)(givenName=Barbara))
+You can also specify ranges of fields. For example, to specify the values
+in the first three fields, use %v1-3. To specify values
+from the third field to the last field, use %v3-. To specify
+the value in the last field, use %v$.
+Descriptions of Filters
+desc1-1, desc1-2,
+and desc2-1 are phrases that briefly describe the
+filters.
+
+Filter Parameters
+
+search filters
+parameters
+
+Filter specifications in the configuration file support the following
+parameters:
+
+%v
+Insert the search criterion as is in place of %v.
+
+For example, if the filter specification is (mail=%v),
+entering bjensen results in the filter (mail=bjensen)
+.
+
+
+%v$
+Insert the last word of the search criterion as is in place
+of %v.
+For example, if the filter specification is (sn=%v$),
+entering Barbara Jensen results in the filter (sn=Jensen)
+.
+
+
+%vN
+Insert the Nth word of the criteria
+in place of %v, where N is a
+single digit between 1 and 9.
+For example, if the filter specification is (sn=%v2),
+entering Barbara Jensen results in the filter (sn=Jensen)
+.
+
+
+%vM-
+N
+Insert the sequence of the Mth
+through Nth words of the criteria in place of
+%v. Here, M and N are
+single digits between 1 and 9.
+For example, if the filter specification is (cn=%v1-2),
+entering Barbara Jensen results in the filter (cn=Barbara
+Jensen).
+
+
+%vN-
+Insert the sequence of the Nth
+through last words of the criteria in place of %v. Here,
+N is a single digit between 1 and 9.
+For example, if the filter specification is (cn=%v2-),
+entering Ms. Barbara Jensen results in the filter (cn=Barbara
+Jensen).
+
+
+
+
+
+Loading Filter Configuration Files With Directory
+SDK for C
+
+filter configuration files
+loading
+
+loading filter configuration files
+
+To load a filter configuration file, call the ldap_init_getfilter
+ function. You can also read the filter configuration file from
+a buffer in memory by calling the ldap_init_getfilter_buf function.
+Both functions return a pointer to an LDAPFiltDesc structure,
+which contains information about the filter. If an error occurs, both functions
+return NULL.
+Retrieving Filters
+
+filter configuration file
+retrieving
+
+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, (bjensen@example.com). Have your client
+automatically search for this value in the mail attribute
+of person entries.
+To retrieve the first filter that matches the search criteria, call
+the ldap_getfirstfilter function. To get the next filter
+that matches the search criteria, call the ldap_getnextfilter function.
+Both functions return a pointer to an LDAPFiltInfo structure,
+which contains information about the filter, as shown here.
+Retrieving Configuration
+Filters
+#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 );
+…
+
+Suppose that the search criteria is bjensen@example.com and
+that the client application finds a single matching entry. Then the application
+prints the following output:
+Found 1 match where email address is bjensen@example.com
+
+
+Filter Prefixes and Suffixes for Directory SDK for
+C
+
+search filters
+prefixes
+
+search filters
+suffixes
+
+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 ldap_getfirstfilter
+ and ldap_getnextfilter functions. The required
+suffix ) needed to balance the number of parentheses is
+also added. For example, suppose you use this filter in a filter configuration
+file:
+(cn=Babs Jensen)
+You can retrieve this filter by using ldap_getfirstfilter or
+ldap_getnextfilter. These functions get a filter that constrains
+your client searches to person entries for the defined filter:
+(&(objectClass=person)(cn=Babs Jensen))
+To add a prefix and suffix automatically to all filters retrieved from
+the filter configuration file, call the ldap_set_filter_additions function.
+The following example adds the prefix (&(objectClass=person) and
+the suffix ) to each filter retrieved.
+Adding Prefixes and Suffixes
+to Filters
+#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 );
+…
+
+
+Freeing Filters From Memory With Directory SDK for
+C
+
+search filters
+freeing from memory
+
+memory
+freeing search filters from
+
+When you complete your search, free the LDAPFiltDesc structure
+from memory. To free LDAPFiltDesc, call the ldap_getfilter_free
+ function as shown here.
+Freeing Filters From Memory
+#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 );
+…
+
+
+Creating Filters Programmatically With Directory
+SDK for C
+
+search filters
+creating programmatically
+
+You can build your own filters by calling the ldap_create_filter function.
+The following example builds the filter (mail=bjensen@example.com).
+
+Creating Filters
+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 );
+…
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-functions.sgm b/mozilla/directory/docs/ldapcsdk/csdk-functions.sgm
new file mode 100644
index 00000000000..27f90604018
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-functions.sgm
@@ -0,0 +1,20727 @@
+
+&DirectorySDKForC; Function Reference
+
+functions
+C SDK functions
+C SDK functions
+
+This chapter contains detailed reference material for each public function
+of &DirectorySDKForC;. Each reference gives a description of the function,
+and its usage syntax, parameters and return values. In many cases, an example
+program is also included. The chapter contains the following sections:
+
+Typographic Conventions
+
+Function Summary by Task
+
+Functions Alphabetically
+
+
+
+Typographic Conventions
+The general purpose of a function is usually given by its name. Table 21–1 lists the
+naming conventions used when adding suffixes to function names.
+
Function Naming
+Conventions
+
+
+
+
+Suffix
+
+Description
+
+
+
+
+
+_ext
+
+Identifies extended functions introduced for LDAP v3. These functions
+are augmented through additional parameters, as compared to the functions
+they replace. As LDAP v3 has become widely adopted, it is recommended you
+use extended functions whenever possible in your new applications.
+
+
+
+
+_s
+
+Identifies the synchronous form of functions. A synchronous function
+will not return until it receives a response from the server, thereby blocking
+the caller. Similar function names without this suffix are asynchronous, allowing
+the caller to perform other operations while waiting for a result.
+The synchronous and asynchronous forms exist only for functions which
+involve possible delays due to communication with the LDAP server. Functions
+which do not involve communication do not use this suffix.
+
+
+
+
+
+Function Summary by Task
+
+C SDK
+functions
+summary of
+
+functions
+C SDK
+
+In the following sections the functions of &DirectorySDKForC; are
+grouped into task categories.
+Working with Basic Encoding Rules
+
+C SDK
+functions
+for BER
+
+The functions listed in Table
+21–2 may be used to encode and decode with Basic Encoding Rules
+(BER). They are often used inside of control and extension values.
+
+
+Managing LDAP Sessions
+
+C SDK
+functions
+for LDAP sessions
+
+The functions listed in Table
+21–3 manage the different phases of an LDAP session: initialization,
+configuration, authentication (binding) and termination (unbinding).
+
Functions to Manage
+an LDAP Session
+
+
+
+
+Function
+
+Description
+
+
+
+
+
+ldap_init, prldap_init
+ (IPv6)
+
+Initializes an LDAP session.
+
+
+
+ldapssl_init
+
+Initializes an LDAP session over SSL.
+
+
+
+ldapssl_pkcs_init
+
+Initializes a thread-safe session over SSL.
+
+
+
+ldap_get_option,
+ldap_set_option
+
+Read and writes the current preference settings for a session.
+
+
+
+
+ldap_memcache_init, ldap_memcache_set, ldap_memcache_get
+, ldap_memcache_update, ldap_memcache_flush, ldap_memcache_destroy
+
+
+Creates a memory cache and uses it for search results from this session.
+Manages the data in the cache and frees the memory when the cache is no longer
+needed. The in-memory cache for search results is an extension to the API.
+
+
+
+
+ldap_unbind_ext
+
+Ends an LDAP session and frees the associated data structures.
+
+
+
+
+
+
+Performing LDAP Operations
+
+C SDK
+functions
+for LDAP operations
+
+The functions listed in Table 21–4
+ perform LDAP operations on a server and retrieve the results.
+
Functions to Perform Operations
+on LDAP Server
+
+
+
+
+Function
+
+Description
+
+
+
+
+
+ldap_add_ext or ldap_add_ext_s
+
+
+Adds a new entry to the directory.
+
+
+
+ldap_modify_ext or ldap_modify_ext_s
+
+Modifies an entry in the directory
+
+
+
+ldap_delete_ext or ldap_delete_ext_s
+
+Deletes an entry from the directory.
+
+
+
+ldap_rename orldap_rename_s
+
+
+Renames or moves one or more entries.
+
+
+
+ldap_search_ext or ldap_search_ext_s
+
+Searches the directory.
+
+
+
+ldap_compare_ext or ldap_compare_ext_s
+
+Compares a value with the values of an entry's attribute.
+
+
+
+ldap_result
+
+Checks the results of an asynchronous operation.
+
+
+
+ldap_abandon_ext
+
+Cancels an asynchronous operation.
+
+
+
+ldap_extended_operation or ldap_extended_operation_s
+
+Performs an LDAP v3 extended operation.
+
+
+
+ldap_parse_extended_result
+
+Parses the results of an LDAP v3 extended operation.
+
+
+
+ldap_msgfree
+
+Frees the memory used by the data structure for the results.
+
+
+
+
+ldap_simple_bind or ldap_simple_bind_s
+
+Authenticates to an LDAP server using a password.
+
+
+
+ldap_sasl_bind and ldap_parse_sasl_bind_result or
+ldap_sasl_bind_s
+
+Authenticates to an LDAP server using a SASL mechanism.
+
+
+
+ldap_set_rebind_proc
+
+Specifies the function used to get authentication information when following
+referrals.
+
+
+
+
+
+Processing Search Results
+
+C SDK
+functions
+for search results processing
+
+Search results are given as a chain of LDAPMessage
+ structures which can contain both entry messages and search reference
+messages. The functions listed in Table
+21–5 retrieve the results of a search operation and process
+the data structures which are returned.
+
Functions to Process Search
+Results
+
+
+
+
+Function
+
+Description
+
+
+
+
+
+ldap_first_message
+
+Gets the first message (an entry or search reference) in a chain of
+search results.
+
+
+
+ldap_next_message
+
+Gets the next message (an entry or search reference) in a chain of search
+results.
+
+
+
+ldap_count_messages
+
+Counts the number of messages (entries and search references) in a chain
+of search results.
+
+
+
+ldap_msgid
+
+Gets the ID number of a message structure containing part of a result.
+
+
+
+
+ldap_msgtype
+
+Determines whether a message structure contains an entry or a search
+reference.
+
+
+
+ldap_msgfree
+
+Frees the memory allocated for search results or other LDAP operation
+results.
+
+
+
+ldap_first_entry
+
+Gets the first entry in a chain of search results.
+
+
+
+ldap_next_entry
+
+Gets the next entry in a chain of search results.
+
+
+
+ldap_count_entries
+
+Counts the number of entries in a chain of search results.
+
+
+
+ldap_first_reference
+
+Gets the first search reference in a chain of search results.
+
+
+
+
+ldap_next_reference
+
+Gets the next search reference in a chain of search results.
+
+
+
+
+ldap_count_references
+
+Counts the number of search references in a chain of search results.
+
+
+
+
+ldap_parse_reference
+
+Extracts the referral strings from a search reference.
+
+
+
+
+
+Reading the Contents of an Entry
+
+C SDK
+functions
+for reading entry contents
+
+The functions listed in Table 21–6
+ are used to access the contents of an entry returned as a search
+result.
+
Functions to Access Contents
+of an Entry
+
+
+
+
+Function
+
+Description
+
+
+
+
+
+ldap_get_dn
+
+Get the DN for an entry.
+
+
+
+ldap_explode_dnldap_explode_rdn
+
+
+Split a DN or relative DN into its components.
+
+
+
+ldap_explode_dns
+
+Takes a DNS-style DN and breaks it up into its components.
+
+
+
+ldap_is_dns_dn
+
+Determines the style of the DN.
+
+
+
+ldap_dn2ufn
+
+Removes cryptic type names to make a DN easier to read.
+
+
+
+ldap_first_attribute
+
+Get the name of the first attribute in an entry.
+
+
+
+ldap_next_attribute
+
+Get the name of the next attribute in an entry.
+
+
+
+ldap_get_values
+
+Get the string values of an attribute.
+
+
+
+ldap_get_values_len
+
+Get the binary values of an attribute.
+
+
+
+ldap_count_values
+
+Count the string values of an attribute.
+
+
+
+ldap_count_values_len
+
+Count the binary values of an attribute.
+
+
+
+ldap_value_free
+
+Free the memory allocated for the string values of an attribute.
+
+
+
+
+ldap_value_free_len
+
+Free the memory allocated for the binary values of an attribute.
+
+
+
+
+
+
+Sorting Search Results
+
+C SDK
+functions
+for sorting search results
+
+With the functions listed in Table
+21–7, your LDAP client can sort the data structures returned
+as search results.
+
Client-side Sorting
+Functions
+
+
+
+
+Function
+
+Description
+
+
+
+
+
+ldap_sort_entries
+
+Sorts search results by DN or by a single attribute.
+
+
+
+ldap_multisort_entries
+
+Sorts search results by multiple attributes
+
+
+
+ldap_keysort_entries
+
+Sorts search results using key(s).
+
+
+
+ldap_sort_values
+
+Sorts the values of an attribute.
+
+
+
+ldap_sort_strcasecmp
+
+A case-insensitive comparison function that you can pass to ldap_sort_values.
+
+
+
+
+&cnDirectoryServer; and others also provide server-side sorting through
+LDAP v3 controls.
+
Server-Side Sorting
+Functions
+
+
+
+
+Function
+
+Description
+
+
+
+
+
+ldap_create_sort_keylist
+
+Define the criteria for sorting entries by attribute values.
+
+
+
+
+ldap_free_sort_keylist
+
+Free the memory for the sort criteria data structure.
+
+
+
+ldap_create_sort_control
+
+Create the sort control structure needed for server-side sorting.
+
+
+
+
+ldap_control_free
+
+Free the memory for the sort control data structure.
+
+
+
+ldap_parse_sort_control
+
+Analyze the server’s response to the sort control.
+
+
+
+ldap_controls_free
+
+Free the memory for the sort control response data structure.
+
+
+
+
+
+
+Working with Search Filters
+
+C SDK
+functions
+for search filters
+
+The functions listed in Table 21–9
+ retrieve and build filters using a filter configuration file. Use
+this mechanism to create complex filters to pass to the search functions.
+
Functions to Initialize,
+Retrieve, and Build Filters
+
+
+
+
+Function
+
+Description
+
+
+
+
+
+ldap_init_getfilter
+
+Read a filter configuration file into memory.
+
+
+
+ldap_init_getfilter_buf
+
+Read a filter configuration string from a buffer.
+
+
+
+ldap_getfilter_free
+
+Free the filter configuration data structure from memory.
+
+
+
+ldap_set_filter_additions
+
+Specify the prefix and suffix to be added to all filters retrieved from
+the filter configuration.
+
+
+
+ldap_getfirstfilter
+
+Retrieve the first matching filter from the filter configuration.
+
+
+
+
+ldap_getnextfilter
+
+Retrieve the next matching filter from the filter configuration.
+
+
+
+
+ldap_create_filter
+
+Build a filter without using the filter configuration file mechanism.
+
+
+
+
+
+
+Using LDAP v3 Controls
+
+C SDK
+functions
+for LDAP v3 controls
+
+&cnDirectoryServer; and others also provide additional functionality
+through LDAP v3 controls. The functions listed in Table 21–10 configure LDAP v3
+control structures which ask the server to perform advanced operations.
+
Functions to Manage LDAP
+v3 Controls
+
+
+
+
+Function
+
+Description
+
+
+
+
+
+ldap_create_authzid_control, ldap_parse_authzid_control
+
+
+Examine the authorization ID used for the operation.
+
+
+
+ldap_create_persistentsearch_control, ldap_get_entry_controls, ldap_parse_entrychange_control
+
+
+Track changes to an entry or a set of entries by setting the persistent
+search control and analyzing the entry change control sent by the server.
+
+
+
+
+ldap_create_proxiedauth_control
+
+
+Define a proxy authorization control to perform an operation under a
+different bind DN
+
+
+
+ldap_create_pwdpolicy_control
+, ldap_parse_pwdpolicy_control
+
+
+Examine password policy information for an entry.
+
+
+
+ldap_create_sort_keylist, ldap_free_sort_keylist, ldap_create_sort_control
+, ldap_parse_sort_control
+
+
+Define and send criteria for server-side sorting of search results and
+check the server’s response
+
+
+
+ldap_create_userstatus_control
+, ldap_parse_userstatus_control
+
+
+Examine account availability information for an entry.
+
+
+
+ldap_create_virtuallist_control, ldap_parse_virtuallist_control
+
+Use in conjunction with server-side sorting to limit and handle the
+number of results returned to the client.
+
+
+
+ldap_parse_result
+
+Parse an LDAP response from the server to extract the result and the
+response to the control.
+
+
+
+
+
+Using Extensions
+
+C SDK
+functions
+for parsing host lists
+
+The functions listed in Table
+21–11 are utility functions for parsing space-separated host
+lists. This is useful for implementing an extended I/O CONNECT callback function.
+
+
+
+Working with LDAP URLs
+
+C SDK
+functions
+for LDAP URLs
+
+The functions listed in Table 21–12
+ interpret LDAP URLs, universal resource locators of the form ldap://...
+.
+
Functions to Interpret
+LDAP URLs
+
+
+
+
+Function
+
+Description
+
+
+
+
+
+ldap_is_ldap_url
+
+Determine if a URL is an LDAP URL.
+
+
+
+ldap_url_parse
+
+Split up an LDAP URL into its components.
+
+
+
+ldap_url_search,
+ldap_url_search_s, ldap_url_search_st
+
+
+Perform the search specified by an LDAP URL.
+
+
+
+ldap_free_urldesc
+
+Free the memory allocated for a parsed URL.
+
+
+
+
+
+Working with UTF-8 Encoding
+
+C SDK
+functions
+for UTF-8 encoding
+
+The functions listed in Table 21–13
+ work with strings and characters that use UTF-8 encoding.
+
Functions to Handle UTF-8
+Encoding
+
+
+
+
+Function
+
+Description
+
+
+
+
+
+ldap_utf8len
+
+Function to determine byte length.
+
+
+
+ldap_utf8next
+
+Function to get next character.
+
+
+
+ldap_utf8prev
+
+Function to get previous character.
+
+
+
+ldap_utf8copy
+
+Function to copy a character to a destination.
+
+
+
+ldap_utf8characters
+
+Function to return the number of characters.
+
+
+
+ldap_utf8getcc
+
+Function moves the pointer to the next character following a UCS-4 character.
+
+
+
+
+ldap_utf8strtok_r
+
+Function moves the pointer to the next character following a UCS-4 character.
+
+
+
+
+ldap_utf8isalnum,
+ldap_utf8isalpha, ldap_utf8isdigit, ldap_utf8len, ldap_utf8isspace
+
+
+Functions to determine characteristics of the character.
+
+
+
+
+
+Handling Errors
+
+C SDK
+functions
+for error handling
+
+The functions listed in Table 21–14
+ handle errors returned by the functions. Chapter 22,
+Directory SDK for C Result Codes lists all of the error and status
+codes used in the &DirectorySDKForC;. You can also find details about possible
+errors in the reference section for each function.
+
Functions for Error Handling
+
+
+
+
+Function
+
+Description
+
+
+
+
+
+ldap_parse_result
+
+Get the error code resulting from an asynchronous LDAP operation.
+
+
+
+
+ldap_get_lderrno
+
+Get information about the last error that occurred.
+
+
+
+ldap_set_lderrno
+
+Set information about an error.
+
+
+
+ldap_err2string
+
+Get the error message for a specific error code.
+
+
+
+ldapssl_err2string
+
+Get the error message for a specific SSL error code.
+
+
+
+
+
+Managing Memory
+
+C SDK
+functions
+for memory management
+
+The functions listed in Table 21–15
+ free memory allocated by the &DirectorySDKForC; functions.
+
Functions to Free Memory
+
+
+
+
+Function
+
+Description
+
+
+
+
+
+ber_bvfree
+
+Free the memory allocated for a berval structure.
+
+
+
+
+ber_free
+
+Free the memory of a BerElement structure.
+
+
+
+
+ldap_control_free
+
+Free the memory of an LDAPControl structure.
+
+
+
+
+ldap_controls_free
+
+Free an array of LDAPControl structures.
+
+
+
+
+ldap_free_friendlymap
+
+Free the memory of a FriendlyMap structure
+
+
+
+
+ldap_free_sort_keylist
+
+Free an array of LDAPsortkey structures
+
+
+
+
+ldap_free_urldesc
+
+Free the memory of an LDAPURLDesc structure
+
+
+
+
+ldap_getfilter_free
+
+Free the memory of an LDAPFiltDesc structure.
+
+
+
+
+ldap_memfree
+
+General function for freeing memory of any other data structure
+
+
+
+
+ldap_mods_free
+
+Free an array of LDAPMod structure.
+
+
+
+
+ldap_msgfree
+
+Free the memory of an LDAPMessage structure.
+
+
+
+
+ldap_value_free
+
+Free the memory allocated for the string values of an attribute.
+
+
+
+
+ldap_value_free_len
+
+Free the memory allocated for the binary values of an attribute (an
+array of berval structures)
+
+
+
+
+You may also manage memory directly with the functions in Table 21–16.
+
Functions to Directly
+Manage Memory
+
+
+
+
+Function
+
+Description
+
+
+
+
+
+ldap_x_malloc
+
+Allocates memory.
+
+
+
+ldap_x_calloc
+
+Allocates memory for an array of elements.
+
+
+
+ldap_x_realloc
+
+Changes the size of a memory block.
+
+
+
+ldap_x_free
+
+Frees a block of memory.
+
+
+
+
+
+Working with NSPR
+
+C SDK
+functions
+for NSPR
+
+The functions listed in Table 21–17
+ tie libldap into Netscape Portable Runtime,
+NSPR.
+
Functions to Work with
+NSPR
+
+
+
+
+Function
+
+Description
+
+
+
+
+
+prldap_get_default_socket_info
+
+
+Gets default socket information.
+
+
+
+prldap_get_session_info
+
+Gets application-specific data.
+
+
+
+prldap_get_session_option
+
+Gets a session option specific to the prldap layer.
+
+
+
+
+prldap_get_socket_info
+
+Gets socket information.
+
+
+
+prldap_init
+
+Creates a new NSPR session handle.
+
+
+
+prldap_install_routines
+
+Installs NSPR functions for use with LDAP handle.
+
+
+
+
+prldap_set_default_socket_info
+
+
+Sets default socket information.
+
+
+
+prldap_set_session_info
+
+Sets application-specific data.
+
+
+
+prldap_set_session_option
+
+Sets a session option specific to the prldap layer.
+
+
+
+
+prldap_set_socket_info
+
+Sets socket information.
+
+
+
+
+
+Deprecated and Outdated Functions
+
+C SDK
+functions
+deprecated
+
+The functions listed in first column of Table 21–18 should no longer
+be used; they have been superseded by the newer functions listed in the second
+column. Deprecated functions are those being dropped from the standard or
+from extensions to &DirectorySDKForC;. Outdated functions are those which
+are not officially deprecated but which have newer, extended functions for
+performing the same operation.
+Deprecated functions are not guaranteed to be implemented in future
+versions of the API. However, all of these functions are still implemented
+in this version for backwards compatibility. For maintenance reasons, they
+have often been implemented to call the newer function which performs the
+same task.
+
Deprecated Functions
+and Their Replacements
+
+
+
+
+Deprecated Function
+
+Replacement
+
+
+
+
+
+ldap_ber_free
+
+Replaced by ber_free.
+
+
+
+ldap_bind, ldap_bind_s
+
+
+Replaced by ldap_simple_bind and ldap_simple_bind_s respectively.
+
+
+
+ldap_build_filter
+
+Replaced by ldap_create_filter.
+
+
+
+
+ldap_cache_flush
+
+Replaced by ldap_memcache_* functions.
+
+
+
+ldap_charray_add,
+ldap_charray_dup, ldap_charray_free, ldap_charray_inlist, ldap_charray_merge
+, ldap_charray_position, ldap_str2charray
+
+None documented to replace these character array functions.
+
+
+
+ldap_create_proxyauth_control
+
+
+Replaced by ldap_create_geteffectiveRights_control
+.
+
+
+
+ldap_get_lang_values, ldap_get_lang_values_len
+
+Rarely used, no replacement.
+
+
+
+ldap_modrdn
+
+Replaced by ldap_modrdn2, itself outdated
+by ldap_rename.
+
+
+
+ldap_modrdn_s
+
+Replaced by ldap_modrdn2_s, itself
+outdated by ldap_rename_s.
+
+
+
+ldap_open
+
+Replaced by ldap_init and one of the
+bind functions.
+
+
+
+ldap_result2error
+
+Replaced by ldap_parse_result.
+
+
+
+
+ldap_setfilteraffixes
+
+Replaced by ldap_set_filter_additions.
+
+
+
+
+ldap_ufn_search_c, ldap_ufn_search_ct, ldap_ufn_search_s
+, ldap_ufn_setfilter, ldap_ufn_setprefix, ldap_ufn_timeout
+
+
+None documented to replace these user-friendly search functions.
+
+
+
+
+ldap_version
+
+Replaced by ldap_get_option.
+
+
+
+
+
+
+Outdated Standard Functions and Equivalents
+
+C SDK
+functions
+outdated
+
+Many LDAP v2 functions are outdated now that LDAP v3 has been widely
+adopted. Table 21–19 lists
+both the outdated function and its new equivalent. Although LDAP v2 functions
+remain in the standard specification, you should use the LDAP v3 functions
+in any new client applications. Again, for maintenance reasons, the outdated
+functions have often been implemented to call the newer function.
+
+
+
+Functions Alphabetically
+
+C SDK
+functions
+alphabetically
+
+functions
+C SDK
+C SDK, functions
+ber_alloc
+The ber_alloc function is used to allocate a new
+Basic Encoding Rules (BER) BerElement structure.
+
+Syntax
+#include <lber.h>
+BerElement* ber_alloc( void );
+
+Parameters
+This function has no parameters.
+Returns
+
+If successful, a pointer to the newly allocated BerElement structure.
+If unsuccessful, a NULL pointer.
+
+
+
+Description
+ber_alloc is used to allocate a new BerElement structure for encoding data with the
+BER.
+See Also
+ber_printf, BerElement
+
+
+ber_alloc_t
+The ber_alloc_t function constructs and returns
+a BerElement structure.
+Syntax
+#include <lber.h>
+BerElement* ber_alloc_t( int options );
+
+Parameters
+
ber_alloc_t Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+options
+
+Contains bitwise OR of options to be used when generating the encoding
+of the BerElement. One option is defined
+and must always be supplied:
+#define LBER_USE_DER 0x01
+When this option is present, lengths will always be encoded in the minimum
+number of octets. This option does not cause values of sets and sequences
+to be rearranged in tag and byte order, so these functions are not suitable
+for generating DER output as defined in X.509 and X.680.
+
+
+
+
+
+Returns
+
+If successful, a pointer to the newly allocated BerElement structure.
+If unsuccessful, a NULL pointer.
+
+
+
+Description
+This function is the same as ber_alloc except
+it has an option.
+See Also
+ber_printf, BerElement
+
+
+ber_bvecfree
+The ber_bvecfree function frees an array of berval structures.
+Syntax
+#include <lber.h>
+void ber_bvecfree( struct berval **bv );
+
+Parameters
+
ber_bvecfree Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+bv
+
+Pointer to the array that you want to free from memory.
+
+
+
+
+
+Description
+Each berval in the array is freed using ber_bvfree, and then the array itself is freed.
+
+See Also
+ber_bvfree
+
+ber_bvdup
+The ber_bvdup function returns a copy of a berval structure.
+Syntax
+#include <lber.h>
+berval* ber_bvdup( const struct berval *bv );
+
+Parameters
+
ber_bvdup Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+bv
+
+Pointer to the berval structure to
+be duplicated.
+
+
+
+
+
+Returns
+
+If successful, a pointer to the newly allocated berval structure.
+If unsuccessful, a NULL pointer.
+
+
+
+Description
+The ber_bvdup function returns a copy of a berval structure. The data referenced in the structure
+is also duplicated. The bv_val field in the returned berval points to a different area of memory than
+the bv_val field in the argument berval
+.
+
+ber_bvfree
+The ber_bvfree function frees a berval structure.
+Syntax
+#include <lber.h>
+ void ber_bvfree( struct berval *bv );
+
+Parameters
+
ber_bvfree Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+bv
+
+Pointer to the berval structure that
+you want to free from memory.
+
+
+
+
+
+Description
+The ber_bvfree function frees a berval structure from memory. Call this function
+to free a berval passed back from the ldap_extended_operation_s , ldap_parse_extended_result
+, ldap_sasl_bind_s, or ldap_parse_sasl_bind_result functions.
+See Also
+ldap_extended_operation_s, ldap_parse_extended_result, ldap_sasl_bind_s
+ , ldap_parse_sasl_bind_result
+
+
+ber_dup
+The ber_dup function returns a copy of a BerElement structure.
+Syntax
+#include <lber.h>
+BerElement* ber_dup( BerElement *ber );
+
+Parameters
+
ber_dup Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ber
+
+Pointer to the BerElement to be duplicated.
+
+
+
+
+
+
+Returns
+
+If successful, a pointer to the newly allocated BerElement structure.
+If unsuccessful, a NULL pointer.
+
+
+
+Description
+The ber_dup function returns a copy of a BerElement structure.
+
+ber_first_element
+The ber_first_element function is used to return
+the tag and length of the first element in a set or sequence.
+Syntax
+#include <lber.h>
+unsigned long ber_first_element( BerElement *ber, unsigned long *len,
+ char **last );
+
+Parameters
+
ber_first_element Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ber
+
+Pointer to a BerElement.
+
+
+
+len
+
+Pointer to the address of the unsigned long which returns the length
+of the first element.
+
+
+
+last
+
+Address of the pointer to return the address of the last byte of the
+element.
+
+
+
+
+
+Returns
+NULL pointer is returned on error.
+Description
+The ber_first_element function is used to return
+the tag and length of the first element in a set or sequence. It also returns
+a magic cookie parameter that should be passed to subsequent calls to ber_next_element .
+See Also
+ber_next_element
+
+ber_flatten
+The ber_flatten function allocates a berval structure whose contents are taken from a
+source BerElement structure.
+Syntax
+#include <lber.h>
+int ber_flatten( BerElement *ber, struct berval **bvPtr );
+
+Parameters
+
ber_flatten Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ber
+
+Pointer to the source BerElement.
+
+
+
+
+bvPtr
+
+Pointer to the newly allocated berval structure
+which must be freed using ber_bvfree.
+
+
+
+
+
+
+Returns
+Returns 0 on success and -1 on
+error.
+Description
+This function is usually used when encoding LDAP v3 controls or extended
+operations values.
+See Also
+ber_bvfree
+
+ber_free
+The ber_free function frees a BerElement structure previously allocated with ber_alloc , ber_alloc_t,
+ ber_init, or the ldap_first_attribute
+ and ldap_next_attribute search
+functions.
+Syntax
+#include <ldap.h>
+void ber_free( BerElement *ber, int freebuf );
+
+Parameters
+
ber_free Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ber
+
+Pointer to the BerElement structure
+that you want to free.
+
+
+
+freebuf
+
+Specifies whether or not to free the buffer in the BerElement structure.
+
+
+
+
+
+Description
+This function frees a BerElement structure,
+which is used to keep track of the current attribute. When you are done working
+with the attributes, you should free this structure from memory, if it still
+exists.
+To retrieve attributes from a search result entry, you need to
+call either the ldap_first_attribute or ldap_next_attribute function. When freeing structures
+allocated by these functions, you should specify 0 for
+the freebuf argument. Otherwise, it should always be set
+to 1.
+
+Example
+Example 21–1 frees
+the BerElement structure allocated by the ldap_first_attribute function.
+Using ber_free
+LDAP *ld;
+LDAPMessage *a, *e;
+BerElement *ber;
+...
+for ( a = ldap_first_attribute( ld, e, &ber ); a != NULL;
+ a =ldap_next_attribute( ld, e, ber ) {
+ ...
+ /* Retrieve the value of each attribute */
+ ...
+}
+
+/* Free the BerElement when done */
+if ( ber != NULL ) {
+ ber_free( ber, 0 );
+}
+...
+
+
+See Also
+ber_alloc, ber_alloc_t
+ , ber_init, ldap_first_attribute
+, ldap_next_attribute
+
+ber_get_boolean
+The ber_get_boolean function is used to read a
+boolean value.
+Syntax
+#include <lber.h>
+unsigned long ber_get_boolean( BerElement *ber,
+ int *boolval );
+
+Parameters
+
ber_get_boolean Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ber
+
+Pointer to the BerElement structure
+that contains the boolean.
+
+
+
+boolval
+
+Specifies the boolean to read.
+
+
+
+
+
+Returns
+The value is returned on success and LBER_ERROR (
+-1) on failure.
+
+ber_get_int
+The ber_get_int function tries to interpret the
+next element as an integer, returning the result in num.
+Syntax
+#include <lber.h>
+unsigned long ber_get_int( BerElement *ber, int *num );
+
+Parameters
+
ber_get_int Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ber
+
+Pointer to the BerElement structure
+that contains the boolean.
+
+
+
+num
+
+Pointer to the result.
+
+
+
+
+
+Returns
+The tag of whatever it finds is returned on success and LBER_ERROR
+ (-1) on failure.
+
+ber_get_next
+The ber_get_next function reads the next BER element.
+Syntax
+#include <lber.h>
+unsigned long ber_get_next( Sockbuf *sb, unsigned long *len,
+ BerElement *ber );
+
+Parameters
+
ber_get_next Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+sb
+
+Descriptor (socket or file descriptor) from which to read.
+
+
+
+len
+
+The length of the entire element.
+
+
+
+ber
+
+Pointer to the BerElement structure.
+
+
+
+
+
+
+Description
+ber_get_next strips off and returns the leading
+tag, strips off and returns the length of the entire element, and sets up
+a pointer to ber for subsequent calls to decode the element.
+
+
+ber_get_next_buffer
+The ber_get_next_buffer function reads the next
+BER element from a byte buffer.
+This is an older function included in the SDK for backward-compatibility.
+If you are writing a new LDAP client, use ber_get_next_buffer_ext
+ instead.
+ber_get_next_buffer_ext
+The ber_get_next_buffer_ext function reads the
+next BER element from a byte buffer.
+ber_get_next_buffer_ext is a
+new version of the ber_get_next_buffer function.
+If you are writing a new LDAP client, use ber_get_next_buffer_ext
+ .
+
+Syntax
+#include <lber.h>
+unsigned long ber_get_next_buffer_ext( void *buffer,
+ size_t buffer_size, unsigned long *len, BerElement *ber,
+ unsigned long *Bytes_Scanned, Sockbuf *sb );
+
+Parameters
+
ber_get_next_buffer_ext Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+buffer
+
+Pointer to the buffer.
+
+
+
+buffer_size
+
+The size of the buffer.
+
+
+
+len
+
+The length of the entire element.
+
+
+
+ber
+
+Pointer to a BerElement.
+
+
+
+Bytes_Scanned
+
+Returns the number of bytes actually searched through.
+
+
+
+sb
+
+Descriptor (socket or file descriptor) from which to read.
+
+
+
+
+
+
+ber_get_null
+The ber_get_null function is used to read a NULL
+ element.
+Syntax
+#include <lber.h>
+unsigned long ber_get_null( BerElement *ber );
+
+Parameters
+
ber_get_null Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ber
+
+Pointer to a BerElement.
+
+
+
+
+
+Returns
+Returns the tag of the element it skips over.
+
+ber_get_option
+The ber_get_option function is used to retrieve
+information about the API and about the specific implementation being used.
+Syntax
+#include <lber.h>
+int ber_get_option( BerElement *ber, int option, void *value );
+
+
+ber_get_stringa
+The ber_get_stringa function is used to allocate
+ memory space into which an octet string is read.
+Syntax
+#include <lber.h>
+unsigned long ber_get_stringa( BerElement *ber, char **buf );
+
+
+ber_get_stringal
+The ber_get_stringal function is used to allocate
+memory space into which an octet string and its length are read.
+Syntax
+#include <lber.h>
+unsigned long ber_get_stringal( BerElement *ber, struct berval **bv );
+
+Description
+It takes a berval structure, and returns
+the result in this parameter.
+
+ber_get_stringb
+The ber_get_stringb function is used to read an
+octet string into a preallocated buffer.
+Syntax
+#include <lber.h>
+unsigned long ber_get_stringb( BerElement *ber, char *buf,
+ unsigned long *len );
+
+Description
+The len parameter should be initialized to the size
+of the buffer, and will contain the length of the octet string read upon return.
+The buffer should be big enough to take the octet string value plus a terminating
+NULL byte.
+
+ber_init
+The ber_init function constructs a new BerElement.
+Syntax
+#include <lber.h>
+BerElement * ber_init( const struct berval *bv );
+
+Parameters
+
ber_init Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+bv
+
+Pointer to a berval.
+
+
+
+
+
+Returns
+
+If successful, returns a new BerElement containing
+a copy of the data in the bv argument.
+If not, returns a NULL pointer.
+
+
+
+
+ber_init_w_nullchar
+The ber_init_w_nullchar function constructs a new BerElement with a NULL character.
+Syntax
+#include <lber.h>
+void ber_init_w_nullchar( BerElement *ber, int options );
+
+
+ber_next_element
+The ber_next_element function is used to return
+the tag and length of the next element in a set or sequence.
+Syntax
+#include <lber.h>
+unsigned long ber_next_element( BerElement *ber, unsigned long *len,
+ char *last );
+
+Parameters
+
ber_next_element Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ber
+
+Pointer to a BerElement.
+
+
+
+len
+
+Pointer to the address of the unsigned long which returns the length
+of the next element.
+
+
+
+last
+
+Address of the pointer to return the address of the last byte of the
+element.
+
+
+
+
+
+Returns
+NULL pointer is returned on error.
+Description
+The ber_next_element function is used to return
+the tag and length of the first element in a set or sequence.
+See Also
+ber_first_element
+
+ber_peek_tag
+The ber_peek_tag function returns the tag of the
+next element to be parsed in the supplied BerElement structure.
+
+Syntax
+#include <lber.h>
+unsigned long ber_peek_tag( BerElement *ber, unsigned long *len );
+
+Parameters
+
ber_peek_tag Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ber
+
+Pointer to a BerElement.
+
+
+
+len
+
+Pointer to the address of the unsigned long which returns the length
+of the next element.
+
+
+
+
+
+Returns
+Returns the tag of the next element to be read in the BerElement structure. LBER_DEFAULT is
+returned if there is no further data to be read.
+
+ber_printf
+The ber_printf function encodes a BER element.
+Syntax
+#include <lber.h>
+ber_printf( BerElement *ber, const char *fmt, ... );
+
+Parameters
+
ber_printf Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ber
+
+Pointer to a BerElement returned by ber_alloc or ber_alloc_t.
+
+
+
+
+fmt
+
+Defines the encoding format string. The format string can contain the
+following characters:
+
+-b Boolean. An integer parameter should
+be supplied. A boolean element is output.
+-i Integer. An integer parameter should
+be supplied. An integer element is output.
+-B Bitstring. A char * pointer
+to the start of the bitstring is supplied, followed by the number of bits
+in the bitstring. A bitstring element is output.
+-n Null. No parameter is required. A
+NULL element is output.
+-o Octet string. A char * is
+supplied, followed by the length of the string pointed to. An octet string
+element is output.
+-s Octet string. A NULL terminated
+string is supplied. An octet string element is output, not including the trailing
+ NULL octet.
+-t Tag. An int specifying
+the tag to give the next element is provided. This works across calls.
+
+-v Several octet strings. A NULL terminated
+array of char *s is supplied. Note that a construct like '{v}' is required
+to get an actual sequence of octet strings.
+-{ Begin sequence. No parameter is required.
+
+-} End sequence. No parameter is required.
+
+-[ Begin set. No parameter is required.
+
+-] End set. No parameter is required.
+
+
+
+
+
+
+...
+
+Values to be encoded.
+
+
+
+
+
+Description
+State information is kept with the ber parameter
+so multiple calls can be made to ber_printf to append
+things to the end of the BerElement. ber_printf
+ interprets and formats its arguments according to the format string
+fmt. Each character in fmt refers to an argument
+to ber_printf .
+Returns
+-1 if there is an error during encoding.
+
+ber_put_bitstring
+The ber_put_bitstring function writes a bitstring
+value to the given BerElement.
+Syntax
+#include <lber.h>
+int ber_put_bitstring( BerElement *ber, char *str,
+ unsigned long bitlen, unsigned long tag );
+
+Description
+The ber_put_bitstring function writes bitlen bits
+starting at str as a bitstring value to the given BerElement.
+
+ber_put_boolean
+The ber_put_boolean function writes a boolean value
+to a BerElement.
+Syntax
+#include <lber.h>
+int ber_put_boolean( BerElement *ber, int boolval, unsigned long tag );
+
+Description
+The boolean value is given by boolval to the BerElement.
+
+ber_put_enum
+The ber_put_enum function writes an enumerated
+value to a BerElement.
+Syntax
+#include <lber.h>
+int ber_put_enum( BerElement *ber, long num, unsigned long tag );
+
+
+ber_put_int
+The ber_put_int function writes an integer to a BerElement.
+Syntax
+#include <lber.h>
+int ber_put_int( BerElement *ber, long num, unsigned long tag );
+
+
+ber_put_null
+The ber_put_null function writes a writes a NULL
+ element to a BerElement.
+Syntax
+#include <lber.h>
+int ber_put_null( BerElement *ber, unsigned long tag );
+
+
+ber_put_ostring
+The ber_put_ostring function writes bytes to a
+ BerElement as an octet string.
+Syntax
+#include <lber.h>
+int ber_put_ostring( BerElement *ber, char *str,
+ unsigned long len, unsigned long tag );
+
+
+ber_put_seq
+The ber_put_seq function puts a sequence to a BerElement.
+Syntax
+#include <lber.h>
+int ber_put_seq( BerElement *ber );
+
+Parameters
+
ber_put_seq Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ber
+
+Pointer to a BerElement.
+
+
+
+
+
+Description
+The ber_start_seq function is used
+to start a sequence in the BerElement. The
+end of the sequence is marked by the nearest matching call to ber_put_seq
+.
+
+ber_put_set
+The ber_put_set function puts a set to a BerElement.
+Syntax
+#include <lber.h>
+int ber_put_set( BerElement *ber );
+
+Parameters
+
ber_put_set Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ber
+
+Pointer to a BerElement.
+
+
+
+
+
+Description
+The ber_start_set function is used
+to start a set in the BerElement. The end
+of the set is marked by the nearest matching call to ber_put_set.
+
+
+ber_put_string
+The ber_put_string function writes a NULL terminated
+string (minus the terminating 0) to a BerElement as an octet string.
+Syntax
+#include <lber.h>
+int ber_put_string( BerElement *ber, char *str, unsigned long tag );
+
+
+ber_read
+Syntax
+#include <lber.h>
+long ber_read( BerElement *ber, char *buf, unsigned long len );
+
+
+ber_reset
+Syntax
+#include <lber.h>
+void ber_reset( BerElement *ber, int was_writing );
+
+
+ber_scanf
+The ber_scanf function decodes a BerElement.
+Syntax
+#include <lber.h>
+unsigned long ber_scanf( BerElement *ber, const char *fmt, ... );
+
+Parameters
+
ber_scanf Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ber
+
+Pointer to a BerElement as returned
+by ber_get_next.
+
+
+
+fmt
+
+Defines the encoding format string. The format string can contain the
+following characters:
+
+-a Octet string. A char ** should
+be supplied. Memory is allocated, filled with the contents of the octet string,
+ NULL terminated, and returned in the parameter.
+
+-s Octet string. A char *
+buffer should be supplied, followed by a pointer to an integer initialized
+to the size of the buffer. Upon return, the NULL terminated
+octet string is put into the buffer, and the integer is set to the actual
+size of the octet string.
+-O Octet string. A struct ber_val
+** should be supplied, which upon return points to a memory allocated
+struct berval containing the octet string and its length. Call
+ ber_bvfree to free allocated memory.
+
+-b Boolean. A pointer to an integer should
+be supplied.
+-i Integer. A pointer to an integer should
+be supplied.
+-B Bitstring. A char ** should
+be supplied which will point to the memory allocated bits, followed by an
+ unsigned long *, which will point to the length (in bits)
+of the bitstring returned.
+-n Null. No parameter is required. The
+element is simply skipped if it is recognized.
+-v Sequence of octet strings. A char
+*** should be supplied, which upon return points to a memory allocated
+ NULL terminated array of char *s containing
+the octet strings. NULL is returned if the sequence is
+empty.
+
+
+
+
+
+fmt (continued)
+
+
+-V Sequence of octet strings with lengths.
+A struct berval *** should be supplied, which upon
+return points to a memory allocated, NULL terminated array
+of struct berval *s containing the octet strings and their
+lengths. NULL is returned if the sequence is empty. ber_bvecfree can be called to free the allocated
+memory.
+-x Skip element. The next element is skipped.
+
+-{ Begin sequence. No parameter is required.
+The initial sequence tag and length are skipped.
+-} End sequence. No parameter is required
+and no action is taken.
+-[ Begin set. No parameter is required.
+The initial set tag and length are skipped.
+-] End set. No parameter is required and
+no action is taken.
+
+
+
+
+
+...
+
+Values to be encoded.
+
+
+
+
+
+Description
+ber_scanf reads from ber, interprets
+the bytes according to the format string fmt, and stores
+the results in its additional arguments. The format string contains conversion
+specifications which are used to direct the interpretation of the BER element.
+
+See Also
+ber_printf
+
+ber_set_option
+Syntax
+#include <lber.h>
+int ber_set_option( BerElement *ber, int option, void *value );
+
+
+ber_set_string_translators
+Syntax
+#include <lber.h>
+unsigned long ber_skip_tag( BerElement *ber, unsigned long *len );
+
+
+ber_skip_tag
+The ber_skip_tag function advances the pointer
+to a BerElement past the first tag and length
+to the next tag.
+Syntax
+#include <lber.h>
+unsigned long ber_skip_tag( BerElement *ber, unsigned long *len );
+
+Parameters
+
ber_skip_tag Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ber
+
+Pointer to a BerElement.
+
+
+
+len
+
+Pointer to the length of the value to be skipped.
+
+
+
+
+
+Description
+ber_skip_tag should only be used with constructed
+types and situations when a BER encoding is used as the value of an octet
+string.
+See Also
+ber_peek_tag
+
+ber_sockbuf_alloc
+Syntax
+#include <lber.h>
+Sockbuf* ber_sockbuf_alloc( void );
+
+
+ber_sockbuf_free
+Syntax
+#include <lber.h>
+void ber_sockbuf_free( Sockbuf* p );
+
+
+ber_sockbuf_free_data
+Syntax
+#include <lber.h>
+void ber_sockbuf_free_data(Sockbuf *p);
+
+
+ber_sockbuf_get_option
+Syntax
+#include <lber.h>
+int ber_sockbuf_get_option( Sockbuf *sb, int option, void *value );
+
+
+ber_sockbuf_set_option
+Syntax
+#include <lber.h>
+int ber_sockbuf_set_option( Sockbuf *sb, int option, void *value );
+
+
+ber_special_alloc
+The ber_special_alloc function allocates a BerElement structure plus some extra memory.
+Syntax
+#include <lber.h>
+void* ber_special_alloc( size_t size, BerElement **ppBer );
+
+Returns
+Returns a pointer to the BerElement and
+a pointer to the extra memory.
+Description
+ber_special_alloc allocates a ber data buffer within
+the same block, thus saving a call to calloc later when we read data.
+
+
+ber_special_free
+The ber_special_free function frees an allocated BerElement structure.
+Syntax
+#include <lber.h>
+void ber_special_free( void* buf, BerElement *ber );
+
+See Also
+ber_special_alloc
+
+ber_stack_init
+Syntax
+#include <lber.h>
+int) LDAP_CALL ber_stack_init(BerElement *ber, int options,
+ char * buf, size_t size);
+
+
+ber_start_seq
+The ber_start_seq function is used to start a sequence
+in a BerElement.
+Syntax
+#include <lber.h>
+int ber_start_seq( BerElement *ber, unsigned long tag );
+
+See Also
+ber_put_seq
+
+ber_start_set
+The ber_start_seq function is used to start a set
+in a BerElement.
+Syntax
+#include <lber.h>
+int ber_start_set( BerElement *ber, unsigned long tag );
+
+See Also
+ber_put_set
+
+ber_svecfree
+Syntax
+#include <lber.h>
+void ber_svecfree( char **vals );
+
+
+ber_write
+Syntax
+#include <lber.h>
+long ber_write( BerElement *ber, char *buf,
+ unsigned long len, int nosos );
+
+
+ldap_abandon
+The ldap_abandon function cancels an asynchronous
+LDAP operation that is in progress.
+This is an older function included in the SDK for backward-compatibility.
+If you are writing a new LDAP client, use ldap_abandon_ext
+ instead.
+Syntax
+#include <ldap.h>
+int ldap_abandon( LDAP *ld, int msgid );
+
+Parameters
+
ldap_abandon Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+msgid
+
+Message ID of an LDAP operation.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+-1 if unsuccessful.
+
+The appropriate LDAP error code is also set in the LDAP structure. You can retrieve the error code
+by calling ldap_get_lderrno. Some possible
+codes are:
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+
+
+
+Description
+Please use the newer version of this function, ldap_abandon_ext
+.
+Example
+Example 21–2 cancels
+an ldap_url_search operation, abandoning
+the results of the operation.
+Cancelling an ldap_url_search Operation
+
+LDAP *ld;
+char *url = "ldap://ldap.example.com/c=US?o,description?one?o=sales";
+int msgid;
+...
+/* Initiate a search operation */
+msgid = ldap_url_search( ld, url, 0 );
+...
+/* Abandon the search operation */
+if ( ldap_abandon( ld, msgid ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_abandon" );
+ return( 1 );
+}
+...
+
+
+See Also
+ldap_abandon_ext
+
+ldap_abandon_ext
+The ldap_abandon_ext function cancels an asynchronous
+LDAP operation that is in progress.
+ldap_abandon_ext is a new version
+of the ldap_abandon function. If you are
+writing a new LDAP client, use ldap_abandon_ext.
+
+Syntax
+#include <ldap.h>
+ int ldap_abandon_ext( LDAP *ld, int msgid,
+ LDAPControl **serverctrls, LDAPControl **clientctrls );
+
+Parameters
+
ldap_abandon_ext Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+msgid
+
+Message ID of an LDAP operation to identify the operation to be cancelled.
+When you call an asynchronous function such as ldap_search_ext
+, the msgidp argument returns a pointer to a message
+ID that uniquely identifies the operation. Thus, when you call ldap_abandon_ext, your LDAP client is able to send
+a request specifying the message ID of the operation to be cancelled.
+
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+
+
+Description
+The ldap_abandon_ext function cancels an asynchronous
+LDAP operation that is in progress. For example, if you called ldap_search_ext to initiate an LDAP search operation
+on the server, you can call ldap_abandon_ext to cancel
+it. When you call ldap_abandon_ext, the function checks
+to see if the results of the operation have already been returned. If so,
+ldap_abandon_ext deletes the message ID from the queue of pending
+messages. If the results have not been returned, ldap_abandon_ext sends
+a request to abandon the operation. Once cancelled, the results of the operation
+will not be returned, even if you subsequently call ldap_result
+ to retrieve them. To identify the operation to be cancelled, specify
+the message ID of the operation in the msgid argument of
+the ldap_abandon_ext function.
+Example
+Example 21–3 cancels
+an ldap_url_search operation, abandoning
+the results of the operation.
+Using ldap_abandon_ext
+LDAP *ld;
+char *url = "ldap://ldap.example.com/c=US?o,description?one?o=sales";
+int msgid;
+LDAPControl **srvrctrls, **clntctrls;
+...
+/* Initiate a search operation */
+msgid = ldap_url_search( ld, url, 0 );
+...
+/* Abandon the search operation */
+if ( ldap_abandon_ext( ld, msgid, srvrctrls, clntctrls )
+ != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_abandon" );
+ return( 1 );
+}
+...
+
+
+See Also
+ldap_add_ext, ldap_compare_ext
+ , ldap_delete_ext, ldap_extended_operation, ldap_modify_ext
+, ldap_rename,
+ldap_sasl_bind , ldap_search_ext,
+ ldap_simple_bind, ldap_url_search
+
+
+ldap_add
+The ldap_add function adds a new entry to the directory
+asynchronously.
+This is an older function that is included in the SDK for backward-compatibility.
+If you are writing a new LDAP client, use ldap_add_ext
+instead.
+Syntax
+#include <ldap.h>
+ int ldap_add( LDAP *ld, const char *dn, LDAPMod **attrs );
+
+Parameters
+
ldap_add Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to add. With the exception of the leftmost component,
+all components of the DN (for example, o=organization or
+c=country) must already exist.
+
+
+
+attrs
+
+Pointer to a NULL terminated array of pointers to LDAPMod structures representing the attributes of
+the new entry.
+
+
+
+
+
+Returns
+The message ID of the ldap_add operation.
+To check the result of this operation, call
+ldap_result and ldap_result2error.
+See ldap_add_ext_s for a list of possible
+result codes for the LDAP add operation.
+
+Description
+Please use the newer version of this function, ldap_add_ext
+ .
+Example
+Example 21–4 adds
+a new entry to the directory.
+Using ldap_add
+#include <ldap.h>
+...
+LDAP *ld;
+LDAPMod *list_of_attrs[4];
+LDAPMod attribute1, attribute2, attribute3;
+LDAPMessage *result;
+int msgid, rc;
+struct timeval tv;
+
+/* Distinguished name of the new entry. Note that "dc=example,dc=com" and
+ "ou=People,dc=example,dc=com" must already exist in the directory. */
+char *dn = "uid=bjensen,ou=People,dc=example,dc=com";
+
+/* To add a "person" entry, you must specify values for the sn, cn,
+ and objectClass attributes. (These are required attributes.) */
+char *sn_values[] = { "Jensen", NULL };
+
+/* To specify multiple values for an attribute, add the different values
+ to the array. */
+char *cn_values[] = { "Barbara Jensen", "Babs Jensen", NULL };
+
+/* The object class for a "person" entry is "inetOrgPerson", which is a
+ subclass of "top", "person", and "organizationalPerson". You should add
+ all of these classes as values of the objectClass attribute. */
+char *objectClass_values[] = { "top", "person", "organizationalPerson",
+ "inetOrgPerson", NULL };
+...
+/* Specify the value and type of each attribute in separate LDAPMod
+ structures */
+attribute1.mod_type = "sn";
+attribute1.mod_values = sn_values;
+attribute2.mod_type = "cn";
+attribute2.mod_values = cn_values;
+attribute3.mod_type = "objectClass";
+attribute3.mod_values = objectClass_values;
+
+/* Add the pointers to these LDAPMod structures to an array */
+list_of_attrs[0] = &attribute1;
+list_of_attrs[1] = &attribute2;
+list_of_attrs[2] = &attribute3;
+list_of_attrs[3] = NULL;
+...
+/* Set up the timeout period for adding the new entry */
+tv.tv_sec = tv.tv_usec = 0;
+
+/* Add the user "Barbara Jensen" */
+if ( ( msgid = ldap_add( ld, dn, list_of_attrs ) ) == -1 ) {
+ ldap_perror( ld, "ldap_add" );
+ return( 1 );
+}
+
+/* Check to see if the operation has completed */
+while ( ( rc = ldap_result( ld, msgid, 0, &tv, &result ) ) == 0 ) {
+ ...
+ /* do other work while waiting for the operation to complete */
+ ...
+}
+
+/* Check the result to see if any errors occurred */
+if (( rc = ldap_result2error( ld, result, 1 )) != LDAP_SUCCESS ) {
+ printf( "Error while adding entry: %s\n", ldap_err2string( rc ));
+}
+...
+
+
+See Also
+ldap_add_ext
+
+ldap_add_ext
+The ldap_add_ext function adds a new entry to the
+directory asynchronously.
+ldap_add_ext is a new version
+of the ldap_add function. If you are writing
+a new LDAP client, use ldap_add_ext.
+
+Syntax
+#include <ldap.h>
+ int ldap_add_ext( LDAP *ld, const char *dn, LDAPMod **attrs,
+ LDAPControl **serverctrls, LDAPControl **clientctrls,
+ int *msgidp );
+
+Parameters
+
ldap_add_ext Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to add. With the exception of the leftmost component,
+all components of the DN (for example, o=organization or
+c=country) must already exist.
+
+
+
+attrs
+
+Pointer to a NULL terminated array of pointers to LDAPMod structures representing the attributes of
+the new entry.
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+msgidp
+
+Pointer to an integer that will be set to the message ID of the LDAP
+operation.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+
+Description
+The ldap_add_ext adds a new entry to the directory.
+To add a new entry to the directory, you need to specify:
+
+A unique DN identifying the new entry.Use the
+ dn argument to specify the DN of the new entry. The parents
+of the entry should already exist. For example, if you are adding the entry
+uid=bjensen,ou=People,dc=example,dc=com , the entries ou=People
+ and dc=example,dc=com must already exist in
+the directory.
+A set of attributes for the new entry.Create
+an LDAPMod structure for each attribute.
+Set the mod_op field to 0 if the attribute
+values are string values. To specify values that consist of binary data (such
+as a sound file or a JPEG file), set the mod_op field to
+LDAP_MOD_BVALUES. Create an array of these LDAPMod
+ structures and pass the array as the attrs argument.
+ldap_add_ext is an asynchronous function; it does
+not directly return results. In order to get the results of the asynchronous
+operation, you need to call the ldap_result and ldap_parse_result functions. If you want the results
+to be returned directly by the function, call the synchronous function ldap_add_ext_s. For a list of possible result codes
+for an LDAP add operation, see the ldap_add_ext_s
+function.
+
+
+See Also
+ldap_add_ext_s,
+ldap_result, ldap_parse_result, LDAPMod
+
+ldap_add_ext_s
+The ldap_add_ext_s function adds a new entry to
+the directory synchronously.
+ldap_add_ext_s is a new version
+of the ldap_add_s function. If you are writing
+a new LDAP client, use ldap_add_ext_s.
+
+Syntax
+#include <ldap.h>
+ int ldap_add_ext_s( LDAP *ld, const char *dn, LDAPMod **attrs,
+ LDAPControl **serverctrls, LDAPControl **clientctrls );
+
+Parameters
+
ldap_add_ext_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to add. With the exception of the leftmost component,
+all components of the DN (for example, o=organization or
+c=country) must already exist.
+
+
+
+attrs
+
+Pointer to a NULL terminated array of pointers to LDAPMod structures representing the attributes of
+the new entry.
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_LOCAL_ERROR if an error occurred
+when receiving the results from the server.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded results from the server.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+&cnDirectoryServer; and other LDAP server products may send result
+codes in addition to those described. For example, the server may have loaded
+a plug-in that returns custom result codes. Check your LDAP server documentation
+for other result codes.
+
+Description
+The ldap_add_ext_s function adds a new entry to
+the directory. To add a new entry to the directory, you need to specify:
+
+A unique DN identifying the new entry.Use the
+ dn argument to specify the DN of the new entry. The parents
+of the entry should already exist. For example, if you are adding the entry
+uid=bjensen,ou=People,dc=example,dc=com , the entries ou=People
+ and dc=example,dc=com must already exist in
+the directory.
+A set of attributes for the new entry.Create
+an LDAPMod structure for each attribute.
+Set the mod_op field to 0 if the attribute
+values are string values. To specify values that consist of binary data (such
+as a sound file or a JPEG file), set the mod_op field to
+LDAP_MOD_BVALUES. Create an array of these LDAPMod
+ structures and pass the array as the attrs argument.
+ldap_add_ext_s is a synchronous function; it directly
+returns the results of the operation. If you want to perform other operations
+while waiting for the results of this operation, call the asynchronous function ldap_add_ext.
+
+
+See Also
+ldap_add_ext, LDAPMod
+
+
+ldap_add_s
+The ldap_add_s function adds a new entry to the
+directory synchronously.
+This is an older function that is included in the SDK for backward-compatibility.
+If you are writing a new LDAP client, use ldap_add_ext_s
+ instead.
+Syntax
+#include <ldap.h>
+int ldap_add_s( LDAP *ld, const char *dn, LDAPMod **attrs );
+
+Parameters
+
ldap_add_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to add. With the exception of the leftmost component,
+all components of the DN (for example, o=organization or
+c=country) must already exist.
+
+
+
+attrs
+
+Pointer to a NULL terminated array of pointers to LDAPMod structures representing the attributes of
+the new entry.
+
+
+
+
+
+Returns
+See ldap_add_ext_s for a list of possible
+return codes.
+Description
+Please use the newer version of this function, ldap_add_ext_s
+ .
+Example
+Example 21–5 adds
+a new entry to the directory.
+Using ldap_add_s
+#include <ldap.h>
+...
+LDAP *ld;
+LDAPMod *list_of_attrs[4];
+LDAPMod attribute1, attribute2, attribute3;
+
+/* Distinguished name of the new entry. Note that "dc=example,dc=com" and
+ "ou=People,dc=example,dc=com" must already exist in the directory. */
+char *dn = "uid=bjensen,ou=People,dc=example, dc=com";
+
+/* To add a "person" entry, you must specify values for the sn, cn,
+ and objectClass attributes. (These are required attributes.) */
+char *sn_values[] = { "Jensen", NULL };
+
+/* To specify multiple values for an attribute, add the different values
+ to the array. */
+char *cn_values[] = { "Barbara Jensen", "Babs Jensen", NULL };
+
+/* The object class for a "person" entry is "inetOrgPerson", which is a
+ * subclass of "top", "person", and "organizationalPerson". You should add
+ * all of these classes as values of the objectClass attribute. */
+char *objectClass_values[] = { "top", "person", "organizationalPerson",
+ "inetOrgPerson", NULL };
+...
+/* Specify the value and type of each attribute in separate LDAPMod
+ structures */
+attribute1.mod_type = "sn";
+attribute1.mod_values = sn_values;
+attribute2.mod_type = "cn";
+attribute2.mod_values = cn_values;
+attribute3.mod_type = "objectClass";
+attribute3.mod_values = objectClass_values;
+
+/* Add the pointers to these LDAPMod structures to an array */
+list_of_attrs[0] = &attribute1;
+list_of_attrs[1] = &attribute2;
+list_of_attrs[2] = &attribute3;
+list_of_attrs[3] = NULL;
+...
+/* Add the user "Barbara Jensen" */
+if ( ldap_add_s( ld, dn, list_of_attrs ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_add_s" );
+ return( 1 );
+}
+...
+
+
+See Also
+ldap_add_ext_s
+
+ldap_ber_free
+The ldap_ber_free function frees a BerElement structure from memory.
+This is an older function that is included in the SDK for backward-compatibility.
+If you are writing a new LDAP client, use ber_free instead.
+Except in name, the two functions are identical.
+Syntax
+#include <ldap.h>
+ void ldap_ber_free( BerElement *ber, int freebuf );
+
+Parameters
+
ldap_ber_free Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ber
+
+Pointer to the BerElement structure
+that you want to free.
+
+
+
+freebuf
+
+Specifies whether or not to free the buffer in the BerElement structure.
+
+
+
+
+
+Description
+Please use the newer version of this function, ber_free
+ .
+See Also
+ber_free
+
+ldap_bind
+This function is deprecated and should not be used. It is included
+in ldap-deprecated.h for backward-compatibility. Use ldap_simple_bind instead.
+ldap_bind can be used when the authentication method
+being used needs to be selected at runtime.
+Syntax
+#include <ldap-deprecated.h>
+ ldap_bind( LDAP *ld, const char *who, const char *passwd, int method );
+
+Parameters
+
ldap_bind Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+who
+
+DN of the user who wants to authenticate. For anonymous authentication,
+set this or the passwd argument to NULL.
+
+
+
+
+passwd
+
+Password of the user who wants to authenticate. For anonymous authentication,
+set this or the who argument to NULL.
+
+
+
+method
+
+Defines the authentication method to be used. It should be set to
+LDAP_AUTH_SIMPLE to select simple authentication.
+
+
+
+
+
+Returns
+ldap_bind returns the message ID of the request
+it initiates.
+Description
+This is an asynchronous function that authenticates a specified entry
+to the directory. After a connection is made to an LDAP server using ldap_open, a bind operation must be performed before
+other operations can be attempted over the connection.
+See Also
+ldap_open, ldap_init
+, prldap_init (IPv6), ldap_bind_s
+
+ldap_bind_s
+This function is deprecated and should not be used. It is included
+in ldap-deprecated.h for backward-compatibility. Use ldap_simple_bind_s instead.
+ldap_bind_s can be used when the authentication
+method needs to be selected at runtime.
+Syntax
+#include <ldap-deprecated.h>
+ ldap_bind_s( LDAP *ld, const char *who, const char *cred, int method );
+
+Parameters
+
ldap_bind_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+who
+
+DN of the user who wants to authenticate. For anonymous authentication,
+set this or the passwd argument to NULL.
+
+
+
+
+cred
+
+Password of the user who wants to authenticate. For anonymous authentication,
+set this or the who argument to NULL.
+
+
+
+method
+
+Defines the authentication method to be used. It should be set to
+LDAP_AUTH_SIMPLE to select simple authentication.
+
+
+
+
+
+Returns
+ldap_bind_s returns an LDAP error indication.
+
+Description
+This is a synchronous function that authenticates a specified entry
+to the directory. After a connection is made to an LDAP server using ldap_open , a bind operation must be performed
+before other operations can be attempted over the connection.
+See Also
+ldap_open, ldap_init
+, prldap_init (IPv6), ldap_bind
+
+ldap_build_filter
+This function is deprecated and should not be used. It is included
+in ldap-deprecated.h for backward-compatibility. Use ldap_create_filter instead.
+See Also
+ldap_create_filter
+
+ldap_cache_flush
+This function is deprecated and should not be used. It is included
+in ldap-deprecated.h for backward-compatibility. Use the
+ ldap_memcache_* functions instead.
+For more specific information, see the header file ldap-deprecated.h
+ .
+See Also
+ldap_memcache_init, ldap_memcache_set, ldap_memcache_get
+, ldap_memcache_update, ldap_memcache_flush , ldap_memcache_destroy
+
+
+ldap_charray_add
+This function is deprecated and should not be used. It is included
+in ldap-to-be-deprecated.h for backward-compatibility.
+
+For more specific information, see the header file ldap-to-be-deprecated.h
+ .
+ldap_charray_dup
+This function is deprecated and should not be used. It is included
+in ldap-to-be-deprecated.h for backward-compatibility.
+
+For more specific information, see the header file ldap-to-be-deprecated.h
+ .
+
+ldap_charray_free
+This function is deprecated and should not be used. It is included
+in ldap-to-be-deprecated.h for backward-compatibility.
+
+For more specific information, see the header file ldap-to-be-deprecated.h
+ .
+ldap_charray_inlist
+This function is deprecated and should not be used. It is included
+in ldap-to-be-deprecated.h for backward-compatibility.
+
+For more specific information, see the header file ldap-to-be-deprecated.h
+ .
+
+ldap_charray_merge
+This function is deprecated and should not be used. It is included
+in ldap-to-be-deprecated.h for backward-compatibility.
+
+For more specific information, see the header file ldap-to-be-deprecated.h
+ .
+ldap_charray_position
+This function is deprecated and should not be used. It is included
+in ldap-to-be-deprecated.h for backward-compatibility.
+
+For more specific information, see the header file ldap-to-be-deprecated.h
+ .
+
+ldap_compare
+The ldap_compare function asynchronously determines
+if an attribute of an entry contains a specified value.
+This is an older function that is included in the SDK for backward-compatibility.
+If you are writing a new LDAP client, use ldap_compare_ext
+ instead.
+Syntax
+#include <ldap.h>
+ int ldap_compare( LDAP *ld, const char *dn, const char *attr,
+ const char *value );
+
+Parameters
+
ldap_compare Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry used in the comparison.
+
+
+
+attr
+
+Attribute type that you want to check the value against.
+
+
+
+value
+
+Value that you want to compare against the attribute values.
+
+
+
+
+
+
+Returns
+Returns the message ID of the ldap_compare operation.
+To check the result of this operation, call
+ldap_result and ldap_result2error.
+See ldap_compare_ext_s function for a list
+of possible result codes for the LDAP compare operation.
+
+Description
+Please use the newer version of this function, ldap_compare_ext
+ .
+Example
+Example 21–6 checks
+to see if Barbara Jensen has the email address bjensen@example.com.
+
+Using ldap_compare
+#include <stdio.h>
+#include <ldap.h>
+...
+LDAP *ld;
+char *dn = "uid=bjensen,ou=People,dc=example, dc=com";
+int msgid;
+...
+msg_id = ldap_compare( ld, dn, "mail", "bjensen@example.com" );
+...
+
+
+See Also
+ldap_compare_ext
+
+ldap_compare_ext
+The ldap_compare_ext function asynchronously determines
+if an attribute of an entry contains a specified value.
+ldap_compare_ext is a new version
+of the ldap_compare function. If you are
+writing a new LDAP client, use ldap_compare_ext.
+
+Syntax
+#include <ldap.h>
+int ldap_compare_ext( LDAP *ld, const char *dn, const char *attr,
+ struct berval *bvalue, LDAPControl **serverctrls,
+ LDAPControl **clientctrls, int *msgidp );
+
+Parameters
+
ldap_compare_ext Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry used in the comparison.
+
+
+
+attr
+
+Attribute type that you want to check the value against.
+
+
+
+value
+
+Value that you want to compare against the attribute values.
+
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+msgidp
+
+Pointer to an integer that will be set to the message ID of the LDAP
+operation.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+To check the result of this operation, call
+ldap_result and ldap_parse_result.
+
+
+Returns
+For a list of the possible result codes for an LDAP compare operation,
+see ldap_compare_ext_s.
+Description
+The ldap_compare_ext function compares the value
+of an attribute in an entry against a specified value. Because ldap_compare_ext
+ is an asynchronous function, it does not directly return results.
+If you want the results to be returned directly by the function, call the
+synchronous function ldap_compare_ext_s.
+
+See Also
+ldap_compare_ext_s, ldap_result, ldap_parse_result
+
+
+ldap_compare_ext_s
+The ldap_compare_ext_s function synchronously determines
+if an attribute of an entry contains a specified value.
+Syntax
+#include <ldap.h>
+ int ldap_compare_ext_s( LDAP *ld, const char *dn,
+ const char *attr, struct berval *bvalue,
+ LDAPControl **serverctrls, LDAPControl **clientctrls );
+
+Parameters
+
ldap_compare_ext_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry used in the comparison.
+
+
+
+attr
+
+Attribute type that you want to check the value against.
+
+
+
+value
+
+Value that you want to compare against the attribute values.
+
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_COMPARE_TRUE if the entry contains
+the attribute value.
+LDAP_COMPARE_FALSE if the entry does
+not contain the attribute value.
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_LOCAL_ERROR if an error occurred
+when receiving the results from the server.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded results from the server.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+&cnDirectoryServer; and other LDAP server products may send result
+codes in addition to those described. For example, the server may have loaded
+a plug-in that returns custom result codes. Check your LDAP server documentation
+for other result codes.
+
+Description
+The ldap_compare_ext_s function compares the value
+of an attribute in an entry against a specified value. ldap_compare_ext_s
+ is a synchronous function, which directly returns the results
+of the operation. If you want to perform other operations while waiting for
+the results of this operation, call the asynchronous function ldap_compare_ext.
+See Also
+ldap_compare_ext
+
+ldap_compare_s
+The ldap_compare_s function synchronously determines
+if an attribute of an entry contains a specified value.
+This is an older function that is included in the SDK for backward-compatibility.
+If you are writing a new LDAP client, use ldap_compare_ext_s
+ instead.
+Syntax
+#include <ldap.h>
+ int ldap_compare_s( LDAP *ld, const char *dn,
+ const char *attr, const char *value );
+
+Parameters
+
ldap_compare_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry used in the comparison.
+
+
+
+attr
+
+Attribute type that you want to check the value against.
+
+
+
+value
+
+Value that you want to compare against the attribute values.
+
+
+
+
+
+
+Returns
+For a list of the possible result codes for an LDAP compare operation,
+see ldap_compare_ext_s.
+Description
+Please use the newer version of this function, ldap_compare_ext_s
+ .
+Example
+Example 21–7 checks
+to see if Barbara Jensen has the email address bjensen@example.com.
+
+Using ldap_compare_s
+#include <stdio.h>
+#include <ldap.h>
+LDAP *ld;
+char *dn = "uid=bjensen,ou=People,dc=example, dc=com";
+int has_value;
+...
+has_value = ldap_compare_s( ld, dn, "mail", "bjensen@example.com" );
+switch ( has_value ) {
+ case LDAP_COMPARE_TRUE:
+ printf( "The mail attribute contains bjensen@example.com.\n");
+ break;
+ case LDAP_COMPARE_FALSE:
+ printf( "The mail attribute does not contain bjensen@example.com.\n");
+ break;
+ default:
+ ldap_perror( ld, "ldap_compare_s" );
+ return( 1 );
+}
+...
+
+
+See Also
+ldap_compare_ext_s
+
+ldap_control_free
+The ldap_control_free function frees an LDAPControl structure from memory.
+Syntax
+#include <ldap.h>
+void ldap_control_free( LDAPControl *ctrl );
+
+Parameters
+
ldap_control_free Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ctrl
+
+Pointer to an LDAPControl structure
+that you want to free from memory.
+
+
+
+
+
+Description
+The ldap_control_free function frees an LDAPControl structure from memory. You should call
+this function to free controls that you create; for example, if you call the ldap_create_sort_control function.
+See Also
+ldap_controls_free
+
+ldap_controls_free
+The ldap_controls_free function frees an array
+of LDAPControl structures from memory.
+Syntax
+#include <ldap.h>
+void ldap_controls_free( LDAPControl **ctrls );
+
+Parameters
+
ldap_controls_free Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ctrls
+
+Pointer to an array of LDAPControl structures
+that you want to free from memory.
+
+
+
+
+
+Description
+The ldap_controls_free function frees an array
+of LDAPControl structures from memory. You
+should call this function to free arrays of controls that you create or any
+arrays returned by ldap_parse_result.
+
+See Also
+ldap_control_free, ldap_parse_result
+
+ldap_count_entries
+The ldap_count_entries function returns the number
+of LDAPMessage structures representing directory
+entries in a chain of search results.
+Syntax
+#include <ldap.h>
+ int ldap_count_entries( LDAP *ld, LDAPMessage *result );
+
+Parameters
+
ldap_count_entries Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+result
+
+Chain of search results, represented by pointer to an LDAPMessage structure.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, the number of LDAPMessage
+ structures of the type LDAP_RES_SEARCH_ENTRY in
+a chain of search results. If there are no structures of this type, returns
+0.
+-1 if ld is not a valid
+connection handle.
+
+
+Description
+The ldap_count_entries function returns the number
+of LDAPMessage structures representing directory
+entries in a chain of search results. These messages have the type LDAP_RES_SEARCH_ENTRY
+ .
+If you pass in a pointer to an LDAPMessage structure
+in the middle of the chain of results, the function counts only the entries
+between that structure and the last structure in the chain. In this type of
+situation, the function does not return the count of all entries in the chain.
+
+
+Example
+See the examples under ldap_search_ext and ldap_search_ext_s.
+See Also
+ldap_result, ldap_search_ext
+ , ldap_search_ext_s, ldap_first_entry, ldap_next_entry
+, ldap_first_entry, ldap_next_message
+
+ldap_count_messages
+The ldap_count_messages function returns the number
+of LDAPMessage structures in a chain of search
+results.
+Syntax
+#include <ldap.h>
+ int ldap_count_messages( LDAP *ld, LDAPMessage *res );
+
+Parameters
+
ldap_count_messages Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+result
+
+Chain of search results, represented by pointer to an LDAPMessage structure.
+
+
+
+
+
+Returns
+One of the following values:
+
+The number of LDAPMessage structures
+in a chain of search results, if successful. If there are no structures, returns
+ 0.
+-1 if ld is not a valid
+connection handle.
+
+
+Description
+The ldap_count_messages function returns the number
+of LDAPMessage structures in a chain of search
+results. The count is the number of search entries plus the number of search
+references.
+If you pass in a pointer to an LDAPMessage structure
+in the middle of the chain of results, the function counts only between that
+structure and the last structure in the chain. In this type of situation,
+the function does not return the count of all structures in the chain.
+
+
+Example
+See the examples under ldap_search_ext and ldap_search_ext_s.
+See Also
+ldap_result, ldap_search_ext
+ , ldap_search_ext_s, ldap_first_message, ldap_next_message
+, ldap_first_entry, ldap_next_entry , ldap_first_reference
+, ldap_next_reference
+
+ldap_count_references
+The ldap_count_references function returns the
+number of LDAPMessage structures representing
+search references in a chain of search results.
+Syntax
+#include <ldap.h>
+ int ldap_count_references( LDAP *ld, LDAPMessage *res );
+
+Parameters
+
ldap_count_references Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+result
+
+Chain of search results, represented by pointer to an LDAPMessage structure.
+
+
+
+
+
+Returns
+One of the following values:
+
+The number of LDAPMessage structures
+of the type LDAP_RES_SEARCH_REFERENCE in a chain of search
+results, if successful. (If there are no structures of this type, returns
+0.)
+-1 if ld is not a valid
+connection handle.
+
+
+Description
+The ldap_count_references function returns the
+number of LDAPMessage structures representing
+search references in a chain of search results. These messages have the type
+LDAP_RES_SEARCH_REFERENCE, continuation references as specified
+in LDAPv3 that are stored as referral entries. Like a referral, each continuation
+reference itself may contain a number of URLs assumed to be equivalent, and
+the client should use one of those URLs.
+If you pass in a pointer to an LDAPMessage structure
+in the middle of the chain of results, the function counts only the references
+between that structure and the last structure in the chain. In this type of
+situation, the function does not return the count of all references in the
+chain.
+
+Example
+See the examples under ldap_search_ext and ldap_search_ext_s.
+See Also
+ldap_result, ldap_search_ext
+ , ldap_search_ext_s, ldap_first_reference, ldap_next_reference
+
+
+ldap_count_values
+The ldap_count_values function returns the number
+of values in an array of strings.
+Use the ldap_count_values_len function
+if the array contains berval structures.
+
+Syntax
+#include <ldap.h>
+int ldap_count_values( char **values );
+
+Parameters
+
+
+Returns
+One of the following values:
+
+The number of values in the array, if successful.
+
+-1 if unsuccessful.
+
+
+Example
+Example 21–8 counts
+the number of values assigned to an attribute.
+Using ldap_count_values
+#include <ldap.h>
+...
+LDAP *ld;
+LDAPMessage *e;
+char *a="cn";
+char **vals;
+int count;
+...
+
+/* Get the values of the cn attribute */
+vals = ldap_get_values( ld, e, a );
+
+/* Count the values of the attribute */
+count = ldap_count_values( vals );
+...
+
+
+See Also
+ldap_count_values_len, ldap_get_values
+
+ldap_count_values_len
+The ldap_count_values_len function returns the
+number of values in an array of berval structures.
+
+Use the ldap_count_values function
+if the array contains strings.
+Syntax
+#include <ldap.h>
+int ldap_count_values_len( struct berval **vals );
+
+Parameters
+
+
+Returns
+One of the following values:
+
+The number of values in the array, if successful.
+
+-1 if unsuccessful.
+
+
+Example
+Example 21–9
+counts the number of values assigned to an attribute.
+Using ldap_count_values_len
+
+#include <ldap.h>
+LDAP *ld;
+LDAPMessage *e;
+char *a="jpegPhoto";
+struct berval **bvals;
+int count;
+...
+/* Get the values of the jpegPhoto attribute */
+bvals = ldap_get_values_len( ld, e, a );
+
+/* Count the values of the attribute */
+count = ldap_count_values_len( vals );
+...
+
+
+See Also
+ldap_count_values, ldap_get_values_len
+
+ldap_create_authzid_control
+
+The ldap_create_authzid_control function creates
+a control that requests the authorization ID for a bind operation. This is
+defined in RFC 3829.
+In order for the control to work, the LDAP server that you are
+connecting to must support the server controls for authorization bind identity
+(OID 2.16.840.1.113730.3.4.16 or LDAP_CONTROL_AUTHZID_REQ
+, and OID 2.16.840.1.113730.3.4.15 or LDAP_CONTROL_AUTHZID_RES
+).
+Calling ldap_create_authzid_control creates an
+LDAP control that you can pass to the ldap_simple_bind function
+to retrieve the authorization ID in the response. You call ldap_parse_authzid_control function
+on the controls returned with an entry to retrieve a char * containing
+the authorization ID.
+When you are done with the search, you should free the control by calling
+the ldap_control_free function.
+Syntax
+#include <ldap.h>
+LDAP_API(int) LDAP_CALL ldap_create_authzid_control( LDAP *ld,
+ const char ctl_iscritical, LDAPControl **ctrlp );
+
+Parameters
+
ldap_create_authzid_control Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+ctl_iscritical
+
+Specifies whether the control is critical to the operation.
+
+If non-zero, the control is critical to the operation. If
+the server does not support it, the server returns an LDAP_UNAVAILABLE_CRITICAL_EXTENSION
+ error.
+If 0, the control is not critical to the
+operation. Even if the server does not support the control, the operation
+is still attempted and the control is ignored.
+
+
+
+
+
+ctrlp
+
+Pointer to an LDAPControl structure
+created by this function. When you are done using this control, you should
+free it by calling ldap_control_free.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the control.
+
+
+See Also
+ldap_parse_authzid_control
+
+
+ldap_create_filter
+The ldap_create_filter routine constructs an LDAP
+search filter.
+Syntax
+#include <ldap.h>
+int ldap_create_filter( char *buf, unsigned long buflen,
+ char *pattern, char *prefix, char *suffix, char *attr,
+ char *value, char **valwords );
+
+Parameters
+
ldap_create_filter Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+buf
+
+Buffer to contain the constructed filter.
+
+
+
+buflen
+
+Size of the buffer.
+
+
+
+pattern
+
+Pattern for the filter.
+
+
+
+prefix
+
+Prefix to prepend to the filter. (NULL if not used.)
+
+
+
+
+suffix
+
+Suffix to append to the filter. (NULL if not used.)
+
+
+
+
+attr
+
+Replaces %a in the pattern.
+
+
+
+value
+
+Replaces %v in the pattern.
+
+
+
+valwords
+
+Replaces %vM through %vN in the
+pattern.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_SIZELIMIT_EXCEEDED if the created
+filter exceeds the size of the buffer.
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+
+
+Example
+Example 21–10 builds
+the filter (mail=bjensen@example.com).
+Creating a Filter with
+ldap_create_filter
+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 );
+...
+
+
+See Also
+ldap_init_getfilter, ldap_init_getfilter_buf, ldap_getfirstfilter
+ , ldap_getnextfilter, ldap_set_filter_additions
+
+ldap_create_geteffectiveRights_control
+The ldap_create_geteffectiveRights_control function
+allows a user having correct privileges to query about the access rights another
+identity has on one or more entries in the directory.
+Syntax
+#include <ldap.h>
+LDAP_API(int) LDAP_CALL ldap_create_geteffectiveRights_control( LDAP *ld,
+ const char *authzid, const char **attrlist, const char ctl_iscritical,
+ LDAPControl **ctrlp );
+
+Parameters
+
ldap_create_geteffectiveRights_control
+ Function Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+authzid
+
+The DN of the identity for which you are checking access rights.
+
+
+
+
+attrlist
+
+List of attributes to return, such as aclRights and
+aclRightsInfo.
+
+
+
+ctl_iscritical
+
+Specifies whether the control is critical to the operation.
+
+If non-zero, the control is critical to the operation. If
+the server does not support it, the server will return an LDAP_UNAVAILABLE_CRITICAL_EXTENSION
+ error.
+If 0, the control is not critical to the
+operation. Even if the server does not support the control, the operation
+is still attempted and the control is ignored.
+
+
+
+
+
+ctrlp
+
+Pointer to an LDAPControl structure
+created by this function. When you are done using this control, you should
+free it by calling ldap_control_free.
+
+
+
+
+
+
+
+ldap_create_persistentsearch_control
+The ldap_create_persistentsearch_control function
+creates a control that allows your client to perform a search of an LDAP v3
+server that continues without termination until your client abandons it.
+Persistent search is an optional feature; it may not be supported
+on all LDAP servers. In order for the control to work, the server that you
+are connecting to must support the server control for persistent searches
+(OID 2.16.840.1.113730.3.4.3, or LDAP_CONTROL_PERSISTENTSEARCH,
+as defined in the ldap.h header file).
+Syntax
+#include <ldap.h>
+ int ldap_create_persistentsearch_control( LDAP *ld,
+ int changetypes, int changesonly, int return_echg_ctls,
+ char ctl_iscritical, LDAPControl **ctrlp );
+
+Parameters
+
ldap_create_persistentsearch_control
+ Function Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+changetypes
+
+Specifies the types of changes that you want to keep track of. This
+field can have one or more of the following values:
+
+LDAP_CHANGETYPE_ADD specifies that you
+want to keep track of entries added to the directory.
+LDAP_CHANGETYPE_DELETE specifies that you
+want to keep track of entries deleted from the directory.
+LDAP_CHANGETYPE_MODIFY specifies that you
+want to keep track of entries that are modified.
+LDAP_CHANGETYPE_MODDN specifies that you
+want to keep track of entries that are renamed.
+LDAP_CHANGETYPE_ANY specifies that you
+want to keep track of all of the above changes to the directory.You
+can OR the values together to specify multiple types.
+
+
+
+
+
+
+changesonly
+
+Specifies whether or not you want skip the initial search and only get
+the latest changes as they occur:
+
+If non-zero, the initial search is skipped and only entries
+that have changed after the initial search are returned.
+If 0, the results of the initial search
+are returned first.
+
+
+
+
+
+return_echg_ctls
+
+Specifies whether or not entry controls are included with each entry
+returned to your client:
+
+If non-zero, a control is included with each entry.
+
+If 0, controls are not included with the
+entries returned from the server.
+
+
+
+
+
+ctl_iscritical
+
+Specifies whether the control is critical to the operation.
+
+If non-zero, the control is critical to the operation. If
+the server does not support it, the server will return an LDAP_UNAVAILABLE_CRITICAL_EXTENSION
+ error.
+If 0, the control is not critical to the
+operation. Even if the server does not support the control, the operation
+is still attempted and the control is ignored.
+
+
+
+
+
+ctrlp
+
+Pointer to an LDAPControl structure
+created by this function. When you are done using this control, you should
+free it by calling ldap_control_free.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the control.
+
+
+Description
+The ldap_create_persistentsearch_control function
+allows you to perform persistent searches. A persistent search provides
+the means to track changes to a set of entries that match the search criteria.
+After the initial search is performed, the server keeps track of the search
+criteria and sends back information when any entry that matches the criteria
+is added, deleted, modified, or renamed. Calling ldap_create_persistentsearch_control
+ creates an LDAP server control that you can pass to the ldap_search_ext function.
+As stated, after you create the control, you can pass it to the LDAP
+server during a search operation. If you specify that you want “entry
+change notification” controls sent back (that is, if you specify a non-zero
+value for the return_echg_ctls parameter), the server
+includes controls with each changed entry it sends back. To retrieve the controls
+from each entry, call the ldap_get_entry_controls function.
+To get data about the changes made to the entry from the control, call the ldap_parse_entrychange_control function.
+When you are done with the search, you can cancel the persistent search
+by calling the ldap_abandon_ext function.
+You should also free the control from memory by calling the ldap_control_free function.
+See Also
+ldap_search_ext,
+ldap_abandon_ext, ldap_get_entry_controls, ldap_parse_entrychange_control, ldap_control_free
+
+ldap_create_pwdpolicy_control
+
+The ldap_create_pwdpolicy_control function creates
+a control that requests information about the status of a user account.
+ldap_create_pwdpolicy_control implements
+an extension to the LDAP v3 supported by &cnDirectoryServer;.In
+order for the control to work, the LDAP server that you are connecting to
+must support the server control for password policy (OID 1.3.6.1.4.1.42.2.27.8.5.1
+, or LDAP_CONTROL_ACCOUNT_USABLE).
+Calling ldap_create_pwdpolicy_control creates an
+LDAP control that you can pass to the ldap_simple_bind functions
+to retrieve password policy information from bind, modify, add, compare, and
+potentially extended operation responses including password policy response
+controls. You call ldap_parse_pwdpolicy_control
+ function on the controls returned with an entry to retrieve a LDAPpwdpolicy structure containing information
+about the status of the account.
+When you are done with the search, you should free the control by calling
+the ldap_control_free function.
+Syntax
+#include <ldap.h>
+LDAP_API(int) LDAP_CALL ldap_create_pwdpolicy_control( LDAP *ld,
+ const char ctl_iscritical, LDAPControl **ctrlp );
+
+Parameters
+
ldap_create_pwdpolicy_control Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+ctl_iscritical
+
+Specifies whether the control is critical to the operation.
+
+If non-zero, the control is critical to the operation. If
+the server does not support it, the server returns an LDAP_UNAVAILABLE_CRITICAL_EXTENSION
+ error.
+If 0, the control is not critical to the
+operation. Even if the server does not support the control, the operation
+is still attempted and the control is ignored.
+
+
+
+
+
+ctrlp
+
+Pointer to an LDAPControl structure
+created by this function. When you are done using this control, you should
+free it by calling ldap_control_free.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the control.
+
+
+See Also
+ldap_parse_pwdpolicy_control
+, LDAPpwdpolicy
+
+ldap_create_proxiedauth_control
+The ldap_create_proxiedauth_control function creates
+an LDAP v3 control that allows a bound entity to assume the identity of another
+directory entry.
+ldap_create_proxiedauth_control is
+a new version of the ldap_create_proxyauth_control function.
+If you are writing a new LDAP client, use ldap_create_proxiedauth_control
+ .
+Syntax
+#include <ldap.h>
+int ldap_create_proxiedauth_control( LDAP *ld, char *authzid,
+ LDAPControl **ctrlp);
+
+Parameters
+
ldap_create_proxiedauth_control
+ Function Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+authzid
+
+The string representing the identity to assume for the access rights,
+defined in the format specified by the following Augmented Backus-Naur Form
+(ABNF) from RFC 4513:
+; Specific predefined authorization (authz)
+; id schemes are defined below --
+; new schemes may be defined in the future.
+
+authzId = dnAuthzId / uAuthzId
+
+; distinguished-name-based authz id.
+dnAuthzId = "dn:" dn
+dn = utf8string ; syntax from RFC 4514
+
+; unspecified userid, UTF-8 encoded.
+uAuthzId = "u:" userid
+userid = utf8string ; syntax unspecified
+
+
+
+
+ctrlp
+
+Pointer to an LDAPControl structure
+created by this function. When you are done using this control, you should
+free it by calling ldap_control_free.
+
+
+
+
+
+
+Description
+More information on proxy authorization can be found in the LDAP
+Proxied Authorization Control Internet Draft ().
+Proxy authorization is an optional feature; it may not be supported
+on all LDAP servers. In order for the control to work, the server that you
+are connecting to must support the server control for proxy authorization
+(OID 2.16.840.1.113730.3.4.18, or LDAP_CONTROL_PROXIEDAUTH,
+as defined in the ldap-extension.h header file).
+
+
+
+ldap_create_proxyauth_control
+The ldap_create_proxyauth_control function creates
+an LDAP v3 control that allows a bound entity to assume the identity of another
+directory entry.
+This is an older function that is included in the SDK for backward-compatibility.
+If you are writing a new LDAP client, use ldap_create_proxiedauth_control
+ .
+Syntax
+#include <ldap.h>
+ int ldap_create_proxyauth_control( LDAP *ld, char *DN,
+ char ctl_iscritical, LDAPControl **ctrlp);
+
+Parameters
+
ldap_create_proxyauth_control Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+DN
+
+String representing the DN of the entry who's identity the client will
+be assuming.
+
+
+
+ctl_iscritical
+
+Specifies whether the control is critical to the operation.
+
+If non-zero, the control is critical to the operation. If
+the server does not support it, the server will return an LDAP_UNAVAILABLE_CRITICAL_EXTENSION
+ error.
+If 0, the control is not critical to the
+operation. Even if the server does not support the control, the operation
+is still attempted and the control is ignored.
+
+
+
+
+
+ctrlp
+
+Pointer to an LDAPControl structure
+created by this function. When you are done using this control, you should
+free it by calling ldap_control_free.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the control.
+LDAP_UNAVAILABLE_CRITICAL_EXTENSION if
+the server does not support proxy authorization and ctl_iscritical is
+set to a non-zero value.
+
+
+See Also
+ldap_control_free
+
+ldap_create_sort_control
+The ldap_create_sort_control function creates a
+control that specifies the order in which you want search results returned.
+This function implements an extension to the LDAP v3. Server-side
+sorting is an optional feature; it may not be supported on all LDAP servers.
+Call this function when interacting with LDAP servers that support this LDAP
+v3 extension.
+Syntax
+#include <ldap.h>
+ int ldap_create_sort_control( LDAP *ld,
+ LDAPsortkey **sortKeyList, const char ctl_iscritical,
+ LDAPControl **ctrlp );
+
+Parameters
+
ldap_create_sort_control Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+sortKeyList
+
+Pointer to an array of LDAPsortkey structures
+that specify the attribute types or matching rules used for sorting and the
+order (ascending or descending) in which to sort the results.
+
+
+
+ctl_iscritical
+
+Specifies whether the control is critical to the operation.
+
+If non-zero, the control is critical to the operation. If
+the server does not support it, the server will return an LDAP_UNAVAILABLE_CRITICAL_EXTENSION
+ error.
+If 0, the control is not critical to the
+operation. Even if the server does not support the control, the operation
+is still attempted and the control is ignored.
+
+
+
+
+
+ctrlp
+
+Pointer to an LDAPControl structure
+created by this function. When you are done using this control, you should
+free it by calling ldap_control_free.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the control.
+
+
+Description
+The ldap_create_sort_control function allows you
+to specify the order in which you want to receive data from the server. Calling
+this function creates an LDAP control that you can pass to the ldap_search_ext and ldap_search_ext_s
+ functions.
+In order for the control to work, the LDAP server that you are
+connecting to must support the server control for sorting search results (OID
+1.2.840.113556.1.4.473, or LDAP_CONTROL_SORTREQUEST, as
+defined in the ldap.h header file).
+To specify the attributes to use for sorting the results, you can call ldap_create_sort_keylist to create an array of LDAPsortkey structures and pass the array as the
+ sortKeyList argument. When you are done with the search,
+you should free the control and the array of LDAPsortkey
+ structures by calling the ldap_control_free and
+ ldap_free_sort_keylist functions.
+
+See Also
+ldap_create_sort_keylist, ldap_search_ext, ldap_search_ext_s
+, ldap_control_free
+
+ldap_create_sort_keylist
+The ldap_create_sort_keylist function creates an
+array of LDAPsortkey structures from a string
+representation of a set of sort keys.
+Syntax
+#include <ldap.h>
+ int ldap_create_sort_keylist(LDAPsortkey ***sortKeyList,
+ const char *string_rep);
+
+Parameters
+
ldap_create_sort_keylist Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+sortKeyList
+
+Pointer to an array of LDAPsortkey structures
+that specify the attribute types or matching rules used for sorting and the
+order (ascending or descending) in which to sort the results.
+
+
+
+string_rep
+
+String representation of a set of sort keys. The value should specify
+the name of the attribute that you want to sort by. To sort in reverse order,
+precede the attribute name with a hyphen, -. To use a matching
+rule for sorting, append a colon to the attribute name and specify the object
+identifier (OID) of a matching rule after the colon. For example:
+
+cn (sorts by the cn attribute)
+
+-cn (sorts by the cn attribute
+in reverse order)
+-cn:1.2.3.4 (sorts by the cn attribute
+in reverse order using the matching rule identified by the OID 1.2.3.4)
+
+
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+-1 if an error occurred.
+
+
+Description
+Calling the ldap_create_sort_keylist function allows
+you to create an array of LDAPsortkey structures
+from a string representation of a set of sort keys. You can then pass the
+array to the ldap_create_sort_control function.
+The string representation specified by the string_rep argument
+should specify the name of the attribute that you want to sort by and how
+the sort will work. When you are done sorting the results, you should free
+the array of LDAPsortkey structures by calling
+the ldap_free_sort_keylist function.
+
+See Also
+ldap_create_sort_control, ldap_free_sort_keylist
+
+ldap_create_userstatus_control
+
+The ldap_create_userstatus_control function creates
+a control that requests information about the status of a user account.
+ldap_create_userstatus_control implements
+an extension to the LDAP v3 supported by &cnDirectoryServer;.In
+order for the control to work, the LDAP server that you are connecting to
+must support the server control for account availability (OID 1.3.6.1.4.1.42.2.27.9.5.8
+, or LDAP_CONTROL_ACCOUNT_USABLE).
+Calling ldap_create_userstatus_control creates
+an LDAP control that you can pass to the ldap_search_ext
+ and ldap_search_ext_s functions.
+You call ldap_parse_userstatus_control
+ function on the controls returned with an entry to retrieve a LDAPuserstatus structure containing information
+about the status of the account.
+When you are done with the search, you should free the control by calling
+the ldap_control_free function.
+Syntax
+#include <ldap.h>
+LDAP_API(int) LDAP_CALL ldap_create_userstatus_control( LDAP *ld,
+ const char ctl_iscritical, LDAPControl **ctrlp );
+
+Parameters
+
ldap_create_userstatus_control Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+ctl_iscritical
+
+Specifies whether the control is critical to the operation.
+
+If non-zero, the control is critical to the operation. If
+the server does not support it, the server returns an LDAP_UNAVAILABLE_CRITICAL_EXTENSION
+ error.
+If 0, the control is not critical to the
+operation. Even if the server does not support the control, the operation
+is still attempted and the control is ignored.
+
+
+
+
+
+ctrlp
+
+Pointer to an LDAPControl structure
+created by this function. When you are done using this control, you should
+free it by calling ldap_control_free.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the control.
+
+
+See Also
+ldap_parse_userstatus_control
+, LDAPuserstatus
+
+
+ldap_create_virtuallist_control
+The ldap_create_virtuallist_control function creates
+a control that requests a subset of search results for use in a virtual list
+box.
+ldap_create_virtuallist_control implements
+an extension to the LDAP v3 supported by &cnDirectoryServer;.
+Syntax
+#include <ldap.h>
+int ldap_create_virtuallist_control( LDAP *ld,
+ LDAPVirtualList *ldvlistp, LDAPControl **ctrlp );
+
+Parameters
+
ldap_create_virtuallist_control
+ Function Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+ldvlistp
+
+Pointer to an LDAPVirtualList structure
+that specifies the subset of entries that you want retrieved from the server
+and the selected entry.
+
+
+
+ctrlp
+
+Pointer to an LDAPControl structure
+created by this function. When you are done using this control, you should
+free it by calling ldap_control_free.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the control.
+
+
+Description
+The ldap_create_virtuallist_control function allows
+you to retrieve a subset of entries from the server for use in a virtual list
+box. To specify the subset of entries that you want to retrieve, create an
+ LDAPVirtualList structure and pass in a
+pointer to this structure as the ldvlistp argument.
+In order for the control to work, the LDAP server that you are
+connecting to must support the server control for sorting search results (OID
+2.16.840.1.113730.3.4.9, or LDAP_CONTROL_VLVREQUEST, as
+defined in the ldap.h header file).
+Calling ldap_create_virtuallist_control creates
+an LDAP control that you can pass to the ldap_search_ext
+ and ldap_search_ext_s functions.
+You also need to pass a server-side sorting control to the search functions.
+You can call ldap_create_sort_keylist and ldap_create_sort_control to create a server-side
+sorting control. When you are done with the search, you should free the control
+by calling the ldap_control_free function.
+
+See Also
+LDAPVirtualList,
+ldap_parse_virtuallist_control, ldap_search_ext , ldap_search_ext_s, ldap_control_free
+
+
+ldap_delete
+The ldap_delete function removes an entry from
+the directory asynchronously.
+This is an older function that is included in the SDK for backward-compatibility.
+If you are writing a new LDAP client, use ldap_delete_ext
+ instead.
+Syntax
+#include <ldap.h>
+int ldap_delete( LDAP *ld, const char *dn );
+
+Parameters
+
ldap_delete Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to remove.
+
+
+
+
+
+Returns
+Returns the message ID of the ldap_delete operation.
+To check the result of this operation, call
+ldap_result and ldap_result2error.
+See ldap_delete_ext_s for a list of possible
+result codes for the LDAP delete operation.
+
+Description
+Please use the newer version of this function, ldap_delete_ext
+ .
+Example
+Example 21–11 uses
+the asynchronous ldap_delete function to remove the entry
+for Barbara Jensen from the directory.
+Using ldap_delete
+#include <ldap.h>
+...
+LDAP *ld;
+LDAPMessage *result;
+int msgid, rc;
+struct timeval tv;
+
+/* Distinguished name of the entry that you want to delete. */
+char *dn = "uid=bjensen,ou=People,dc=example, dc=com";
+...
+/* Set up the timeout period to wait for the "modify" operation */
+tv.tv_sec = tv.tv_usec = 0;
+
+/* Delete the entry */
+if ( ( msgid = ldap_delete( ld, dn ) ) == -1 ) {
+ ldap_perror( ld, "ldap_delete" );
+ return( 1 );
+}
+/* Check to see if the operation has completed */
+while ( ( rc = ldap_result( ld, msgid, 0, &tv, &result ) ) == 0 ) {
+ ...
+ /* do other work while waiting for the operation to complete */
+ ...
+}
+/* Check the result to see if any errors occurred */
+ldap_result2error( ld, result, 1 );
+ldap_perror( ld, "ldap_delete" );
+...
+
+
+See Also
+ldap_delete_ext
+
+ldap_delete_ext
+The ldap_delete_ext function deletes an entry from
+the directory asynchronously.
+ldap_delete_ext is a new version of the ldap_delete function. If you are writing a new LDAP
+client, you should call ldap_delete_ext.
+
+Syntax
+#include <ldap.h>
+int ldap_delete_ext( LDAP *ld, const char *dn,
+ LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp );
+
+Parameters
+
ldap_delete_ext Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to remove.
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+msgidp
+
+Pointer to an integer that will be set to the message ID of the LDAP
+operation.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the control.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+To check the result of this operation, call
+ldap_result and ldap_result2error.
+See ldap_delete_ext_s for a list of possible
+result codes for the LDAP delete operation.
+
+Description
+The ldap_delete_ext function deletes an entry from
+the directory, using the dn argument to specify the entry
+that you want to delete. ldap_delete_ext is an asynchronous
+function; it does not directly return results. If you want the results to
+be returned directly by the function, call the synchronous function ldap_delete_ext_s .
+See Also
+ldap_delete_ext_s, ldap_result, ldap_parse_result
+
+
+ldap_delete_ext_s
+The ldap_delete_ext_s function deletes an entry
+from the directory synchronously.
+ldap_delete_ext_s is a new version of the ldap_delete_s function. If you are writing a new
+LDAP client, you should call ldap_delete_ext_s.
+
+Syntax
+#include <ldap.h>
+int ldap_delete_ext_s( LDAP *ld, const char *dn,
+ LDAPControl **serverctrls, LDAPControl **clientctrls );
+
+Parameters
+
ldap_delete_ext_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to remove.
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+
+
+Returns
+One of the following values:
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the control.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+LDAP_LOCAL_ERROR if an error occurred
+when receiving the results from the server.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded results from the server.
+
+&cnDirectoryServer; and other LDAP server products may send result
+codes in addition to those described. For example, the server may have loaded
+a plug-in that returns custom result codes. Check your LDAP server documentation
+for other result codes.
+
+Description
+The ldap_delete_ext_s function deletes an entry
+from the directory, using the dn argument to specify the
+entry that you want to delete. ldap_delete_ext_s is a
+synchronous function, which directly returns the results of the operation.
+If you want to perform other operations while waiting for the results of this
+operation, call the asynchronous function ldap_delete_ext
+ instead.
+See Also
+ldap_delete_ext
+
+ldap_delete_s
+The ldap_delete_s deletes an entry from the directory
+synchronously.
+This is an older function that is included in the SDK for backward-compatibility.
+If you are writing a new LDAP client, use ldap_delete_ext_s
+ instead.
+Syntax
+#include <ldap.h>
+ int ldap_delete_s(LDAP *ld, const char *dn);
+
+Parameters
+
ldap_delete_s Function
+Parameters
+
+
+
+
+Parameters
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to remove.
+
+
+
+
+
+Returns
+For a list of possible result codes for an LDAP delete operation, see
+the ldap_delete_ext_s function.
+Description
+Please use the newer version of this function, ldap_delete_ext_s
+ .
+Example
+Example 21–12 uses
+the synchronous ldap_delete_s function to delete the
+entry for Barbara Jensen from the directory.
+Using ldap_delete_s
+#include <ldap.h>
+LDAP *ld;
+
+/* Distinguished name of the entry that you want to delete. */
+char *dn = "uid=bjensen,ou=People,dc=example, dc=com";
+...
+/* Delete the entry */
+if ( ldap_delete_s( ld, dn ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_delete_s" );
+ return( 1 );
+}
+...
+
+
+See Also
+ldap_delete_ext_s
+
+ldap_dn2ufn
+The ldap_dn2ufn function converts a DN into a more
+user-friendly form by stripping off the cryptic type names.
+Syntax
+#include <ldap.h>
+ char * ldap_dn2ufn( const char *dn );
+
+Parameters
+
ldap_dn2ufn Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+dn
+
+The DN that you want converted.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns the DN in its friendlier form.
+
+If unsuccessful, returns NULL.
+
+
+
+Description
+For more information on user friendly naming (UFN), see RFC 1781,
+ Using the OSI Directory to Achieve User Friendly Naming ().
+
+
+ldap_entry2html
+The ldap_entry2html function writes the HTML representation
+of an LDAP entry.
+Syntax
+#include <disptmpl.h>
+ int ldap_entry2html( LDAP *ld, char *buf, LDAPMessage *entry,
+ struct ldap_disptmpl *tmpl, char **defattrs, char ***defvals,
+ writeptype writeproc, void *writeparm, char *eol, int rdncount,
+ unsigned long opts, char *urlprefix, char *base );
+
+Parameters
+
ldap_entry2html Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+buf
+
+A pointer to a buffer of size LDAP_DTMPL_BUFSIZ or
+larger. If NULL, a buffer is allocated and freed internally.
+
+
+
+
+entry
+
+Specifies the attribute values to be represented.
+
+
+
+tmpl
+
+Pointer to the display template to be used, usually obtained by calling ldap_oc2template.
+
+
+
+defattrs
+
+A NULL terminated array of LDAP attribute names for
+which you wish to provide default values. It is only used if the entry contains
+no values for the attribute.
+
+
+
+defvals
+
+An array of NULL terminated arrays of default values
+corresponding to the attributes.
+
+
+
+writeproc
+
+Your writeproc function should be declared as:
+int writeproc( writeparm, p, len )
+void *writeparm;
+char *p;
+int len;
+where p is a pointer to text to be written and
+len is the length of the text. p is guaranteed
+to be zero terminated.
+
+
+
+writeparm
+
+A pointer to a structure that will be passed as the first parameter
+of the writeproc procedure. Typically, this is used to
+pass the file descriptor of the file to write to.
+
+
+
+eol
+
+Lines of text are terminated with this string.
+
+
+
+rdncount
+
+Limits the number of components that are displayed for DN attributes.
+
+
+
+
+opts
+
+Specifies output options. The allowed values are:
+
+zero (default output)
+LDAP_DISP_OPT_AUTOLABELWIDTH which causes
+the width for labels to be determined based on the longest label in tmpl
+.
+LDAP_DISP_OPT_HTMLBODYONLY which instructs
+the library not to include <HTML>, <HEAD>,
+ <TITLE>, and <BODY> tags. In
+other words, an HTML fragment is generated, and the caller is responsible
+for prepending and appending the appropriate HTML tags to construct a correct
+HTML document.
+
+
+
+
+
+urlprefix
+
+Starting text to use when constructing an LDAP URL. The default is
+the string ldap://.
+
+
+
+base
+
+The base with which to begin when executing search actions. If NULL
+ , search action template items are ignored.
+
+
+
+
+
+Returns
+
+LDAP_SUCCESS if successful.
+
+An LDAP error code on error.
+
+
+Description
+ldap_entry2html produces an HTML representation
+of an entry. It behaves exactly like ldap_entry2text except
+for the output and the addition of two parameters.
+See Also
+ldap_entry2text,
+ldap_oc2template
+
+ldap_entry2html_search
+The ldap_entry2html_search function determines
+the appropriate display template to use by calling ldap_oc2template
+.
+Syntax
+#include <disptmpl.h>
+ int ldap_entry2html_search( LDAP *ld, char *dn, char *base,
+ LDAPMessage *entry, struct ldap_disptmpl *tmpllist, char **defattrs,
+ char ***defvals, writeptype writeproc, void *writeparm, char *eol,
+ int rdncount, unsigned long opts, char *urlprefix );
+
+Parameters
+
ldap_entry2html_search Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to write as HTML.
+
+
+
+base
+
+The base with which to begin when executing search actions. If NULL
+ , search action template items are ignored.
+
+
+
+entry
+
+Specifies the attribute values to be represented.
+
+
+
+tmpllist
+
+Pointer to the entire list of templates available, usually obtained
+by calling ldap_init_templates or ldap_init_templates_buf. If NULL,
+will attempt to read a load templates from the default template configuration
+file.
+
+
+
+defattrs
+
+A NULL terminated array of LDAP attribute names for
+which you wish to provide default values. It is only used if the entry contains
+no values for the attribute.
+
+
+
+defvals
+
+An array of NULL terminated arrays of default values
+corresponding to the attributes.
+
+
+
+writeproc
+
+writeproc function should be declared as:
+int writeproc( writeparm, p, len )
+void *writeparm;
+char *p;
+int len;
+where p is a pointer to text to be written and
+len is the length of the text. p is guaranteed
+to be zero terminated.
+
+
+
+writeparm
+
+A pointer to a structure that will be passed as the first parameter
+of the writeproc procedure. Typically, this is used to
+pass the file descriptor of the file to write to.
+
+
+
+eol
+
+Lines of text are terminated with this string.
+
+
+
+rdncount
+
+Limits the number of components that are displayed for DN attributes.
+
+
+
+
+opts
+
+Specifies output options. The allowed values are:
+
+zero (default output)
+LDAP_DISP_OPT_AUTOLABELWIDTH which causes
+the width for labels to be determined based on the longest label in tmpl
+.
+LDAP_DISP_OPT_HTMLBODYONLY which instructs
+the library not to include <HTML>, <HEAD>,
+ <TITLE>, and <BODY> tags. In
+other words, an HTML fragment is generated, and the caller is responsible
+for prepending and appending the appropriate HTML tags to construct a correct
+HTML document.
+
+
+
+
+
+urlprefix
+
+Starting text to use when constructing an LDAP URL. The default
+is the string ldap://
+
+
+
+
+
+Returns
+
+LDAP_SUCCESS if successful.
+
+An LDAP error code on error.
+
+
+Description
+ldap_entry2html_search will call ldap_search_s to retrieve any attribute values to
+be displayed. It behaves exactly like ldap_entry2text_search
+, except the urlprefix parameter is required and
+HTML is the output.
+See Also
+ldap_search_s, ldap_entry2text_search
+, ldap_init_templates, ldap_init_templates_buf, ldap_entry2text
+
+
+ldap_entry2text
+The ldap_entry2text function writes the text representation
+of an LDAP entry.
+Syntax
+#include <disptmpl.h>
+ int ldap_entry2text( LDAP *ld, char *buf, LDAPMessage *entry,
+ struct ldap_disptmpl *tmpl, char **defattrs, char ***defvals,
+ writeptype writeproc, void *writeparm, char *eol, int rdncount,
+ unsigned long opts );
+
+Parameters
+
ldap_entry2text Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+buf
+
+A pointer to a buffer of size LDAP_DTMPL_BUFSIZ or
+larger. If NULL, a buffer is allocated and freed internally.
+
+
+
+
+entry
+
+Specifies the attribute values to be represented.
+
+
+
+tmpl
+
+Pointer to the display template to be used, usually obtained by calling ldap_oc2template.
+
+
+
+defattrs
+
+A NULL terminated array of LDAP attribute names for
+which you wish to provide default values. It is only used if the entry contains
+no values for the attribute.
+
+
+
+defvals
+
+An array of NULL terminated arrays of default values
+corresponding to the attributes.
+
+
+
+writeproc
+
+writeproc function should be declared as:
+int writeproc( writeparm, p, len )
+void *writeparm;
+char *p;
+int len;
+where p is a pointer to text to be written and
+len is the length of the text. p is guaranteed
+to be zero terminated.
+
+
+
+writeparm
+
+A pointer to a structure that will be passed as the first parameter
+of the writeproc procedure. Typically, this is used to
+pass the file descriptor of the file to write to.
+
+
+
+eol
+
+Lines of text are terminated with this string.
+
+
+
+rdncount
+
+Limits the number of components that are displayed for DN attributes.
+
+
+
+
+opts
+
+Specifies output options. The allowed values are:
+
+zero (default output)
+LDAP_DISP_OPT_AUTOLABELWIDTH which causes
+the width for labels to be determined based on the longest label in tmpl
+.
+LDAP_DISP_OPT_HTMLBODYONLY which instructs
+the library not to include <HTML>, <HEAD>,
+ <TITLE>, and <BODY> tags. In
+other words, an HTML fragment is generated, and the caller is responsible
+for prepending and appending the appropriate HTML tags to construct a correct
+HTML document.
+
+
+
+
+
+
+
+Returns
+
+LDAP_SUCCESS if successful.
+
+An LDAP error code on error.
+
+
+Description
+ldap_entry2text produces a text representation
+of an entry and writes the text by calling the writeproc function.
+All of the attribute values to be displayed must be present in entry as no
+interaction with the LDAP server will be performed.
+See Also
+ldap_entry2html,
+ldap_oc2template
+
+ldap_entry2text_search
+The ldap_entry2text_search function determines
+the appropriate display template to use by calling ldap_oc2template
+.
+Syntax
+#include <disptmpl.h>
+ int ldap_entry2text_search( LDAP *ld, char *dn, char *base,
+ LDAPMessage *entry, struct ldap_disptmpl *tmpllist, char **defattrs,
+ char ***defvals, writeptype writeproc, void *writeparm,
+ char *eol, int rdncount, unsigned long opts );
+
+Parameters
+
ldap_entry2text_search Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to write.
+
+
+
+base
+
+If NULL, the search action template items are ignored.
+If not NULL, it is the search base to use when executing
+search actions.
+
+
+
+entry
+
+If entry is not NULL, it should contain the objectClass
+ attribute values for the entry to be displayed. If NULL,
+dn can not be NULL, and ldap_entry2text_search
+ will retrieve the objectClass values itself by
+calling ldap_search_s.
+
+
+
+tmpllist
+
+Pointer to the entire list of templates available, usually obtained
+by calling ldap_init_templates or ldap_init_templates_buf. If NULL,
+will attempt to read a load templates from the default template configuration
+file.
+
+
+
+defattrs
+
+A NULL terminated array of LDAP attribute names for
+which you wish to provide default values. It is only used if the entry contains
+no values for the attribute.
+
+
+
+defvals
+
+An array of NULL terminated arrays of default values
+corresponding to the attributes.
+
+
+
+writeproc
+
+writeproc function should be declared as:
+int writeproc( writeparm, p, len )
+void *writeparm;
+char *p;
+int len;
+where p is a pointer to text to be written and
+len is the length of the text. p is guaranteed
+to be zero terminated.
+
+
+
+writeparm
+
+A pointer to a structure that will be passed as the first parameter
+of the writeproc procedure. Typically, this is used to
+pass the file descriptor of the file to write to.
+
+
+
+eol
+
+Lines of text are terminated with this string.
+
+
+
+rdncount
+
+Limits the number of components that are displayed for DN attributes.
+
+
+
+
+opts
+
+Specifies output options. The allowed values are:
+
+zero (default output)
+LDAP_DISP_OPT_AUTOLABELWIDTH which causes
+the width for labels to be determined based on the longest label in tmpl
+.
+LDAP_DISP_OPT_HTMLBODYONLY which instructs
+the library not to include <HTML>, <HEAD>,
+ <TITLE>, and <BODY> tags. In
+other words, an HTML fragment is generated, and the caller is responsible
+for prepending and appending the appropriate HTML tags to construct a correct
+HTML document.
+
+
+
+
+
+
+
+Returns
+
+LDAP_SUCCESS if successful.
+
+An LDAP error code on error.
+
+
+Description
+ldap_entry2text_search will call ldap_search_s to retrieve any attribute values to
+be displayed.
+See Also
+ldap_entry2html_search, ldap_oc2template, ldap_search_s
+, ldap_init_templates, ldap_init_templates_buf
+
+ldap_err2string
+The ldap_err2string function returns the corresponding
+error message for an error code.
+Syntax
+#include <ldap.h>
+ char * ldap_err2string( int err );
+
+Parameters
+
ldap_err2string Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+err
+
+Error code that you want interpreted into an error message.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns the corresponding error message for
+the error code.
+If unsuccessful (for example, if the error code is not a valid
+LDAP API error code), returns Unknown error.
+
+
+
+Example
+Example 21–13 sets
+the variable err_msg to the error message corresponding
+to the error code returned by the ldap_simple_bind_s function.
+
+Using ldap_err2string
+#include <ldap.h>
+...
+LDAP *ld;
+char *dn = "uid=bjensen,ou=People,dc=example, dc=com";
+char *pw = "hifalutin";
+char *err_msg;
+...
+err_msg = ldap_err2string( ldap_simple_bind_s( ld, dn, pw ) );
+...
+
+
+See Also
+ldap_get_lderrno, ldap_perror, ldap_result2error
+, ldap_set_lderrno, ldapssl_err2string
+
+ldap_explode_dn
+The ldap_explode_dn function converts a DN into
+its component parts.
+Syntax
+#include <ldap.h>
+ char ** ldap_explode_dn( const char *dn, int notypes );
+
+Parameters
+
ldap_explode_dn Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+dn
+
+DN that you want separated into components.
+
+
+
+notypes
+
+Specifies whether or not type names in the DN are returned. This parameter
+can have the following possible values:
+
+0 specifies that type names are returned.
+
+A non-zero value specifies that type names are not returned.
+
+
+
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns a NULL terminated
+array containing the components of the DN.
+If unsuccessful, returns NULL.
+
+
+
+Example
+The following function call:
+ldap_explode_dn( "uid=bjensen,ou=People,dc=example,dc=com", 0 );
+returns this array:
+{ "uid=bjensen", "ou=People", "dc=example,dc=com", NULL }
+If you change the notypes parameter from 0 to
+ 1:
+ldap_explode_dn( "uid=bjensen,ou=People,dc=example,dc=com", 1 );
+The component names are not returned in the array:
+{ "bjensen", "People", "example.com", NULL }
+
+See Also
+ldap_explode_rdn, ldap_get_dn
+
+ldap_explode_dns
+This function is to be deprecated and should not be used. It is
+included in ldap-to-be-deprecated.h for backward-compatibility.
+
+The ldap_explode_dns function takes a DNS-style
+DN, breaks it up into its component parts, and returns a NULL terminated
+array. For example, the DN ldap.example.com will return
+{ "ldap", "example", "com", NULL }. The result can be freed by calling
+ ldap_value_free.
+Syntax
+#include <ldap-to-be-deprecated.h>
+ char ** ldap_explode_dns( const char *dn );
+
+Parameters
+
ldap_explode_dns Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+dn
+
+DN that you want separated into components.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns a NULL terminated
+array containing the components of the DN.
+If unsuccessful, returns NULL.
+
+
+
+
+ldap_explode_rdn
+The ldap_explode_rdn function converts a relative
+distinguished name (RDN) into its component parts.
+Syntax
+#include <ldap.h>
+char ** ldap_explode_rdn( const char *dn, int notypes );
+
+Parameters
+
ldap_explode_rdn Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+dn
+
+RDN that you want separated into components.
+
+
+
+notypes
+
+Specifies whether or not type names in the RDN are returned. This parameter
+can have the following possible values:
+
+0 specifies that type names are returned.
+
+A non-zero value specifies that type names are not returned.
+
+
+
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns a NULL terminated
+array containing the components of the RDN.
+If unsuccessful, returns NULL.
+
+
+
+Example
+The following function call:
+ldap_explode_rdn( "ou=Sales + cn=Barbara Jensen", 0 );
+returns this array:
+{ "ou=Sales", "cn=Barbara Jensen", NULL }
+
+See Also
+ldap_explode_dn,
+ldap_get_dn
+
+ldap_extended_operation
+The ldap_extended_operation function sends a request
+to the server to perform an extended operation asynchronously.
+Syntax
+#include <ldap.h>
+int ldap_extended_operation( LDAP *ld, const char *requestoid,
+ struct berval *requestdata, LDAPControl **serverctrls,
+ LDAPControl **clientctrls, int *msgidp );
+
+Parameters
+
ldap_extended_operation Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+requestoid
+
+Object identifier (OID) of the extended operation that you want the
+server to perform. After processing an LDAP v3 extended operation, an LDAP
+server can return an OID and data in the result. To parse the OID and data
+from the result, call the ldap_parse_extended_result function.
+
+
+
+
+requestdata
+
+Pointer to a berval structure containing
+the data that you want passed to the server to perform the extended operation.
+The data in the berval is a buffer of the
+BER encoded data type, usually obtained using the ber_flatten
+ function.
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+msgidp
+
+Pointer to an integer that will be set to the message ID of the LDAP
+operation.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the control.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+To check the result of this operation, call
+ldap_result, ldap_parse_extended_result,
+and ldap_get_lderrno.
+
+Description
+The ldap_extended_operation function sends a request
+to the server to perform an LDAP v3 extended operation. ldap_extended_operation
+ is an asynchronous function; it does not directly return results.
+If you want the results to be returned directly by the function, call the
+synchronous function ldap_extended_operation_s.
+
+See Also
+ldap_extended_operation_s, ldap_result, ldap_parse_extended_result
+, ldap_get_lderrno, ber_flatten
+
+ldap_extended_operation_s
+The ldap_extended_operation_s function sends a
+request to the server to perform an extended operation synchronously.
+Syntax
+#include <ldap.h>
+ int ldap_extended_operation_s( LDAP *ld, const char *requestoid,
+ struct berval *requestdata, LDAPControl **serverctrls,
+ LDAPControl **clientctrls, char **retoidp, struct berval **retdatap );
+
+Parameters
+
ldap_extended_operation_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+requestoid
+
+Object identifier (OID) of the extended operation that you want the
+server to perform.
+
+
+
+requestdata
+
+Pointer to a berval structure containing
+the data that you want passed to the server to perform the extended operation.
+The data in the berval is a buffer of the
+BER encoded data type, usually obtained using the ber_flatten
+ function.
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+retoidp
+
+Pointer to the OID returned by the server after performing the extended
+operation. When done, you can free this by calling the ldap_memfree
+ function.
+
+
+
+retdatap
+
+Pointer to the pointer for a berval structure
+containing the data returned by the server after performing the extended operation.
+When done, you can free this by calling the ber_bvfree
+function.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the control.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_LOCAL_ERROR if an error occurred
+when receiving the results from the server.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded results from the server.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+&cnDirectoryServer; and other LDAP server products may send result
+codes in addition to those described. For example, the server may have loaded
+a plug-in that returns custom result codes. Check your LDAP server documentation
+for other result codes.
+
+Description
+The ldap_extended_operation_s function sends a
+request to the server to perform an LDAP v3 extended operation.
+The LDAP server must support the extended operation. &cnDirectoryServer; supports
+a server plug-in interface that you can use to add support for extended operations.
+
+ldap_extended_operation_s is a synchronous function,
+which directly returns the results of the operation. If you want to perform
+other operations while waiting for the results of this operation, call the
+asynchronous function ldap_extended_operation.
+After processing an LDAP v3 extended operation, an LDAP server can return
+an object identifier and data in the results. The retoidp and
+retdatap arguments point to these values.
+See Also
+ldap_extended_operation, ber_flatten
+
+ldap_first_attribute
+The ldap_first_attribute function returns the name
+of the first attribute in an entry returned by the ldap_first_entry
+ , the ldap_next_entry, or the ldap_result functions.
+Syntax
+#include <ldap.h>
+ char * ldap_first_attribute( LDAP *ld, LDAPMessage *entry,
+ BerElement **ber );
+
+Parameters
+
ldap_first_attribute Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+entry
+
+Pointer to the LDAPMessage structure
+representing the entry returned by the ldap_first_entry or ldap_next_entry function.
+
+
+
+ber
+
+Pointer to a BerElement allocated to
+keep track of its current position. Pass this pointer to subsequent calls
+to ldap_next_attribute to step through the
+entry's attributes.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns the pointer to the name of the first
+attribute in an entry. When you are done using this data, you should free
+the memory by calling the ldap_memfree function.
+
+If unsuccessful, returns a NULL and sets
+the appropriate error code in the LDAP structure.
+To get the error code, call the ldap_get_lderrno function.
+
+
+
+Example
+Example 21–14
+retrieves each attribute for an entry.
+Using ldap_first_attribute
+
+#include <stdio.h>
+#include <ldap.h>
+...
+LDAP *ld;
+LDAPMessage *result, *e;
+BerElement *ber;
+char *a;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(sn=Jensen)"
+...
+/* Search the directory */
+if ( ldap_search_s( ld, my_searchbase, LDAP_SCOPE_SUBTREE,
+ my_filter, NULL, 0, &result ) !=
+ LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+
+/* Get the first matching entry.*/
+e = ldap_first_entry( ld, result );
+
+/* Retrieve the attributes the entry */
+ for ( a = ldap_first_attribute( ld, e, &ber ); a != NULL;
+ a = ldap_next_attribute( ld, e, ber ) ) {
+ ...
+ /* Code to get and manipulate attribute values */
+ ...
+ }
+ ldap_memfree( a );
+ }
+ /* Free the BerElement from memory when done */
+ if ( ber != NULL ) {
+ ldap_ber_free( ber, 0 );
+ }
+...
+
+
+See Also
+ldap_first_entry, ldap_next_entry, ldap_next_attribute
+, BerElement
+
+ldap_first_disptmpl
+The ldap_first_disptmpl function returns the first
+template in a list.
+Syntax
+#include <disptmpl.h>
+ ldap_first_disptmpl( struct ldap_disptmpl *tmpllist );
+
+Parameters
+
ldap_first_disptmpl Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+tmpllistp
+
+Pointer to a list of template data structures.
+
+
+
+
+
+Description
+ldap_first_disptmpl returns the first template
+in the list of templates pointed to by the parameter tmpllistp.
+tmpllistp is typically obtained by calling ldap_init_templates
+ .
+See Also
+ldap_next_disptmpl, ldap_init_templates, ldap_init_templates_buf
+
+
+ldap_first_entry
+The ldap_first_entry function returns a pointer
+to the LDAPMessage structure representing
+the first directory entry in a chain of search results.
+Syntax
+#include <ldap.h>
+ LDAPMessage * ldap_first_entry( LDAP *ld, LDAPMessage *result );
+
+Parameters
+
ldap_first_entry Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+result
+
+Chain of search results, which are represented by a pointer to the LDAPMessage structure.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns the pointer to the first LDAPMessage structure of the type LDAP_RES_SEARCH_ENTRY
+ in the chain of search results.
+If no LDAPMessage structures
+of the type LDAP_RES_SEARCH_ENTRY are in the chain of the
+search results or if the function is unsuccessful, returns a NULLMSG.
+
+
+
+Description
+The ldap_first_entry function returns a pointer
+to the LDAPMessage structure representing
+the first directory entry in a chain of search results. Search result entries
+are in messages of the type LDAP_RES_SEARCH_ENTRY. You
+can use this function in conjunction with the ldap_next_entry
+ function to iterate through the directory entries in a chain of search
+results. These functions skip over any messages in the chain that do not have
+the type LDAP_RES_SEARCH_ENTRY.
+Do not free the LDAPMessage structure
+returned by this function. Because this is a structure within a chain of search
+results, freeing this structure will free part of the chain of search results.
+When you are done working with the search results, you can free the chain
+itself, rather than individual structures within the chain.
+See Also
+ldap_result, ldap_search_ext
+ , ldap_search_ext_s, ldap_next_entry
+
+ldap_first_message
+The ldap_first_message function returns a pointer
+to the first LDAPMessage structure in a chain
+of search results.
+Syntax
+#include <ldap.h>
+ LDAPMessage * ldap_first_message( LDAP *ld, LDAPMessage *res );
+
+Parameters
+
ldap_first_message Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+res
+
+Chain of search results, represented by a pointer to the LDAPMessage structure.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns the pointer to the first LDAPMessage structure in the chain of search results.
+
+If no LDAPMessage structures
+are in the chain or if the function is unsuccessful, returns a NULLMSG.
+
+
+
+Description
+The ldap_first_message function returns a pointer
+to the first LDAPMessage structure in a chain
+of search results. You can use this function in conjunction with the ldap_next_message function to iterate through the
+chain of search results. You can also call the ldap_msgtype
+ function to determine if each message contains a matching entry,
+a message of the type LDAP_RES_SEARCH_ENTRY, or a search
+reference, a message of the type LDAP_RES_SEARCH_REFERENCE.
+Do not free the LDAPMessage structure
+returned by this function. Because this is a structure within a chain of search
+results, freeing this structure will free part of the chain of search results.
+When you are done working with the search results, you can free the chain
+itself, rather than individual structures within the chain.
+See Also
+ldap_result, ldap_search_ext
+ , ldap_search_ext_s, ldap_next_message, ldap_first_entry
+, ldap_first_reference
+
+ldap_first_reference
+The ldap_first_reference function returns a pointer
+to the LDAPMessage structure representing
+the first search reference in a chain of search results.
+Syntax
+#include <ldap.h>
+ LDAPMessage * ldap_first_reference(LDAP *ld, LDAPMessage *res );
+
+Parameters
+
ldap_first_reference Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+res
+
+Chain of search results, which are represented by a pointer to the LDAPMessage structure.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns the pointer to the first LDAPMessage structure of the type LDAP_RES_SEARCH_REFERENCE
+ in the chain of search results.
+If no LDAPMessage structures
+of the type LDAP_RES_SEARCH_REFERENCE are in the chain
+of the search results or if the function is unsuccessful, returns a NULLMSG
+.
+
+
+Description
+The ldap_first_reference function returns a pointer
+to the LDAPMessage structure representing
+the first search reference in a chain of search results. Search references
+are in messages of the type LDAP_RES_SEARCH_REFERENCE,
+continuation references as specified in LDAPv3 that are stored as referral
+entries. Like a referral, each continuation reference itself may contain a
+number of URLs assumed to be equivalent, and the client should use one of
+those URLs.
+You can use this function in conjunction with the
+ldap_next_reference function to iterate through the search references
+in a chain of search results. These functions skip over any messages in the
+chain that do not have the type LDAP_RES_SEARCH_REFERENCE.
+Do not free the LDAPMessage structure
+returned by this function. Because this is a structure within a chain of search
+results, freeing this structure will free part of the chain of search results.
+When you are done working with the search results, you can free the chain
+itself, rather than individual structures within the chain.
+See Also
+ldap_result, ldap_search_ext
+ , ldap_search_ext_s, ldap_next_reference, ldap_first_message
+
+
+ldap_first_searchobj
+The ldap_first_searchobj function returns the first
+search preference configuration from a data structure defined in the list
+solist .
+Syntax
+#include <ldap.h>
+ ldap_searchobj * ldap_first_searchobj( struct ldap_searchobj *solist );
+
+Parameters
+
ldap_first_searchobj Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+solist
+
+Pointer to the search preference data structures, typically obtained
+by calling ldap_init_searchprefs.
+
+
+
+
+
+
+Description
+ldap_first_searchobj provides access to LDAP search
+preference configuration data. LDAP search preference configurations are typically
+used by LDAP client programs to specify which attributes a user may search
+by, the labels for the attributes, and the LDAP filters and scopes associated
+with those searches.
+See Also
+ldap_init_searchprefs, ldap_init_searchprefs_buf
+
+ldap_first_tmplcol
+The ldap_first_tmplcol function returns a pointer
+to the first item within a template.
+Syntax
+#include <disptmpl.h>
+ struct ldap_tmplitem * ldap_first_tmplcol( struct ldap_disptmpl *tmpl,
+ struct ldap_tmplitem *row );
+
+Parameters
+
ldap_first_tmplcol Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+tmpl
+
+The name of the template to be retrieved.
+
+
+
+row
+
+The row in which the item is to be retrieved from.
+
+
+
+
+
+Returns
+
+If successful, a pointer to an ldap_tmplitem structure.
+
+A NULL pointer on error.
+
+
+Description
+ldap_first_tmplcol returns a pointer to the first
+item (in the first column) of the row, defined by row,
+within the template defined by tmpl.
+See Also
+ldap_first_tmplrow, ldap_next_tmplcol
+
+ldap_first_tmplrow
+The ldap_first_tmplrow function returns a pointer
+to the first row of items in a template.
+Syntax
+#include <disptmpl.h>
+ struct ldap_tmplitem * ldap_first_tmplrow( struct ldap_disptmpl *tmpl );
+
+Parameters
+
ldap_first_tmplrow Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+tmpl
+
+The name of the template to be retrieved.
+
+
+
+
+
+Returns
+
+If successful, a pointer to an ldap_tmplitem structure.
+
+A NULL pointer on error.
+
+
+See Also
+ldap_next_tmplrow, ldap_first_tmplcol
+
+ldap_free_friendlymap
+The ldap_free_friendlymap function frees the FriendlyMap structures allocated by the ldap_friendly_name function when no more calls
+to it are to be made.
+Syntax
+#include <ldap.h>
+ void ldap_free_friendlymap( FriendlyMap *map );
+
+Parameters
+
ldap_free_friendlymap Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+map
+
+Pointer to the FriendlyMap mapping
+structure in memory.
+
+
+
+
+
+Example
+Example 21–15
+frees memory allocated by the ldap_friendly_name
+function.
+Using ldap_free_friendlymap
+
+#include <ldap.h>
+#include <stdio.h>
+...
+FriendlyMap map = NULL;
+char *map_file = "/u/mozilla/ldapsdk/examples/ldapfriendly";
+char *unfriendly_name = "IS";
+char *friendly_name;
+...
+/* Read the ldapfriendly file into the map in memory */
+friendly_name = ldap_friendly_name( map_file, unfriendly_name, &map );
+printf( "Friendly Name for %s: %s\n", unfriendly_name, friendly_name );
+
+/* Since file is in memory, no need to reference it in subsequent calls */
+friendly_name = ldap_friendly_name( NULL, "VI", &map );
+printf( "Friendly Name for VI: %s\n", friendly_name );
+...
+ldap_free_friendlymap( map );
+...
+
+
+See Also
+ldap_friendly_name, FriendlyMap
+
+ldap_free_searchprefs
+The ldap_free_searchprefs function disposes of
+the data structures allocated by ldap_init_searchprefs.
+
+Syntax
+#include <ldap.h>
+ void ldap_free_searchprefs( struct ldap_searchobj *solist );
+
+Parameters
+
ldap_free_searchprefs Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+solist
+
+Pointer to the data structures, typically obtained by calling ldap_init_searchprefs.
+
+
+
+
+
+See Also
+ldap_init_searchprefs, ldap_init_searchprefs_buf
+
+ldap_free_sort_keylist
+The ldap_free_sort_keylist function frees the structures
+allocated by the ldap_create_sort_keylist function.
+
+Syntax
+#include <ldap.h>
+ void ldap_free_sort_keylist (LDAPsortkey **sortKeyList);
+
+Parameters
+
ldap_free_sort_keylist Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+sortKeyList
+
+Array of LDAPsortkey structures that
+you want to free from memory.
+
+
+
+
+
+Description
+The ldap_free_sort_keylist function frees the array
+of LDAPsortkey structures allocated by the
+ ldap_create_sort_keylist function. When
+done sorting results, call this function to free the memory that you have
+allocated. This function must be called after the ldap_create_sort_control
+ function has completed.
+See Also
+ldap_create_sort_keylist, ldap_create_sort_control
+
+ldap_free_templates
+The ldap_free_templates function disposes of the
+templates allocated by ldap_init_templates.
+Syntax
+#include <disptmpl.h>
+ void ldap_free_templates( struct ldap_disptmpl *tmpllist );
+
+Parameters
+
ldap_free_templates Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+tmpllistp
+
+Pointer to a list of template data structures.
+
+
+
+
+
+Description
+ldap_free_templates releases the templates allocated
+by ldap_init_templates. Each template defined
+in the file is an ldap_disptmpl structure.
+
+ldap_free_urldesc
+The ldap_free_urldesc function frees memory allocated
+by the ldap_url_parse function.
+Syntax
+#include <ldap.h>
+ void ldap_free_urldesc( LDAPURLDesc *ludp );
+
+Parameters
+
ldap_free_urldesc Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ludp
+
+Pointer to a LDAPURLDesc structure.
+
+
+
+
+
+
+Example
+Example 21–16 parses
+an LDAP URL and then frees the LDAPURLDesc structure
+from memory after verifying that the LDAP URL is valid.
+Using ldap_free_urldesc
+#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 );
+...
+
+
+See Also
+ldap_url_parse
+
+ldap_friendly_name
+The ldap_friendly_name function maps a set of standard
+identifiers to their user-friendly counterparts. For example, you can represent
+the list of two-letter state codes (CA, IA) with their corresponding state
+names (California, Iowa), or map country ISO codes to the full country names.
+ldapfriendly, located in lib/ldapcsdk/etc
+, is a sample file that maps two letter country codes to their full
+names. It can be used in context with ldap_friendly_name
+.
+Syntax
+#include <ldap.h>
+ char * ldap_friendly_name( char *filename, char *uname,
+ FriendlyMap *map );
+
+Parameters
+
ldap_friendly_name function
+parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+filename
+
+Name of the file mapping the standard identifiers to the user-friendly
+names.
+
+
+
+uname
+
+Standard identifier name for which you want to find the user-friendly
+name.
+
+
+
+map
+
+Pointer to the FriendlyMap mapping
+in memory. Initialize this pointer to NULL on the first
+call, then use it during subsequent calls so that the mapping file does not
+need to be read again.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns the user-friendly name for the specified
+identifier.
+If unsuccessful—for example, if the file cannot be read,
+if the file is in a bad format, or if the map parameter is set to NULL—returns
+the original identifier (the value passed as the uname parameter).
+
+
+
+Description
+This function relies on the existence of a text file mapping standard
+identifiers to user-friendly names. The names in the file are tab-delimited.
+Unfriendly to Friendly Name Mapping File
+<unfriendly_name> <friendly_name>
+AD Andorra
+AE United Arab Emirates
+AF Afghanistan
+AG Antigua and Barbuda
+AI Anguilla
+
+
+Example
+Example 21–18
+reads in a map of user-friendly names and prints the name corresponding to
+the standard identifier IS.
+Using ldap_friendly_name
+
+#include <ldap.h>
+#include <stdio.h>
+...
+FriendlyMap map = NULL;
+char *map_file = "/u/mozilla/ldapsdk/examples/ldapfriendly";
+char *unfriendly_name = "IS";
+char *friendly_name;
+...
+/* Read the ldapfriendly file into the map in memory */
+friendly_name = ldap_friendly_name( map_file, unfriendly_name, &map );
+printf( "Friendly Name for %s: %s\n", unfriendly_name, friendly_name );
+
+/* Since file is in memory, no need to reference it in subsequent calls */
+friendly_name = ldap_friendly_name( NULL, "VI", &map );
+printf( "Friendly Name for VI: %s\n", friendly_name );
+...
+
+
+See Also
+ldap_free_friendlymap, FriendlyMap
+
+ldap_get_dn
+The ldap_get_dn routine returns the DN for an entry
+in a chain of search results.
+Syntax
+#include <ldap.h>
+ char * ldap_get_dn( LDAP *ld, LDAPMessage *entry );
+
+Parameters
+
ldap_get_dn Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+entry
+
+Pointer to an entry in a chain of search results, as returned by the ldap_first_entry and ldap_next_entry
+ functions.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns the DN for the specified entry.
+
+If unsuccessful, returns a NULL and sets
+the appropriate error code in the LDAP structure. To get the error code, call
+the ldap_get_lderrno function.
+
+
+
+Description
+You can get an entry from a chain of search results by calling the ldap_first_entry and ldap_next_entry
+ functions.
+Example
+Example 21–19 prints
+the DN for each entry found in a search.
+Using ldap_get_dn
+#include <stdio.h>
+#include <ldap.h>
+...
+LDAP *ld;
+LDAPMessage *result, *e;
+char *dn;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(sn=Jensen)";
+...
+/* Search the directory */
+if ( ldap_search_s( ld, my_searchbase, LDAP_SCOPE_SUBTREE, my_filter,
+ NULL, 0, &result ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+
+/* For each matching entry found, print out the name of the entry.*/
+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 );
+ /* Free the memory used for the DN when done */
+ ldap_memfree( dn );
+ }
+}
+/* Free the result from memory when done. */
+ldap_msgfree( result );
+...
+
+
+See Also
+ldap_first_entry, ldap_next_entry, ldap_get_lderrno
+
+
+ldap_get_entry_controls
+The ldap_get_entry_controls function gets the LDAP
+controls included with a directory entry in a set of search results.
+Syntax
+#include <ldap.h>
+ int ldap_get_entry_controls( LDAP *ld, LDAPMessage *entry,
+ LDAPControl ***serverctrlsp );
+
+Parameters
+
ldap_get_entry_controls Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+entry
+
+Pointer to an LDAPMessage structure
+representing an entry in a chain of search results.
+
+
+
+serverctrlsp
+
+Pointer to an array of LDAPControl structures,
+which represent the LDAP v3 server controls returned by the server.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded results from the server.
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+
+
+Description
+The ldap_get_entry_controls function retrieves
+the LDAP v3 controls included in a directory entry in a chain of search results.
+The LDAP controls are specified in an array of LDAPControl
+ structures with each structure representing one LDAP control. Other
+controls are returned with results sent from the server. You can call ldap_parse_result to retrieve those controls.
+
+
+ldap_getfilter_free
+The ldap_getfilter_free function frees the memory
+used by a filter set.
+Syntax
+#include <ldap.h>
+ void ldap_getfilter_free( LDAPFiltDesc *lfdp );
+
+Parameters
+
ldap_getfilter_free Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+lfdp
+
+Pointer to a LDAPFiltDesc structure.
+
+
+
+
+
+
+Description
+Once you call ldap_getfilter_free, the LDAPFiltDesc structure is no longer valid and cannot
+be used again.
+Example
+Example 21–20 frees
+the LDAPFiltDesc structure from memory after
+all searches are completed.
+Using ldap_getfilter_free
+
+#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 );
+...
+
+
+See Also
+ldap_init_getfilter, ldap_init_getfilter_buf
+
+ldap_getfirstfilter
+The ldap_getfirstfilter function retrieves the
+first filter that is appropriate for a given value.
+Syntax
+#include <ldap.h>
+ LDAPFiltInfo * ldap_getfirstfilter( LDAPFiltDesc *lfdp,
+ char *tagpat, char *value );
+
+Parameters
+
ldap_getfirstfilter Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+lfdp
+
+Pointer to an LDAPFiltDesc structure.
+
+
+
+
+tagpat
+
+Regular expression for a tag in the filter configuration.
+
+
+
+value
+
+Value for which to find the first appropriate filter.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns a pointer to an LDAPFiltInfo
+ structure.
+If no more filters can be returned, returns a NULL.
+
+If unsuccessful, returns a NULL.
+
+
+
+Example
+Example 21–21
+is based on the getfilt command-line program example provided
+with the &DirectorySDKForC;. The program prompts the user to enter search
+criteria and, based on the criteria entered, it retrieves filters that match
+the criteria.
+Using ldap_getfirstfilter
+
+#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" );
+ return( 1 );
+}
+
+/* Read a string to search for */
+printf( "Enter a string to search for: " );
+gets( buf );
+if ( strlen( buf ) == 0 ) {
+ fprintf( stderr, "usage: %s search-string\n", argv[ 0 ]);
+ return( 1 );
+}
+
+/* Select a filter to use when searching for the value in buf */
+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 %s match%s for \"%s\"\n\n", found,
+ ldfi->lfi_desc, found == 1 ? "" : "es", buf );
+}
+
+ldap_msgfree( result );
+ldap_getfilter_free( ldfp );
+...
+
+
+See Also
+ldap_init_getfilter, ldap_init_getfilter_buf, ldap_getnextfilter
+
+
+ldap_get_lang_values
+This function is deprecated and should not be used. It is included
+in ldap-deprecated.h for backward-compatibility. Please
+use ldap_get_values.
+The ldap_get_lang_values function returns a NULL
+ terminated array of an attribute’s string values that match
+a specified language subtype.
+Syntax
+#include <ldap.h>
+char ** ldap_get_lang_values( LDAP *ld, LDAPMessage *entry,
+ const char *target, char **type );
+
+Parameters
+
ldap_get_lang_values Function
+Parameters
+
+
+
+
+Parameters
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+entry
+
+Entry retrieved from the directory.
+
+
+
+target
+
+Attribute type (including an optional language subtype) that you want
+to retrieve the values of.
+
+
+
+type
+
+Pointer to a buffer that returns the attribute type retrieved by this
+function.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns a NULL terminated
+array of the attribute’s values.
+If unsuccessful or if no such attribute exists in the entry,
+returns a NULL and sets the appropriate error code in the
+ LDAP structure. To get the error code, call
+the ldap_get_lderrno function.
+
+
+
+Description
+Unlike the ldap_get_values function,
+if a language subtype is specified, this function first attempts to find and
+return values that match that subtype—for example, cn;lang-en.
+If you want to retrieve binary data from an attribute, call the ldap_get_lang_values_len function.
+See Also
+ldap_first_entry, ldap_first_attribute, ldap_get_lang_values_len
+ , ldap_get_values, ldap_next_entry, ldap_next_attribute
+
+
+ldap_get_lang_values_len
+This function is deprecated and should not be used. It is included
+in ldap-deprecated.h for backward-compatibility. Please
+use ldap_get_values_len.
+The ldap_get_lang_values_len function returns a
+ NULL terminated array of pointers to
+berval structures, each containing the length and pointer to a binary
+value of an attribute for a given entry.
+Syntax
+#include <ldap-deprecated.h>
+struct berval ** ldap_get_lang_values_len( LDAP *ld,
+ LDAPMessage *entry, const char *target, char **type );
+
+Parameters
+
ldap_get_lang_values_len Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+entry
+
+Result returned by the ldap_result or ldap_search_s function.
+
+
+
+target
+
+Attribute returned by ldap_first_attribute or ldap_next_attribute, or the attribute as a literal
+string, such as jpegPhoto or audio.
+
+
+
+
+type
+
+Pointer to a buffer that returns the attribute type retrieved by this
+function.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns a NULL terminated
+array of pointers to berval structures, which,
+in turn, contain pointers to the attribute’s binary values.
+
+If unsuccessful or if no such attribute exists in the entry,
+returns a NULL and sets the appropriate error code in the
+ LDAP structure. To get the error code, call
+the ldap_get_lderrno function.
+
+
+
+Description
+Use the ldap_get_lang_values routine
+if the attribute values are string values.
+See Also
+ldap_first_attribute, ldap_first_entry, ldap_get_lang_values
+, ldap_next_entry, ldap_next_attribute
+
+ldap_get_lderrno
+The ldap_get_lderrno function gets information
+about the last error that occurred for an LDAP operation.
+Syntax
+#include <ldap.h>
+int ldap_get_lderrno( LDAP *ld, char **m, char **s );
+
+Parameters
+
ldap_get_lderrno Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+m
+
+In the event of an LDAP_NO_SUCH_OBJECT error
+return, this parameter contains the portion of the DN that identifies an existing
+entry.
+
+
+
+s
+
+The text of the error message.
+
+
+
+
+
+Returns
+The LDAP error code for the last operation.
+Description
+ldap_get_lderrno gets information about the last
+error that occurred for an LDAP operation. You can also call this function
+to get error codes for functions that do not return errors, such as ldap_next_attribute.
+Example
+Example 21–22 attempts
+to add a new user to the directory. If the entry identified by a DN does not
+exist, the server returns the portion of the DN that matches an existing entry;
+this is the variable matched.
+Using ldap_get_lderrno
+#include <ldap.h>
+LDAP *ld;
+char *dn = "uid=bjensen,ou=People,dc=example,dc=com";
+LDAPMod **list_of_attrs;
+char *matched;
+int rc;
+...
+if ( ldap_add_s( ld, dn, list_of_attrs ) != LDAP_SUCCESS ) {
+ rc = ldap_get_lderrno( ld, &matched, NULL );
+ return( rc );
+}
+...
+
+In Example 21–22,
+if no organizational unit named People exists, the matched
+variable is set to dc=example,dc=com .
+See Also
+ldap_err2string,
+ldap_perror, ldap_result2error, ldap_set_lderrno
+
+ldap_getnextfilter
+The ldap_getnextfilter function retrieves the next
+filter that is appropriate for a given value.
+Syntax
+#include <ldap.h>
+ LDAPFiltInfo * ldap_getnextfilter( LDAPFiltDesc *lfdp );
+
+Parameters
+
ldap_getnextfilter Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+lfdp
+
+Pointer to an LDAPFiltDesc structure.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns a pointer to an LDAPFiltInfo
+ structure.
+If no more filters can be returned, returns a NULL.
+
+If unsuccessful, returns a NULL.
+
+
+
+Description
+Call this function to get subsequent filters after calling ldap_getfirstfilter.
+Example
+See Example 21–21.
+
+See Also
+ldap_getfirstfilter
+
+ldap_get_option
+The function ldap_get_option retrieves session
+preferences from an LDAP structure.
+Syntax
+#include <ldap.h>
+ int ldap_get_option( LDAP *ld, int option, void *optdata );
+
+Parameters
+
ldap_get_option Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+option
+
+Option that you want to retrieve. This parameter must be set to one
+of the option values.
+
+
+
+optdata
+
+Pointer to the buffer in which the value of the option will be put.
+
+
+
+
+
+Table 21–110 describes
+the options that you can retrieve with ldap_get_option.
+
Options for the
+ldap_get_options Function
+
+
+
+
+Option
+
+Description
+
+
+
+
+
+LDAP_OPT_API_FEATURE_INFO
+
+Retrieves information about the revision of a supported LDAP feature.
+This option is READ-ONLY and cannot be set.
+The data type for the optdata parameter is (LDAPAPIFeatureInfo
+*).
+
+
+
+LDAP_OPT_API_INFO
+
+Retrieves information about the API implementation at execution time
+(API version, protocol version, the names of supported API extensions with
+their vendor name version, etc.). For details on the structure returned, refer
+to the ldap.h header file. This option is READ-ONLY and
+cannot be set.
+The data type for the optdata parameter is (LDAPAPIInfo
+*).
+
+
+
+LDAP_OPT_CLIENT_CONTROLS
+
+Pointer to an array of LDAPControl structures
+representing the LDAP v3 client controls you want sent with every request
+by default.
+The data type for the optdata parameter is (LDAPControl
+***).
+
+
+
+LDAP_OPT_DESC
+
+Socket descriptor underlying the main LDAP connection. The LBER_SOCKET
+ data type depends on the platform that you are using:
+
+int in UNIX.
+SOCKET in Windows.The data
+type for the optdata parameter is (LBER_SOCKET
+*).
+
+
+
+
+
+LDAP_OPT_DEREF
+
+Determines how aliases work during a search. optdata can
+be one of the following values:
+
+LDAP_DEREF_NEVER specifies that aliases
+are never dereferenced.
+LDAP_DEREF_SEARCHING specifies that aliases
+are dereferenced when searching under the base object (but not when finding
+the base object).
+LDAP_DEREF_FINDING specifies that aliases
+are dereferenced when finding the base object (but not when searching under
+the base object).
+LDAP_DEREF_ALWAYS specifies that aliases
+are always dereferenced when finding and searching under the base object.
+The data type for the optdata parameter is (int
+*).
+
+
+
+
+
+LDAP_OPT_DNS_FN_PTRS
+
+DEPRECATED OPTION: Lets you use alternate
+DNS functions for getting the host entry of the LDAP server.
+The data type for the optdata parameter is (struct
+ldap_dns_fns *).
+
+
+
+LDAP_OPT_ERROR_NUMBER
+
+Retrieves the result code for the most recent LDAP error that occurred
+in this session.
+The data type for the optdata parameter is (int
+*).
+
+
+
+LDAP_OPT_ERROR_STRING
+
+Retrieves the error message returned with the result code for the most
+recent LDAP error that occurred in this session.
+The data type for the optdata parameter is (char
+**).
+
+
+
+LDAP_OPT_EXTRA_THREAD_FN_PTRS
+
+Lets you specify the locking and semaphore functions that you want called
+when getting results from the server.
+The data type for the optdata parameter is (struct
+ldap_extra_thread_fns *).
+
+
+
+LDAP_OPT_HOST_NAME
+
+Sets the host name (or list of hosts) for the primary LDAP server.
+The data type for the optdata parameter is (char
+**).
+
+
+
+LDAP_OPT_IO_FN_PTRS
+
+DEPRECATED OPTION: Lets you use alternate
+communication stacks.
+The data type for the optdata parameter is (struct
+ldap_io_fns *).
+
+
+
+LDAP_OPT_MATCHED_DN
+
+Gets the matched DN value returned with the most recent LDAP error that
+occurred for this session.
+The data type for the optdata parameter is (char
+**)
+
+
+
+LDAP_OPT_MEMALLOC_FN_PTRS
+
+Gets a pointer to the callback structure which you previously set.
+The data type for the optdata parameter is (struct
+ldap_memalloc_fnsldap_io_fns *).
+
+
+
+LDAP_OPT_PROTOCOL_VERSION
+
+Version of the protocol supported by your client. You can specify either
+LDAP_VERSION2 or LDAP_VERSION3. If no version
+is set, the default is LDAP_VERSION2. In order to use LDAP
+v3 features, you need to set the protocol version to LDAP_VERSION3.
+
+The data type for the optdata parameter is (int
+*).
+
+
+
+LDAP_OPT_REBIND_ARG
+
+Lets you set the last argument passed to the routine specified by
+LDAP_OPT_REBIND_FN. You can also set this option by calling the ldap_set_rebind_proc function.
+The data type for the optdata parameter is (void
+*).
+
+
+
+LDAP_OPT_REBIND_FN
+
+Lets you set the routine to be called when you need to authenticate
+a connection with another LDAP server (for example, during the course of following
+a referral). You can also set this option by calling the
+ldap_set_rebind_proc function.
+The data type for the optdata parameter is (LDAP_REBINDPROC_CALLBACK
+*).
+
+
+
+LDAP_OPT_RECONNECT
+
+If the connection to the server is lost, determines whether or not the
+same connection handle should be used to reconnect to the server. By default,
+this option is off. You handle failover with the following values:
+
+LDAP_OPT_ON specifies that the same connection
+handle can be used to reconnect to the server.
+LDAP_OPT_OFF specifies that you want to
+create a new connection handle to connect to the server.The data
+type for the optdata parameter is (int *).
+
+
+
+
+
+
+LDAP_OPT_REFERRALS
+
+Determines whether or not the client should follow referrals. By default,
+the client follows referrals. optdata can be one of the
+following values:
+
+LDAP_OPT_ON specifies that the server should
+follow referrals.
+LDAP_OPT_OFF specifies that the server
+should not follow referrals.The data type for the optdata parameter
+is (int *).
+
+
+
+
+
+LDAP_OPT_REFERRAL_HOP_LIMIT
+
+Maximum number of referrals the client should follow in a sequence.
+In other words, the client can only be referred this number of times before
+it gives up. By default, the maximum number of referrals that the client can
+follow in a sequence is 5 for the initial connection. This limit does not
+apply to individual requests that generate multiple referrals in parallel.
+The data type for the optdata parameter is (int
+*).
+
+
+
+LDAP_OPT_RESTART
+
+Determines whether or not LDAP I/O operations should be restarted automatically
+if they are prematurely aborted. optdata can be one of
+the following values:
+
+LDAP_OPT_ON specifies that I/O operations
+should be restarted automatically.
+LDAP_OPT_OFF specifies that I/O operations
+should not be restarted automatically.The data type for the
+optdata parameter is (int *).
+
+
+
+
+
+LDAP_OPT_SERVER_CONTROLS
+
+Pointer to an array of LDAPControl structures
+representing the LDAP v3 server controls you want sent with every request
+by default. Typically, since controls are specific to the type of request,
+you may want to pass the controls using operation-specific functions, such
+as ldap_add_ext, instead.
+The data type for the optdata parameter is (LDAPControl
+***).
+
+
+
+LDAP_OPT_SIZELIMIT
+
+Maximum number of entries that should be returned by the server in search
+results. The LDAP server may impose a smaller size limit than the limit you
+specify as the server administrator also has the ability to set this limit.
+The data type for the optdata parameter is (int
+*).
+
+
+
+LDAP_OPT_SSL
+
+Determines whether or not SSL is enabled. optdata can
+be one of the following values:
+
+LDAP_OPT_ON specifies that SSL is enabled.
+
+LDAP_OPT_OFF specifies that SSL is disabled.
+The data type for the optdata parameter is (int
+*).
+
+
+
+
+
+LDAP_OPT_THREAD_FN_PTRS
+
+Lets you specify the thread function pointers.
+The data type for the optdata parameter is (struct
+ldap_thread_fns *).
+
+
+
+LDAP_OPT_TIMELIMIT
+
+Maximum number of seconds that should be spent by the server when answering
+a search request. The LDAP server may impose a shorter time limit than the
+limit you specify as the server administrator also has the ability to set
+this limit.
+The data type for the optdata parameter is (int
+*).
+
+
+
+LDAP_X_OPT_EXTIO_FN_PTRS
+
+Extended I/O function callback option.
+
+
+
+LDAP_X_OPT_CONNECT_TIMEOUT
+
+Value of a time out (expressed in milliseconds) for non-blocking connect
+call.
+The data type for the optdata parameter is (int
+*).
+
+
+
+LDAP_X_OPT_SOCKBUF
+
+Socket buffer structure associated to the LDAP connection.
+
+
+
+
+See also ldap_get_option
+3LDAP for details on LDAP_OPT_X_SASL*
+ parameters.
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+-1 if unsuccessful.
+
+
+Examples
+Example 21–23 gets
+the session preference for the maximum number of entries to be returned from
+search operations.
+Using ldap_get_option
+#include <ldap.h>
+...
+LDAP *ld;
+int max_ret;
+...
+/* Get the maximum number of entries returned */
+if (ldap_get_option, LDAP_OPT_SIZELIMIT, &max_ret) != LDAP_SUCCESS) {
+ ldap_perror( ld, "ldap_get_option" );
+ return( 1 );
+}
+
+Example 21–23 could
+also include the following two small sections of code that show how to use
+the LDAP_OPT_API_FEATURE_INFO and the LDAP_OPT_API_INFO
+ options, respectively.
+Using LDAP_OPT_API_FEATURE_INFO and
+LDAP_OPT_API_INFO
+LDAPIIFeatureInfo ldfi;
+ldfi.ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
+ldfi.ldapaif_name = "VIRTUAL_LIST_VIEW";
+if (ldap_get_option(NULL, LDAP_OPT_API_FEATURE_INFO, &ldfi)==0) {
+/* use the info here */ }
+
+LDAPIInfo ldai;
+ldai.ldapiai_info_version = LDAP_API_INFO_VERSION;
+if (ldap_get_option( NULL, LDAP_OPT_API_INFO, &ldia ) == 0) {
+/* use the ldai info here */
+}
+
+
+See Also
+ldap_init, prldap_init
+ (IPv6), ldap_set_option
+
+ldap_get_values
+The ldap_get_values function returns a NULL terminated
+array of an attribute’s string values for a given entry.
+Syntax
+#include <ldap.h>
+ char ** ldap_get_values( LDAP *ld, LDAPMessage *entry,
+ const char *target );
+
+Parameters
+
ldap_get_values Function
+Parameters
+
+
+
+
+Parameters
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+entry
+
+Result returned by the ldap_result or ldap_search_s function.
+
+
+
+target
+
+Attribute returned by ldap_first_attribute or ldap_next_attribute, or the attribute as a literal
+string, such as jpegPhoto or audio.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns a NULL terminated
+array of the attribute’s values.
+If unsuccessful or if no such attribute exists in the entry,
+returns a NULL and sets the appropriate error code in the
+ LDAP structure. To get the error code, call
+the ldap_get_lderrno function.
+
+
+
+Description
+Use the ldap_get_values_len function
+if the attribute values are binary.
+Example
+Example 21–25 gets
+and prints the values of an attribute in an entry. This example assumes that
+all attributes have string values.
+Using ldap_get_values
+#include <stdio.h>
+#include <ldap.h>
+...
+LDAP *ld;
+LDAPMessage *result, *e;
+BerElement *ber;
+char *a;
+char **vals;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(sn=Jensen)";
+int i;
+...
+/* Search the directory */
+if ( ldap_search_s( ld, my_searchbase, LDAP_SCOPE_SUBTREE, my_filter,
+ NULL, 0, &result ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+
+/* Get the first matching entry.*/
+e = ldap_first_entry( ld, result );
+
+/* Get the first matching attribute */
+a = ldap_first_attribute( ld, e, &ber );
+
+/* Get the values of the attribute */
+if ( ( vals = ldap_get_values( ld, e, a ) ) != NULL ) {
+ for ( i = 0; vals[i] != NULL; i++ ) {
+ /* Print the name of the attribute and each value */
+ printf( "%s: %s\n", a, vals[i] );
+ }
+ /* Free the attribute values from memory when done. */
+ ldap_value_free( vals );
+}
+...
+
+
+See Also
+ldap_first_entry, ldap_first_attribute, ldap_get_values_len
+, ldap_next_entry, ldap_next_attribute
+
+ldap_get_values_len
+The ldap_get_values_len function returns a NULL
+ terminated array of pointers to berval structures,
+each containing the length and pointer to a binary value of an attribute for
+a given entry.
+Syntax
+#include <ldap.h>
+ struct berval ** ldap_get_values_len( LDAP *ld,
+ LDAPMessage *entry, const char *target );
+
+Parameters
+
ldap_get_values_len Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+entry
+
+Result returned by the ldap_result or ldap_search_s function.
+
+
+
+target
+
+Attribute returned by ldap_first_attribute or ldap_next_attribute, or the attribute as a literal
+string, such as jpegPhoto or audio.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns a NULL terminated
+array of pointers to berval structures, which in
+turn contains pointers to the attribute’s binary values.
+If unsuccessful or if no such attribute exists in the entry,
+returns NULL and sets the appropriate error code in the
+ LDAP structure. To get the error code, call
+the ldap_get_lderrno function.
+
+
+
+Description
+Use the ldap_get_values routine if
+the attribute values are string values.
+Example
+Example 21–26
+gets the first value of the jpegPhoto attribute and saves
+the JPEG data to a file.
+ldap_get_values_len
+#include <stdio.h>
+#include <ldap.h>
+...
+LDAP *ld;
+LDAPMessage *result, *e;
+BerElement *ber;
+struct berval photo_data;
+struct berval **list_of_photos;
+FILE *out;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(sn=Jensen)";
+...
+/* Search the directory */
+if ( ldap_search_s( ld, my_searchbase, LDAP_SCOPE_SUBTREE, my_filter, NULL,
+ 0, &result ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+
+/* Get the first matching entry.*/
+e = ldap_first_entry( ld, result );
+
+/* Get the value of the jpegPhoto attribute */
+if ( ( list_of_photos = ldap_get_values_len( ld, e, "jpegPhoto" ) ) !=
+ NULL ) {
+ /* Prepare to write the JPEG data to a file */
+ if ( ( out = fopen( "photo.jpg", "wb" ) ) == NULL ) {
+ perror( "fopen" );
+ return( 1 );
+ }
+ /* Get the first JPEG */
+ photo_data = *list_of_photos[0];
+ /* Write the JPEG data to a file */
+ fwrite( photo_data.bv_val, photo_data.bv_len, 1, out );
+ fclose( out );
+ /* Free the attribute values from memory when done. */
+ ldap_value_free_len( list_of_photos );
+}
+...
+
+
+See Also
+ldap_first_entry, ldap_first_attribute, ldap_get_values
+, ldap_next_entry, ldap_next_attribute
+
+ldap_init
+The ldap_init function initializes a session with
+an LDAP server and returns an LDAP structure
+that represents the context of the connection to that server.
+Syntax
+#include <ldap.h>
+LDAP * ldap_init( const char *defhost, int defport );
+
+Parameters
+
ldap_init Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+defhost
+
+Space-delimited list of one or more host names (or IP address in dotted
+notation, such as "141.211.83.36") of the LDAP servers that you want the LDAP
+client to connect to. The names can be in hostname:
+portnumber format (in which case, portnumber overrides
+the port number specified by the defport argument.
+
+
+
+
+defport
+
+Default port number of the LDAP server. To specify the standard LDAP
+port (port 389), use LDAP_PORT as the value for this parameter.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns a pointer to an LDAP
+ structure.
+If unsuccessful, returns a NULL.
+
+
+
+Description
+The ldap_init function initializes a session with
+an LDAP server by allocating an LDAP structure
+containing information about the session including the host name and port
+of the LDAP server, preferences for the session (such as the maximum number
+of entries to return in a search), and the error code of the last LDAP operation
+performed. The LDAP structure defaults to
+LDAP v2. It is highly recommended to set it to LDAP v3 using the ldap_set_option.
+ldap_init does not open a connection
+to the LDAP server. The actual connection opening will occur when the first
+operation is attempted. Certain fields in the LDAP structure
+can be set using ldap_set_option.
+You can specify a list of LDAP servers to which you want to attempt
+to connect by passing a space-delimited list of the host names as the defhost
+ argument. Your client will attempt to connect to the first LDAP
+server in the list. If the attempt fails, your client will attempt to connect
+to the next LDAP server in the list. In Example
+21–27ld1.example.com, port 389.
+If that server does not respond, the client will attempt to connect to the
+LDAP server on ld2.example.com, port 389.
+If that server does not respond, the client will use the server on ld3.example.com
+ , port 389.
+Space-Delimited List for ldap_init
+
+...
+LDAP *ld
+...
+ld = ldap_init( "ld1.example.com ld2.example.com ld3.example.com",
+ LDAP_PORT );
+
+If any of the servers do not use the default port specified by the
+defport argument, use the hostname:
+portnumber format to specify the server name. In Example 21–27ld1.example.com
+, port 389. If that server does not respond,
+the client will attempt to connect to the LDAP server on ld2.example.com
+, port 1389.
+ldap_init Example
+Using Variable Argument
+...
+LDAP *ld
+...
+ld = ldap_init( "ld1.example.com ld2.example.com:1389", LDAP_PORT );
+
+If you are connecting to a secure LDAP server over SSL, you should
+be calling the ldapssl_init function.
+
+
+Example
+Example 21–29 initializes
+a session with the LDAP server at ldap.example.com:389,
+and sets a session preference that identifies the client as an LDAP v3 client.
+Using ldap_init
+#include <ldap.h>
+...
+LDAP *ld;
+
+/* Specify the host name of the LDAP server. */
+char *ldap_host = "ldap.example.com";
+
+/* Because the LDAP server is running on the standard LDAP port (port 389),
+ * you can use LDAP_PORT to identify the port number. */
+int ldap_port = LDAP_PORT;
+...
+/* Initialize the session with ldap.example.com:389 */
+/* Use prldap_init() for IPv6 support. */
+if ( ( ld = ldap_init( ldap_host, ldap_port ) ) == NULL ) {
+ perror( "ldap_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 that authenticate to the LDAP server. */
+...
+
+
+See Also
+prldap_init (IPv6), ldap_unbind, ldap_unbind_s , ldap_simple_bind, ldap_simple_bind_s
+
+
+ldap_init_getfilter
+The ldap_init_getfilter function reads a valid
+LDAP filter configuration file (such as ldapfilter.conf)
+and returns a pointer to an LDAPFiltDesc structure.
+
+ldapfilter.conf, the sample LDAP filter configuration
+file located in lib/ldapcsdk/etc directory, can be used
+in context with ldap_init_getfilter .
+
+Syntax
+#include <ldap.h>
+LDAPFiltDesc * ldap_init_getfilter( char *fname );
+
+Parameters
+
ldap_init_getfilter Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+fname
+
+Name of the LDAP filter configuration file to use.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns a pointer to an LDAPFiltDesc
+ structure.
+If unsuccessful (for example, if there is an error reading
+the file), returns a NULL.
+
+
+Example
+Example 21–30
+loads a filter configuration file named myfilters.conf into
+memory.
+Loading a Filter Configuration File
+#include <ldap.h>
+...
+LDAPFiltDesc *lfdp;
+char *filter_file = "myfilters.conf";
+...
+lfdp = ldap_init_getfilter( filter_file );
+...
+
+
+See Also
+ldap_init_getfilter_buf, ldap_getfilter_free
+
+ldap_init_getfilter_buf
+The ldap_init_getfilter_buf function reads LDAP
+filter configuration information from a buffer and returns a pointer to an
+ LDAPFiltDesc structure.
+Syntax
+#include <ldap.h>
+ LDAPFiltDesc * ldap_init_getfilter_buf(char *buf, long buflen );
+
+Parameters
+
+
+Returns
+One of the following values:
+
+If successful, returns a pointer to an LDAPFiltDesc
+ structure.
+If unsuccessful—for example, if there is an error reading
+the file—returns a NULL.
+
+
+Example
+Example 21–31
+copies the following filter configuration to a buffer in memory and uses this
+buffer to fill an LDAPFiltDesc structure.
+"ldap-example"
+ "@" " " "(mail=%v)" "email address"
+ "(mail=%v*)" "start of email address"
+Using ldap_init_getfilter
+
+#include <string.h>
+#include <ldap.h>
+...
+LDAPFiltDesc *lfdp;
+char filtbuf[ 1024 ];
+...
+/* Create the filter config buffer */
+strcpy( filtbuf, "\"ldap-example\"\n" );
+strcat( filtbuf, " \"@\"\t\" \"\t\"(mail=%v)\"\t\"email address\"\n" );
+strcat( filtbuf, " \t\t\"(mail=%v*)\"\t\"start of email address\"\n" );
+lfdp = ldap_init_getfilter( filtbuf, strlen( filtbuf ) );
+...
+
+
+See Also
+ldap_init_getfilter, ldap_getfilter_free
+
+ldap_init_searchprefs
+The ldap_init_searchprefs function reads a sequence
+of search preference configurations from a valid LDAP searchpref configuration
+file.
+Syntax
+#include <ldap.h>
+int ldap_init_searchprefs( char *file, struct ldap_searchobj **solistp );
+
+Parameters
+
ldap_init_searchprefs Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+file
+
+Pointer to a valid LDAP searchpref configuration
+file.
+
+
+
+solistp
+
+Pointer to a list of search preference data structures.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SEARCHPREF_ERR_VERSION.
+
+LDAP_SEARCHPREF_ERR_MEM if there is a memory
+allocation problem.
+Upon success, 0 is returned and solistp
+ is set to point to a list of search preference data structures.
+
+
+
+Description
+ldap_init_searchprefs provides a standard way to
+access LDAP search preference configuration data.
+LDAP search preference configurations are typically used by LDAP
+client programs to specify which attributes a user may search by, labels for
+the attributes, and LDAP filters and scopes associated with those searches.
+Client software presents these choices to a user, who can then specify the
+type of search to be performed.
+
+See Also
+ldap_free_searchprefs, ldap_init_searchprefs_buf
+
+ldap_init_searchprefs_buf
+The ldap_init_searchprefs_buf function reads a
+sequence of search preference configurations from the parameter, buf.
+
+Syntax
+#include <ldap.h>
+int ldap_init_searchprefs_buf( char *buf, long buflen,
+ struct ldap_searchobj **solistp );
+
+Parameters
+
ldap_init_searchprefs_buf Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+buf
+
+Pointer to data in the format defined for an LDAP search preference
+configuration file.
+
+
+
+buflen
+
+The size of buf.
+
+
+
+solistp
+
+Pointer to a list of search preference data structures.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SEARCHPREF_ERR_VERSION if buf points
+to data that is newer than can be handled.
+LDAP_SEARCHPREF_ERR_MEM if there is a memory
+allocation problem.
+Upon success, 0 is returned and solistp
+ is set to point to a list of search preference data structures.
+
+
+
+Description
+ldap_init_searchprefs_buf reads a sequence of search
+preference configurations from buf.
+LDAP search preference configurations are typically used by LDAP
+client programs to specify which attributes a user may search by, labels for
+the attributes, and LDAP filters and scopes associated with those searches.
+Client software presents these choices to a user, who can then specify the
+type of search to be performed.
+
+See Also
+ldap_init_searchprefs, ldap_free_searchprefs
+
+ldap_init_templates
+The ldap_init_templates function reads a sequence
+of templates from a valid LDAP template configuration file.
+Syntax
+#include <disptmpl.h>
+int ldap_init_templates( char *file, struct ldap_disptmpl **tmpllistp );
+
+Parameters
+
ldap_init_templates Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+file
+
+Pointer to a valid LDAP template configuration file.
+
+
+
+tmpllistp
+
+Pointer to a list of template data structures.
+
+
+
+
+
+Returns
+
+If successful, 0 is returned and tmpllistp
+ is configured.
+Upon error:
+
+LDAP_TMPL_ERR_VERSION if buf points
+to data that is newer than can be handled.
+LDAP_TMPL_ERR_MEM if there is a memory
+allocation problem.
+LDAP_TMPL_ERR_SYNTAX if there is a problem
+with the format of the templates buffer or file.
+LDAP_TMPL_ERR_FILE if the file cannot be
+read.
+
+
+
+
+Description
+ldap_init_templates reads a sequence of templates
+from a valid LDAP template configuration file. Each template defined in the
+file is an ldap_disptmpl structure.
+See Also
+ldap_init_templates_buf, ldap_free_templates
+
+ldap_init_templates_buf
+The ldap_init_templates_buf function reads a sequence
+of templates from a buffer.
+Syntax
+#include <disptmpl.h>
+int ldap_init_templates_buf( char *buf, long buflen,
+ struct ldap_disptmpl **tmpllistp );
+
+Parameters
+
ldap_init_templates_buf Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+buf
+
+Pointer to data in the format defined for a valid LDAP template configuration
+file.
+
+
+
+buflen
+
+The size of buf.
+
+
+
+tmpllistp
+
+Pointer to a list of template data structures.
+
+
+
+
+
+Returns
+
+If successful, 0 is returned and tmpllistp
+ is configured.
+Upon error:
+
+LDAP_TMPL_ERR_VERSION if buf points
+to data that is newer than can be handled.
+LDAP_TMPL_ERR_MEM if there is a memory
+allocation problem.
+LDAP_TMPL_ERR_SYNTAX if there is a problem
+with the format of the templates buffer or file.
+LDAP_TMPL_ERR_FILE if the file cannot be
+read.
+
+
+
+
+Description
+The ldap_init_templates_buf function reads a sequence
+of templates from a buffer.
+See Also
+ldap_init_templates, ldap_free_templates
+
+ldap_is_dns_dn
+This function is deprecated and should not be used. It is included
+in ldap-to-be-deprecated.h for backward-compatibility.
+
+The ldap_is_dns_dn function determines whether
+a DN string is of the experimental DNS-style DN (generally in the form of
+an RFC 822 email address) or the RFC 1779 formatted DN.
+Description
+This function is specific to LDAP v2 and should not be used when dealing
+with LDAP v3 servers or data.
+More information can be found in RFC 1779 - A String
+Representation of Distinguished Names () and
+RFC 822 - Standard for the Format of ARPA Internet Text Messages ().
+
+
+
+ldap_is_ldap_url
+The ldap_is_ldap_url function determines whether
+or not a URL is an LDAP URL.
+Syntax
+#include <ldap.h>
+ int ldap_is_ldap_url( const char *url );
+
+Parameters
+
ldap_is_ldap_url Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+url
+
+The URL that you want to check.
+
+
+
+
+
+Returns
+One of the following values:
+
+1 if the URL is an LDAP URL.
+
+0 if the URL is not an LDAP URL.
+
+
+
+Description
+The ldap_is_ldap_url function determines whether
+or not a URL is an LDAP URL. An LDAP URL is a URL with the protocol set to
+ldap:// (or ldaps://, if the server is communicating
+over a SSL connection).
+Example
+Example 21–32 determines
+if a URL is a LDAP URL.
+Using ldap_is_ldap_url
+#include <stdio.h>
+#include <ldap.h>
+...
+char *my_url = "ldap://ldap.sun.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 );
+}
+...
+
+
+See Also
+ldap_url_parse
+
+ldap_keysort_entries
+The ldap_keysort_entries function is used for sorting
+entries.
+Syntax
+#include <ldap-extension.h>
+ int ldap_keysort_entries( LDAP *ld, LDAPMessage **chain,
+ void *arg, LDAP_KEYGEN_CALLBACK *gen, LDAP_KEYCMP_CALLBACK *cmp,
+ LDAP_KEYFREE_CALLBACK *fre );
+
+Parameters
+
ldap_keysort_entries Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+chain
+
+Chain of entries returned by the ldap_result or ldap_search_s function.
+
+
+
+arg
+
+Pointer to an additional argument that you want to pass.
+
+
+
+gen
+
+Callback used to generate the key(s) for sorting once the compare function
+has been applied.
+
+
+
+cmp
+
+Comparison function used when sorting the values.
+
+
+
+fre
+
+Callback used to free the key once the compare function has been applied.
+
+
+
+
+
+
+See Also
+LDAP_KEYGEN_CALLBACK, LDAP_KEYCMP_CALLBACK, LDAP_KEYFREE_CALLBACK
+
+
+ldap_memcache_destroy
+The ldap_memcache_destroy function frees an LDAPMemCache structure from memory.
+Syntax
+#include <ldap.h>
+ void ldap_memcache_destroy( LDAPMemCache *cache );
+
+Parameters
+
ldap_memcache_destroy Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+cache
+
+Pointer to the LDAPMemCache structure
+that you want freed from memory.
+
+
+
+
+
+Description
+The ldap_memcache_destroy function frees the specified LDAPMemCache structure from memory. Call this function
+after you are done working with a cache.
+See Also
+ldap_memcache_init
+
+ldap_memcache_flush
+The ldap_memcache_flush function flushes items
+from the specified cache.
+Syntax
+#include <ldap.h>
+ void ldap_memcache_flush( LDAPMemCache *cache, char *dn,
+ int scope );
+
+Parameters
+
ldap_memcache_flush Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+cache
+
+Pointer to the LDAPMemCache structure
+that you want to flush entries from.
+
+
+
+dn
+
+Base DN identifying the search requests that you want flushed from the
+cache. If the base DN of a search request is within the scope specified by
+this DN and the scope argument, the search request is flushed from the cache.
+If this argument is NULL, the entire cache is flushed.
+
+
+
+scope
+
+Scope that (together with the dn argument) identifies
+the search requests that you want flushed from the cache. If the base DN of
+the request is within the scope specified by this argument and the dn argument,
+the request is flushed from the cache. This argument can have one of the following
+values:
+
+LDAP_SCOPE_BASE
+LDAP_SCOPE_ONELEVEL
+LDAP_SCOPE_SUBTREE
+
+
+
+
+
+
+
+Description
+The ldap_memcache_flush function flushes search
+requests from the cache. If the base DN of a search request is within the
+scope specified by the dn and scope arguments, the search
+request is flushed from the cache. If no DN is specified, the entire cache
+is flushed.
+
+ldap_memcache_get
+The ldap_memcache_get function gets the in-memory
+cache associated with an LDAP connection handle.
+Syntax
+#include <ldap.h>
+int ldap_memcache_get( LDAP *ld, LDAPMemCache **cachep );
+
+Parameters
+
ldap_memcache_get Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+cachep
+
+When you call ldap_memcache_get, it sets this parameter
+to the pointer to the LDAPMemCache structure
+associated with the connection handle.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if the cache for the specified
+connection handle was retrieved successfully.
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+
+
+Description
+The ldap_memcache_get function gets the cache associated
+with the specified connection handle (LDAP structure).
+This cache is used by all search requests made through that connection. You
+can call this function if you want to associate a cache with multiple LDAP
+connection handles. For example, you can call this function to get the cache
+associated with one connection, then you can call the ldap_memcache_set
+ function to associate the cache with another connection.
+See Also
+ldap_memcache_set
+
+ldap_memcache_init
+The ldap_memcache_init function creates an in-memory
+cache for your LDAP client that you can associate with an LDAP connection.
+Syntax
+#include <ldap.h>
+ int ldap_memcache_init( unsigned long ttl, unsigned long size,
+ char **baseDNs, struct ldap_thread_fns *thread_fns,
+ LDAPMemCache **cachep );
+
+Parameters
+
ldap_memcache_init Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ttl
+
+The maximum amount of time (in seconds) that an item can be cached.
+If 0, there is no limit to the amount of time that an
+item can be cached.
+
+
+
+size
+
+Maximum amount of memory (in bytes) that the cache will consume. If
+ 0, the cache has no size limit.
+
+
+
+baseDNs
+
+An array of the base DN strings representing the base DNs of the search
+requests you want cached. If not NULL, only the search
+requests with the specified base DNs will be cached. If NULL,
+all search requests are cached.
+
+
+
+thread_fns
+
+An ldap_thread_fns structure specifying
+the functions that you want used to ensure that the cache is thread-safe.
+You should specify this if you have multiple threads that are using the same
+connection handle and cache. If you are not using multiple threads, pass
+NULL for this parameter.
+
+
+
+cachep
+
+When you call this function, it sets this parameter to the pointer to
+the newly created LDAPMemCache structure.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if the cache for the specified
+connection handle was retrieved successfully.
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_SIZELIMIT_EXCEEDED if the initial
+size of the cache (specified by the size argument) is too small.
+
+
+
+Description
+The ldap_memcache_init function creates an in-memory,
+client-side cache that you can use to cache search requests. The function
+passes back a pointer to an LDAPMemCache structure,
+which represents the cache. You should call the ldap_memcache_set
+ function to associate this cache with an LDAP connection handle (an
+ LDAP structure).
+The cache uses search criteria as the key to cached items. When you
+send a search request, the cache checks the search criteria to determine if
+that request has been cached previously. If the request was cached, the search
+results are read from the cache. To flush the cache, call the ldap_memcache_flush function. When you are done
+with the cache, you can free it from memory by calling the ldap_memcache_destroy function.
+On Windows systems, if the ldap_memcache_init
+ function returns an LDAP_PARAM_ERROR result
+code, verify that your client is using the version of the nsldap32v30.dll
+ file provided with the &DirectorySDKForC;.
+
+See Also
+LDAPMemCache, ldap_memcache_set
+ , ldap_memcache_flush, ldap_memcache_destroy, ldap_memcache_update
+
+
+ldap_memcache_set
+The ldap_memcache_set function associates an in-memory
+cache with an LDAP connection handle.
+Syntax
+#include <ldap.h>
+ int ldap_memcache_set( LDAP *ld, LDAPMemCache *cache );
+
+Parameters
+
ldap_memcache_set Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+cache
+
+Pointer to an LDAPMemCache structure,
+which represents the cache that you want used for this connection.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if the cache for the specified
+connection handle was retrieved successfully.
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_SIZELIMIT_EXCEEDED if the initial
+size of the cache (specified by the size argument) is too small.
+
+
+
+Description
+The ldap_memcache_set function associates a cache
+(created by calling ldap_memcache_init) with
+an LDAP connection handle. You can call this function if you want to associate
+a cache with multiple LDAP connection handles. For example, you can call the ldap_memcache_get function to get the cache associated
+with one connection, then you can call ldap_memcache_set to
+associate the cache with another connection.
+After you call this function, search requests made over the specified
+LDAP connection will use this cache. Calling the ldap_unbind
+ function will disassociate the cache from the LDAP connection handle.
+
+See Also
+ldap_memcache_init, ldap_memcache_get
+
+ldap_memcache_update
+The ldap_memcache_update function checks the cache
+for items that have expired and removes them.
+Syntax
+#include <ldap.h>
+void ldap_memcache_update( LDAPMemCache *cache );
+
+Parameters
+
ldap_memcache_update Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+cache
+
+Pointer to an LDAPMemCache structure,
+which represents the cache that you want to updated.
+
+
+
+
+
+Description
+The ldap_memcache_update function checks the cache
+for items that have expired and removes them. This check is typically done
+as part of the way the cache normally works. You do not need to call this
+function unless you want to update the cache at this point in time.
+This function is only useful in a multithreaded application, since
+it will not return until the cache is destroyed.
+
+See Also
+ldap_memcache_flush
+
+ldap_memfree
+The ldap_memfree function frees memory allocated
+by an LDAP API function call.
+Syntax
+#include <ldap.h>
+ void ldap_memfree( void *p );
+
+Parameters
+
ldap_memfree Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+p
+
+Pointer to memory used by the LDAP library.
+
+
+
+
+
+Example
+Example 21–33 frees
+the memory allocated by the ldap_get_dn function.
+
+Using ldap_memfree
+#include <ldap.h>
+...
+LDAP *ld;
+char *dn;
+LDAPMessage *entry;
+...
+/* Get the distinguished name (DN) for an entry */
+dn = ldap_get_dn( ld, entry );
+...
+/* When you are finished working with the DN, free the memory allocated. */
+ldap_memfree( dn );
+...
+
+
+See Also
+ldap_free_friendlymap, ldap_free_urldesc, ldap_msgfree
+, ldap_value_free, ldap_value_free_len
+
+ldap_modify
+The ldap_modify function modifies an existing entry
+in the directory asynchronously.
+This is an older function included in the SDK for backward-compatibility.
+If you are writing a new LDAP client, use ldap_modify_ext
+ instead.
+Syntax
+#include <ldap.h>
+int ldap_modify( LDAP *ld, const char *dn, LDAPMod **mods );
+
+Parameters
+
ldap_modify Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to modify.
+
+
+
+mods
+
+Pointer to a NULL terminated array of pointers to LDAPMod structures representing the attributes that
+you want to modify.
+
+
+
+
+
+Returns
+Returns the message ID of the ldap_modify operation.
+To check the result of this operation, call ldap_result and ldap_result2error. For a list of possible result
+codes for an LDAP modify operation, see ldap_modify_ext_s
+.
+Description
+Please use the newer version of this function, ldap_modify_ext
+ .
+Example
+Example 21–34 uses
+the asynchronous ldap_modify function to modify the entry
+for Barbara Jensen in the directory. It makes the following
+changes to the entry:
+
+Adds the homePhone attribute.
+
+Changes the telephoneNumber attribute.
+
+Removes the facsimileTelephoneNumber attribute.
+
+
+Using ldap_modify
+#include <ldap.h>
+...
+LDAP *ld;
+LDAPMod *list_of_attrs[4];
+LDAPMod attribute1, attribute2, attribute3;
+LDAPMessage *result;
+int msgid, rc;
+struct timeval tv;
+
+/* Distinguished name of the entry that you want to modify. */
+char *dn = "uid=bjensen,ou=People,dc=example,dc=com";
+
+/* Values to add or change */
+char *homePhone_values[] = { "555-1212", NULL };
+char *telephoneNumber_values[] = { "869-5309", NULL };
+
+...
+/* Specify each change in separate LDAPMod structures */
+attribute1.mod_type = "homePhone";
+attribute1.mod_op = LDAP_MOD_ADD;
+attribute1.mod_values = homePhone_values;
+attribute2.mod_type = "telephoneNumber";
+attribute2.mod_op = LDAP_MOD_REPLACE;
+attribute2.mod_values = telephoneNumber_values;
+attribute3.mod_type = "facsimileTelephoneNumber";
+attribute3.mod_op = LDAP_MOD_DELETE;
+attribute3.mod_values = NULL;
+/* NOTE: When removing entire attributes, you need to specify a NULL value
+ * for the mod_values field. */
+
+/* Add the pointers to these LDAPMod structures to an array */
+list_of_attrs[0] = &attribute1;
+list_of_attrs[1] = &attribute2;
+list_of_attrs[2] = &attribute3;
+list_of_attrs[3] = NULL;
+...
+/* Set up the timeout period to wait for the "modify" operation */
+tv.tv_sec = tv.tv_usec = 0;
+
+/* Change the entry */
+if ( ( msgid = ldap_modify( ld, dn, list_of_attrs ) ) == -1 ) {
+ ldap_perror( ld, "ldap_modify" );
+ return( 1 );
+}
+
+/* Check to see if the operation has completed */
+while ( ( rc = ldap_result( ld, msgid, 0, &tv, &result ) ) == 0 ) {
+ ...
+ /* do other work while waiting for the operation to complete */
+ ...
+}
+
+/* Check the result to see if any errors occurred */
+ldap_result2error( ld, result, 1 );
+ldap_perror( ld, "ldap_modify" );
+...
+
+
+See Also
+ldap_modify_ext
+
+ldap_modify_ext
+The ldap_modify_ext function modifies an existing
+entry in the directory asynchronously.
+ldap_modify_ext is a new version
+of the ldap_modify function. If you are writing
+a new LDAP client, use ldap_modify_ext.
+
+Syntax
+#include <ldap.h>
+int ldap_modify_ext( LDAP *ld, const char *dn, LDAPMod **mods,
+ LDAPControl **serverctrls, LDAPControl **clientctrls,
+ int *msgidp );
+
+Parameters
+
ldap_modify_ext Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to modify.
+
+
+
+mods
+
+Pointer to a NULL terminated array of pointers to LDAPMod structures representing the attributes that
+you want to modify.
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+msgidp
+
+Pointer to an integer that will be set to the message ID of the LDAP
+operation. To check the result of this operation, call ldap_result
+ and ldap_parse_result.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the control.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+
+Description
+The ldap_modify_ext modifies an entry in the directory
+asynchronous; it does not directly return results. If you want the results
+to be returned directly by the function, call the synchronous function ldap_modify_ext_s instead. In order to get the results
+of this LDAP modify operation, you need to call the ldap_result
+ and the ldap_parse_result functions.
+To make changes to an entry to the directory, you need to specify the following
+information:
+
+A unique DN identifying the new entryUse the
+ dn argument to specify the DN of the entry you want to
+modify.
+A set of attributes for the new entryCreate an LDAPMod structure for changes that you want to make
+to an attribute. Create an array of these LDAPMod structures
+and pass the array as the mods argument.
+
+
+See Also
+ldap_modify_ext_s, ldap_result, ldap_parse_result
+, LDAPMod
+
+ldap_modify_ext_s
+The ldap_modify_ext_s modifies an existing entry
+in the directory synchronously.
+ldap_modify_ext_s is a new version
+of the ldap_modify_s function. If you are
+writing a new LDAP client, use ldap_modify_ext_s.
+
+Syntax
+#include <ldap.h>
+ int ldap_modify_ext_s( LDAP *ld, const char *dn, LDAPMod **mods,
+ LDAPControl **serverctrls, LDAPControl **clientctrls );
+
+Parameters
+
ldap_modify_ext_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to modify.
+
+
+
+mods
+
+Pointer to a NULL terminated array of pointers to LDAPMod structures representing the attributes that
+you want to modify.
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the control.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_LOCAL_ERROR if an error occurred
+when receiving the results from the server.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded results from the server.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+&cnDirectoryServer; and other LDAP server products may send result
+codes in addition to those described. For example, the server may have loaded
+a plug-in that returns custom result codes. Check your LDAP server documentation
+for other result codes.
+
+Description
+The ldap_modify_ext_s modifies an entry in the
+directory. ldap_modify_ext_s is a synchronous function,
+which directly returns the results of the operation. If you want to perform
+other operations while waiting for the results of this operation, call the
+asynchronous function ldap_modify_ext instead.
+To make changes to an entry to the directory, you need to specify the
+following information:
+
+A unique DN identifying the new entryUse the
+ dn argument to specify the DN of the entry that you want
+to modify.
+A set of attributes for the new entryCreate an LDAPMod structure for change that you want to make
+to an attribute. Create an array of these LDAPMod structures
+and pass the array as the mods argument.
+
+
+See Also
+ldap_modify_ext,
+LDAPMod
+
+ldap_modify_s
+The ldap_modify_s function modifies an existing
+entry in the directory synchronously.
+This is an older function that is included in the SDK for backward-compatibility.
+If you are writing a new LDAP client, use ldap_modify_ext_s
+ instead.
+Syntax
+#include <ldap.h>
+ int ldap_modify_s( LDAP *ld, const char *dn, LDAPMod **mods );
+
+Parameters
+
ldap_modify_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to modify.
+
+
+
+mods
+
+Pointer to a NULL terminated array of pointers to LDAPMod structures representing the attributes that
+you want to modify.
+
+
+
+
+
+Returns
+For a list of possible result codes for an LDAP modify operation, see ldap_modify_ext_s.
+Description
+Use the newer version of this function, ldap_modify_ext_s
+ .
+Example
+Example 21–35 uses
+the synchronous ldap_modify_s function to makes the following
+changes to the Barbara Jensen entry:
+
+Adds the homePhone attribute.
+
+Changes the telephoneNumber attribute.
+
+Removes the facsimileTelephoneNumber attribute.
+
+
+Using ldap_modify_s
+#include <ldap.h>
+...
+LDAP *ld;
+LDAPMod *list_of_attrs[4];
+LDAPMod attribute1, attribute2, attribute3;
+LDAPControl **srvrctrls, **clntctrls;
+
+/* Distinguished name of the entry that you want to modify. */
+char *dn = "uid=bjensen,ou=People,dc=example,dc=com";
+
+/* Values to add or change */
+char *homePhone_values[] = { "555-1212", NULL };
+char *telephoneNumber_values[] = { "869-5309", NULL };
+
+...
+/* Specify each change in separate LDAPMod structures */
+attribute1.mod_type = "homePhone";
+attribute1.mod_op = LDAP_MOD_ADD;
+attribute1.mod_values = homePhone_values;
+attribute2.mod_type = "telephoneNumber";
+attribute2.mod_op = LDAP_MOD_REPLACE;
+attribute2.mod_values = telephoneNumber_values;
+attribute3.mod_type = "facsimileTelephoneNumber";
+attribute3.mod_op = LDAP_MOD_DELETE;
+attribute3.mod_values = NULL;
+/* NOTE: When removing entire attributes, you need to specify a NULL value
+ * for the mod_values or mod_bvalues field. */
+
+/* Add the pointers to these LDAPMod structures to an array */
+list_of_attrs[0] = &attribute1;
+list_of_attrs[1] = &attribute2;
+list_of_attrs[2] = &attribute3;
+list_of_attrs[3] = NULL;
+...
+/* Change the entry */
+if ( ldap_modify_s( ld, dn, list_of_attrs ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_modify_s" );
+ return( 1 );
+}
+...
+
+
+See Also
+ldap_modify_ext_s
+
+ldap_modrdn
+This function is deprecated and should not be used. It is included
+in ldap-deprecated.h for backward-compatibility. Use ldap_rename instead.
+ldap_modrdn_s
+This function is deprecated and should not be used. It is included
+in ldap-deprecated.h for backward-compatibility. Use ldap_rename_s instead.
+
+
+ldap_modrdn2
+This function is deprecated and should not be used. It is included
+in ldap-deprecated.h for backward-compatibility. Use ldap_rename instead.
+The ldap_modrdn2 function changes the relative
+distinguished name (RDN) of an entry in the directory asynchronously.
+Syntax
+#include <ldap-deprecated.h>
+int ldap_modrdn2( LDAP *ld, const char *dn, const char *newrdn,
+ int deleteoldrdn );
+
+Parameters
+
ldap_modrdn2 Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to modify.
+
+
+
+newrdn
+
+New RDN to assign to the entry.
+
+
+
+deleteoldrdn
+
+If this is a non-zero value, the old RDN is not retained as a value
+in the modified entry. If 0, the old RDN is retained as
+an attribute in the modified entry.
+
+
+
+
+
+Returns
+Returns the message ID of the ldap_modrdn2 operation.
+To check the result of this operation, call ldap_result and ldap_result2error. For a list of possible result
+codes, see ldap_rename.
+Description
+Please use the newer version of this function, ldap_rename
+ .
+Example
+Example 21–36 uses
+the asynchronous ldap_modrdn2 function to change the
+RDN of an entry from uid=bjensen to uid=babs.
+The code removes the existing RDN bjensen from the uid
+ attribute of the entry.
+Using ldap_modrdn2
+#include <ldap-deprecated.h>
+...
+LDAP *ld;
+LDAPMessage *result;
+int msgid, rc;
+struct timeval tv;
+
+/* Distinguished name of the entry that you want to rename. */
+char *dn = "uid=bjensen,ou=People,dc=example,dc=com";
+
+/* New relative distinguished name (RDN) of the entry */
+char *rdn = "uid=babs";
+...
+/* Set up the timeout period to wait for the "modify RDN" operation */
+tv.tv_sec = tv.tv_usec = 0;
+
+/* Rename the entry */
+if ( ( msgid = ldap_modrdn2( ld, dn, rdn, 1 ) ) == -1 ) {
+ ldap_perror( ld, "ldap_modrdn2" );
+ return( 1 );
+}
+
+/* Check to see if the operation has completed */
+while ( ( rc = ldap_result( ld, msgid, 0, &tv, &result ) ) == 0 ) {
+ ...
+ /* do other work while waiting for the operation to complete */
+ ...
+}
+
+/* Check the result to see if any errors occurred */
+ldap_result2error( ld, result, 1 );
+ldap_perror( ld, "ldap_modrdn2" );
+...
+
+
+See Also
+ldap_rename
+
+ldap_modrdn2_s
+This function is deprecated and should not be used. It is included
+in ldap-deprecated.h for backward-compatibility. Use ldap_rename_s instead.
+The ldap_modrdn2_s function changes the relative
+distinguished name (RDN) of an entry in the directory synchronously.
+Syntax
+#include <ldap-deprecated.h>
+ int ldap_modrdn2_s( LDAP *ld, const char *dn,
+ const char *newrdn, int deleteoldrdn );
+
+Parameters
+
ldap_modrdn2_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to modify.
+
+
+
+newrdn
+
+New RDN to assign to the entry.
+
+
+
+deleteoldrdn
+
+If this is a non-zero value, the old RDN is not retained as a value
+in the modified entry. If 0, the old RDN is retained as
+an attribute in the modified entry.
+
+
+
+
+
+Returns
+For a list of possible result codes, see ldap_rename_s
+ .
+Description
+Please use the newer version of this function, ldap_rename_s
+ .
+Example
+Example 21–37 uses
+the synchronous ldap_modrdn2_s function to change the
+RDN of an entry from uid=bjensen to uid=babs.
+The code removes the existing RDN babs from the uid attribute
+of the entry.
+Using ldap_modrdn2_s
+#include <ldap.h>
+...
+LDAP *ld;
+
+/* Distinguished name of the entry that you want to rename. */
+char *dn = "uid=bjensen,ou=People,dc=example,dc=com";
+
+/* New relative distinguished name (RDN) of the entry */
+char *rdn = "uid=babs";
+...
+/* Rename the entry */
+if ( ldap_modrdn2_s( ld, dn, rdn, 1 ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_modrdn2_s" );
+ return( 1 );
+}
+...
+
+
+See Also
+ldap_rename_s
+
+ldap_mods_free
+The ldap_mods_free function frees the LDAPMod structures that you’ve allocated to
+add or modify entries.
+You need to call this function only if you’ve allocated
+memory for these structures yourself. For more information, see the ldap-extension.h
+ header file.
+Syntax
+#include <ldap.h>
+ void ldap_mods_free( LDAPMod **mods, int freemods );
+
+Parameters
+
ldap_mods_free Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+mods
+
+Pointer to a NULL terminated array of pointers to LDAPMod structures.
+
+
+
+freemods
+
+If this is a non-zero value, frees the array of pointers as well as
+the LDAPMod structures. If 0,
+just frees the LDAPMod structures.
+
+
+
+
+
+
+Example
+Example 21–38 allocates
+memory for LDAPMod structures and frees them
+when done.
+Using ldap_mods_free
+#include <stdio.h>
+#include <ldap.h>
+...
+LDAP *ld;
+char *dn;
+int i, msgid;
+LDAPMod **mods;
+...
+/* Construct the array of values to add */
+mods = ( LDAPMod ** ) malloc(( NMODS + 1 ) * sizeof( LDAPMod * ));
+if ( mods == NULL ) {
+ fprintf( stderr, "Cannot allocate memory for mods array\n" );
+}
+for ( i = 0; i < NMODS; i++ ) {
+ if (( mods[ i ] = ( LDAPMod * ) malloc( sizeof( LDAPMod ))) == NULL) {
+ fprintf( stderr, "Cannot allocate memory for mods element\n" );
+ exit( 1 );
+ }
+}
+...
+/* Code for filling the structures goes here. */
+...
+/* Initiate the add operation */
+if (( msgid = ldap_add( ld, dn, mods )) < 0 ) {
+ ldap_perror( ld, "ldap_add" );
+ ldap_mods_free( mods, 1 );
+ return( 1 );
+}
+...
+
+
+
+ldap_msgfree
+The ldap_msgfree function frees the memory allocated
+for a result by ldap_result or ldap_search_s.
+Syntax
+#include <ldap.h>
+ int ldap_msgfree( LDAPMessage *lm );
+
+Parameters
+
ldap_msgfree Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+lm
+
+Pointer to the result to be freed from memory.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_RES_BIND indicates that the LDAPMessage structure contains the result of an
+LDAP bind operation.
+LDAP_RES_SEARCH_ENTRY indicates that the LDAPMessage structure contains an entry found during
+an LDAP search operation.
+LDAP_RES_SEARCH_REFERENCE indicates that
+the LDAPMessage structure contains an LDAP
+v3 search reference (a referral to another LDAP server) found during an LDAP
+search operation.
+LDAP_RES_SEARCH_RESULT indicates that the LDAPMessage structure contains the result of an
+LDAP search operation.
+LDAP_RES_MODIFY indicates that the LDAPMessage structure contains the result of an
+LDAP modify operation.
+LDAP_RES_ADD indicates that the LDAPMessage structure contains the result of an
+LDAP add operation.
+LDAP_RES_DELETE indicates that the LDAPMessage structure contains the result of an
+LDAP delete operation.
+LDAP_RES_MODRDN or LDAP_RES_RENAME indicates
+that the LDAPMessage structure contains the
+result of an LDAP modify DN operation.
+LDAP_RES_COMPARE indicates that the LDAPMessage structure contains the result of an
+LDAP compare operation.
+LDAP_RES_EXTENDED indicates that the LDAPMessage structure contains the result of an
+LDAP v3 extended operation.
+LDAP_SUCCESS if the operation times
+out.
+-1 indicates that the lm argument
+is not a pointer to a valid LDAPMessage structure.
+
+If unsuccessful, returns the LDAP error code for the operation.
+
+
+
+Example
+Example 21–39 frees
+the results of a search.
+Using ldap_msgfree
+#include <stdio.h>
+#include <ldap.h>
+...
+LDAP *ld;
+LDAPMessage *result;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(sn=Jensen)";
+char *get_attr[] = { "cn", "mail", NULL };
+...
+/* Search the directory */
+if ( ldap_search_s( ld, my_searchbase, LDAP_SCOPE_SUBTREE, my_filter,
+ get_attr, 0, &result ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+...
+/* Free the results when done */
+ldap_msgfree( result );
+...
+
+
+See Also
+ldap_result, ldap_search_s
+
+
+ldap_msgid
+The ldap_msgid function determines the message
+ID of a result obtained by calling ldap_result or ldap_search_s.
+Syntax
+#include <ldap.h>
+ int ldap_msgid( LDAPMessage *lm );
+
+Parameters
+
ldap_msgid Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+lm
+
+Pointer to the result to check.
+
+
+
+
+
+Returns
+One of the following values:
+
+The message ID if successful.
+-1 if unsuccessful.
+
+
+Example
+Example 21–40 prints
+the message ID from the result obtained from a synchronous LDAP search operation.
+
+Using ldap_msgid
+#include <stdio.h>
+#include <ldap.h>
+...
+LDAP *ld;
+LDAPMessage *result;
+...
+/* Perform a search */
+if ( ldap_search_s( ld, MY_SEARCHBASE, LDAP_SCOPE_SUBTREE, MY_FILTER,
+ NULL, 0, &result ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+
+/* Get and print the message ID */
+if ( ldap_msgid( result ) != -1 ) {
+ printf( "Message ID: %d\n" );
+} else {
+ printf( "An error occurred.\n" );
+}
+...
+
+
+See Also
+ldap_msgtype, ldap_result
+ , ldap_search_s
+
+ldap_msgtype
+
+C SDK functions
+ldap_msgtype
+
+ldap_msgtype
+
+The ldap_msgtype function determines the type of
+result obtained by calling ldap_result or
+ ldap_search_s.
+Syntax
+#include <ldap.h>
+ int ldap_msgtype( LDAPMessage *lm );
+
+Parameters
+
ldap_msgtype Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+lm
+
+Pointer to the LDAPMessage structure
+to check.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_RES_BIND indicates that the LDAPMessage structure contains the result of an
+LDAP bind operation.
+LDAP_RES_SEARCH_ENTRY indicates that the LDAPMessage structure contains an entry found during
+an LDAP search operation.
+LDAP_RES_SEARCH_REFERENCE indicates that
+the LDAPMessage structure contains an LDAP
+v3 search reference (a referral to another LDAP server) found during an LDAP
+search operation.
+LDAP_RES_SEARCH_RESULT indicates that the LDAPMessage structure contains the result of an
+LDAP search operation.
+LDAP_RES_MODIFY indicates that the LDAPMessage structure contains the result of an
+LDAP modify operation.
+LDAP_RES_ADD indicates that the LDAPMessage structure contains the result of an
+LDAP add operation.
+LDAP_RES_DELETE indicates that the LDAPMessage structure contains the result of an
+LDAP delete operation.
+LDAP_RES_MODRDN or LDAP_RES_RENAME indicates
+that the LDAPMessage structure contains the
+result of an LDAP modify DN operation.
+LDAP_RES_COMPARE indicates that the LDAPMessage structure contains the result of an
+LDAP compare operation.
+LDAP_RES_EXTENDED indicates that the LDAPMessage structure contains the result of an
+LDAP v3 extended operation.
+-1 indicates that the lm argument
+is not a pointer to a valid LDAPMessage structure.
+
+
+
+Example
+Example 21–41 prints
+the message type for a result obtained from a synchronous LDAP search operation.
+Using ldap_msgtype
+#include <stdio.h>
+#include <ldap.h>
+...
+LDAP *ld;
+LDAPMessage *result;
+int msgtype;
+...
+/* Perform a search */
+if ( ldap_search_s( ld, MY_SEARCHBASE, LDAP_SCOPE_SUBTREE, MY_FILTER,
+ NULL, 0, &result ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+
+/* Get and print the message type */
+msgtype = ldap_msgtype( result );
+if ( msgtype != -1 ) {
+ printf( "Message type: %d\n", msgtype );
+} else {
+ printf( "An error occurred.\n" );
+}
+...
+
+
+See Also
+ldap_msgid, ldap_result
+ , ldap_search_s
+
+ldap_multisort_entries
+The ldap_multisort_entries function sorts a chain
+of entries retrieved from an LDAP search call (ldap_search_s
+ or ldap_result) by either a specified
+set of attributes in the entries or DN.
+Syntax
+#include <ldap.h>
+ int ldap_multisort_entries( LDAP *ld, LDAPMessage **chain,
+ char **attr, LDAP_CMP_CALLBACK *cmp );
+
+Parameters
+
ldap_multisort_entries Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+chain
+
+Chain of entries returned by the ldap_result or ldap_search_s function.
+
+
+
+attr
+
+Array of attributes to use for sorting the results. If NULL,
+results are sorted by DN.
+
+
+
+cmp
+
+Comparison function used when sorting the values.
+
+
+
+
+
+Returns
+One of the following values:
+
+0 if successful.
+-1 if memory cannot be allocated by this
+function. (The error code LDAP_NO_MEMORY is set in
+the LDAP structure. To get the error code,
+call the ldap_get_lderrno function.)
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function
+
+
+Example
+Example 21–42
+sorts entries first by the roomNumber attribute, then by
+the telephoneNumber attribute.
+Using ldap_multisort_entries
+
+#include <stdio.h>
+#include <string.h>
+#include <ldap.h>
+...
+LDAP *ld;
+LDAPMessage *result;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(sn=Jensen)";
+char *attrs[3];
+attrs[0] = "roomNumber";
+attrs[1] = "telephoneNumber";
+attrs[2] = NULL;
+...
+/* Search the directory */
+if ( ldap_search_s( ld, my_searchbase, LDAP_SCOPE_SUBTREE, my_filter,
+ NULL, 0, &result ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+
+/* Sort the results, using strcasecmp */
+if ( ldap_multisort_entries( ld, &result, attrs, strcasecmp ) !=
+ LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_multisort_entries" );
+ return( 1 );
+}
+...
+
+
+See Also
+ldap_result, ldap_search_s
+ , ldap_sort_entries, LDAP_CMP_CALLBACK
+
+ldap_name2template
+The ldap_name2template function obtains a pointer
+to the correct ldap_disptmpl structure.
+Syntax
+#include <disptmpl.h>
+ struct ldap_disptmpl * ldap_name2template( char *name
+ struct ldap_disptmpl *tmpllist );
+
+Parameters
+
ldap_name2template Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+name
+
+Name of the template.
+
+
+
+tmpllistp
+
+Pointer to a list of template data structures.
+
+
+
+
+
+Returns
+
+If successful, 0 is returned and tmpllistp
+ is configured.
+Upon error:
+
+LDAP_TMPL_ERR_VERSION if buf points
+to data that is newer than can be handled.
+LDAP_TMPL_ERR_MEM if there is a memory
+allocation problem.
+LDAP_TMPL_ERR_SYNTAX if there is a problem
+with the format of the templates buffer or file.
+LDAP_TMPL_ERR_FILE if the file cannot be
+read.
+
+
+
+
+Description
+ldap_name2template obtains a pointer to the correct
+ ldap_disptmpl structure. Links to templates can be defined
+by name.
+
+ldap_next_attribute
+The ldap_next_attribute function returns the name
+of the next attribute in an entry returned by ldap_first_entry
+ or ldap_next_entry.
+Syntax
+#include <ldap.h>
+char * ldap_next_attribute( LDAP *ld, LDAPMessage *entry,
+ BerElement *ber);
+
+Parameters
+
ldap_next_attribute Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+entry
+
+Pointer to the LDAPMessage structure
+representing the entry returned by the ldap_first_entry or ldap_next_entry function.
+
+
+
+ber
+
+A pointer to a BerElement allocated
+to keep track of its current position. Pass this pointer to subsequent calls
+to ldap_next_attribute to step through the entry's attributes.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns the name of the next attribute in an
+entry. When you are done using this data, you should free the memory by calling
+the ldap_memfree function.
+If no more attributes exist in the entry, returns a NULL
+ .
+If unsuccessful, returns a NULL and sets
+the appropriate error code in the LDAP structure.
+To get the error code, call the ldap_get_lderrno function.
+
+
+
+Description
+The ldap_first_attribute function returns
+a pointer to a BerElement. You use this pointer
+with ldap_next_attribute to iterate through the list
+of elements. After the last call to ldap_next_element,
+you should free the BerElement pointer using ldap_ber_free. When calling ldap_ber_free
+, make sure to specify that the buffer is not freed (pass 0 for
+the freebuf parameter).
+Example
+See the example under ldap_first_attribute.
+
+See Also
+ldap_first_attribute, ldap_getfirstfilter, ldap_next_entry
+
+
+ldap_next_disptmpl
+The ldap_next_disptmpl function returns the next
+template in a list.
+Syntax
+#include <disptmpl.h>
+ struct ldap_disptmpl * ldap_next_disptmpl( struct ldap_disptmpl *tmpllist,
+ struct ldap_disptmpl *tmpl );;
+
+Parameters
+
ldap_next_disptmpl Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+tmpl
+
+Defines a template from the template list tmpllist.
+A NULL pointer is returned if tmpl is
+the last template in the list.
+
+
+
+tmpllistp
+
+Pointer to a list of template data structures typically obtained by
+calling ldap_init_templates.
+
+
+
+
+
+Returns
+
+If successful, 0 is returned and tmpllistp
+ is configured.
+Upon error:
+
+LDAP_TMPL_ERR_VERSION if buf points
+to data that is newer than can be handled.
+LDAP_TMPL_ERR_MEM if there is a memory
+allocation problem.
+LDAP_TMPL_ERR_SYNTAX if there is a problem
+with the format of the templates buffer or file.
+LDAP_TMPL_ERR_FILE if the file cannot be
+read.
+
+
+
+
+Description
+ldap_next_disptmpl returns the template following
+the previous one in the list of templates pointed to by the parameter tmpllistp
+. tmpllistp is typically obtained by calling ldap_init_templates .
+See Also
+ldap_first_disptmpl
+
+ldap_next_entry
+The ldap_next_entry function returns a pointer
+to the LDAPMessage structure representing
+the next directory entry in a chain of search results.
+Syntax
+#include <ldap.h>
+ LDAPMessage * ldap_next_entry( LDAP *ld, LDAPMessage *entry );
+
+Parameters
+
ldap_next_entry Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+entry
+
+Pointer to an LDAPMessage structure
+in a chain of search results.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns the pointer to the next LDAPMessage structure of the type LDAP_RES_SEARCH_ENTRY
+ in a chain of search results.
+If no more LDAPMessage structures
+of the type LDAP_RES_SEARCH_ENTRY are in the chain or if
+the function is unsuccessful, returns a NULLMSG.
+
+
+
+Description
+The ldap_next_entry function returns a pointer
+to the LDAPMessage structure representing
+the next directory entry in a chain of search results. You can use this function
+in conjunction with the ldap_first_entry function
+to iterate through the directory entries in a chain of search results. These
+functions skip over any messages in the chain that do not have the type
+LDAP_RES_SEARCH_ENTRY as messages containing directory entries have
+the type LDAP_RES_SEARCH_ENTRY.
+See Also
+ldap_first_entry
+
+ldap_next_message
+The ldap_next_message function returns a pointer
+to the next LDAPMessage structure in a chain
+of search results.
+Syntax
+#include <ldap.h>
+ LDAPMessage * ldap_next_message( LDAP *ld, LDAPMessage *msg );
+
+Parameters
+
ldap_next_message Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+msg
+
+Pointer to an LDAPMessage structure
+in a chain of search results.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns the pointer to the next LDAPMessage structure in a chain of search results.
+
+If no more LDAPMessage structures
+are in the chain or if the function is unsuccessful, returns a NULLMSG.
+
+
+
+Description
+The ldap_next_message function returns a pointer
+to the next LDAPMessage structure in a chain
+of search results. You can use this function in conjunction with the ldap_first_message function to iterate through
+the chain of search results. You can also call the ldap_msgtype
+ function to determine if each message contains a matching entry (a
+message of the type LDAP_RES_SEARCH_ENTRY ) or a search
+reference (a message of the type LDAP_RES_SEARCH_REFERENCE).
+
+See Also
+ldap_first_message, ldap_msgtype
+
+ldap_next_reference
+The ldap_next_reference function returns a pointer
+to the LDAPMessage structure representing
+the next search reference in a chain of search results.
+Syntax
+#include <ldap.h>
+LDAPMessage * ldap_next_reference( LDAP *ld, LDAPMessage *ref );
+
+Parameters
+
ldap_next_reference Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+msg
+
+Pointer to an LDAPMessage structure
+in a chain of search results.
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns the pointer to the next LDAPMessage structure of the type LDAP_RES_SEARCH_REFERENCE
+ in a chain of search results.
+If no more LDAPMessage structures
+of the type LDAP_RES_SEARCH_REFERENCE are in the chain
+or if the function is unsuccessful, returns a NULLMSG.
+
+
+
+Description
+The ldap_next_reference function returns a pointer
+to the LDAPMessage structure representing
+the next search reference in a chain of search results. You can use this function
+in conjunction with the ldap_first_reference function
+to iterate through the search references in a chain of search results.
+These functions skip over any messages in the chain that do not have
+the type LDAP_RES_SEARCH_REFERENCE. Messages containing
+search references have the type LDAP_RES_SEARCH_REFERENCE,
+continuation references as specified in LDAPv3 that are stored as referral
+entries. Like a referral, each continuation reference itself may contain a
+number of URLs assumed to be equivalent, and the client should use one of
+those URLs.
+See Also
+ldap_first_reference
+
+ldap_next_searchobj
+The ldap_next_searchobj function returns the following
+search preference in a defined list.
+Syntax
+#include <ldap.h>
+ struct ldap_searchobj * ldap_next_searchobj
+ ( struct ldap_searchobj *sollist, struct ldap_searchobj *so );
+
+Parameters
+
ldap_next_searchobj Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+sollist
+
+Pointer to a list of data structures, typically obtained by calling
+ ldap_init_searchprefs.
+
+
+
+so
+
+Pointer to the most recent search object returned in the template list
+ sollist. The search object returned by ldap_next_searchobj
+ follows this one.
+
+
+
+
+
+Returns
+
+If successful, a pointer to an ldap_searchobj structure.
+
+A NULL pointer is returned if so is
+the last entry in the list.
+
+
+Description
+The search object returned by ldap_next_searchobj follows
+the one defined by the so parameter.
+See Also
+ldap_init_searchprefs, ldap_first_searchobj
+
+ldap_next_tmplcol
+The ldap_next_tmplcol function returns a pointer
+to the following item (in the column) within a template.
+Syntax
+#include <disptmpl.h>
+ struct ldap_tmplitem * ldap_next_tmplcol( struct ldap_disptmpl *tmpl,
+ struct ldap_tmplitem *row, struct ldap_tmplitem *col );
+
+Parameters
+
ldap_next_tmplcol Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+tmpl
+
+The name of the template to be retrieved.
+
+
+
+row
+
+The row in which the item is to be retrieved from.
+
+
+
+col
+
+The column in which the item is to be retrieved from.
+
+
+
+
+
+Returns
+
+If successful, a pointer to an ldap_tmplitem structure.
+
+A NULL pointer on error or if col was
+the last item.
+
+
+Description
+ldap_next_tmplcol returns a pointer to the next
+item (in the column) of the row, defined by row, within
+the template defined by tmpl.
+See Also
+ldap_first_tmplcol
+
+ldap_next_tmplrow
+The ldap_next_tmplrow function returns a pointer
+to the following row in a template.
+Syntax
+#include <disptmpl.h>
+ struct ldap_tmplitem * ldap_next_tmplrow( struct ldap_disptmpl *tmpl,
+ struct ldap_tmplitem *row );
+
+Parameters
+
ldap_next_tmplrow Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+tmpl
+
+The name of the template to be retrieved.
+
+
+
+row
+
+The row in the template to be retrieved.
+
+
+
+
+
+Returns
+
+If successful, a pointer to an ldap_tmplitem structure.
+
+A NULL pointer on error.
+
+
+Description
+ldap_next_tmplrow returns a pointer to the row
+that follows the one defined by row in the template defined
+by tmpl .
+
+ldap_oc2template
+The ldap_oc2template function obtains a pointer
+to the correct ldap_disptmpl structure.
+Syntax
+#include <disptmpl.h>
+ struct ldap_disptmpl * ldap_oc2template( char **oclist,
+ struct ldap_disptmpl *tmpllist );
+
+Parameters
+
ldap_oc2template Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+oclist
+
+A NULL terminated array of strings that contains
+the values of the objectClass attribute of the entry.
+
+
+
+
+tmpllistp
+
+Pointer to a list of template data structures.
+
+
+
+
+
+Returns
+
+Pointer to the first template where all of the object classes
+listed in one of the template's dt_oclist elements are
+contained in oclist.
+A NULL pointer if no appropriate template
+is found.
+
+
+Description
+ldap_oc2templatesearches tmpllist for
+the best template to use to display an entry that has a specific set of
+objectClass values.
+
+ldap_open
+This function is deprecated and should not be used. Use ldap_init or prldap_init (IPv6)
+instead.
+The ldap_open function opens a connection to an
+LDAP server and allocates an LDAP structure
+which is used to identify the connection and maintain per-connection information.
+
+Syntax
+#include <ldap-deprecated.h>
+ ldap_open( const char *host, int port );
+
+Parameters
+
ldap_open Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+host
+
+The hostname on which the LDAP server is running. It may contain a blank-separated
+list of hosts to try to connect to, and each host may optionally be of the
+form host:port. If
+present, port overrides the port parameter. Upon
+successfully making a connection to an LDAP server, ldap_open returns
+a pointer to an LDAP structure, which
+should be passed to subsequent calls ldap_bind, ldap_search
+
+
+
+port
+
+The port number to which to connect. If the default IANA-assigned port
+of 389 is desired, LDAP_PORT should be specified as the
+value of port.
+
+
+
+
+
+Description
+Please use a newer version of this function, ldap_init
+ or prldap_init (IPv6).
+
+ldap_parse_authzid_control
+
+The ldap_parse_authzid_control function parses
+the authorization identity bind response control retrieved from the server
+to extract the authorization ID.
+Syntax
+#include <ldap.h>
+LDAP_API(int) LDAP_CALL ldap_parse_authzid_control( LDAP *ld,
+ LDAPControl **ctrlp, char **authzid );
+
+Parameters
+
ldap_parse_authzid_control Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+ctrlp
+
+Pointer to an LDAPControl structure
+retrieved from the server.
+
+
+
+authzid
+
+Pointer to string holding the authorization ID.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_NO_MEMORY if memory cannot be
+allocated to decode the control returned by the server.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded message.
+LDAP_CONTROL_NOT_FOUND if no control
+can be found in the response returned from the server.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+
+See Also
+ldap_create_authzid_control
+
+
+ldap_parse_entrychange_control
+The ldap_parse_entrychange_control function examines
+a list of controls returned from a persistent search operation, retrieves
+an entry change control, and parses that control for information (such as
+the type of change made to the entry and the change number).
+This function implements an extension to the LDAP v3. Entry change
+notification is an optional feature; it may not be supported on all LDAP servers.
+Call this function when interacting with LDAP servers that support this LDAP
+v3 extension.
+Syntax
+#include <ldap.h>
+ int ldap_parse_entrychange_control( LDAP *ld,
+ LDAPControl **ctrls, int *chgtypep, char **prevdnp,
+ int *chgnumpresentp, long *chgnump );
+
+Parameters
+
ldap_parse_entrychange_control Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+ctrlp
+
+An array of controls returned by the server. You obtain these controls
+by calling the ldap_get_entry_controls function
+on an entry returned by the server.
+
+
+
+changetypes
+
+Pointer to an integer specifying the type of change made to the entry.
+This field can have one of the following values:
+
+LDAP_CHANGETYPE_ADD specifies that the
+entry was added to the directory.
+LDAP_CHANGETYPE_DELETE specifies that the
+entry was deleted from the directory.
+LDAP_CHANGETYPE_MODIFY specifies that the
+entry was modified.
+LDAP_CHANGETYPE_MODDN specifies that the
+DN or RDN of the entry was changed (a modify RDN or modify DN operation was
+performed).
+
+
+
+
+
+prevdnp
+
+Pointer to the previous DN of the entry, if the changetypes argument
+is LDAP_CHANGETYPE_MODDN. If the changetypes argument
+has a different value, this argument is set to NULL. When
+done, you can free this by calling the ldap_memfree function.
+
+
+
+
+chgnumpresentp
+
+Pointer to an integer specifying whether or not to the change number
+is included in the control. The parameter can have the following possible
+values:
+
+0 specifies that the change number is not
+included.
+A non-zero value specifies that the change number is included
+and is available as the chgnump argument.
+
+
+
+
+
+chgnump
+
+Pointer to the change number identifying the change made to the entry,
+if chgnumpresentp points to a non-zero value.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_DECODING_ERROR if an error occurred
+when BER-decoding the control.
+
+
+Description
+The ldap_parse_entrychange_control function can
+be called:
+
+To parse an entry returned from a persistent search operation
+and retrieve an entry change control.
+After receiving an entry from a persistent search and retrieving
+the controls from the entry. Call ldap_get_entry_controls
+ to get the controls.
+
+
+See Also
+ldap_create_persistentsearch_control, ldap_get_entry_controls
+
+ldap_parse_extended_result
+The ldap_parse_extended_result function parses
+the results of an LDAP extended operation and retrieves the object identifier
+(OID) and data returned by the server.
+This function implements an extension to the LDAP v3. Extended
+operations might not be supported on all LDAP servers. Call this function
+only when interacting with LDAP servers that support this LDAP v3 extension.
+
+Syntax
+#include <ldap.h>
+ int ldap_parse_extended_result( LDAP *ld, LDAPMessage *res,
+ char **retoidp, struct berval **retdatap, int freeit );
+
+Parameters
+
ldap_parse_extended_result Function
+Parameters
+
+
+
+
+Parameters
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+res
+
+Pointer to the LDAPMessage structure
+containing the results of an LDAP operation.
+
+
+
+retoidp
+
+Pointer to the OID returned by the server after performing the extended
+operation. When done, you can free this by calling the ldap_memfree
+ function.
+
+
+
+retdatap
+
+Pointer to the pointer to a berval structure
+containing the data returned by the server after performing the extended operation.
+When done, you can free this by calling the ber_bvfree
+function.
+
+
+
+freeit
+
+Specifies whether or not to free the results of the operation (the LDAPMessage structure specified by the res argument).
+The parameter can have the following possible values:
+
+0 specifies that the result should not
+be freed.
+A non-zero value specifies that the result should be freed.
+
+
+
+
+
+
+
+
+Returns
+One of the following values, which indicates the result of parsing the
+server’s response:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded results from the server.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+This value does not apply to the operation itself.
+
+Description
+ldap_parse_extended_result parses the server’s
+response to an extended operation. After you call the ldap_extended_operation
+ and the ldap_result functions,
+you can pass the results to ldap_parse_extended_result.
+This function gets the following data from the server’s response:
+
+The extended operation OID received from the server is passed
+back as the retoidp argument.
+The data received from the server is passed back in the berval structure as the retdatap argument.
+
+The LDAP result code for the LDAP extended operation is placed
+in the ld structure. You can get the result code by calling
+the ldap_get_lderrno function.For
+a list of possible result codes for an LDAP extended operation, see ldap_extended_operation_s .
+
+The LDAP server must support the extended operation. &cnDirectoryServer; supports
+a server plug-in interface that you can use to add support for extended operations.
+
+
+See Also
+ldap_extended_operation_s, ldap_get_lderrno
+
+ldap_parse_passwd
+The ldap_parse_passwd function lets you examine
+the result of an LDAP Password Modify extended operation to obtain the password
+generated by the server when you reset a password without providing a new
+password value.
+Syntax
+#include <ldap.h>
+LDAP_API(int) LDAP_CALL ldap_parse_passwd( LDAP *ld, LDAPMessage *result,
+ struct berval *genpasswd );
+
+Parameters
+
ldap_parse_passwd Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+result
+
+Pointer to the message retrieved using the message ID from ldap_passwd.
+
+
+
+genpasswd
+
+Pointer to the BER value structure to hold the password generated by
+the server.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_NO_MEMORY if memory cannot be
+allocated for the authorization identity.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded message.
+LDAP_NOT_SUPPORTED if your LDAP client
+does not specify that it is using LDAP v3.Make sure that you
+set the version of your LDAP client to version 3 before calling this function.
+
+
+
+
+ldap_parse_passwd_result
+The ldap_parse_passwd_result function lets you
+examine the result of an LDAP Password Modify extended operation to obtain
+the password generated by the server when you reset a password without providing
+a new password value.
+Syntax
+#include <ldap.h>
+LDAP_API(int) LDAP_CALL ldap_parse_passwd_result( LDAP *ld, int *msgidp,
+ struct timeval *timeout, struct berval *genpasswd );
+
+Parameters
+
ldap_parse_passwd_result Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+msgidp
+
+Pointer to the message ID retrieved using ldap_passwd
+.
+
+
+
+timeout
+
+Specifies a maximum interval to wait for the selection to complete.
+If timeout is a NULL pointer, the
+select blocks indefinitely. To effect a poll, the timeout parameter
+should be a non-NULL pointer, pointing to a zero-valued
+timeval structure.
+
+
+
+genpasswd
+
+Pointer to the BER value structure to hold the password generated by
+the server.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_NO_MEMORY if memory cannot be
+allocated for the authorization identity.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded message.
+LDAP_NOT_SUPPORTED if your LDAP client
+does not specify that it is using LDAP v3.Make sure that you
+set the version of your LDAP client to version 3 before calling this function.
+
+
+
+
+ldap_parse_pwdpolicy_control
+
+The ldap_parse_pwdpolicy_control function parses
+information about the password policy relative to a user account contained
+in a control returned with a bind, add, modify, or compare result after the ldap_create_userstatus_control is
+used to create a request control sent to the server. The ldap_parse_pwdpolicy_control
+ function populates an LDAPpwdpolicy structure.
+
+Syntax
+#include <ldap.h>
+LDAP_API(int) LDAP_CALL ldap_parse_pwdpolicy_control( LDAP *ld,
+ LDAPControl **ctrlp, LDAPpwdpolicy *pp );
+
+Parameters
+
ldap_parse_pwdpolicy_control Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+ctrlp
+
+Pointer to an LDAPControl structure
+retrieved from the server.
+
+
+
+pp
+
+Pointer to an LDAPpwdpolicy structure
+to hold the information about password policy.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_NO_MEMORY if memory cannot be
+allocated to decode the control returned by the server.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded message.
+LDAP_CONTROL_NOT_FOUND if no control
+can be found in the response returned from the server.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+
+See Also
+ldap_create_pwdpolicy_control
+, LDAPpwdpolicy
+
+ldap_parse_reference
+The ldap_parse_reference function parses search
+references from the results received from an LDAP server.
+Search references are part of the LDAP v3. When calling this function,
+make sure that you are working with a server that supports the LDAP v3.
+
+Syntax
+#include <ldap.h>
+ int ldap_parse_reference( LDAP *ld, LDAPMessage *ref,
+ char ***referralsp, LDAPControl ***serverctrlsp,
+ int freeit );
+
+Parameters
+
ldap_parse_reference Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+ref
+
+Pointer to an LDAPMessage structure
+of the type LDAP_RES_SEARCH_REFERENCE.
+
+
+
+referralsp
+
+Pointer to an array of strings representing the referrals found by an
+LDAP search operation and returned by the server (applicable only if the LDAP
+operation was a search operation). When done, you can free this by calling
+the ldap_value_free function.
+
+
+
+serverctrlsp
+
+Pointer to an array of LDAPControl structures,
+which represent the LDAP v3 server controls returned by the server. When done,
+you can free this by calling the ldap_controls_free function.
+
+
+
+
+freeit
+
+Specifies whether or not to free the results of the operation (the LDAPMessage structure specified by the res argument).
+The parameter can have the following possible values:
+
+0 specifies that the result should not
+be freed.
+A non-zero value specifies that the result should be freed.
+
+
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded results from the server.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+
+
+Description
+The ldap_parse_reference function parses the referral
+URLs from an LDAPMessage structure of the
+type LDAP_RES_SEARCH_REFERENCE, continuation references
+as specified in LDAPv3 that are stored as referral entries. Like a referral,
+each continuation reference itself may contain a number of URLs assumed to
+be equivalent, and the client should use one of those URLs.
+
+ldap_parse_result
+The ldap_parse_result function parses the results
+of an LDAP operation received from an LDAP server.
+Syntax
+#include <ldap.h>
+int ldap_parse_result( LDAP *ld, LDAPMessage *res,
+ int *errcodep, char **matcheddnp, char **errmsgp,
+ char ***referralsp, LDAPControl ***serverctrlsp, int freeit);
+
+Parameters
+
ldap_parse_result Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+res
+
+Pointer to the LDAPMessage structure
+containing the results of an LDAP operation.
+
+
+
+errcodep
+
+Pointer to the LDAP result code specifying the result of the operation.
+
+
+
+
+matcheddnp
+
+Pointer to a string specifying the portion of a DN that finds an existing
+entry (in cases where the server cannot find the entry specified by a DN).
+When done, you can free this by calling the ldap_memfree
+ function.
+
+
+
+errmsgp
+
+Pointer to an additional error message string sent from the server.
+When done, you can free this by calling the ldap_memfree
+ function.
+
+
+
+referralsp
+
+Pointer to an array of strings representing the referrals returned by
+the server. When done, you can free this by calling the
+ldap_value_free function.
+
+
+
+serverctrlsp
+
+Pointer to an array of LDAPControl structures,
+which represent the LDAPv3 server controls returned by the server. When done,
+you can free this by calling the ldap_controls_free function.
+
+
+
+
+freeit
+
+Specifies whether or not to automatically free the results of the operation
+(the LDAPMessage structure specified by the
+ res argument). The parameter can have the following possible
+values:
+
+0 specifies that the result should not
+be freed.
+A non-zero value specifies that the result should be freed.
+
+
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_NO_RESULTS_RETURNED if the specified LDAPMessage structure does not contain the result
+of an LDAP operation (for example, if it contains an entry, search reference,
+or chain of search results instead of the result of an LDAP operation).
+
+LDAP_MORE_RESULTS_TO_RETURN if the
+result in the LDAPMessage structure is part
+of a chain of results and the last result is not included.
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded results from the server.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+
+
+Description
+The ldap_parse_result function parses the results
+of an LDAP operation (received from an LDAP server) and retrieves:
+
+The LDAP result code that indicates the result of the LDAP
+operation (errcodep).
+An additional error message (optional)
+sent by the server (errmsgp).
+The portion of the DN that finds an entry, if the server is
+unable to find an entry from a DN that you specify (matcheddnp).
+
+A set of referrals, if the server does not contain the entries
+that you’ve specified and if the server is configured to refer clients
+to other servers (referralsp).
+A set of server response controls that are relevant to the
+operation (serverctrlsp).Calling this function
+creates an array of LDAPControl structures
+that you can pass to subsequent API functions (such as the ldap_parse_sort_control function.
+
+This function is not intended to be used to parse entries and
+search references. Use the ldap_msgtype function
+to determine the type of result contained in the LDAPMessage
+ structure. If the result is an entry returned as a search result,
+call the ldap_first_entry function to retrieve
+the entry. If the result is a search reference, call the
+ldap_parse_reference function to retrieve the reference.
+
+See Also
+ldap_result
+
+ldap_parse_sasl_bind_result
+The ldap_parse_sasl_bind_result function parses
+the results of an LDAP SASL bind operation and retrieves data returned by
+the server.
+SASL authentication is part of the LDAP v3. When calling this
+function, make sure that you are working with a server that supports the LDAP
+v3.
+Syntax
+#include <ldap.h>
+int ldap_parse_sasl_bind_result( LDAP *ld, LDAPMessage *res,
+ struct berval **servercredp, int freeit );
+
+Parameters
+
ldap_parse_sals_bind_result Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+res
+
+Pointer to the LDAPMessage structure
+containing the results of an LDAP operation.
+
+
+
+servercredp
+
+Pointer to a pointer to an berval structure
+containing any challenge or credentials returned by the server. When done,
+you can free this by calling the ber_bvfree function.
+
+
+
+
+freeit
+
+Specifies whether or not to free the results of the operation (the LDAPMessage structure specified by the res argument).
+The parameter can have the following possible values:
+
+0 specifies that the result should not
+be freed.
+A non-zero value specifies that the result should be freed.
+
+
+
+
+
+
+
+
+Returns
+One of the following values, which indicates the result of parsing the
+server’s response:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded message.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+This value does not apply to the SASL bind operation itself)
+
+
+Description
+After you call the ldap_sasl_bind function
+and the ldap_result function, you can pass
+the results to ldap_parse_sasl_bind_result for
+parsing. This function gets the following data from the server’s response:
+
+The challenge or credentials sent back from the server are
+passed back in the berval structure as the
+servercredp argument.
+The LDAP result code for the SASL bind operation is placed
+in the ld structure. You can get the result code by calling
+the ldap_get_lderrno function. (If the result
+code is LDAP_SASL_BIND_IN_PROGRESS , you can call ldap_sasl_bind again to send a response to the server’s
+challenge and call ldap_result and ldap_parse_sasl_bind_result again to get the next
+challenge from the server. For a list of possible result codes for an LDAP
+SASL bind operation, see ldap_sasl_bind.
+
+
+The LDAP server must support authentication through SASL mechanisms. &cnDirectoryServer; supports
+a plug-in interface that you can use to add SASL support to the server.
+
+
+See Also
+ldap_sasl_bind,
+ldap_get_lderrno
+
+ldap_parse_sort_control
+
+C SDK functions
+ldap_parse_sort_control
+
+ldap_parse_sort_control
+
+The parse_sort_control function parses the result
+returned from a search operation that used a server control for sorting search
+results.
+This function implements an extension to the LDAP v3. Server-side
+sorting is an optional feature; it may not be supported on all LDAP servers.
+Call this function when interacting with LDAP servers that support this LDAP
+v3 extension
+Syntax
+#include <ldap.h>
+ int ldap_parse_sort_control( LDAP *ld, LDAPControl **ctrls,
+ unsigned long *result, char **attribute );
+
+Parameters
+
ldap_parse_sort_control Function
+Parameters
+
+
+
+
+Parameters
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+ctrls
+
+An array of controls returned by the server. You obtain these controls
+by calling the ldap_parse_result function
+on the set of results returned by the server.
+
+
+
+result
+
+Pointer to the sort control result code retrieved by this function.
+
+
+
+
+attribute
+
+If the sorting operation fails, the function sets this to point to the
+name of the attribute that caused the failure. When done, you can free this
+by calling the ldap_memfree function.
+
+
+
+
+
+
+Returns
+One of the following values, which indicates the result of parsing the
+server’s response:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_NO_MEMORY if memory cannot be
+allocated to decode the control returned by the server.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded message.
+LDAP_CONTROL_NOT_FOUND if no control
+can be found in the response returned from the server.
+
+
+Description
+Call the ldap_parse_sort_control function as part
+of the process of retrieving sorted search results from a server. First, though,
+call ldap_result to get the results, and
+ ldap_parse_result to parse the server controls
+from the results.
+See Also
+ldap_create_sort_control
+
+ldap_parse_userstatus_control
+
+
+C SDK functions
+ldap_parse_userstatus_control
+
+ldap_parse_userstatus_control
+
+The ldap_parse_userstatus_control function parses
+information about the status of a user account contained in a control returned
+with an entry resulting from a search request that included the control created
+with ldap_create_userstatus_control
+. The ldap_parse_userstatus_control function
+populates an LDAPuserstatus structure.
+Syntax
+#include <ldap.h>
+LDAP_API(int) LDAP_CALL ldap_parse_userstatus_control( LDAP *ld,
+ LDAPControl **ctrlp, LDAPuserstatus *us );
+
+Parameters
+
ldap_parse_userstatus_control Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+ctrlp
+
+Pointer to an LDAPControl structure
+retrieved with ldap_get_entry_controls.
+
+
+
+
+us
+
+Pointer to an LDAPuserstatus structure
+to hold the information about account status.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_NO_MEMORY if memory cannot be
+allocated to decode the control returned by the server.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded message.
+LDAP_CONTROL_NOT_FOUND if no control
+can be found in the response returned from the server.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+
+See Also
+ldap_create_userstatus_control
+, LDAPuserstatus
+
+
+ldap_parse_whoami
+
+C SDK functions
+ldap_parse_whoami
+
+ldap_parse_whoami
+
+The ldap_parse_whoami function retrieves the authorization
+identity from the result of an asynchronous Who am I? extended operation request.
+
+Syntax
+#include <ldap.h>
+LDAP_API(int) LDAP_CALL ldap_parse_whoami_result( LDAP *ld,
+ LDAPMessage *result, char **authzid );
+
+Parameters
+
ldap_parse_whoami Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+result
+
+Pointer to the message retrieved using the message ID from ldap_whoami.
+
+
+
+authzid
+
+Pointer to the string to hold the authorization identity retrieved for
+the connection.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_NO_MEMORY if memory cannot be
+allocated for the authorization identity.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded message.
+LDAP_NOT_SUPPORTED if your LDAP client
+does not specify that it is using LDAP v3. Make sure that you set the version
+of your LDAP client to version 3 before calling this function.
+
+
+
+ldap_parse_whoami_result
+
+C SDK functions
+ldap_parse_whoami_result
+
+ldap_parse_whoami_result
+
+The ldap_parse_whoami_result function retrieves
+the authorization identity from the result of an asynchronous Who am I? extended
+operation request.
+Syntax
+#include <ldap.h>
+LDAP_API(int) LDAP_CALL ldap_parse_whoami_result( LDAP *ld, int *msgidp,
+ struct timeval *timeout, char **authzid );
+
+Parameters
+
ldap_parse_whoami_result Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+msgidp
+
+Pointer to the message ID retrieved using ldap_whoami
+.
+
+
+
+timeout
+
+Specifies a maximum interval to wait for the selection to complete.
+If timeout is a NULL pointer, the
+select blocks indefinitely. To effect a poll, the timeout parameter
+should be a non-NULL pointer, pointing to a zero-valued
+timeval structure.
+
+
+
+authzid
+
+Pointer to the string to hold the authorization identity retrieved for
+the connection.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_NO_MEMORY if memory cannot be
+allocated for the authorization identity.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded message.
+LDAP_NOT_SUPPORTED if your LDAP client
+does not specify that it is using LDAP v3. Make sure that you set the version
+of your LDAP client to version 3 before calling this function.
+
+
+
+ldap_parse_virtuallist_control
+
+C SDK functions
+ldap_parse_virtuallist_control
+
+ldap_parse_virtuallist_control
+
+The ldap_parse_virtuallist_control function parses
+the result returned from a search operation that used a server control for
+virtual list views.
+This function implements an extension to the LDAP v3. A virtual
+list view is an optional LDAP server feature that may not be supported
+on all LDAP servers.
+Syntax
+#include <ldap.h>
+ int ldap_parse_virtuallist_control( LDAP *ld,
+ LDAPControl **ctrls, unsigned long *target_posp,
+ unsigned long *list_sizep, int *errcodep );
+
+Parameters
+
ldap_parse_virtuallist_control Function
+Parameters
+
+
+
+
+Parameters
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+ctrls
+
+An array of controls returned by the server. You obtain these controls
+by calling the ldap_parse_result function
+on the set of results returned by the server.
+
+
+
+target_posp
+
+Pointer to an unsigned long that is set by the function. The function
+sets this to the index or offset of the selected entry in the list of entries.
+
+
+
+
+list_sizep
+
+Pointer to an unsigned long that is set by the function. The function
+sets this to the number of entries in the total number of entries in the entire
+list (not just the subset).
+
+
+
+errcodep
+
+Pointer to the sort control result code retrieved by this function.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_NO_MEMORY if memory cannot be
+allocated to decode the control returned by the server.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded message.
+LDAP_CONTROL_NOT_FOUND if no control
+can be found in the response returned from the server.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+
+Description
+The ldap_parse_virtuallist_control function can
+be called:
+
+As part of the process of retrieving a subset of entries from
+a list when working with a virtual list view box.
+After, calling ldap_result to
+get the results, and ldap_parse_result to
+parse the server controls from the results.
+
+
+See Also
+ldap_create_virtuallist_control
+
+
+ldap_passwd
+
+C SDK functions
+ldap_passwd
+
+ldap_passwd
+
+The ldap_passwd asynchronous function allows you
+to perform an LDAP Password Modify extended operation, as defined in RFC 3062.
+Syntax
+#include <ldap.h>
+int ldap_passwd( LDAP *ld, struct berval *userid,
+ struct berval *oldpasswd, struct berval *newpasswd,
+ LDAPControl **serverctrls, LDAPControl **clientctrls,
+ int *msgidp );
+
+Parameters
+
ldap_passwd Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+userid
+
+DN of the user whose password you want to modify.
+
+
+
+oldpasswd
+
+Old password used before expiration.
+If the password has not yet expired, this is the current password.
+
+
+
+
+newpasswd
+
+New password to use after modification
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this LDAP operation. If you
+do not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this LDAP operation. If you
+do not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+msgidp
+
+Pointer to an integer to be set to the message ID of the operation.
+To check the result of this operation, call the ldap_result
+ and ldap_parse_passwd function,
+or ldap_parse_passwd_result function.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the control.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NOT_SUPPORTED if your LDAP client
+does not specify that it is using LDAP v3.Make sure that you
+set the version of your LDAP client to version 3 before calling this function.
+
+
+
+
+ldap_passwd_s
+
+C SDK functions
+ldap_passwd_s
+
+ldap_passwd_s
+
+The ldap_passwd_s synchronous function allows you
+to perform an LDAP Password Modify extended operation, as defined in RFC 3062.
+Syntax
+#include <ldap.h>
+int ldap_passwd_s( LDAP *ld, struct berval *userid,
+ struct berval *oldpasswd, struct berval *newpasswd,
+ struct berval *genpasswd, LDAPControl **serverctrls,
+ LDAPControl **clientctrls );
+
+Parameters
+
ldap_passwd Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+userid
+
+DN of the user whose password you want to modify.
+
+
+
+oldpasswd
+
+Old password used before expiration.
+If the password has not yet expired, this is the current password.
+
+
+
+
+newpasswd
+
+New password to use after modification
+
+
+
+genpasswd
+
+New password generated by the server when an expired password is reset,
+but no newpasswd value is provided.
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this LDAP operation. If you
+do not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this LDAP operation. If you
+do not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the control.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NOT_SUPPORTED if your LDAP client
+does not specify that it is using LDAP v3.Make sure that you
+set the version of your LDAP client to version 3 before calling this function.
+
+
+
+
+ldap_perror
+
+C SDK functions
+ldap_perror
+
+ldap_perror
+
+This function is deprecated and should not be used. It is included
+in ldap-deprecated.h for backward-compatibility. Use ldap_get_lderrno instead.
+The ldap_perror function prints, to standard output,
+the last LDAP error message.
+Syntax
+#include <ldap-deprecated.h>
+ void ldap_perror( LDAP *ld, const char *s );
+
+Parameters
+
ldap_perror Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+s
+
+Optional text to print out before printing the error message.
+
+
+
+
+
+
+Description
+Use the newer version of this function, ldap_get_lderrno
+ .
+Example
+Example 21–43 prints
+out an error message if the search operation cannot complete successfully.
+Using ldap_perror
+...
+if ( ldap_search_s( ld, my_searchbase, LDAP_SCOPE_SUBTREE, my_filter,
+ get_attr, 0, &result ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+...
+
+
+See Also
+ldap_get_lderrno, ldap_err2string, ldap_result2error
+, ldap_set_lderrno
+
+ldap_rename
+
+C SDK functions
+ldap_rename
+
+ldap_rename
+
+The ldap_rename function changes the DN of an entry
+in the directory asynchronously.
+ldap_rename is a new version of the ldap_modrdn2 function. If you are writing a new
+LDAP client, you should call ldap_rename.
+Syntax
+#include <ldap.h>
+int ldap_rename( LDAP *ld, const char *dn, const char *newrdn,
+ const char *newparent, int deleteoldrdn,
+ LDAPControl **serverctrls, LDAPControl **clientctrls,
+ int *msgidp );
+
+Parameters
+
ldap_rename Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to rename.
+
+
+
+newrdn
+
+New Relative Distinguished Name (RDN) to assign to the entry.
+
+
+
+
+newparent
+
+DN of the new parent entry you want to move the entry under. Pass
+NULL if you do not want to move the entry to a different location
+in the directory tree.
+
+
+
+deleteoldrdn
+
+Specifies whether or not the old RDN is retained as an attribute of
+the entry. For example, an entry has the following values for the cn attribute:
+
+cn: Barbara Jensen
+cn: Babs Jensen
+If you change the RDN to cn=Barbie Jensen and pass
+ 1 as deleteoldrdn, the resulting entry
+has the following values:
+cn: Barbie Jensen
+cn: Babs Jensen
+If instead you pass 0 as deleteoldrdn,
+the Barbara Jensen value is not removed from the entry:
+cn: Barbie Jensen
+cn: Babs Jensen
+cn: Barbara Jensen
+So, if this is a non-zero value, the old RDN is not retained as a value
+in the entry. If 0, the old RDN is retained as an attribute
+in the entry.
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this LDAP operation. If you
+do not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this LDAP operation. If you
+do not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+msgidp
+
+Pointer to an integer that will be set to the message ID of the LDAP
+operation. To check the result of this operation, call the ldap_result and ldap_parse_result
+ functions.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_NO_MEMORY if memory cannot be
+allocated to decode the control returned by the server.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+
+Description
+The ldap_rename changes the DN of an entry in the
+directory and allows you to move the entry under a different parent entry
+in the directory tree. ldap_rename is an asynchronous
+function; it does not directly return results. In order to get the results
+of the LDAP rename operation, you need to call the ldap_result
+ function and the ldap_parse_result function.
+If you want the results to be returned directly by the function, call the
+synchronous function ldap_rename_s instead.
+
+See Also
+ldap_rename_s, ldap_result
+, ldap_parse_result
+
+ldap_rename_s
+
+C SDK functions
+ldap_rename_s
+
+ldap_rename_s
+
+The ldap_rename_s function changes the DN of an
+entry in the directory synchronously.
+ldap_rename_s is a new version of the ldap_modrdn2_s function. If you are writing a new
+LDAP client, you should call ldap_rename_s.
+Syntax
+#include <ldap.h>
+ int ldap_rename_s( LDAP *ld, const char *dn, const char *newrdn,
+ const char *newparent, int deleteoldrdn,
+ LDAPControl **serverctrls, LDAPControl **clientctrls );
+
+Parameters
+
ldap_rename Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the entry to rename.
+
+
+
+newrdn
+
+New Relative Distinguished Name (RDN) to assign to the entry.
+
+
+
+
+newparent
+
+DN of the new parent entry you want to move the entry under. Pass
+NULL if you do not want to move the entry to a different location
+in the directory tree.
+
+
+
+deleteoldrdn
+
+Specifies whether or not the old RDN is retained as an attribute of
+the entry. For example, an entry has the following values for the cn attribute:
+
+cn: Barbara Jensen
+cn: Babs Jensen
+If you change the RDN to cn=Barbie Jensen and pass
+ 1 as deleteoldrdn, the resulting entry
+has the following values:
+cn: Barbie Jensen
+cn: Babs Jensen
+If instead you pass 0 as deleteoldrdn,
+the Barbara Jensen value is not removed from the entry:
+cn: Barbie Jensen
+cn: Babs Jensen
+cn: Barbara Jensen
+So, if this is a non-zero value, the old RDN is not retained as a value
+in the entry. If 0, the old RDN is retained as an attribute
+in the entry.
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_NO_MEMORY if memory cannot be
+allocated to decode the control returned by the server.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_LOCAL_ERROR if an error occurred
+when receiving the results from the server.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded results from the server.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAPv3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+&cnDirectoryServer; and other LDAP server products may send result
+codes in addition to those described. For example, the server may have loaded
+a plug-in that returns custom result codes. Check your LDAP server documentation
+for other result codes.
+
+Description
+The ldap_rename_s changes the DN of an entry in
+the directory and allows you to move the entry under a different parent entry
+in the directory tree. The function ldap_rename_s is
+synchronous; it directly returns the results of the operation. If you want
+to perform other operations while waiting for the results of this operation,
+call the asynchronous function ldap_rename.
+
+See Also
+ldap_rename
+
+ldap_result
+
+C SDK functions
+ldap_result
+
+ldap_result
+
+The function ldap_result waits for and returns
+the result of an LDAP operation initiated by one of the asynchronous LDAP
+API functions.
+Syntax
+#include <ldap.h>
+ int ldap_result( LDAP *ld, int msgid, int all,
+ struct timeval *timeout, LDAPMessage **result );
+
+Parameters
+
ldap_result Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+msgid
+
+Asynchronous functions return a unique message ID. This parameter takes
+message ID of the operation for which you want the results. To check any operation,
+pass LDAP_RES_ANY as the value of this parameter.
+
+
+
+
+all
+
+Specifies how the results of a search are returned. This parameter can
+have the following values:
+
+0 specifies that the results are returned
+one entry at a time, using separate calls to ldap_result.
+
+A non-zero value specifies that all results are returned at
+the same time (after the final search result is obtained by the library).
+
+
+
+
+
+
+timeout
+
+Specifies a maximum interval to wait for the selection to complete.
+If timeout is a NULL pointer, the
+select blocks indefinitely. To effect a poll, the timeout parameter
+should be a non-NULL pointer, pointing to a zero-valued
+timeval structure.
+
+
+
+result
+
+Result of the operation. To interpret the results, pass this to the
+LDAP parsing routines, such as ldap_result2error,
+ ldap_parse_result, and
+ldap_first_entry.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_RES_BIND indicates that the LDAPMessage structure contains the result of an
+LDAP bind operation.
+LDAP_RES_SEARCH_ENTRY indicates that the LDAPMessage structure contains an entry found during
+an LDAP search operation.
+LDAP_RES_SEARCH_REFERENCE indicates that
+the LDAPMessage structure contains an LDAPv3
+search reference (a referral to another LDAP server) found during an LDAP
+search operation.
+LDAP_RES_SEARCH_RESULT indicates that the LDAPMessage structure contains the result of an
+LDAP search operation.
+LDAP_RES_MODIFY indicates that the LDAPMessage structure contains the result of an
+LDAP modify operation.
+LDAP_RES_ADD indicates that the LDAPMessage structure contains the result of an
+LDAP add operation.
+LDAP_RES_DELETE indicates that the LDAPMessage structure contains the result of an
+LDAP delete operation.
+LDAP_RES_MODDN or LDAP_RES_RENAME indicates
+that the LDAPMessage structure contains the
+result of an LDAP modify DN operation.
+LDAP_RES_COMPARE indicates that the LDAPMessage structure contains the result of an
+LDAP compare operation.
+LDAP_RES_EXTENDED indicates that the LDAPMessage structure contains the result of an
+LDAP v3 extended operation.
+-1 indicates that an error occurred. The
+error code is set in the LDAP structure.
+To get the error code, call the ldap_get_lderrno function.
+
+0 indicates that the operation has timed
+out.
+
+
+See Also
+ldap_add_ext, ldap_compare_ext
+ , ldap_delete_ext, ldap_modify_ext, ldap_rename, ldap_simple_bind, ldap_url_search
+
+
+ldap_result2error
+
+C SDK functions
+ldap_result2error
+
+ldap_result2error
+
+This function is deprecated and should not be used. It is included
+in ldap-deprecated.h for backward-compatibility. Use the
+newer version, ldap_parse_result.
+The ldap_result2error function returns the corresponding
+error code for a result produced by the ldap_result and ldap_search_s functions.
+Syntax
+#include <ldap-deprecated.h>
+int ldap_result2error( LDAP *ld, LDAPMessage *r, int freeit );
+
+Parameters
+
ldap_result2error Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+r
+
+Pointer to the LDAPMessage structure
+representing the results returned by the ldap_result or ldap_search function.
+
+
+
+freeit
+
+Specifies whether or not the result should be freed after the error
+code is extracted. The parameter can have the following possible values:
+
+0 specifies that the result should not
+be freed.
+A non-zero value specifies that the result should be freed.
+
+
+
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, sets the error code and other error information
+in the LDAP structure and returns the error
+code.
+If unsuccessful, returns LDAP_PARAM_ERROR.
+
+
+
+Example
+See ldap_result.
+See Also
+ldap_parse_result, ldap_get_lderrno, ldap_err2string
+, ldap_result,
+ldap_set_lderrno
+
+ldap_sasl_bind
+
+C SDK functions
+ldap_sasl_bind
+
+ldap_sasl_bind
+
+The ldap_sasl_bind function authenticates your
+client to an LDAP server using an Simple Authentication and Security Layer
+(SASL) mechanism.
+The LDAP server must support authentication through SASL. &cnDirectoryServer; supports
+a server plug-in interface that you can use to add SASL support to the server.
+
+Syntax
+#include <ldap.h>
+ int ldap_sasl_bind( LDAP *ld, const char *dn,
+ const char *mechanism, const struct berval *cred,
+ LDAPControl **serverctrls, LDAPControl **clientctrls,
+ int *msgidp );
+
+Parameters
+
ldap_sasl_bind Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the user who wants to authenticate. For anonymous authentication,
+set this to NULL.
+
+
+
+mechanism
+
+Name of the SASL mechanism that you want to use for authentication.
+
+
+
+
+cred
+
+Pointer to the berval structure containing
+the credentials that you want to use for authentication.
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+msgidp
+
+Pointer to an integer that will be set to the message ID of the LDAP
+operation. To check the result of this operation, call ldap_result
+ and ldap_parse_sasl_bind_result functions.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if the SASL bind request
+was sent successfully.
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NOT_SUPPORTED if controls are
+included in your request—for example, as a session preference—and
+your LDAP client does not specify that it is using the LDAP v3. Make sure
+that you set the version of your LDAP client to version 3 before calling this
+function.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request to send to the server.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+
+
+Description
+The ldap_sasl_bind function authenticates your
+client to an LDAP server by using a specified SASL mechanism. ldap_sasl_bind
+ is an asynchronous function; it does not directly return results.
+If you want the results to be returned directly by the function, call the
+synchronous function ldap_sasl_bind_s. In
+order to get the results of the LDAP SASL bind operation, call the ldap_result, the ldap_parse_sasl_bind_result
+, and the ldap_get_lderrno functions.
+
+See Also
+ldap_result, ldap_parse_sasl_bind_result
+ , ldap_get_lderrno, ldap_sasl_bind_s
+
+ldap_sasl_bind_s
+
+C SDK functions
+ldap_sasl_bind_s
+
+ldap_sasl_bind_s
+
+The ldap_sasl_bind_s function authenticates your
+client to an LDAP server synchronously using an SASL mechanism.
+The LDAP server must support authentication through SASL. &cnDirectoryServer; supports
+a server plug-in interface that you can use to add SASL support to the server.
+Syntax
+#include <ldap.h>
+ int ldap_sasl_bind_s( LDAP *ld, const char *dn,
+ const char *mechanism, const struct berval *cred,
+ LDAPControl **serverctrls, LDAPControl **clientctrls,
+ struct berval **servercredp );
+
+Parameters
+
ldap_sasl_bind_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+dn
+
+DN of the user who wants to authenticate. For anonymous authentication,
+set this to NULL.
+
+
+
+mechanism
+
+Name of the SASL mechanism that you want to use for authentication.
+
+
+
+
+cred
+
+Pointer to the berval structure containing
+the credentials that you want to use for authentication.
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+servercredp
+
+Pointer to a pointer to an berval structure
+containing any credentials returned by the server. When done, you can free
+this by calling the ber_alloc function.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if the SASL bind request
+was sent successfully.
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAPv3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request to send to the server.
+LDAP_DECODING_ERROR if an error occurred
+when the LDAP API library was decoding the BER-encoded results received from
+the server.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_LOCAL_ERROR if an error occurred
+when receiving the results from the server.
+
+&cnDirectoryServer; and other LDAP server products may send result
+codes in addition to those described. For example, the server may have loaded
+a plug-in that returns custom result codes. Check your LDAP server documentation
+for other result codes.
+
+Description
+The ldap_sasl_bind_s function authenticates your
+client to an LDAP server by using a specified SASL mechanism. It is a synchronous
+function, which directly returns the results of the operation. If you want
+to perform other operations while waiting for the results of this operation,
+call the asynchronous function ldap_sasl_bind.
+After authenticating a client through SASL, an LDAP server can return a set
+of credentials in the results. The servercredp argument
+points to this value.
+See Also
+ldap_sasl_bind
+
+ldap_search
+
+C SDK functions
+ldap_search
+
+ldap_search
+
+The ldap_search function searches the directory
+asynchronously.
+This is an older function that is included in the SDK for backward-compatibility.
+If you are writing a new LDAP client, use ldap_search_ext
+ instead.
+Syntax
+#include <ldap.h>
+int ldap_search( LDAP *ld, const char *base, int scope,
+ const char* filter, char **attrs, int attrsonly );
+
+Parameters
+
ldap_search Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+base
+
+DN of the entry that serves as the starting point for the search. For
+example, setting base to dc=example,dc=com restricts the
+search to entries at example.com.
+
+
+
+scope
+
+Scope of the search, which can be one of the following values:
+
+LDAP_SCOPE_BASE searches the entry specified
+by base.
+LDAP_SCOPE_ONELEVEL searches all entries
+one level beneath the entry specified by base.
+LDAP_SCOPE_SUBTREE searches the entry specified
+by base and all entries at all levels beneath the entry specified by base.
+
+
+
+
+
+
+filter
+
+String representation of the filter to apply in the search. You can
+specify simple filters with the following syntax:
+(attributetype=
+attributevalue)
+
+
+
+attrs
+
+A NULL terminated array of attribute types to return
+from entries that match filter. If you specify a NULL,
+all attributes will be returned.
+
+
+
+attrsonly
+
+Specifies whether or not attribute values are returned along with the
+attribute types. This parameter can have the following values:
+
+0 specifies that both attribute types and
+attribute values are returned.
+1 specifies that only attribute types are
+returned.
+
+
+
+
+
+
+
+Returns
+Returns the message ID of the ldap_search operation.
+To check the result of this operation, call
+ldap_result and ldap_result2error.
+See ldap_search_ext_s for a list of possible
+result codes.
+
+Description
+Please use the newer version of this function, ldap_search_ext
+ .
+Example
+Example 21–44 searches
+a directory.
+Using ldap_search
+#include "examples.h"
+
+static void do_other_work();
+unsigned long global_counter = 0;
+
+int
+main( int argc, char **argv )
+{
+ LDAP *ld;
+ LDAPMessage *result, *e;
+ BerElement *ber;
+ char *a, *dn;
+ char **vals;
+ int i, rc, finished, msgid;
+ int num_entries = 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( MY_HOST, MY_PORT )) == NULL ) {
+ perror( "ldap_init" );
+ return( 1 );
+}
+/* authenticate to the directory as nobody */
+if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_simple_bind_s" );
+ return( 1 );
+}
+/* search for all entries with surname of Jensen */
+if (( msgid = ldap_search( ld, MY_SEARCHBASE, LDAP_SCOPE_SUBTREE,
+ MY_FILTER, NULL, 0 )) == -1 ) {
+ ldap_perror( ld, "ldap_search" );
+ return( 1 );
+}
+
+/* Loop, polling for results until finished */
+finished = 0;
+while ( !finished ) {
+ /*
+ * Poll for results. We call ldap_result with the "all" parameter
+ * set to zero. This causes ldap_result() to return exactly one
+ * entry if at least one entry is available. This allows us to
+ * display the entries as they are received.
+ */
+ result = NULL;
+ rc = ldap_result( ld, msgid, 0, &zerotime, &result );
+ switch ( rc ) {
+ case -1:
+ /* some error occurred */
+ ldap_perror( ld, "ldap_result" );
+ return( 1 );
+ case 0:
+ /* Timeout was exceeded. No entries are ready for retrieval. */
+ if ( result != NULL ) {
+ ldap_msgfree( result );
+ }
+ break;
+ default:
+ /*
+ * Either an entry is ready for retrieval, or all entries have
+ * been retrieved.
+ */
+ if (( e = ldap_first_entry( ld, result )) == NULL ) {
+ /* All done */
+ finished = 1;
+ if ( result != NULL ) {
+ ldap_msgfree( result );
+ }
+ continue;
+ }
+ /* for each entry print out name + all attrs and values */
+ num_entries++;
+ if (( dn = ldap_get_dn( ld, e )) != NULL ) {
+ printf( "dn: %s\n", dn );
+ ldap_memfree( dn );
+ }
+ for ( a = ldap_first_attribute( ld, e, &ber );
+ a != NULL; a = ldap_next_attribute( ld, e, ber ) ) {
+ 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 ) {
+ ldap_ber_free( ber, 0 );
+ }
+ printf( "\n" );
+ ldap_msgfree( result );
+ }
+ /* Do other work here while you are waiting... */
+ do_other_work();
+}
+
+/* All done. Print a summary. */
+printf( "%d entries retrieved. I counted to %ld "
+ "while waiting.\n", num_entries, global_counter );
+ldap_unbind( ld );
+return( 0 );
+}
+
+/*
+ * Perform other work while polling for results. */
+static void
+do_other_work()
+{
+ global_counter++;
+}
+
+
+See Also
+ldap_search_ext
+
+ldap_search_ext
+
+C SDK functions
+ldap_search_ext
+
+ldap_search_ext
+
+The ldap_search_ext function searches the directory
+asynchronously.
+ldap_search_ext is a new version of the ldap_search function. If you are writing a new LDAP
+client, you should call ldap_search_ext.
+Syntax
+#include <ldap.h>
+ int ldap_search_ext( LDAP *ld, const char *base, int scope,
+ const char *filter, char **attrs, int attrsonly,
+ LDAPControl **serverctrls, LDAPControl **clientctrls,
+ struct timeval *timeoutp, int sizelimit, int *msgidp );
+
+Parameters
+
ldap_search_ext Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+base
+
+DN of the entry that serves as the starting point for the search. For
+example, setting base to dc=example,dc=com restricts the
+search to entries at example.com.
+
+
+
+scope
+
+Scope of the search, which can be one of the following values:
+
+LDAP_SCOPE_BASE searches the entry specified
+by base.
+LDAP_SCOPE_ONELEVEL searches all entries
+one level beneath the entry specified by base.
+LDAP_SCOPE_SUBTREE searches the entry specified
+by base and all entries at all levels beneath the entry specified by base.
+
+
+
+
+
+
+filter
+
+String representation of the filter to apply in the search. You can
+specify simple filters with the following syntax:
+(attributetype=
+attributevalue)
+
+
+
+attrs
+
+A NULL terminated array of attribute types to return
+from entries that match filter. If you specify a NULL,
+all attributes will be returned.
+
+
+
+attrsonly
+
+Specifies whether or not attribute values are returned along with the
+attribute types. This parameter can have the following values:
+
+0 specifies that both attribute types and
+attribute values are returned.
+1 specifies that only attribute types are
+returned.
+
+
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+timeoutp
+
+Pointer to a timeval structure specifying the maximum
+time to wait for the results of the search. Pass NULL to
+use the default time limit for the current connection. To specify an infinite
+time limit, set the tv_sec and tv_usec fields
+in the timeval structure to 0.
+
+
+
+sizelimit
+
+Maximum number of results to return in the search. Pass -1 to
+use the default size limit for the current connection.
+
+
+
+msgidp
+
+Pointer to an integer that will be set to the message ID of the LDAP
+operation.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if the SASL bind request
+was sent successfully.
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NOT_SUPPORTED if controls are
+included in your request—for example, as a session preference—and
+your LDAP client does not specify that it is using the LDAP v3. Make sure
+that you set the version of your LDAP client to version 3 before calling this
+function.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request to send to the server.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+
+
+Description
+The ldap_search_ext function searches the directory
+for matching entries. ldap_search_ext is an asynchronous
+function; it does not directly return results. If you want the results to
+be returned directly by the function, call the synchronous function ldap_search_ext_s . You can also use this function
+to pass LDAP server controls to the server if you want the server to sort
+the results or if you want to request a persistent search. (See ldap_create_sort_control and ldap_create_persistentsearch_control
+ for more information.) In order to get the results of the ldap_search_ext
+ operation, you need to call the ldap_result and
+the ldap_parse_result functions.
+See Also
+ldap_search_ext_s, ldap_result, ldap_parse_result
+
+
+ldap_search_ext_s
+
+C SDK functions
+ldap_search_ext_s
+
+ldap_search_ext_s
+
+The ldap_search_ext_s function searches the directory
+synchronously.
+ldap_search_ext_s is a new version of the ldap_search_s function. If you are writing a new
+LDAP client, you should call ldap_search_ext_s.
+
+Syntax
+#include <ldap.h>
+ int ldap_search_ext_s( LDAP *ld, const char *base, int scope,
+ const char *filter, char **attrs, int attrsonly,
+ LDAPControl **serverctrls, LDAPControl **clientctrls,
+ struct timeval *timeoutp, int sizelimit, LDAPMessage **res );
+
+Parameters
+
ldap_search_ext_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+base
+
+DN of the entry that serves as the starting point for the search. For
+example, setting base to dc=example,dc=com restricts the
+search to entries at example.com.
+
+
+
+scope
+
+Scope of the search, which can be one of the following values:
+
+LDAP_SCOPE_BASE searches the entry specified
+by base.
+LDAP_SCOPE_ONELEVEL searches all entries
+one level beneath the entry specified by base.
+LDAP_SCOPE_SUBTREE searches all entries
+at all levels beneath the entry specified by base.
+
+
+
+
+
+filter
+
+String representation of the filter to apply in the search. You can
+specify simple filters with the following syntax:
+(attributetype=
+attributevalue)
+
+
+
+attrs
+
+A NULL terminated array of attribute types to return
+from entries that match filter. If you specify a NULL,
+all attributes will be returned.
+
+
+
+attrsonly
+
+Specifies whether or not attribute values are returned along with the
+attribute types. This parameter can have the following values:
+
+0 specifies that both attribute types and
+attribute values are returned.
+1 specifies that only attribute types are
+returned.
+
+
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+timeoutp
+
+Pointer to a timeval structure specifying the maximum
+time to wait for the results of the search.
+
+
+
+sizelimit
+
+Maximum number of results to return in the search.
+
+
+
+res
+
+Results of the search (when the call is completed).
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if the SASL bind request
+was sent successfully.
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NOT_SUPPORTED if controls are
+included in your request—for example, as a session preference—and
+your LDAP client does not specify that it is using the LDAP v3. Make sure
+that you set the version of your LDAP client to version 3 before calling this
+function.
+LDAP_FILTER_ERROR if an error occurred
+when parsing and BER-encoding the search filter specified by the filter argument.
+
+LDAP_TIMEOUT if the search exceeded
+the time specified by the timeoutp argument.
+
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request to send to the server.
+LDAP_DECODING_ERROR if an error occurred
+when the LDAP API library was decoding the BER-encoded results received from
+the server.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_LOCAL_ERROR if an error occurred
+when receiving the results from the server.
+
+&cnDirectoryServer; and other LDAP server products may send result
+codes in addition to those described. For example, the server may have loaded
+a plug-in that returns custom result codes. Check your LDAP server documentation
+for other result codes.
+
+Description
+The ldap_search_ext_s searches the directory for
+matching entries. The function ldap_search_ext_s is synchronous;
+it directly returns the results of the operation. If you want to perform other
+operations while waiting for the results of this operation, call the asynchronous
+function ldap_search_ext. You can also use
+ldap_search_ext_s to pass LDAP server controls to the server if
+you want the server to sort the results or if you want to request a persistent
+search. (See ldap_create_sort_control and ldap_create_persistentsearch_control for more information.)
+
+See Also
+ldap_search_ext
+
+ldap_search_s
+
+C SDK functions
+ldap_search_s
+
+ldap_search_s
+
+The ldap_search_s function searches the directory
+synchronously.
+This is an older function that is included in the SDK for backward-compatibility.
+If you are writing a new LDAP client, use ldap_search_ext_s
+ instead.
+Syntax
+#include <ldap.h>
+ int ldap_search_s( LDAP *ld, const char *base, int scope,
+ const char* filter, char **attrs, int attrsonly,
+ LDAPMessage **res );
+
+Parameters
+This function has the parameters listed in ldap_search_s
+ .
+
ldap_search_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+base
+
+DN of the entry that serves as the starting point for the search. For
+example, setting base to dc=example,dc=com restricts the
+search to entries at example.com.
+
+
+
+scope
+
+Scope of the search, which can be one of the following values:
+
+LDAP_SCOPE_BASE searches the entry specified
+by base.
+LDAP_SCOPE_ONELEVEL searches all entries
+one level beneath the entry specified by base.
+LDAP_SCOPE_SUBTREE searches all entries
+at all levels beneath the entry specified by base.
+
+
+
+
+
+filter
+
+String representation of the filter to apply in the search. You can
+specify simple filters with the following syntax:
+(attributetype=attributevalue)
+
+
+
+
+attrs
+
+A NULL terminated array of attribute types to return
+from entries that match filter. If you specify a NULL,
+all attributes will be returned.
+
+
+
+attrsonly
+
+Specifies whether or not attribute values are returned along with the
+attribute types. This parameter can have the following values:
+
+0 specifies that both attribute types and
+attribute values are returned.
+1 specifies that only attribute types are
+returned.
+
+
+
+
+
+res
+
+Results of the search (when the call is completed).
+
+
+
+
+
+Returns
+For a list of possible result codes for an LDAP search operation, see ldap_search_ext_s.
+Description
+Use the newer version of this function, ldap_search_ext_s
+ .
+Example
+Example 21–45 searches
+the directory for all people whose surname (last name) is Jensen.
+
+Using ldap_search_s
+#include "examples.h"
+
+int main( int argc, char **argv )
+{
+ LDAP *ld;
+ LDAPMessage *result, *e;
+ BerElement *ber;
+ char *a, *dn;
+ char **vals;
+ int i;
+ /* 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 as nobody */
+ if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_simple_bind_s" );
+ return( 1 );
+ }
+ /* search for all entries with surname of Jensen */
+ if ( ldap_search_s( ld, MY_SEARCHBASE, LDAP_SCOPE_SUBTREE,
+ MY_FILTER, NULL, 0, &result ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+ }
+ /* for each entry print out name + all attrs and values */
+ 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 );
+ }
+ for ( a = ldap_first_attribute( ld, e, &ber );
+ a != NULL; a = ldap_next_attribute( ld, e, ber ) ) {
+ 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 ) {
+ ldap_ber_free( ber, 0 );
+ }
+ printf( "\n" );
+ }
+ ldap_msgfree( result );
+ ldap_unbind( ld );
+ return( 0 );
+}
+
+
+See Also
+ldap_search_ext_s
+
+ldap_search_st
+
+C SDK functions
+ldap_search_st
+
+ldap_search_st
+
+The ldap_search_st function searches the directory
+synchronously within a specified time limit.
+This is an older function that is included in the SDK for backward-compatibility.
+If you are writing a new LDAP client, use ldap_search_ext_s
+ instead.
+Syntax
+#include <ldap.h>
+int ldap_search_st( LDAP *ld, const char *base, int scope,
+ const char* filter, char **attrs, int attrsonly,
+ struct timeval *timeout, LDAPMessage **res );
+
+Parameters
+
ldap_search_st Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+base
+
+DN of the entry that serves as the starting point for the search. For
+example, setting base to dc=example,dc=com restricts the
+search to entries at example.com.
+
+
+
+scope
+
+Scope of the search, which can be one of the following values:
+
+LDAP_SCOPE_BASE searches the entry specified
+by base.
+LDAP_SCOPE_ONELEVEL searches all entries
+one level beneath the entry specified by base.
+LDAP_SCOPE_SUBTREE searches all entries
+at all levels beneath the entry specified by base.
+
+
+
+
+
+filter
+
+String representation of the filter to apply in the search. You can
+specify simple filters with the following syntax:
+(attributetype=attributevalue)
+
+
+
+
+attrs
+
+A NULL terminated array of attribute types to return
+from entries that match filter. If you specify a NULL,
+all attributes will be returned.
+
+
+
+attrsonly
+
+Specifies whether or not attribute values are returned along with the
+attribute types. This parameter can have the following values:
+
+0 specifies that both attribute types and attribute values
+are returned.
+1 specifies that only attribute types are returned.
+
+
+
+
+
+
+timeout
+
+Maximum time to wait for the results of the search.
+
+
+
+res
+
+Results of the search (when the call is completed).
+
+
+
+
+
+Returns
+For a list of possible result codes for an LDAP search operation, see ldap_search_ext_s.
+Description
+Please use the newer version of this function, ldap_search_ext_s
+ .
+See Also
+ldap_search_ext_s
+
+ldap_set_filter_additions
+
+C SDK functions
+ldap_set_filter_additions
+
+ldap_set_filter_additions
+
+The ldap_set_filter_additions function sets a prefix
+to be prepended and a suffix to be appended to all filters returned by the
+ ldap_getfirstfilter and ldap_getnextfilter function
+calls.
+Syntax
+#include <ldap.h>
+ int ldap_set_filter_additions( LDAPFiltDesc *lfdp, char *prefix,
+ char *suffix );
+
+Parameters
+
ldap_set_filter_additions Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+lfdp
+
+Pointer to an LDAPFiltDesc structure.
+
+
+
+
+prefix
+
+Prefix to prepend to all filters. If NULL, no prefix
+is prepended.
+
+
+
+suffix
+
+Suffix to append to all filters. If NULL, no suffix
+is appended.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+If unsuccessful, returns an LDAP error code.
+
+
+Example
+Example 21–46 loads
+the filter configuration file named myfilters.conf into
+memory and adds the prefix "(&(objectClass=person)" and
+the suffix ")" to each filter retrieved.
+Using ldap_set_filter_additions
+
+#include <ldap.h>
+...
+LDAPFiltDesc *lfdp;
+char *filter_file = "myfilters.conf";
+char *prefix = "(&(objectClass=person)";
+char *suffix = ")";
+int rc;
+...
+lfdp = ldap_init_getfilter( filter_file );
+rc = ldap_set_filter_additions( ldfp, prefix, suffix );
+if ( rc != LDAP_SUCCESS ) {
+ printf( "Error setting filter prefix and suffix\n");
+ return( rc );
+}
+...
+
+
+See Also
+ldap_getfirstfilter, ldap_getnextfilter
+
+ldap_setfilteraffixes
+
+C SDK functions
+ldap_setfilteraffixes
+
+ldap_setfilteraffixes
+
+This function is deprecated and should not be used. It is included
+in ldap-deprecated.h for backward-compatibility. Use ldap_set_filter_additions instead.
+See Also
+ldap_set_filter_additions
+
+ldap_set_lderrno
+
+C SDK functions
+ldap_set_lderrno
+
+ldap_set_lderrno
+
+The ldap_set_lderrno function sets an error code
+and information about an error in an LDAP structure.
+
+Syntax
+#include <ldap.h>
+int ldap_set_lderrno( LDAP *ld, int e, char *m, char *s );
+
+Parameters
+
ldap_set_lderrno Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+e
+
+The error code that you want to set.
+
+
+
+m
+
+In the event that an entry for a specified DN cannot be found, set this
+parameter to the portion of the DN that identifies an existing entry.
+
+
+
+
+s
+
+The text of the error message that you want associated with this error
+code.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+If unsuccessful, returns an LDAP error code.
+
+
+Description
+The ldap_set_lderrno function sets an error code
+and information about an error in an LDAP structure.
+You can call this function to set error information that will be retrieved
+by subsequent ldap_get_lderrno function calls.
+
+Example
+Example 21–47 attempts
+to perform an operation. If the operation fails, the LDAP_PARAM_ERROR error
+code is placed in the LDAP structure.
+Using ldap_set_lderrno
+#include <ldap.h>
+int rc;
+char *errmsg = "Invalid parameter";
+...
+if ( ldap_my_function() != LDAP_SUCCESS ) {
+ rc = ldap_set_lderrno( ld, LDAP_PARAM_ERROR, NULL, errmsg );
+ if ( rc != LDAP_SUCCESS ) {
+ printf( "Error: %d\nError code could not be set.\n", rc );
+ }
+ return( rc );
+}
+...
+
+
+See Also
+ldap_err2string,
+ldap_perror, ldap_result2error
+
+
+ldap_set_option
+
+C SDK functions
+ldap_set_option
+
+ldap_set_option
+
+The function ldap_set_option sets session preferences
+in the LDAP structure.
+Syntax
+#include <ldap.h>
+ int ldap_set_option( LDAP *ld, int option, const void *optdata );
+
+Parameters
+
ldap_set_option Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server. If NULL, you are setting
+the default options that will apply to any new LDAP connection handles that
+are subsequently created.
+
+
+
+option
+
+Option that you want to set. See
+Table 21–182 for available options of this parameter.
+
+
+
+
+optdata
+
+Pointer to the value of the option that you want to set. Available data
+types are also listed in Table
+21–182.
+
+
+
+
+The option parameter can have one of the values listed
+in Table 21–182.
+
Options for ldap_set_option
+
+
+
+
+
+Option
+
+Description
+
+
+
+
+
+LDAP_OPT_API_FEATURE_INFO
+
+Retrieves information about the revision of a supported LDAP feature.
+This option is READ-ONLY and cannot be set.
+The data type for the optdata parameter is (LDAPAPIFeatureInfo
+*).
+
+
+
+LDAP_OPT_API_INFO
+
+Retrieves information about the API implementation at execution time
+(API version, protocol version, the names of supported API extensions with
+their vendor name version, etc.). For details on the structure returned, refer
+to the ldap.h header file. This option is READ-ONLY and
+cannot be set.
+The data type for the optdata parameter is (LDAPAPIInfo
+ *).
+
+
+
+LDAP_OPT_CLIENT_CONTROLS
+
+Pointer to an array of LDAPControl structures
+representing the LDAP v3 client controls you want sent with every request
+by default.
+The data type for the optdata parameter is (LDAPControl
+***).
+
+
+
+LDAP_OPT_DESC
+
+Socket descriptor underlying the main LDAP connection. The LBER_SOCKET
+ data type depends on the platform that you are using:
+
+int in UNIX.
+SOCKET in Windows.The data
+type for the optdata parameter is (LBER_SOCKET
+*).
+
+
+
+
+
+LDAP_OPT_DEREF
+
+Determines how aliases work during a search. optdata can
+be one of the following values:
+
+LDAP_DEREF_NEVER specifies that aliases
+are never dereferenced.
+LDAP_DEREF_SEARCHING specifies that aliases
+are dereferenced when searching under the base object (but not when finding
+the base object).
+LDAP_DEREF_FINDING specifies that aliases
+are dereferenced when finding the base object (but not when searching under
+the base object).
+LDAP_DEREF_ALWAYS specifies that aliases
+are always dereferenced when finding and searching under the base object.
+The data type for the optdata parameter is (int
+*).
+
+
+
+
+
+LDAP_OPT_DNS_FN_PTRS
+
+DEPRECATED OPTION: Lets you use alternate
+DNS functions for getting the host entry of the LDAP server.
+The data type for the optdata parameter is (struct
+ldap_dns_fns *).
+
+
+
+LDAP_OPT_ERROR_NUMBER
+
+Retrieves the result code for the most recent LDAP error that occurred
+in this session.
+The data type for the optdata parameter is (int
+*).
+
+
+
+LDAP_OPT_ERROR_STRING
+
+Retrieves the error message returned with the result code for the most
+recent LDAP error that occurred in this session.
+The data type for the optdata parameter is (char
+**).
+
+
+
+LDAP_OPT_EXTRA_THREAD_FN_PTRS
+
+Lets you specify the locking and semaphore functions that you want called
+when getting results from the server.
+The data type for the optdata parameter is (struct
+ldap_extra_thread_fns *).
+
+
+
+LDAP_OPT_HOST_NAME
+
+Sets the host name (or list of hosts) for the primary LDAP server.
+The data type for the optdata parameter is (char
+**).
+
+
+
+LDAP_OPT_IO_FN_PTRS
+
+DEPRECATED OPTION: Lets you use alternate
+communication stacks.
+The data type for the optdata parameter is (struct
+ldap_io_fns *).
+
+
+
+LDAP_OPT_MATCHED_DN
+
+Gets the matched DN value returned with the most recent LDAP error that
+occurred for this session.
+The data type for the optdata parameter is (char
+**)
+
+
+
+LDAP_OPT_MEMALLOC_FN_PTRS
+
+Gets a pointer to the callback structure which you previously set.
+The data type for the optdata parameter is (struct
+ldap_memalloc_fnsldap_io_fns *).
+
+
+
+LDAP_OPT_PROTOCOL_VERSION
+
+Version of the protocol supported by your client. You can specify either
+LDAP_VERSION2 or LDAP_VERSION3. If no version
+is set, the default is LDAP_VERSION2. In order to use LDAP
+v3 features, you need to set the protocol version to LDAP_VERSION3.
+
+The data type for the optdata parameter is (int
+*).
+
+
+
+LDAP_OPT_REBIND_ARG
+
+Lets you set the last argument passed to the routine specified by
+LDAP_OPT_REBIND_FN. You can also set this option by calling the ldap_set_rebind_proc function.
+The data type for the optdata parameter is (void
+*).
+
+
+
+LDAP_OPT_REBIND_FN
+
+Lets you set the routine to be called when you need to authenticate
+a connection with another LDAP server (for example, during the course of following
+a referral). You can also set this option by calling the
+ldap_set_rebind_proc function.
+The data type for the optdata parameter is (LDAP_REBINDPROC_CALLBACK
+*).
+
+
+
+LDAP_OPT_RECONNECT
+
+If the connection to the server is lost, determines whether or not the
+same connection handle should be used to reconnect to the server. By default,
+this option is off. To handle failover use following values:
+
+LDAP_OPT_ON specifies that the same connection
+handle can be used to reconnect to the server.
+LDAP_OPT_OFF specifies that you want to
+create a new connection handle to connect to the server.The data
+type for the optdata parameter is (int *).
+
+
+
+
+
+
+LDAP_OPT_REFERRALS
+
+Determines whether or not the client should follow referrals. By default,
+the client follows referrals. optdata can be one of the
+following values:
+
+LDAP_OPT_ON specifies that the server should
+follow referrals.
+LDAP_OPT_OFF specifies that the server
+should not follow referrals.The data type for the optdata parameter
+is (int *).
+
+
+
+
+
+LDAP_OPT_REFERRAL_HOP_LIMIT
+
+Maximum number of referrals the client should follow in a sequence.
+In other words, the client can only be referred this number of times before
+it gives up. By default, the maximum number of referrals that the client can
+follow in a sequence is 5 for the initial connection. This limit does not
+apply to individual requests that generate multiple referrals in parallel.
+The data type for the optdata parameter is (int
+*).
+
+
+
+LDAP_OPT_RESTART
+
+Determines whether or not LDAP I/O operations should be restarted automatically
+if they are prematurely aborted. optdata can be one of
+the following values:
+
+LDAP_OPT_ON specifies that I/O operations
+should be restarted automatically.
+LDAP_OPT_OFF specifies that I/O operations
+should not be restarted automatically.The data type for the
+optdata parameter is (int *).
+
+
+
+
+
+LDAP_OPT_SERVER_CONTROLS
+
+Pointer to an array of LDAPControl structures
+representing the LDAP v3 server controls you want sent with every request
+by default. Typically, since controls are specific to the type of request,
+you may want to pass the controls using operation-specific functions (such
+as ldap_add_ext) instead.
+The data type for the optdata parameter is (LDAPControl
+***).
+
+
+
+LDAP_OPT_SIZELIMIT
+
+Maximum number of entries that should be returned by the server in search
+results. The LDAP server may impose a smaller size limit than the limit you
+specify as the server administrator also has the ability to set this limit.
+The data type for the optdata parameter is (int
+*).
+
+
+
+LDAP_OPT_SSL
+
+Determines whether or not SSL is enabled. optdata can
+be one of the following values:
+
+LDAP_OPT_ON specifies that SSL is enabled.
+
+LDAP_OPT_OFF specifies that SSL is disabled.
+The data type for the optdata parameter is (int
+*).
+
+
+
+
+
+LDAP_OPT_THREAD_FN_PTRS
+
+Lets you specify the thread function pointers.
+The data type for the optdata parameter is (struct
+ldap_thread_fns *).
+
+
+
+LDAP_OPT_TIMELIMIT
+
+Maximum number of seconds that should be spent by the server when answering
+a search request. The LDAP server may impose a shorter time limit than the
+limit you specify as the server administrator also has the ability to set
+this limit.
+The data type for the optdata parameter is (int
+*).
+
+
+
+LDAP_X_OPT_EXTIO_FN_PTRS
+
+Extended I/O function callback option.
+
+
+
+LDAP_X_OPT_CONNECT_TIMEOUT
+
+Value of a time out (expressed in milliseconds) for non-blocking connect
+call.
+The data type for the optdata parameter is (int
+*).
+
+
+
+LDAP_X_OPT_SOCKBUF
+
+Socket buffer structure associated to the LDAP connection.
+
+
+
+
+See also ldap_set_option
+3LDAP for details on LDAP_OPT_X_SASL*
+ parameters.
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+-1 if unsuccessful.
+
+
+Example
+Using ldap_set_option
+#include <stdio.h>
+#include <ldap.h>
+...
+LDAP *ld;
+int max_ret = 100, max_tim = 30;
+char *host = "ldap.sun.com";
+...
+/* Initialize a session with the LDAP server ldap.sun.com:389 */
+/* Use prldap_init() for IPv6 support. */
+if ( ( ld = ldap_init( host, LDAP_PORT ) ) == NULL ) {
+ perror( "ldap_init" );
+ return( 1 );
+}
+
+/* Set the maximum number of entries returned */
+if ( ldap_set_option( ld, LDAP_OPT_SIZELIMIT, &max_ret) !
+ LDAP_SUCCESS) {
+ ldap_perror( ld, "ldap_set_option" );
+ return( 1 );
+}
+...
+
+
+See Also
+ldap_init, prldap_init
+ (IPv6), ldap_get_option
+
+ldap_set_rebind_proc
+
+C SDK functions
+ldap_set_rebind_proc
+
+ldap_set_rebind_proc
+
+The ldap_set_rebind_proc function sets a rebind
+ , which is called by your client to obtain authentication credentials
+when following a referral.
+Syntax
+#include <ldap.h>
+void ldap_set_rebind_proc( LDAP *ld,
+ LDAP_REBINDPROC_CALLBACK *rebindproc, void *arg );
+
+Parameters
+
ldap_set_rebind_proc Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+rebindproc
+
+Pointer to a function called back to obtain bind credentials when a
+new server is contacted during an LDAP referral.
+
+
+
+arg
+
+Pointer to an additional argument that you want to pass to the rebind
+function.
+
+
+
+
+
+Description
+Call ldap_set_rebind_proc to specify the rebind
+function. This rebind function is called by the LDAP client when following
+a referral to a new LDAP server. It is responsible for obtaining the credentials
+used to authenticate to the new server. For example, suppose LDAP server A
+sends a referral to your client. The referral points your client to LDAP server
+B. When automatically following the referral, your client calls the rebind
+function to obtain a DN and credentials; your client uses these to authenticate
+to server B. By default, if you do not call ldap_set_rebind_proc or
+if you pass NULL for the rebindproc argument,
+your client authenticates anonymously when following referrals.
+The rebind function that you specify with ldap_set_rebind_proc should
+have the following prototype:
+int LDAP_CALL LDAP_CALLBACK rebindproc( LDAP *ld, char **dnp,
+ char **passwdp, int *authmethodp, int freeit, void *arg );
+LDAP_CALL and LDAP_CALLBACK are
+used to set up calling conventions, such as Pascal calling conventions on
+Windows. These are defined in the lber.h header file.
+
+The following procedure explains what the rebind function is expected
+to do. LDAP clients that are built with &DirectorySDKForC; use this procedure
+when following referrals.
+To Follow Referrals
+
+The LDAP server sends a referral back to the client.
+The client calls the rebind function, passing
+ 0 as the freeit argument.
+
+The rebind function sets the dnp,
+ passwdp, and
+ authmethodp arguments to point to the following information:
+
+
+The dnp argument is set to point to the
+DN to be used to authenticate to the new LDAP server.
+
+The passwdp argument is set to point to
+the credentials for this DN.
+The authmethodp argument is set to point
+to the method of authentication used (for example, LDAP_AUTH_SIMPLE).
+
+
+
+
+
+If successful, the rebind function returns
+ LDAP_SUCCESS
+ , and referral processing continues. (If any other value is returned,
+referral processing stops, and that value is returned as the result code for
+the original LDAP request.)
+The client gets the DN, credentials, and authentication method
+from the arguments of the rebind function and uses this information to authenticate
+to the new LDAP server.
+The client calls the rebind function again, passing
+ 1 as the freeit argument.
+
+The rebind function frees any memory allocated earlier to specify
+the DN and credentials.You need to write a rebind function that
+does the following:
+
+If freeit is 0, set
+the following pointers:
+
+Set dnp to point to the DN to be used for
+authentication.
+Set passwdp to point to the credentials
+to be used for authentication.
+Set authmethodp to point to the method
+of authentication used (for example, LDAP_AUTH_SIMPLE).
+You can also make use of the arg argument, which
+is a pointer to the argument specified in the ldap_set_rebind_proc function.
+If successful, returns LDAP_SUCCESS. Otherwise, returns
+the appropriate LDAP error code.
+
+If freeit is 1, free any memory
+that you allocated to create the DN and credentials.After you
+have defined this function, pass the function name to ldap_set_rebind_proc
+ to register your rebind function.
+
+In order to use the rebind function, the LDAP_OPT_REFERRALS option
+must be set to LDAP_OPT_ON, so that your client automatically
+follows referrals. This option is set to LDAP_OPT_ON by
+default.
+
+
+
+
+Example
+Example 21–49
+demonstrates how to write and register a rebind function.
+Using ldap_set_rebind_proc
+
+#include "ldap.h"
+...
+/* Declare your rebind function */
+int rebindproc( LDAP *ld, char **dnp, char **passwdp,
+ int *authmethodp, int freeit, void *arg );
+...
+int main( int argc, char **argv )
+{
+ LDAP *ld;
+ /* Additional argument to be passed to the rebind function */
+ char *testarg = "cn=admin,cn=Administrators,cn=config";
+ /* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
+ if ( (ld = ldap_init( "directory.example.com", 389 )) == NULL ) {
+ perror( "ldap_init" );
+ return( 1 );
+ }
+ /* Specify the function used for reauthentication on referrals */
+ ldap_set_rebind_proc( ld, rebindproc, (void *)testarg );
+ /* Authenticate */
+ if ( ldap_simple_bind_s( ld, "uid=bjensen,ou=People,dc=example,dc=com",
+ "hifalutin" ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_simple_bind_s" );
+ return( 1 );
+ }
+ ...
+ /* Your code to interact with the LDAP server */
+ ...
+}
+...
+/* rebindproc is the rebind function responsible for providing the DN,
+ credentials, and authentication method used for authenticating the
+ client to other Directory Servers.
+ The function should set the following arguments:
+ - dnp should point to the DN that will be used for authentication.
+ - passwdp should point to the credentials used for authentication.
+ - authmethodp should point to the method of authentication to be used
+ (for example, LDAP_AUTH_SIMPLE).
+ The function should return LDAP_SUCCESS if successful or an LDAP
+ error code if an error occurs.
+ In order to demonstrate how the freeit argument works, this example
+ uses strdup() to copy the DN and password. You can also just copy
+ string pointers if the DN and password are already available as
+ global variables.
+*/
+int LDAP_CALL LDAP_CALLBACK rebindproc(
+ LDAP *ld, char **dnp, char **passwdp,
+ int *authmethodp, int freeit, void *arg )
+{
+ printf( "Rebind function called.\n" );
+ switch ( freeit ) {
+ /* Your client calls the rebind function with freeit==1 when it needs
+ to free any memory you've allocated. */
+ case 1:
+ printf( "\tFreeing memory.\n" );
+ if ( dnp && *dnp ) {
+ free( *dnp );
+ }
+ if ( passwdp && *passwdp ) {
+ free( *passwdp );
+ }
+ break;
+ /* Your client calls the rebind function with freeit==0 when it needs
+ to get the DN, credentials, and authentication method. */
+ case 0:
+ printf( "\tGetting DN and credentials.\n" );
+ *dnp = strdup( "uid=username,o=OtherServerSuffix" );
+ *passwdp = strdup( "23skidoo" );
+ *authmethodp = LDAP_AUTH_SIMPLE;
+ break;
+ default:
+ printf( "\tUnknown value of freeit argument: %d\n", freeit );
+ break;
+ }
+ /* If you successfully set the DN and credentials, you should return
+ LDAP_SUCCESS. (Any other return code will stop the client from
+ automatically following the referral. */
+ return LDAP_SUCCESS;
+}
+
+
+See Also
+ldap_simple_bind, ldap_simple_bind_s
+
+ldap_simple_bind
+
+C SDK functions
+ldap_simple_bind
+
+ldap_simple_bind
+
+The ldap_simple_bind function synchronously authenticates
+your client to the LDAP server using a DN and a password.
+Syntax
+#include <ldap.h>
+ int ldap_simple_bind(LDAP *ld, const char *who, const char *passwd);
+
+Parameters
+
ldap_simple_bind Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+who
+
+DN of the user who wants to authenticate. For anonymous authentication,
+set this or the passwd argument to NULL.
+
+
+
+
+passwd
+
+Password of the user who wants to authenticate. For anonymous authentication,
+set this or the who argument to NULL.
+
+
+
+
+
+Returns
+Returns the message ID of the ldap_simple_bind operation.
+To check the result of this operation, call ldap_result
+and ldap_result2error.
+Description
+The ldap_simple_bind function authenticates to
+the LDAP server. It verifies that the password supplied for authentication
+matches the userPassword attribute of the given entry.
+ldap_simple_bind is an asynchronous function; it does not directly
+return results. If you want the results to be returned directly by the function,
+call the synchronous function ldap_simple_bind_s.
+
+If you specify a DN but no password, your client will bind to
+the server anonymously. If you want a NULL password to
+be rejected as an incorrect password, you need to write code to perform the
+check before you call the ldap_simple_bind function.
+The use of this function may be a security threat if used on a non-secured
+connection as the password is transmitted in clear text. For password-based
+authentication, use a secure connection (ldapssl_init or ldapssl_tls_start_s) or SASL Digest-MD5 mechanism
+(ldap_sasl_bind or ldap_sasl_bind_s
+).
+
+Example
+Example 21–50 calls
+ ldap_simple_bind to authenticate the user Barbara
+Jensen to the directory.
+Using ldap_simple_bind
+#include <stdio.h>
+#include <ldap.h>
+...
+LDAP *ld;
+char *host = "ldap.sun.com";
+char *dn = "uid=bjensen,ou=People,dc=example,dc=com";
+char *pw = "hifalutin";
+struct timeval zerotime;
+zerotime.tv_sec = zerotime.tv_usec = 0L;
+...
+/* Initialize a session with the LDAP server ldap.example.com:389 */
+/* Use prldap_init() for IPv6 support. */
+if ( ( ld = ldap_init( host, LDAP_PORT ) ) == NULL ) {
+ perror( "ldap_init" );
+ return( 1 );
+}
+/* Attempt to bind with the LDAP server */
+msgid = ldap_simple_bind( ld, dn, pw );
+
+/* Initialize the value returned by ldap_result() */
+rc = 0;
+
+/* While the operation is still running, do this: */
+while ( rc == 0 ) {
+ ... /* do other work while waiting */...
+
+ /* Check the status of the LDAP operation */
+ rc = ldap_result( ld, msgid, NULL, &zerotime, &result );
+ switch( rc ) {
+ /* If -1 was returned, an error occurred */
+ case -1:
+ ldap_perror( ld, "Error in results: " );
+ return( 1 );
+ /* If 0 was returned, the operation is still in progress */
+ case 0:
+ continue;
+ /* If any other value is returned, assume we are done */
+ default:
+ /* Check if the "bind" operation was successful */
+ if ( ldap_result2error( result ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "Error binding to server: " );
+ return( 1 );
+ }
+ }
+}
+...
+
+
+See Also
+ldap_simple_bind_s
+
+ldap_simple_bind_s
+
+C SDK functions
+ldap_simple_bind_s
+
+ldap_simple_bind_s
+
+The ldap_simple_bind function synchronously authenticates
+your client to the LDAP server using a DN and a password.
+Syntax
+#include <ldap.h>
+int ldap_simple_bind_s( LDAP *ld, const char *who, const char *passwd );
+
+Parameters
+
ldap_simple_bind_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+who
+
+DN of the user who wants to authenticate. For anonymous authentication,
+set this or the passwd argument to NULL.
+
+
+
+
+passwd
+
+Password of the user who wants to authenticate. For anonymous authentication,
+set this or the who argument to NULL.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if an invalid parameter
+was passed to the function.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request to send to the server.
+LDAP_DECODING_ERROR if an error occurred
+when the LDAP API library was decoding the BER-encoded results received from
+the server.
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_LOCAL_ERROR if an error occurred
+when receiving the results from the server.
+
+&cnDirectoryServer; and other LDAP server products may send result
+codes in addition to those described. For example, the server may have loaded
+a plug-in that returns custom result codes. Check your LDAP server documentation
+for other result codes.
+
+Description
+The ldap_simple_bind_s function authenticates to
+the LDAP server. It verifies that the password supplied for authentication
+matches the userPassword attribute of the given entry.
+ldap_simple_bind_s is a synchronous function, which directly returns
+the results of the operation. If you want to perform other operations while
+waiting for the results of this operation, call the asynchronous function ldap_simple_bind instead.
+If you specify a DN but no password, your client will bind to
+the server anonymously. If you want a NULL password to
+be rejected as an incorrect password, you need to write code to perform the
+check before you call the ldap_simple_bind_s function.
+The use of this function may be a security threat if used on a non-secured
+connection as the password is transmitted in clear text. For password-based
+authentication, use a secure connection (ldapssl_init or ldapssl_tls_start_s) or SASL Digest-MD5 mechanism
+(ldap_sasl_bind or ldap_sasl_bind_s
+).
+
+Example
+Example 21–51
+uses the synchronous ldap_simple_bind_s function to authenticate
+to the directory as the user Barbara Jensen.
+Using ldap_simple_bind_s
+
+#include <stdio.h>
+#include <ldap.h>
+...
+LDAP *ld;
+char *host = "ldap.sun.com";
+char *dn = "uid=bjensen,ou=People,dc=example,dc=com";
+char *pw = "hifalutin";
+...
+/* Initialize a session with the LDAP server ldap.sun.com:389 */
+/* Use prldap_init() for IPv6 support. */
+if ( ( ld = ldap_init( host, LDAP_PORT ) ) == NULL ) {
+ perror( "ldap_init" );
+ return( 1 );
+}
+/* Attempt to bind with the LDAP server */
+if ( ldap_simple_bind_s( ld, dn, pw ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "Authentication failed: " );
+ return( 1 );
+}
+...
+
+
+See Also
+ldap_simple_bind
+
+ldap_sort_entries
+
+C SDK functions
+ldap_sort_entries
+
+ldap_sort_entries
+
+The ldap_sort_entries function sorts a chain of
+entries retrieved from an LDAP search call.
+Syntax
+#include <ldap.h>
+ int ldap_sort_entries( LDAP *ld, LDAPMessage *chain, char *attr,
+ LDAP_CMP_CALLBACK *cmp );
+
+Parameters
+
ldap_sort_entries Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+chain
+
+Chain of entries returned by the ldap_result or ldap_search_s function.
+
+
+
+attr
+
+Attribute to use when sorting the results. To sort by DN instead of
+by attribute, use NULL.
+
+
+
+cmp
+
+Comparison function used when sorting the values.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+If unsuccessful, returns a NULL and sets
+the appropriate error code in the LDAP structure.
+To get the error code, call ldap_get_lderrno.
+
+
+
+Description
+The ldap_sort_entries function sorts a chain of
+entries retrieved from an LDAP search call (ldap_search_s
+ or ldap_result) either by DN or
+a specified attribute in the entries.
+Example
+Example 21–52
+sorts entries by the roomNumber attribute.
+Using ldap_sort_entries
+#include <stdio.h>
+#include <string.h>
+#include <ldap.h>
+LDAP *ld;
+LDAPMessage *result;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(sn=Jensen)";
+char *sortby = "roomNumber";
+...
+/* Search the directory */
+if ( ldap_search_s( ld, my_searchbase, LDAP_SCOPE_SUBTREE, my_filter,
+ NULL, 0, &result ) !=
+ LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+/* Sort the results by room number, using strcasecmp */
+if ( ldap_sort_entries( ld, &result, sortby, strcasecmp ) !=
+ LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_sort_entries" );
+ return( 1 );
+}
+...
+
+
+See Also
+ldap_multisort_entries, ldap_result, ldap_search_s,
+ LDAP_CMP_CALLBACK
+
+ldap_start_tls_s
+
+C SDK functions
+ldap_start_tls_s
+
+ldap_start_tls_s
+
+The ldap_start_tls_s initiates a Start Transport
+Layer Security (TLS) operation as defined in RFC 4513.
+Before using this function, call ldapssl_client_init
+, ldapssl_clientauth_init, or ldapssl_advclientauth_init to initialize use of
+the certificate database.
+Syntax
+#include <ldap_ssl.h>
+int ldap_start_tls_s( LDAP *ld, LDAPControl **serverctrls,
+ LDAPControl **clientctrls );
+
+Parameters
+
ldap_start_tls_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+serverctrls
+
+List of LDAP server controls.
+
+
+
+clientctrls
+
+List of client controls.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_OPERATIONS_ERROR if TLS has already
+been established.
+LDAP_PROTOCOL_ERROR if TLS is not supported.
+
+LDAP_REFERRAL if this server does not
+support TLS, but the server referred to may.
+LDAP_UNAVAILABLE if the server is shutting
+down, or supports TLS but cannot provide it at this time.
+
+
+
+ldap_sort_strcasecmp
+
+C SDK functions
+ldap_sort_strcasecmp
+
+ldap_sort_strcasecmp
+
+The ldap_sort_strcasecmp routine compares two strings
+and ignores any differences in case when comparing uppercase and lowercase
+characters.
+Syntax
+#include <ldap.h>
+ int ldap_sort_strcasecmp( const char **a, const char **b );
+
+Parameters
+
ldap_sort_strcasecmp Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+a
+
+Pointer to first string to compare
+
+
+
+b
+
+Pointer to second string to compare
+
+
+
+
+
+Returns
+One of the following values:
+
+If a is greater than b,
+returns a value greater than 0.
+If a is equal to b,
+returns 0.
+If a is less than b,
+returns a value less than 0.
+
+
+Description
+The ldap_sort_strcasecmp routine compares two strings
+and ignores any differences in case when comparing uppercase and lowercase
+characters. This function is similar to the C function strcasecmp.
+When sorting attribute values with ldap_sort_strcasecmp,
+call ldap_sort_strcasecmp to compare the attribute values.
+This function works with ASCII values only. For UTF-8 data, the
+comparison result is unspecified.
+
+See Also
+ldap_sort_strcasecmp, LDAP_VALCMP_CALLBACK
+
+ldap_sort_values
+
+C SDK functions
+ldap_sort_values
+
+ldap_sort_values
+
+The ldap_sort_values function sorts an array of
+values retrieved from an ldap_get_values call.
+Syntax
+#include <ldap.h>
+int ldap_sort_values( LDAP *ld, char **vals,
+ LDAP_VALCMP_CALLBACK cmp );
+
+Parameters
+
ldap_sort_values Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+vals
+
+The array of values to sort.
+
+
+
+cmp
+
+Comparison function used when sorting the values. In the ldap_sort_strcasecmp function, the comparison function
+must pass char ** parameters. Because of this, you need
+to use the ldap_sort_strcasecmp function,
+rather than a function like strcasecmp.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+If unsuccessful, returns an LDAP error code.
+
+
+Example
+Example 21–53 sorts
+the values of attributes before printing them.
+Using ldap_sort_values
+#include <stdio.h>
+#include <string.h>
+#include <ldap.h>
+...
+LDAP *ld;
+LDAPMessage *result, *e;
+BerElement *ber;
+char *a, *dn;
+char **vals;
+int i;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(sn=Jensen)";
+...
+ if ( ( vals = ldap_get_values( ld, e, a ) ) != NULL ) {
+ /* Sort the values of the attribute */
+ if ( ldap_sort_values( ld, vals, strcasecmp ) ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_sort_values" );
+ return( 1 );
+ }
+ /* Print the values of the attribute */
+ for ( i = 0; vals[i] != NULL; i++ ) {
+ printf( "%s: %s\n", a, vals[i] );
+ }
+ /* Free the values from memory */
+ ldap_value_free( vals );
+ }
+...
+
+
+See Also
+ldap_get_values,
+ldap_sort_strcasecmp, LDAP_VALCMP_CALLBACK.
+
+
+ldapssl_advclientauth_init
+
+C SDK functions
+ldap_ldapssl_*
+
+ldap_ldapssl_*
+
+The ldapssl_advclientauth_init function initialize
+the secure parts (Security and SSL) of the runtime for use by a client application
+that may want to do SSL client authentication.
+Syntax
+#include <ldap_ssl.h>
+ int LDAP_CALL ldapssl_advclientauth_init( char *certdbpath,
+ void *certdbhandle, int needkeydb, char *keydbpath,
+ void *keydbhandle, int needsecmoddb, char *secmodpath,
+ const int sslstrength);
+
+Parameters
+Please see the description of the sslstrength value
+and note the potential problems that can be caused by passing in wrong host
+and port name values.
+
ldapssl_advclientauth_init Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+certdbpath
+
+Specifies the path to the database containing certificates for your
+client. You can include the database filename in the path (for example,
+/usr/mozilla/cert_file_name.db).
+
+
+
+
+certdbhandle
+
+Pass a NULL value for this. (This parameter is not
+currently used.)
+
+
+
+needkeydb
+
+Specifies whether or not the private key database needs to be opened
+for use. This parameter can have one of the following values:
+
+If it is a non-zero value, the function opens the private
+key database, which is identified by the keydbpath argument.
+
+If 0, the function does not open the private
+key database.
+
+
+
+
+
+keydbpath
+
+Specifies the path to the database containing the private key certified
+by your certificate. You can include the database filename in the path (for
+example, /usr/mozilla/key_file_name
+.db).
+
+
+
+needsecmoddb
+
+Specifies whether or not the security module database file needs to
+be opened for use. This parameter can have one of the following values:
+
+If it is a non-zero value, the function opens the security
+module database, which is identified by the keydbpath argument.
+
+If 0, the function does not open the security
+modules database.
+
+
+
+
+
+secmodpath
+
+Path to the database containing security modules. You can include the
+database filename in the path (for example, /usr/mozilla/
+secmod_file_name.db).
+
+
+
+sslstrength
+
+Specifies how the server certificate is evaluated. It takes one of the
+following:
+
+LDAPSSL_AUTH_WEAK indicates that you accept
+the server’s certificate without checking the for certificate authority
+(CA) that issued the certificate.
+LDAPSSL_AUTH_CERT indicates that you accept
+the server’s certificate only if you trust the CA that issued the certificate.
+
+LDAPSSL_AUTH_CNCHECK indicates that you
+accept the server’s certificate only if you trust the CA that issued
+the certificate and if the value of the cn attribute is
+the DNS hostname of the server. If this option is selected, ensure that the
+defhost parameter passed to ldapssl_init consists
+of only one hostname and not a list of hosts. Furthermore, the port number
+must be passed via the defport parameter, and cannot be
+passed via a host: port option.
+
+
+
+
+
+
+
+
+Returns
+One of the following values:
+
+0 if successful.
+-1 if unsuccessful.
+
+
+Description
+You can call ldapssl_advclientauth_init to initialize
+your client application for SSL and certificate-based client authentication.
+This function is similar to ldapssl_clientauth_init and
+allows you to:
+
+Specify the name and path of a security module database.
+
+Specify the method used to verify the server’s certificate.
+
+
+You must call ldapssl_advclientauth_init before
+calling ldapssl_init to connect to the server.
+
+
+Example
+Example 21–54 initializes
+a client before connecting with a secure LDAP server.
+Using ldapssl_advclientauth_init
+
+#include <ldap.h>
+#include <ldap_ssl.h>
+#include <stdio.h>
+...
+/* Initialize client, using mozilla’s certificate database */
+if ( ldapssl_advclientauth_init( "/u/mozilla/.netscape/
+ cert_file_name.db",
+ NULL, 1, "/u/mozilla/.netscape/
+ key_file_name.db", NULL , 1,
+ "/u/mozilla/.netscape/
+ secmod_file_name.db", LDAPSSL_AUTH_CNCHECK) < 0 ) {
+ perror( "ldap_advclientauth_init" );
+ return( 1 );
+ }
+}
+...
+
+
+See Also
+ldap_init, prldap_init
+ (IPv6), ldapssl_clientauth_init, ldapssl_init, ldapssl_install_routines
+
+
+ldapssl_client_init
+The ldapssl_client_init function initializes the
+secure parts (Security and SSL) of the runtime for use by your client application
+to connect to a secure LDAP server over SSL.
+Syntax
+#include <ldap_ssl.h>
+int ldapssl_client_init( const char *certdbpath, void *certdbhandle );
+
+Parameters
+
ldapssl_client_init Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+certdbpath
+
+Specifies the path to the database containing certificates for your
+client.
+
+
+
+certdbhandle
+
+Pass a NULL value for this. (This parameter is not
+used currently.)
+
+
+
+
+
+Returns
+One of the following values:
+
+0 if successful.
+-1 if unsuccessful.
+
+
+Description
+You can call the ldapssl_client_init function to
+initialize your client application for SSL. It is only called once and returns
+0 if all goes well. If you plan to use certificate-based authentication,
+you should call either the ldapssl_clientauth_init or
+the ldapssl_advclientauth_init function.
+You must call ldapssl_client_init before
+calling the ldapssl_init function to connect
+to the server, or the ldap_start_tls_s function
+to start transport layer security.
+
+Example
+Example 21–55
+initializes a client before connecting with a secure LDAP server.
+Using ldapssl_client_init
+
+#include <ldap.h>
+#include <ldap_ssl.h>
+#include <stdio.h>
+...
+/* Initialize client using a certificate database
+ copied from &cnDirectoryServer;. */
+if ( ldapssl_client_init( "/local/client/alias/", NULL ) < 0) {
+ printf( "Failed to initialize SSL client...\n" );
+ return( 1 );
+}
+The certdbpath is a path to the file system directory
+containing the certificate database files. For example:
+$ ls /local/client/alias/*.db
+/local/client/alias/cert8.db
+/local/client/alias/key3.db
+/local/client/alias/secmod.db
+$
+
+
+See Also
+ldap_start_tls_s, ldap_init, prldap_init (IPv6), ldapssl_init, ldapssl_install_routines
+
+
+ldapssl_clientauth_init
+The ldapssl_clientauth_init function initializes
+your client application to connect to a secure LDAP server over SSL and to
+use certificate-based client authentication.
+Syntax
+#include <ldap_ssl.h>
+int ldapssl_clientauth_init( char *certdbpath, void *certdbhandle,
+ int needkeydb, char *keydbpath, void *keydbhandle );
+
+Parameters
+
ldapssl_clientauth_init Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+certdbpath
+
+Specifies the path to the database containing certificates for your
+client. You can include the database filename in the path (for example,
+/usr/mozilla/cert_file_name.db).
+
+
+
+
+needkeydb
+
+Specifies whether or not the private key database needs to be opened
+for use. This parameter can have one of the following values:
+
+If it is a non-zero value, the function opens the private
+key database, which is identified by the keydbpath argument.
+If 0, the function does not open the private
+key database.
+
+
+
+
+
+keydbpath
+
+Specifies the path to the database containing the private key certified
+by your certificate. You can include the database filename in the path (for
+example, /usr/mozilla/ key_file_name.db).
+
+
+
+
+certdbhandle
+
+Pass a NULL value for this. (This parameter is not
+currently used.)
+
+
+
+
+
+Returns
+One of the following values:
+
+0 if successful.
+-1 if unsuccessful.
+
+
+Description
+You can call the ldapssl_clientauth_init function
+to initialize your client application for SSL and certificate-based client
+authentication. However, if you need to specify the name and path of the security
+modules database or if you need to specify how the server’s certificate
+will be verified, you should call the ldapssl_advclientauth_init function
+instead.
+You must call ldapssl_clientauth_init before
+calling ldapssl_init to connect to the server.
+
+
+Example
+Example 21–56
+initializes a client before connecting with a secure LDAP server.
+Using ldapssl_clientauth_init
+
+#include <ldap.h>
+#include <ldap_ssl.h>
+#include <stdio.h>
+...
+/* Initialize client, using mozilla’s certificate database */
+if ( ldapssl_clientauth_init( "/u/mozilla/.netscape/
+ cert_file_name.db", NULL, 1,
+ "/u/mozilla/.netscape/
+ key_file_name.db", NULL ) < 0 ) {
+ perror( "ldap_clientauth_init" );
+ return( 1 );
+ }
+}
+...
+
+
+See Also
+ldap_init, prldap_init
+ (IPv6), ldapssl_init, ldapssl_install_routines
+
+ldapssl_enable_clientauth
+The ldapssl_enable_clientauth function enables
+SSL client authentication on the given connection (passed using the ld parameter).
+
+Syntax
+#include <ldap_ssl.h>
+int ldapssl_enable_clientauth( LDAP *ld, char *keynickname,
+ char *keypasswd, char *certnickname );
+
+Parameters
+
ldapssl_enable_clientauth Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+keynickname
+
+Pass an empty string, "", for this value. (This parameter
+is not currently used.)
+
+
+
+keypasswd
+
+Password to the encrypted private key database.
+
+
+
+certnickname
+
+Nickname of the certificate that you want to use for client authentication.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+0 if successful.
+-1 if unsuccessful.
+
+
+See Also
+ldapssl_clientauth_init
+
+ldapssl_err2string
+The ldapssl_err2string function returns the corresponding
+error message for an SSL-specific error code.
+Syntax
+#include <ldap_ssl.h>
+ const char * LDAP_CALL ldapssl_err2string ( const int prerrno );
+
+Parameters
+
ldapssl_err2string Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+prerrno
+
+The SSL error code that you want interpreted into an error message.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns the corresponding error message for
+the given error code.
+If unsuccessful (for example, if the error code is not a known
+SSL error code), returns a pointer to the string Unknown error.
+
+
+
+Description
+ldapssl_err2string provides support for SSL-specific
+error messages that are not covered by the regular message routine ldap_err2string. If any ldapssl_* function
+returns an error code that is unknown to ldap_err2string
+–it returns Unknown error– this function
+should be called to determine the SSL-specific error message. To check for
+SSL errors, call ldapssl_err2string after you call any
+of the following SSL initialization functions:
+
+ldapssl_client_init
+
+ldapssl_clientauth_init
+
+ldapssl_advclientauth_init
+
+ldapssl_pkcs_initThe
+errors returned by these functions are usually related to certificate database
+corruption, missing certificates in a certificate database, client authentication
+failures, and other general SSL errors.
+
+
+See Also
+ldapssl_client_init, ldapssl_clientauth_init, ldapssl_advclientauth_init
+, ldapssl_pkcs_init, ldap_err2string
+
+ldapssl_init
+The ldapssl_init function initializes the LDAP
+library for SSL and installs the I/O routines for SSL.
+Syntax
+#include <ldap_ssl.h>
+ LDAP *ldapssl_init( const char *defhost, int defport, int defsecure );
+
+Parameters
+
ldapssl_init Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+defhost
+
+Connect to this LDAP server, if no other server is specified.
+
+
+
+
+defport
+
+Connect to this server port, if no other port is specified. To specify
+the default port 389, use LDAP_PORT as the value for this
+parameter.
+
+
+
+defsecure
+
+Determines whether or not to establish the default connection over SSL.
+Set this to a non-zero value to establish the default connection over SSL.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+If successful, returns a pointer to an LDAP
+ structure, which should be passed to subsequent calls to other LDAP
+API functions.
+If unsuccessful, returns -1.
+
+
+
+Description
+ldapssl_init allocates an LDAP
+ structure but does not open an initial connection. Before calling
+this function, call ldapssl_client_init to
+initialize your client for SSL.
+Calling this function is equivalent to calling ldap_init or prldap_init (IPv6)
+followed by ldapssl_install_routines and ldap_set_option to set the LDAP_OPT_SSL option
+to LDAP_OPT_ON.
+
+Example
+Example 21–57 connects
+your client to a secure LDAP server.
+Using ldapssl_init
+#include <ldap.h>
+#include <ldap_ssl.h>
+#include <stdio.h>
+...
+/* Initialize client, using mozilla’s certificate database */
+if ( ldapssl_client_init( "/u/mozilla/.netscape/
+ cert_file_name.db", 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 */
+...
+
+
+See Also
+ldap_init, prldap_init
+ (IPv6), ldapssl_client_init, ldapssl_install_routines
+
+ldapssl_install_routines
+The ldapssl_install_routines function installs
+the I/O routines that enable SSL over LDAP.
+Syntax
+#include <ldap_ssl.h>
+ int ldapssl_install_routines( LDAP *ld );
+
+Parameters
+
ldapssl_install_routines Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+
+
+Returns
+One of the following values:
+
+0 if successful.
+-1 if unsuccessful.
+
+
+Description
+You need to call ldapssl_install_routines in combination
+with ldap_init or prldap_init
+ (IPv6) and ldap_set_option. As an
+alternative, you can call ldapssl_init rather
+than these three functions.
+As is the case with the ldapssl_init function,
+you need to call ldapssl_client_init to initialize
+your client for SSL before calling ldapssl_install_routines.
+
+
+Example
+Example
+21–58 connects your client to a secure LDAP server.
+Using ldapssl_install_routines
+
+#include <ldap.h>
+#include <ldap_ssl.h>
+#include <stdio.h>
+...
+/* Initialize client, using mozilla’s certificate database */
+if ( ldapssl_client_init( "/u/mozilla/.netscape/
+ cert_file_name.db", NULL ) < 0) {
+ printf( "Failed to initialize SSL client...\n" );
+ return( 1 );
+}
+/* Get the handle to an LDAP connection. Use prldap_init() for IPv6. */
+if ( (ld = ldap_init( MY_HOST, 636 )) == NULL ) {
+ perror( "ldap_init" );
+ return( 1 );
+}
+
+/* Load SSL routines */
+if ( ldapssl_install_routines( ld ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldapssl_install_routines" );
+ return( 1 );
+}
+
+/* Set the option to use SSL with the default connection */
+if (ldap_set_option( ld, LDAP_OPT_SSL, LDAP_OPT_ON ) != LDAP_SUCCESS) {
+ ldap_perror( ld, "ldap_set_option" );
+ return( 1 );
+}
+...
+
+
+See Also
+ldap_init, prldap_init
+ (IPv6), ldapssl_init, ldapssl_client_init
+
+ldapssl_pkcs_init
+This function is deprecated and should not be used. It is included
+in ldap-deprecated.h for backward-compatibility.
+
+The ldap_pcks_init function provides thread-safe
+SSL initialization.
+Syntax
+int ldapssl_pkcs_init( const struct ldapssl_pkcs_fns *pfns);
+
+Description
+The ldap_pkcs_init structure sets up callbacks
+for the security library to obtain required runtime information. It should
+be used in place of ldapssl_client_init, ldapssl_clientauth_init, and ldapssl_advclientauth_init
+.
+The &DirectorySDKForC; uses the Public Key Cryptography Standard
+(PKCS) API implemented in Network Security Services (NSS) to provide SSL security
+support. Specifically, NSS implements the security API as defined in the PKCS#11
+standard.
+Because ldap_pkcs_init is based on the ldapssl_pkcs_fns
+ structure, you do not need to know all of the security parameters
+at initialization, unlike the other SSL initialization functions (ldapssl_*_init
+), which require all security parameters to be known at the time
+of initialization. Example 21–59
+ defines the ldapssl_pkcs_fns structure.
+ldapssl_pkcs_fns Structure
+Definition
+typedef int (LDAP_PKCS_GET_TOKEN_CALLBACK)
+ (void *context, char **tokenname);
+typedef int (LDAP_PKCS_GET_PIN_CALLBACK)
+ (void *context, const char *tokenname, char **tokenpin);
+typedef int (LDAP_PKCS_GET_CERTPATH_CALLBACK)
+ (void *context, char **certpath);
+typedef int (LDAP_PKCS_GET_KEYPATH_CALLBACK)(void *context,
+ char **keypath);
+typedef int (LDAP_PKCS_GET_MODPATH_CALLBACK)
+ (void *context, char **modulepath);
+typedef int (LDAP_PKCS_GET_CERTNAME_CALLBACK)
+ (void *context, char **certname);
+typedef int (LDAP_PKCS_GET_DONGLEFILENAME_CALLBACK)
+ (void *context, char **filename);
+
+#define PKCS_STRUCTURE_ID 1
+struct ldapssl_pkcs_fns {
+ int local_structure_id;
+ void *local_data;
+ LDAP_PKCS_GET_CERTPATH_CALLBACK *pkcs_getcertpath;
+ LDAP_PKCS_GET_CERTNAME_CALLBACK *pkcs_getcertname;
+ LDAP_PKCS_GET_KEYPATH_CALLBACK *pkcs_getkeypath;
+ LDAP_PKCS_GET_MODPATH_CALLBACK *pkcs_getmodpath;
+ LDAP_PKCS_GET_PIN_CALLBACK *pkcs_getpin;
+ LDAP_PKCS_GET_TOKEN_CALLBACK *pkcs_gettokenname;
+ LDAP_PKCS_GET_DONGLEFILENAME_CALLBACK *pkcs_getdonglefilename;
+};
+
+
+Parameters
+
ldapssl_pkcs_init Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+pfns
+
+Specifies the ldap_pkcs_fns structure for initialization.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+0 is successful.
+-1 if unsuccessful.
+n (a positive integer) denotes
+a Netscape Portable Runtime (NSPR) error as returned by the PR_GetError
+ NSPR function.
+
+
+See Also
+ldapssl_client_init, ldapssl_clientauth_init, ldapssl_advclientauth_init
+
+
+ldapssl_serverauth_init
+The ldapssl_serverauth_init function is a server-authentication
+only version of ldapssl_clientauth_init.
+Syntax
+#include <ldap_ssl.h>
+int ldapssl_serverauth_init(
+ const char *certdbpath, void *certdbhandle, const int sslstrength );
+
+Parameters
+Please see the description of the sslstrength value
+and note the potential problems that can be caused by passing in wrong host
+and port name values.
+
ldapssl_serverauth_init Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+certdbpath
+
+Specifies the path to the database containing certificates for your
+client. You can include the database filename in the path (for example, /usr/mozilla/cert_file_name.db).
+
+
+
+
+certdbhandle
+
+Pass a NULL value for this. (This parameter is not
+currently used.)
+
+
+
+sslstrength
+
+Specifies how the server certificate is evaluated. It takes one of the
+following:
+
+LDAPSSL_AUTH_WEAK indicates that you accept
+the server’s certificate without checking the for certificate authority
+(CA) that issued the certificate.
+LDAPSSL_AUTH_CERT indicates that you accept
+the server’s certificate only if you trust the CA that issued the certificate.
+
+LDAPSSL_AUTH_CNCHECK indicates that you
+accept the server’s certificate only if you trust the CA that issued
+the certificate and if the value of the cn attribute is
+the DNS hostname of the server. If this option is selected, please ensure
+that the defhost parameter passed to
+ldapssl_init consists of only one hostname and not a list of hosts.
+Furthermore, the port number must be passed via the defport parameter,
+and cannot be passed via a host: port option.
+
+
+
+
+
+
+
+
+Returns
+One of the following values:
+
+0 if successful.
+-1 if unsuccessful.
+
+
+Description
+ldapssl_serverauth_init is a server-authentication
+only version of ldapssl_clientauth_init.
+ This function allows the sslstrength parameter to be passed
+in.
+See Also
+ldap_init, prldap_init
+ (IPv6), ldapssl_init, ldapssl_install_routines, ldapssl_clientauth_init
+
+
+ldapssl_set_strength
+The ldapssl_set_strength sets the SSL strength
+for an existing SSL-enabled LDAP session handle.
+Syntax
+#include <ldap_ssl.h>
+int LDAP_CALL ldapssl_set_strength( LDAP *ld, int sslstrength );
+
+Parameters
+See the description of the sslstrength value
+and note the potential problems that can be caused by passing in wrong host
+and port name values.
+
ldapssl_set_strength Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server. If value is NULL,
+the default for the new LDAP session handles is set.
+
+
+
+sslstrength
+
+Specifies how the server certificate is evaluated. It takes one of the
+following:
+
+LDAPSSL_AUTH_WEAK indicates that you accept
+the server’s certificate without checking the for certificate authority
+(CA) that issued the certificate.
+LDAPSSL_AUTH_CERT indicates that you accept
+the server’s certificate only if you trust the CA that issued the certificate.
+
+LDAPSSL_AUTH_CNCHECK indicates that you
+accept the server’s certificate only if you trust the CA that issued
+the certificate and if the value of the cn attribute is
+the DNS hostname of the server. If this option is selected, please ensure
+that the defhost parameter passed to
+ldapssl_init consists of only one hostname and not a list of hosts.
+Furthermore, the port number must be passed via the defport parameter,
+and cannot be passed via a host: port option.
+
+
+
+
+
+
+
+
+
+ldapssl_tls_start_s
+The ldapssl_tls_start_s function starts an SSL
+handshake on a previously established non-secure connection.
+Syntax
+#include <ldap_ssl.h>
+ LDAP_API(int) LDAP_CALL ldapssl_tls_start_s( LDAP *ld, int defsecure,
+ char *certdbpath, char *keydbpath, char ***referralsp );
+
+Parameters
+
ldapssl_tls_start_s Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+defsecure
+
+Determines whether or not to establish the default connection over SSL.
+Set this to a non-zero value to establish the default connection over SSL.
+
+
+
+
+certdbpath
+
+Specifies the path to the database containing certificates for your
+client. You can include the database filename in the path (for example, /usr/mozilla/cert_file_name.db).
+
+
+
+
+keydbpath
+
+Specifies the path to the database containing the private key certified
+by your certificate. You can include the database filename in the path (for
+example, /usr/mozilla/key_file_name
+.db).
+
+
+
+referralsp
+
+Pointer to an array of strings representing the referrals found by an
+LDAP search operation and returned by the server (applicable only if the LDAP
+operation was a search operation). When done, you can free this by calling
+the ldap_value_free function.
+
+
+
+
+
+Description
+The ldapssl_tls_start_s function starts an SSL
+handshake on a previously established non-secure connection.
+
+ldap_str2charray
+
+C SDK functions
+ldap_str2charray
+
+ldap_str2charray
+
+This function is deprecated and should not be used. It is included in
+ ldap-deprecated.h for backward-compatibility.
+ldap_tmplattrs
+
+C SDK functions
+ldap_tmplattrs
+
+ldap_tmplattrs
+
+The ldap_tmplattrs function obtains a pointer to
+the correct ldap_disptmpl structure.
+Syntax
+#include <disptmpl.h>
+ char ** ldap_tmplattrs( struct ldap_disptmpl *tmpl, char **includeattrs,
+ int exclude, unsigned long syntaxmask );
+
+Parameters
+
ldap_tmplattrs Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+tmpl
+
+The name of the template to be retrieved.
+
+
+
+includeattrs
+
+A null terminated array of attributes that should always be included
+(it may be NULL if no extra attributes are required).
+
+
+
+
+exclude
+
+If 0, only attributes where the logical AND of the
+template item syntax id and the syntaxmask is non-zero
+are included. If non-zero, attributes where the logical AND of the template
+item syntax id and the syntaxmask is non-zero are excluded.
+
+
+
+
+syntaxmask
+
+When non-zero, it is used to restrict the attribute set returned.
+
+
+
+
+
+
+Returns
+
+A NULL terminated array that contains the
+names of attributes that need to be retrieved if the template, defined by
+tmpl , is to be used to display an entry.
+A NULL pointer on error.
+
+
+Description
+The attribute list should be freed using ldap_value_free
+ .
+See Also
+ldap_value_free
+
+ldap_tmplerr2string
+
+C SDK functions
+ldap_tmplerr2string
+
+ldap_tmplerr2string
+
+The ldap_templerr2string function returns a string
+representation of the error passed in the parameter.
+Syntax
+#include <disptmpl.h>
+ char * ldap_tmplerr2string( int err );
+
+Parameters
+
+
+
+ldap_ufn_search_c
+
+C SDK functions
+ldap_ufn_*
+
+ldap_ufn_*
+
+This function will be deprecated and should not be used. It is
+included in ldap-to-be-deprecated.h for backward-compatibility.
+
+ldap_ufn_search_ct
+This function will be deprecated and should not be used. It is
+included in ldap-to-be-deprecated.h for backward-compatibility.
+
+
+
+ldap_ufn_search_s
+This function will be deprecated and should not be used. It is
+included in ldap-to-be-deprecated.h for backward-compatibility.
+
+ldap_ufn_setfilter
+This function will be deprecated and should not be used. It is
+included in ldap-to-be-deprecated.h for backward-compatibility.
+
+
+
+ldap_ufn_setprefix
+This function will be deprecated and should not be used. It is
+included in ldap-to-be-deprecated.h for backward-compatibility.
+
+ldap_ufn_timeout
+This function will be deprecated and should not be used. It is
+included in ldap-to-be-deprecated.h for backward-compatibility.
+
+
+
+ldap_unbind
+
+C SDK functions
+ldap_unbind
+
+ldap_unbind
+
+The ldap_unbind function unbinds from the directory,
+terminates the current association, and frees the resources contained in the
+ LDAP structure.
+Syntax
+#include <ldap.h>
+int ldap_unbind( LDAP *ld );
+
+Parameters
+
ldap_unbind Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+
+
+Returns
+For a list of possible results for an LDAP unbind operation, see ldap_unbind_s.
+Description
+The ldap_unbind function unbinds from the directory,
+terminates the current association, and frees the resources contained in the
+ LDAP structure. The three unbind functions
+(ldap_unbind , ldap_unbind_s
+, and ldap_unbind_ext) all work
+synchronously in the sense that they send an unbind request to the server,
+close all open connections associated with the LDAP session handle, and dispose
+of all resources associated with the session handle before returning.
+There is no server response to an LDAP unbind operation. All three
+of the unbind functions return LDAP_SUCCESS (or another
+LDAP error code if the request cannot be sent to the LDAP server). After a
+call to one of the unbind functions, the session handle ld is
+invalid and it is illegal to make any further calls using it.
+
+Example
+Example 21–60 closes
+the current connection with the LDAP server.
+Using ldap_unbind
+#include <ldap.h>
+...
+LDAP *ld;
+...
+/* After completing your LDAP operations with the server, close the
+ connection. */
+if ( ldap_unbind( ld ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "Error while unbinding from the directory" );
+ return( 1 );
+}
+...
+
+
+See Also
+ldap_unbind_s, ldap_unbind_ext
+
+
+ldap_unbind_s
+
+C SDK functions
+ldap_unbind_s
+
+ldap_unbind_s
+
+The ldap_unbind_s function unbinds from the directory,
+terminates the current association, and frees the resources contained in the LDAP structure.
+Syntax
+#include <ldap.h>
+ int ldap_unbind_s( LDAP *ld );
+
+Parameters
+
ldap_unbind_s Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+
+
+Description
+The ldap_unbind_s function unbinds from the directory,
+terminates the current association, and frees the resources contained in the LDAP structure. The three unbind functions ( ldap_unbind, ldap_unbind_s,
+and ldap_unbind_ext) all work synchronously
+in the sense that they send an unbind request to the server, close all open
+connections associated with the LDAP session handle, and dispose of all resources
+associated with the session handle before returning.
+There is no server response to an LDAP unbind operation. All three
+of the unbind functions return LDAP_SUCCESS (or another
+LDAP error code if the request cannot be sent to the LDAP server). After a
+call to one of the unbind functions, the session handle ld is
+invalid and it is illegal to make any further calls using it.
+
+Example
+Example 21–61 closes
+the current connection with the LDAP server.
+Using ldap_unbind_s
+#include <ldap.h>
+...
+LDAP *ld;
+...
+/* After completing your LDAP operations with the server, close the
+ connection. */
+if ( ldap_unbind_s( ld ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "Error while unbinding from the directory" );
+ return( 1 );
+}
+...
+
+
+See Also
+ldap_unbind, ldap_unbind_ext
+
+
+ldap_unbind_ext
+
+C SDK functions
+ldap_unbind_ext
+
+ldap_unbind_ext
+
+The ldap_unbind_ext function unbinds from the directory,
+terminates the current association, and frees the resources contained in the LDAP structure.
+Syntax
+#include <ldap.h>
+ int ldap_unbind_ext( LDAP *ld, LDAPControl **serverctrls,
+ LDAPControl **clientctrls );
+
+Parameters
+
ldap_unbind_ext Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+serverctrls
+
+List of LDAP server controls.
+
+
+
+clientctrls
+
+List of client controls.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+
+Description
+The ldap_unbind_ext function unbinds from the directory,
+terminates the current association, and frees the resources contained in the LDAP structure. The three unbind functions (ldap_unbind, ldap_unbind_s,
+and ldap_unbind_ext) all work synchronously
+in the sense that they send an unbind request to the server, close all open
+connections associated with the LDAP session handle, and dispose of all resources
+associated with the session handle before returning.
+Unlike the other two unbind functions, ldap_unbind_ext allows
+you to explicitly include both server and client controls in your unbind request.
+However, since there is no server response to an unbind request, there is
+no way to receive a response from a server control that is included.
+
+
+See Also
+ldap_unbind, ldap_unbind_s
+
+
+ldap_url_parse
+
+C SDK functions
+ldap_url_parse
+
+ldap_url_parse
+
+The ldap_url_parse function parses an LDAP URL
+into its components.
+Syntax
+#include <ldap.h>
+ int ldap_url_parse( const char *url, LDAPURLDesc **ludpp );
+
+Parameters
+
ldap_url_parse Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+url
+
+The URL that you want to check.
+
+
+
+ludpp
+
+Pointer to a structure containing the components of the URL.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_URL_ERR_NOTLDAP if the URL does not
+begin with the ldap:// or ldaps:// prefix.
+
+LDAP_URL_ERR_NODN if the URL missing trailing
+slash after host or port.
+LDAP_URL_ERR_BADSCOPE if the scope within
+the URL is invalid.
+LDAP_URL_ERR_MEM if not enough free memory
+is available for this operation.
+LDAP_URL_ERR_PARAM if an invalid argument
+was passed to the function.
+
+
+Example
+Example 21–62 parses
+an LDAP URL and prints out each component of it.
+Using ldap_url_parse
+#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 );
+...
+
+
+See Also
+ldap_free_urldesc
+
+ldap_url_parse_no_defaults
+
+C SDK functions
+ldap_url_parse_no_defaults
+
+ldap_url_parse_no_defaults
+
+The ldap_url_parse_no_defaults function parses
+an LDAP URL into its components.
+Syntax
+#include <ldap.h>
+ int ldap_url_parse_no_defaults( const char *url, LDAPURLDesc **ludpp,
+ int dn_required );
+
+Parameters
+
ldap_url_parse_no_defaults Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+url
+
+The URL that you want to check.
+
+
+
+ludpp
+
+Pointer to a structure containing the components of the URL.
+
+
+
+
+dn_required
+
+Specifies if a DN must be present in the URL. Set to 0,
+the DN is not required. Set to 1, the function will return
+an error LDAP_URL_ERR_NODN if no DN is present.
+
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_URL_ERR_NODN if a required DN is not
+present.
+LDAP_URL_ERR_NOTLDAP if the URL does not
+begin with the ldap:// or ldaps:// prefix.
+LDAP_URL_ERR_NODN if the URL missing trailing
+slash after host or port.
+LDAP_URL_ERR_BADSCOPE if the scope within
+the URL is invalid.
+LDAP_URL_ERR_MEM if not enough free memory
+is available for this operation.
+LDAP_URL_ERR_PARAM if an invalid argument
+was passed to the function.
+
+
+Description
+The ldap_url_parse_no_defaults function does not
+set any default value in the fields that would be absent from the URL (for
+example, the port number).
+
+ldap_url_search
+
+C SDK functions
+ldap_url_search
+
+ldap_url_search
+
+The ldap_url_search function searches the directory
+asynchronously for matching entries, based on the contents of the URL.
+Syntax
+#include <ldap.h>
+ int ldap_url_search( LDAP *ld, const char *url, int attrsonly );
+
+Parameters
+
ldap_url_search Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+url
+
+LDAP URL specifying a search of the directory.
+
+
+
+attrsonly
+
+Specifies whether or not attribute values are returned along with the
+attribute types. This parameter can have the following values:
+
+0 specifies that both attribute types and
+attribute values are returned.
+1 specifies that only attribute types are
+returned.
+
+
+
+
+
+
+
+Returns
+Returns the message ID of the ldap_url_search operation.
+To check the result of this operation, call ldap_result
+and ldap_result2error.
+Description
+ldap_url_search searches the directory for matching
+entries, based on the contents of the URL. ldap_url_search is
+an asynchronous function; it does not directly return results. If you want
+the results to be returned directly by the function, call the synchronous
+function ldap_url_search_s.
+Example
+Example 21–63 returns
+the message ID.
+Using ldap_url_search
+
+#include "examples.h"
+
+static void do_other_work();
+unsigned long global_counter = 0;
+
+int
+main( int argc, char **argv )
+{
+ char *my_url = "ldap://ldap.example.com/dc=example,dc=com?
+ cn,mail,telephoneNumber?sub?(sn=Jensen)";
+ LDAP *ld;
+ LDAPMessage *result, *e;
+ BerElement *ber;
+ char *a, *dn;
+ char **vals;
+ int i, rc, finished, msgid;
+ int num_entries = 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( MY_HOST, MY_PORT )) == NULL ) {
+ perror( "ldap_init" );
+ return( 1 );
+}
+/* authenticate to the directory as nobody */
+if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_simple_bind_s" );
+ return( 1 );
+}
+/* search for all entries with surname of Jensen */
+if (( msgid = ldap_url_search( ld, my_url, 0 )) == -1 ) {
+ ldap_perror( ld, "ldap_url_search" );
+ return( 1 );
+}
+
+/* Loop, polling for results until finished */
+finished = 0;
+while ( !finished ) {
+ /*
+ * Poll for results. We call ldap_result with the "all" parameter
+ * set to zero. This causes ldap_result() to return exactly one
+ * entry if at least one entry is available. This allows us to
+ * display the entries as they are received.
+ */
+ result = NULL;
+ rc = ldap_result( ld, msgid, 0, &zerotime, &result );
+ switch ( rc ) {
+ case -1:
+ /* some error occurred */
+ ldap_perror( ld, "ldap_result" );
+ return( 1 );
+ case 0:
+ /* Timeout was exceeded. No entries are ready for retrieval. */
+ if ( result != NULL ) {
+ ldap_msgfree( result );
+ }
+ break;
+ default:
+ /*
+ * Either an entry is ready for retrieval, or all entries have
+ * been retrieved.
+ */
+ if (( e = ldap_first_entry( ld, result )) == NULL ) {
+ /* All done */
+ finished = 1;
+ if ( result != NULL ) {
+ ldap_msgfree( result );
+ }
+ continue;
+ }
+ /* for each entry print out name + all attrs and values */
+ num_entries++;
+ if (( dn = ldap_get_dn( ld, e )) != NULL ) {
+ printf( "dn: %s\n", dn );
+ ldap_memfree( dn );
+ }
+ for ( a = ldap_first_attribute( ld, e, &ber );
+ a != NULL; a = ldap_next_attribute( ld, e, ber ) ) {
+ 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 ) {
+ ldap_ber_free( ber, 0 );
+ }
+ printf( "\n" );
+ ldap_msgfree( result );
+ }
+ /* Do other work here while you are waiting... */
+ do_other_work();
+}
+
+/* All done. Print a summary. */
+printf( "%d entries retrieved. I counted to %ld "
+ "while I was waiting.\n", num_entries,
+ global_counter );
+ldap_unbind( ld );
+return( 0 );
+}
+
+/*
+ * Perform other work while polling for results. */
+static void
+do_other_work()
+{
+ global_counter++;
+}
+
+
+See Also
+ldap_url_search_s, ldap_result, ldap_result2error
+
+
+ldap_url_search_s
+
+C SDK functions
+ldap_url_search_s
+
+ldap_url_search_s
+
+The ldap_url_search_s function searches the directory
+synchronously for matching entries, based on the contents of the URL.
+Syntax
+#include <ldap.h>
+ int ldap_url_search_s( LDAP *ld, const char *url,
+ int attrsonly, LDAPMessage **res );
+
+Parameters
+
ldap_url_search_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+url
+
+LDAP URL specifying a search of the directory.
+
+
+
+attrsonly
+
+Specifies whether or not attribute values are returned along with the
+attribute types. This parameter can have the following values:
+
+0 specifies that both attribute types and
+attribute values are returned.
+1 specifies that only attribute types are
+returned.
+
+
+
+
+
+res
+
+Results of the search (when the call is completed).
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+If unsuccessful, returns the LDAP error code for the operation.
+
+
+
+Description
+The ldap_url_search_s function searches the directory
+for matching entries, based on the contents of the URL. ldap_url_search_s
+ is a synchronous function, which directly returns the results
+of the operation. If you want to perform other operations while waiting for
+the results of this operation, call the asynchronous function ldap_url_search.
+Example
+Example 21–64
+processes a search request from an LDAP URL.
+Using ldap_url_search_s
+#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 );
+}
+...
+
+
+See Also
+ldap_search, ldap_search_st
+
+
+ldap_url_search_st
+
+C SDK functions
+ldap_url_search_st
+
+ldap_url_search_st
+
+The ldap_url_search_st function searches the directory,
+synchronously within a specified time limit, for matching entries, based on
+the contents of the URL.
+Syntax
+#include <ldap.h>
+ int ldap_url_search_st( LDAP *ld, const char *url, int attrsonly,
+ struct timeval *timeout, LDAPMessage **res );
+
+Parameters
+
ldap_url_search_st Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+url
+
+LDAP URL specifying a search of the directory.
+
+
+
+attrsonly
+
+Specifies whether or not attribute values are returned along with the
+attribute types. This parameter can have the following values:
+
+0 specifies that both attribute types and
+attribute values are returned.
+1 specifies that only attribute types are
+returned.
+
+
+
+
+
+timeout
+
+Maximum time to wait for the results of the search.
+
+
+
+res
+
+Results of the search (when the call is completed).
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+LDAP_LOCAL_ERROR if an error occurred
+when receiving the results from the server.
+LDAP_DECODING_ERROR if an error occurred
+when decoding the BER-encoded results from the server.
+LDAP_FILTER_ERROR if an error occurred
+when parsing and BER-encoding the search filter specified by the filter argument.
+
+LDAP_TIMEOUT if the search exceeded
+the time specified by the timeoutp argument.
+
+LDAP_NOT_SUPPORTED if controls are
+included in your request (for example, as a session preference) and your LDAP
+client does not specify that it is using the LDAP v3. Make sure that you set
+the version of your LDAP client to version 3 before calling this function.
+
+
+&cnDirectoryServer; and other LDAP server products may send result
+codes in addition to those described. For example, the server may have loaded
+a plug-in that returns custom result codes. Check your LDAP server documentation
+for other result codes.
+
+Description
+The ldap_url_search_st function searches the directory
+for matching entries, based on the contents of the URL. This function works
+like ldap_url_search_s and lets you specify
+a time out period for the search.
+See Also
+ldap_search, ldap_search_s
+
+
+ldap_utf8characters
+
+C SDK functions
+ldap_utf8characters
+
+ldap_utf8characters
+
+The ldap_utf8characters function accepts a Unicode
+string and returns the number of characters.
+Syntax
+#include <ldap.h>
+ size_t ldap_utf8characters( const char* );
+
+Parameters
+
ldap_utf8characters Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+char
+
+Pointer to a UTF-8 string.
+
+
+
+
+
+Returns
+Returns the number of UTF-8 characters in the 0 terminated
+array.
+
+ldap_utf8copy
+
+C SDK functions
+ldap_utf8copy
+
+ldap_utf8copy
+
+The ldap_utf8copy function accepts a Unicode string
+and copies the characters to a destination.
+Syntax
+#include <ldap.h>
+ int ldap_utf8copy( char* dst, const char* src );
+
+Parameters
+
ldap_utf8copy Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+dst
+
+Pointer to a destination for the copied characters.
+
+
+
+src
+
+Pointer to a UTF-8 string to copy.
+
+
+
+
+
+Description
+ldap_utf8copy copies a character from src to
+ dst. This function handles any valid UTF-8 character (including
+ \0 and ASCII).
+Returns
+The number of characters copied.
+
+ldap_utf8getcc
+
+C SDK functions
+ldap_utf8getcc
+
+ldap_utf8getcc
+
+The ldap_utf8getcc function gets one UCS-4 character
+and moves the pointer to the next character.
+Syntax
+#include <ldap.h>
+ unsigned long ldap_utf8getcc( const char** src );
+
+Parameters
+
ldap_utf8getcc Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+src
+
+Pointer to a UCS-4 character.
+
+
+
+
+
+
+ldap_utf8isalnum
+
+C SDK functions
+ldap_utf8isalnum
+
+ldap_utf8isalnum
+
+The ldap_utf8isalnum function determines whether
+the character is an alphanumeric one.
+Syntax
+#include <ldap.h>
+ int ldap_utf8isalnum( char* s );
+
+Parameters
+
ldap_utf8isalnum Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+s
+
+Pointer to a UTF-8 character.
+
+
+
+
+
+
+ldap_utf8isalpha
+
+C SDK functions
+ldap_utf8isalpha
+
+ldap_utf8isalpha
+
+The ldap_utf8isalpha function determines whether
+the character is a letter.
+Syntax
+#include <ldap.h>
+ int ldap_utf8isalpha( char* s );
+
+Parameters
+
ldap_utf8isalpha Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+s
+
+Pointer to a UTF-8 character.
+
+
+
+
+
+
+ldap_utf8isdigit
+
+C SDK functions
+ldap_utf8isdigit
+
+ldap_utf8isdigit
+
+The ldap_utf8isdigit function determines whether
+the character is a number.
+Syntax
+#include <ldap.h>
+ int ldap_utf8isdigit( char* s );
+
+Parameters
+
ldap_utf8isdigit Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+s
+
+Pointer to a UTF-8 character.
+
+
+
+
+
+
+ldap_utf8isspace
+
+C SDK functions
+ldap_utf8isspace
+
+ldap_utf8isspace
+
+The ldap_utf8isspace function determines whether
+the character is a space, tab, newline, return or formfeed.
+Syntax
+#include <ldap.h>
+ int ldap_utf8isspace( char* s );
+
+Parameters
+
ldap_utf8isspace Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+s
+
+Pointer to a UTF-8 character.
+
+
+
+
+
+
+ldap_utf8len
+
+C SDK functions
+ldap_utf8len
+
+ldap_utf8len
+
+The ldap_utf8len function accepts a Unicode string
+and returns the number of bytes it contains.
+Syntax
+#include <ldap.h>
+ int ldap_utf8len( const char* );
+
+Parameters
+
ldap_utf8len Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+char
+
+Pointer to a UTF-8 string.
+
+
+
+
+
+
+ldap_utf8next
+
+C SDK functions
+ldap_utf8next
+
+ldap_utf8next
+
+The ldap_utf8next function accepts a character
+and returns a pointer to the character immediately following it.
+Syntax
+#include <ldap.h>
+ char* ldap_utf8next( char* );
+
+Parameters
+
ldap_utf8next Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+char
+
+Pointer to a UTF-8 character.
+
+
+
+
+
+
+ldap_utf8prev
+
+C SDK functions
+ldap_utf8prev
+
+ldap_utf8prev
+
+The ldap_utf8prev function accepts a character
+and returns a pointer to the previous character.
+Syntax
+#include <ldap.h>
+ char* ldap_utf8prev( char* );
+
+Parameters
+
ldap_utf8prev Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+char
+
+Pointer to a UTF-8 character.
+
+
+
+
+
+
+ldap_utf8strtok_r
+
+C SDK functions
+ldap_utf8strtok_r
+
+ldap_utf8strtok_r
+
+The ldap_utf8strtok_r function gets the next token
+from a string.
+Syntax
+#include <ldap.h>
+ char* ldap_utf8strtok_r( char* src, const char* brk, char** next);
+
+Parameters
+
ldap_utf8strtok_r Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+src
+
+Pointer to a UTF-8 string from which to extract token.
+
+
+
+brk
+
+Points to a NULL terminated set of delimiter characters.
+
+
+
+
+next
+
+Pointer to the next token.
+
+
+
+
+
+Returns
+Returns a pointer to the next token. If there are no remaining tokens,
+returns a NULL pointer.
+
+ldap_whoami
+
+C SDK functions
+ldap_whoami
+
+ldap_whoami
+
+The ldap_whoami function sends an asynchronous
+Who am I? extended operation request to determine the authorization identity
+associated with a connection.
+Syntax
+LDAP_API(int) LDAP_CALL ldap_whoami( LDAP *ld, LDAPControl **serverctrls,
+ LDAPControl **clientctrls, int *msgidp );
+
+Parameters
+
ldap_whoami Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+msgidp
+
+Pointer to the message ID for this asynchronous call, for use with ldap_parse_whoami_result, or
+to retrieve the result for use with ldap_parse_whoami
+.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+
+
+
+ldap_whoami_s
+
+C SDK functions
+ldap_whoami_s
+
+ldap_whoami_s
+
+The ldap_whoami_s function sends a synchronous
+Who am I? extended operation request to determine the authorization identity
+associated with a connection.
+Syntax
+LDAP_API(int) LDAP_CALL ldap_whoami_s( LDAP *ld, LDAPControl **serverctrls,
+ LDAPControl **clientctrls, char **authzid );
+
+Parameters
+
ldap_whoami_s Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+Pointer to an LDAP structure containing
+information about the connection to the LDAP server.
+
+
+
+serverctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP server controls that apply to this operation. If you do
+not want to pass any server controls, specify NULL for
+this argument.
+
+
+
+clientctrls
+
+Pointer to an array of LDAPControl structures
+representing LDAP client controls that apply to this operation. If you do
+not want to pass any client controls, specify NULL for
+this argument.
+
+
+
+authzid
+
+Pointer to the string to hold the authorization identity retrieved from
+the server.
+
+
+
+
+
+Returns
+One of the following values:
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR if any of the arguments
+are invalid.
+LDAP_ENCODING_ERROR if an error occurred
+when BER-encoding the request.
+LDAP_SERVER_DOWN if the LDAP server
+did not receive the request or if the connection to the server was lost.
+
+LDAP_NO_MEMORY if memory cannot be
+allocated.
+
+
+
+ldap_vals2html
+
+C SDK functions
+ldap_vals2html
+
+ldap_vals2html
+
+The ldap_vals2html function writes the HTML representation
+of a set of values.
+Syntax
+#include <disptmpl.h>
+ int ldap_vals2html( LDAP *ld, char *buf, char **vals, char *label,
+ int labelwidth, unsigned long syntaxid, writeptype writeproc,
+ void *writeparm, char *eol, int rdncount, char *urlprefix );
+
+Parameters
+
ldap_vals2html Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+The LDAP pointer obtained by a previous call to ldap_open
+ .
+
+
+
+buf
+
+
+
+
+vals
+
+A NULL terminated list of values, usually obtained by a call to ldap_get_values.
+
+
+
+label
+
+A string (usually a friendly form of an LDAP attribute name) shown next
+to the values.
+
+
+
+labelwidth
+
+Specifies the label margin (the number of blank spaces displayed to
+the left of the values). If zero is passed, a default label width is used.
+
+
+
+
+syntaxid
+
+Display template attribute syntax identifier for a list of predefined
+LDAP_SYN_... values.
+
+
+
+writeproc
+
+writeproc function should be declared as:
+int writeproc( writeparm, p, len )
+void *writeparm;
+char *p;
+int len;
+where p is a pointer to text to be written and
+len is the length of the text. p is guaranteed
+to be zero terminated.
+
+
+
+writeparm
+
+A pointer to a structure that will be passed as the first parameter
+of the writeproc procedure. Typically, this is used to
+pass the file descriptor of the file to write to.
+
+
+
+eol
+
+Lines of text are terminated with this string.
+
+
+
+rdncount
+
+Limits the number of components that are displayed for DN attributes.
+
+
+
+
+urlprefix
+
+Starting text to use when constructing an LDAP URL. The default
+is the string ldap://
+
+
+
+
+
+Returns
+
+LDAP_SUCCESS if successful.
+
+An LDAP error code on error.
+
+
+Description
+ldap_vals2html produces HTML output of a single
+set of LDAP attribute values.
+See Also
+ldap_vals2text
+
+ldap_vals2text
+
+C SDK functions
+ldap_vals2text
+
+ldap_vals2text
+
+The ldap_vals2text function writes the text representation
+of an LDAP entry.
+Syntax
+#include <disptmpl.h>
+ int ldap_vals2text( LDAP *ld, char *buf, char **vals, char *label,
+ int labelwidth, unsigned long syntaxid, writeptype writeproc,
+ void *writeparm, char *eol, int rdncount );
+
+Parameters
+
ldap_vals2text Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+The LDAP pointer obtained by a previous call to ldap_open
+ .
+
+
+
+buf
+
+
+
+
+vals
+
+A NULL terminated list of values, usually obtained
+by a call to ldap_get_values.
+
+
+
+label
+
+A string (usually a friendly form of an LDAP attribute name) shown next
+to the values.
+
+
+
+labelwidth
+
+Specifies the label margin (the number of blank spaces displayed to
+the left of the values). If zero is passed, a default label width is used.
+
+
+
+
+syntaxid
+
+Display template attribute syntax identifier for a list of predefined
+LDAP_SYN_... values.
+
+
+
+writeproc
+
+writeproc function should be declared as:
+int writeproc( writeparm, p, len )
+void *writeparm;
+char *p;
+int len;
+where p is a pointer to text to be written and
+len is the length of the text. p is guaranteed
+to be zero terminated.
+
+
+
+writeparm
+
+A pointer to a structure that will be passed as the first parameter
+of the writeproc procedure. Typically, this is used to
+pass the file descriptor of the file to write to.
+
+
+
+eol
+
+Lines of text are terminated with this string.
+
+
+
+rdncount
+
+Limits the number of components that are displayed for DN attributes.
+
+
+
+
+
+
+Returns
+
+LDAP_SUCCESS if successful.
+
+An LDAP error code on error.
+
+
+Description
+ldap_vals2text produces a text representation of
+a single set of LDAP attribute values.
+See Also
+ldap_vals2html
+
+ldap_value_free
+
+C SDK functions
+ldap_value_free
+
+ldap_value_free
+
+The ldap_value_free function frees an array of
+values from memory.
+Syntax
+#include <ldap.h>
+ void ldap_value_free( char **values );
+
+Parameters
+
+
+Description
+Use the ldap_value_free function instead
+of this function if the values are string values.
+Example
+See the example under ldap_get_values_len.
+
+See Also
+ldap_get_values,
+ldap_get_values_len
+
+ldap_version
+
+C SDK functions
+ldap_version
+
+ldap_version
+
+This function is deprecated and should not be used. It is included
+in ldap-deprecated.h for backward-compatibility. Please
+use ldap_get_option with LDAP_OPT_API_INFO
+ and an LDAPAPIInfo structure.
+The ldap_version function gets version information
+about the &DirectorySDKForC; libraries.
+Syntax
+#include <ldap.h>
+int ldap_version( LDAPVersion *ver );
+
+Parameters
+
ldap_version Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ver
+
+LDAPVersion structure returning version
+information. If you only want the SDK version, you can pass NULL for
+this parameter.
+
+
+
+
+
+Returns
+The version number of the &DirectorySDKForC;, multiplied by 100.
+For example, for version 1.0, the function returns 100.
+See Also
+ldap_get_option
+
+ldap_x_calloc
+
+C SDK functions
+ldap_x_*
+
+ldap_x_*
+
+The ldap_x_calloc function allocates space for
+an array of elements.
+Syntax
+#include <ldap-extension.h>
+void *ldap_x_calloc( size_t nelem, size_t elsize );
+
+Parameters
+
ldap_x_calloc Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+nelem
+
+Number of elements for which memory is to be allocated.
+
+
+
+elsize
+
+Size of each element.
+
+
+
+
+
+Returns
+
+If successful, returns a pointer to the space.
+If there is no available memory, returns a NULL pointer.
+
+
+
+See Also
+ldap_x_free, ldap_x_malloc
+ , ldap_x_realloc
+
+ldap_x_free
+The ldap_x_free function frees allocated memory.
+Syntax
+#include <ldap-extension.h>
+void ldap_x_free( void *ptr );
+
+Parameters
+
ldap_x_free Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ptr
+
+Pointer to the block of memory to be freed.
+
+
+
+
+
+See Also
+ldap_x_calloc, ldap_x_malloc
+, ldap_x_realloc
+
+ldap_x_hostlist_first
+The ldap_x_hostlist_first function returns the
+first host and port defined in a host list file.
+Syntax
+#include <ldap-extension.h>
+ int ldap_x_hostlist_first( char *hostlist, int defport, char **hostp,
+ int *portp, struct ldap_x_hostlist_status **statusp );
+
+Description
+ldap_x_hostlist_first parses a space-separated
+host list (useful for implementing an extended I/O CONNECT callback function)
+and returns the first host and port defined.
+Returns
+
+LDAP_SUCCESS if successful.
+
+If unsuccessful returns a valid LDAP API error code.
+
+
+A NULL or zero-length hostlist causes
+the host 127.0.0.1 to be returned.
+
+See Also
+ldap_x_hostlist_status, LDAP_X_EXTIOF_CONNECT_CALLBACK,
+
+ldap_x_hostlist_next
+The ldap_x_hostlist_next function returns the host
+and port defined in a host list file following the previous host and port
+returned.
+Syntax
+#include <ldap-extension.h>
+ int ldap_x_hostlist_next( char **hostp, int *portp,
+ struct ldap_x_hostlist_status **statusp );
+
+Description
+This utility parses a space-separated host list (useful for implementing
+an extended I/O CONNECT callback function) and returns the host and port defined
+following the previous host and port returned.
+Returns
+
+LDAP_SUCCESS if successful. If no more
+hosts are available, LDAP_SUCCESS is returned but hostp
+ is set to NULL.
+If unsuccessful returns a valid LDAP API error code.
+
+
+A NULL or zero-length hostlist causes
+the host 127.0.0.1 to be returned.
+
+See Also
+ldap_x_hostlist_status, LDAP_X_EXTIOF_CONNECT_CALLBACK,
+
+ldap_x_hostlist_status
+See Also
+ldap_x_hostlist_first, ldap_x_hostlist_next, LDAP_X_EXTIOF_CONNECT_CALLBACK
+
+
+ldap_x_hostlist_statusfree
+See Also
+ldap_x_hostlist_first, ldap_x_hostlist_next, LDAP_X_EXTIOF_CONNECT_CALLBACK
+
+
+ldap_x_malloc
+The ldap_x_malloc function allocates space for
+an object.
+Syntax
+#include <ldap-extension.h>
+void *ldap_x_malloc( size_t size );
+
+Parameters
+
ldap_x_malloc Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+size
+
+Specifies the size for the allocated block of memory.
+
+
+
+
+
+See Also
+ldap_x_free, ldap_x_calloc
+ , ldap_x_realloc
+
+ldap_x_realloc
+The ldap_x_realloc function changes the size of
+a block of memory.
+Syntax
+#include <ldap-extension.h>
+void *ldap_x_realloc( void *ptr, size_t size );
+
+Parameters
+
ldap_x_realloc Function
+Parameter
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ptr
+
+Pointer to a block of memory.
+
+
+
+size
+
+Specifies the new size of the block.
+
+
+
+
prldap_get_default_socket_info Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+fd
+
+The session handle returned from prldap_init.
+
+
+
+
+soip
+
+Pointer to a structure containing socket specific information.
+
+
+
+
+
+
+Returns
+
+LDAP_SUCCESS if successful.
+
+An LDAP API error code if an error occurs.
+LDAP_PARAM_ERROR is returned if ld
+ is NULL.
+
+
+See Also
+prldap_set_default_socket_info
+
+
+prldap_get_session_info
+The prldap_get_session_info function retrieves
+application-specific data.
+Syntax
+#include <ldappr.h>
+ int prldap_get_session_info( LDAP *ld, void *sessionarg,
+ PRLDAPSessionInfo *seip );
+
+Parameters
+
prldap_get_session_info Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+The session handle returned from prldap_init.
+If NULL, the functions are installed as the default functions
+for all new LDAP handles.
+
+
+
+seip
+
+Pointer to a structure with session information data.
+
+
+
+
+
+Returns
+
+LDAP_SUCCESS if successful.
+
+An LDAP API error code if an error occurs.
+
+
+Description
+The prldap_get_session_option function retrieves
+an option for an LDAP session handle or a session argument that is passed
+to the CONNECT , POLL, NEWHANDLE,
+or DISPOSEHANDLE extended I/O callbacks.
+See Also
+prldap_set_session_info
+
+prldap_get_session_option
+The prldap_get_session_option function retrieves
+an option specific to the prldap layer.
+Syntax
+#include <ldappr.h>
+ int prldap_get_session_option( LDAP *ld, void *sessionarg,
+ int option, ... );
+
+Returns
+
+LDAP_SUCCESS if successful.
+
+An LDAP API error code if an error occurs.
+
+
+Description
+The prldap_get_session_option function retrieves
+an option for an LDAP session handle or a session argument that is passed
+to the CONNECT , POLL, NEWHANDLE,
+or DISPOSEHANDLE extended I/O callbacks.
+See Also
+prldap_set_session_option
+
+prldap_get_socket_info
+The prldap_get_socket_info function retrieves socket-specific
+information based on parameters passed to the extended I/O callback functions.
+Syntax
+#include <ldappr.h>
+ int prldap_get_socket_info( int fd, void *socketarg,
+ PRLDAPSocketInfo *soip );
+
+Parameters
+
prldap_get_socket_info Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+fd
+
+The session handle returned from prldap_init.
+
+
+
+
+soip
+
+Pointer to a structure containing socket information data.
+
+
+
+
+
+Returns
+
+LDAP_SUCCESS if successful.
+
+An LDAP API error code if an error occurs.
+
+
+See Also
+prldap_set_socket_info
+
+prldap_init
+The prldap_init function creates a new session
+handle with Netscape Portable Runtime (NSPR) I/O, threading, support for IPv6,
+and DNS functions installed.
+Syntax
+#include <ldappr.h>
+ LDAP * prldap_init( const char *defhost, int defport, int shared );
+
+Parameters
+
prldap_init Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+defhost
+
+Space-delimited list of one or more host names (or IP address in dotted
+notation, such as 192.168.0.99) of the LDAP servers that
+you want the LDAP client to connect to. The names can be in hostname
+: portnumber format (in which case,
+portnumber overrides the port number specified by the defport
+ argument.
+
+
+
+defport
+
+Default port number of the LDAP server. To specify the standard LDAP
+port (port 389), use LDAP_PORT as the value for this parameter.
+
+
+
+
+shared
+
+Pass a non-zero value if you plan to use this LDAP handle for more than
+one thread.
+
+
+
+
+
+Returns
+
+Pointer to LDAP session handle if successful.
+NULL if an error occurs.
+
+
+Description
+To be able to use LDAP over Internet Protocol, version 6, IPv6,
+this function should be used rather than ldap_init.
+
+See Also
+prldap_install_routines
+
+prldap_install_routines
+The prldap_install_routines function installs Netscape
+Portable Runtime (NSPR) I/O, threading, and DNS functions so they can be used
+by the LDAP session handle.
+Syntax
+#include <ldappr.h>
+ int prldap_install_routines( LDAP *ld, int shared );
+
+Parameters
+
prldap_install_routines Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+The session handle returned from prldap_init.
+If NULL, the functions are installed as the default functions
+for all new LDAP handles.
+
+
+
+shared
+
+Pass a non-zero value if you plan to use this LDAP handle for more than
+one thread.
+
+
+
+
+
+Returns
+
+LDAP_SUCCESS if successful.
+
+An LDAP API error code if an error occurs.
+
+
+See Also
+prldap_init
+
+prldap_set_default_socket_info
+The prldap_set_default_socket_info function sets
+default socket information.
+Syntax
+#include <ldappr.h>
+ int prldap_set_default_socket_info( LDAP *ld, PRLDAPSocketInfo *soip );
+
+Parameters
+
prldap_set_default_socket_info Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+fd
+
+The session handle returned from prldap_init.
+
+
+
+
+soip
+
+Pointer to a structure containing socket specific information.
+
+
+
+
+
+
+Returns
+
+LDAP_SUCCESS if successful.
+
+LDAP_PARAM_ERROR is returned if ld
+ is NULL.
+An LDAP API error code if an error occurs.
+
+
+See Also
+prldap_get_socket_info
+
+prldap_set_session_info
+The prldap_set_session_info function sets application-specific
+data.
+Syntax
+#include <ldappr.h>
+ int prldap_set_session_info( LDAP *ld, void *sessionarg,
+ PRLDAPSessionInfo *seip );
+
+Parameters
+
prldap_set_session_info Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+ld
+
+The session handle returned from prldap_init.
+
+
+
+
+seip
+
+Pointer to a structure containing session information data.
+
+
+
+
+
+Returns
+
+LDAP_SUCCESS if successful.
+
+An LDAP API error code if an error occurs.
+
+
+Description
+The prldap_set_session_info function sets application-specific
+data for an LDAP session handle or a session argument that is passed to the
+ CONNECT, POLL, NEWHANDLE,
+or DISPOSEHANDLE extended I/O callbacks.
+See Also
+prldap_get_session_info
+
+prldap_set_session_option
+The prldap_set_session_option function sets a session
+option specific to the prldap layer.
+Syntax
+#include <ldappr.h>
+ int prldap_set_session_option( LDAP *ld, void *sessionarg,
+ int option, ... );
+
+Parameters
+
+
+Returns
+
+LDAP_SUCCESS if successful.
+
+An LDAP API error code if an error occurs.
+
+
+Description
+The prldap_set_session_option function sets an
+option for an LDAP session handle or a session argument that is passed to
+the CONNECT , POLL, NEWHANDLE,
+or DISPOSEHANDLE extended I/O callbacks.
+See Also
+prldap_get_session_option
+
+prldap_set_socket_info
+The prldap_set_socket_info function sets socket
+information.
+Syntax
+#include <ldappr.h>
+ int prldap_set_socket_info( int fd, void *socketarg,
+ PRLDAPSocketInfo *soip );
+
+Parameters
+
prldap_set_socket_info Function
+Parameters
+
+
+
+
+Parameter
+
+Description
+
+
+
+
+
+fd
+
+The session handle returned from prldap_init.
+
+
+
+
+soip
+
+Pointer to a structure containing socket information data.
+
+
+
+
+
+Returns
+
+LDAP_SUCCESS if successful.
+
+An LDAP API error code if an error occurs.
+
+
+Description
+The prldap_set_socket_info function sets socket-specific
+information based on parameters passed to the extended I/O callback functions.
+For more information, see the ldappr.h header file.
+
+See Also
+prldap_get_socket_info
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-ldap-urls.sgm b/mozilla/directory/docs/ldapcsdk/csdk-ldap-urls.sgm
new file mode 100644
index 00000000000..88d11473ca9
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-ldap-urls.sgm
@@ -0,0 +1,312 @@
+
+LDAP URLs With &DirectorySDKForC;
+
+C SDK
+LDAP URLs
+
+This chapter describes how to use LDAP URLs to search and retrieve data
+from the directory.
+
+This chapter covers the following topics:
+Checking an LDAP URL With Directory
+SDK for C
+Getting the Components of an LDAP
+URL With Directory SDK for C
+Freeing the Components of an LDAP
+URL With Directory SDK for C
+Processing an LDAP URL With Directory
+SDK for C
+
+
+Checking an LDAP URL With &DirectorySDKForC;
+To determine whether a URL is an LDAP URL, call the ldap_is_ldap_url
+ 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 0.
+The following example determines if a URL is an LDAP URL.
+Determining Whether a URL Is an
+LDAP URL
+#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 );
+}
+...
+
+ldap_is_ldap_url determines whether a URL is an
+LDAP URL. To verify that an LDAP URL complies with the LDAP URL syntax, you
+should call the ldap_url_parse function as detailed in Getting the Components of an LDAP URL With Directory SDK
+for C.
+Getting the Components of an LDAP URL With &DirectorySDKForC;
+To retrieve the individual components of an LDAP URL, call ldap_url_parse
+. This function returns the LDAP URL components in an LDAPURLDesc
+ structure as shown in this example.
+LDAPURLDesc Structure
+
+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;
+
+The following table describes the structure's fields.
+
+LDAPURLDesc Field Descriptions
+
+
+
+
+Field Name
+
+Description
+
+
+
+
+
+lud_host
+
+The name of the host in the URL.
+
+
+
+lud_port
+
+The number of the port in the URL.
+
+
+
+lud_dn
+
+The distinguished name in the URL.
+
+
+
+lud_attrs
+
+A pointer to a NULL terminated array of the attributes
+specified in the URL.
+
+
+
+lud_scope
+
+
+The scope of the search specified in the URL. This field can have the
+following values:
+LDAP_SCOPE_BASE specifies a search of the
+base entry.
+LDAP_SCOPE_ONELEVEL specifies a search
+of all entries one level under the base entry, not including the base entry.
+
+LDAP_SCOPE_SUBTREE specifies a search of
+all entries at all levels under the base entry, including the base entry.
+
+
+
+
+
+
+lud_filter
+
+Search filter included in the URL.
+
+
+
+lud_options
+
+Options. If LDAP_URL_OPT_SECURE, indicates that the
+protocol is ldaps:// instead of ldap://.
+
+
+
+
+
+The following example parses an LDAP URL.
+Parsing an LDAP URL
+#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 );
+...
+
+The code in Example 13–3 prints
+each component of the URL as shown in the following example.
+Results of Parsing an LDAP
+URL
+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)
+
+
+Freeing the Components of an LDAP URL With &DirectorySDKForC;
+When you have finished working with the components of an LDAP URL, you
+should free the LDAPURLDesc structure from memory
+by calling the ldap_free_urldesc function. The following
+example parses an LDAP URL. The example then frees the LDAPURLDesc structure
+from memory, after verifying that the LDAP URL is valid.
+Freeing the LDAPURLDesc Structure
+From Memory
+#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 );
+...
+
+
+Processing an LDAP URL With &DirectorySDKForC;
+To process an LDAP URL search request, call one of the following functions:
+
+
+ldap_url_search_s 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 LDAP_SUCCESS if the operation
+completed successfully. If an error occurred, the function returns an error
+code.
+ldap_url_search_st 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.
+ldap_url_search 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 ldap_result function.
+After the operation is completed, call the ldap_result2error
+ function to determine if the operation was successful. If the
+operation completed successfully, the ldap_result2error function
+returns LDAP_SUCCESS. If an error occurred, the function
+returns an error code.
+
+The following example processes a search request from an LDAP URL.
+Processing an LDAP URL Search
+Request
+#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 );
+}
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-multithread.sgm b/mozilla/directory/docs/ldapcsdk/csdk-multithread.sgm
new file mode 100644
index 00000000000..a9e5d1c3529
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-multithread.sgm
@@ -0,0 +1,807 @@
+
+Writing Multithreaded Clients With &DirectorySDKForC;
+
+C SDK
+multithreaded clients
+
+This chapter shows how to write multithreaded LDAP client applications.
+
+This chapter covers the following topics:
+Specifying Thread Functions With Directory SDK for C
+
+POSIX Thread Client Application With Directory SDK for C
+
+
+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.
+
+Specifying Thread Functions With Directory SDK for
+C
+You can write a multithreaded client with different threads accessing
+the same LDAP 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.
+The LDAP_OPT_THREAD_FN_PTRS session option lets you
+set up an ldap_thread_fns 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.
+Setting Up the ldap_thread_fns Structure
+
+You can write a multithreaded client in which different threads use
+the same LDAP connection. Set up the ldap_thread_fns structure.
+Then identify the functions that you want to use in the ldap_thread_fns
+ structure.
+ldap_thread_fns Structure
+
+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;
+};
+
+The fields of the ldap_thread_fns structure
+are described in the following table.
+
ldap_thread_fns
+ Field Descriptions
+
+
+
+
+Field
+
+Description
+
+
+
+
+
+*ltf_mutex_alloc
+
+Function pointer for allocating a mutex. This function is called by
+the client when needed if the function pointer is not NULL.
+
+
+
+
+*ltf_mutex_free
+
+Function pointer for freeing a mutex. This function is called by the
+client when needed if the function pointer is not NULL.
+
+
+
+
+*ltf_mutex_lock
+
+Function pointer for locking critical sections of code. This function
+is called by the client when needed if the function pointer is not NULL.
+
+
+
+
+*ltf_mutex_unlock
+
+Function pointer for unlocking critical sections of code. This function
+is called by the client when needed if the function pointer is not NULL.
+
+
+
+
+*ltf_get_errno
+
+Function pointer for getting the value of the errno variable.
+This function is called by the client when needed if the function pointer
+is not NULL. In a threaded environment, errno 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 libldap library does not know what method your
+code and your threading environment use to get the value of errno for
+each thread. The library therefore calls this function to return the value
+of errno.
+
+
+
+*ltf_set_errno
+
+Function pointer for setting the value of the errno variable.
+This function is called by the client when needed if the function pointer
+is not NULL. In a threaded environment, errno 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 libldap library does not know what method your
+code and your threading environment use to get the value of errno for
+each thread. The library therefore calls this function to set the value of
+errno.
+
+
+
+*ltf_get_lderrno
+
+Function pointer for getting error values from calls to functions in
+the libldap library. This function is called by the client
+when needed if the function pointer is not NULL. If this
+function pointer is not set, the libldap library records
+these errors in fields in the LDAP structure.
+
+
+
+
+*ltf_set_lderrno
+
+Function pointer for setting error values from calls to functions in
+the libldap library. This function is called by the client
+when needed if the function pointer is not NULL. If this
+function pointer is not set, the libldap library records
+these errors in fields in the LDAP structure.
+
+
+
+
+*ltf_lderrno_arg
+
+Additional parameter passed to the functions for getting and setting
+error values from calls to functions in the libldap library.
+*ltf_get_lderrno and *ltf_set_lderrno identify
+these functions.
+
+
+
+
+
+Setting Up the ldap_extra_thread_fns Structure
+
+&DirectorySDKForC; provides a structure, ldap_extra_thread_fns
+, that specifies additional thread functions
+for locking. The structure also specifies thread functions for semaphores
+, which are protected variables. The ldap_extra_thread_fns
+ structure is defined in the following example.
+Declaring the ldap_extra_thread_fns
+ Structure
+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;
+};
+
+&DirectorySDKForC; supports only the LDAP_TF_TREADID_CALLBACK
+*ltf_threadid_fn 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 pthread_self
+ does. If any of the other extra thread callback functions are
+set, the extra functions are ignored.
+Setting Session Options
+After you set up the ldap_thread_fns structure,
+associate the structure with the current session. Call the ldap_set_option
+ function and pass LDAP_OPT_THREAD_FN_PTRS as
+the value of the option parameter. Pass a pointer to the
+ldap_thread_fns structure as the value of the optdata parameter.
+
+Associating the ldap_thread_fns
+ Structure With the Current Session
+#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" );
+}
+...
+
+If you also set up the ldap_extra_thread_fns
+ structure, associate the structure with the current session.
+Call the ldap_set_option function, passing LDAP_OPT_EXTRA_THREAD_FN_PTRS
+ as the value of the option parameter. Also pass
+a pointer to the ldap_extra_thread_fns structure
+as the value of the optdata parameter.
+
+POSIX Thread Client Application With Directory SDK
+for C
+
+C SDK
+POSIX threading
+
+The following example which uses pthreads (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.
+Using POSIX Threading on a Solaris System
+#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 );
+}
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-quickstart.sgm b/mozilla/directory/docs/ldapcsdk/csdk-quickstart.sgm
new file mode 100644
index 00000000000..559836ac98d
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-quickstart.sgm
@@ -0,0 +1,171 @@
+
+Getting Started With &DirectorySDKForC;
+
+C SDK
+quick start
+
+
+This chapter shows how to start using &DirectorySDKForC;and covers
+the following topics:
+Sample Directory Client Code
+
+Compiling Directory SDK for C Client
+Applications
+Running the Client
+
+
+
+Sample Directory Client Code
+
+example programs
+C SDK
+directory entry retrieval
+
+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.
+Retrieving a Directory Entry
+#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 );
+}
+
+
+Compiling &DirectorySDKForC; Client Applications
+
+C SDK
+compiling applications
+
+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.
+Compiling Programs on UNIX Systems
+The &DirectorySDKForC; examples/ directory contains
+a UNIX Makefile. You can modify the Makefile to
+compile the sample by adjusting the flags in the file. The Makefile assumes
+that the &DirectorySDKForC; header files are located in the ../include/
+ directory.
+Compiling Programs on Windows Systems
+
+If you are compiling the sample client on Windows, set up the build
+framework for this application. Make sure to do the following:
+If you are using Microsoft development tools, create a new
+project workspace for a console application. Then add the source file to the
+project.
+Set your options to include lib\ as one
+of the directories for library files, and include\ as
+one of the directories for include files.
+Link to nsldap32v60.lib, the LDAP API
+import library for Windows.
+
+
+
+Running the Client
+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 Example 5–1, the
+entry would be for the full name, last name, email address, and telephone
+number of Barbara Jensen.
+Running Programs on UNIX Systems
+If you have linked the client on a UNIX platform, the client requires
+the SDK library file. Make sure to set your LD_LIBRARY_PATH to
+locate the libldap60.so library file and its dependencies.
+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 to specify the location
+of the libldap60.so file.
+Running Programs on Windows Systems
+If you have linked the client with the nsldap32v60.lib library
+on a Windows system, copy the &DirectorySDKForC; DLL files to one of the
+following directories:
+
+The directory where the application was loaded
+The current directory
+The Windows system directory, such as winnt\system32\
+
+The Windows directory
+The directories listed in the PATH environment
+variable
+
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-resultcodes.sgm b/mozilla/directory/docs/ldapcsdk/csdk-resultcodes.sgm
new file mode 100644
index 00000000000..b6e132f84c0
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-resultcodes.sgm
@@ -0,0 +1,1480 @@
+
+&DirectorySDKForC; Result Codes
+
+result codes
+C SDK result codes
+error codes
+C SDK result codes
+C SDK result codes
+
+C SDK result codes
+
+This chapter lists some of the result codes that can be returned by
+functions in the &DirectorySDKForC;. For ease of use, they are first listed
+in numerical order, then in alphabetical order. This chapter contains the
+following sections:
+
+Overview
+Result Codes Summary in Numerical
+Order
+Result Codes Reference in Alphabetical
+Order
+
+
+Overview
+LDAP result codes are extensible; thus, LDAP v3 extensions may define
+their own error codes, and register them with the Internet Assigned Numbers
+Authority (IANA). The IANA maintains a list of registered
+LDAP parameters, including result codes. This list includes what &DirectorySDKForC; currently
+knows in terms of result codes. More information can be found in RFC 4520,
+Internet Assigned Numbers Authority (IANA) Considerations
+for the Lightweight Directory Access Protocol (LDAP).
+Result Codes Summary in Numerical Order
+Table 22–1 gives
+the decimal and hexadecimal value of all result codes. Values missing from
+the sequence are not assigned to a result code.
+
+
+Result Codes Reference in Alphabetical Order
+
+result codes
+C SDK result codes
+error codes
+C SDK result codes
+C SDK result codes
+
+C SDK result codes
+
+The following sections contain the detailed reference information for
+each result code listed in alphabetical order by code name.
+
+LDAP_ADMINLIMIT_EXCEEDED
+
+This result code indicates that the look-through
+limit on a search operation has been exceeded. The look-through
+limit is the maximum number of entries that the server will check
+when gathering a list of potential search result candidates.
+When working with &cnDirectoryServer;, keep in mind the following:
+
+If you are bound as the root DN, the server sets an infinite
+look-through limit.
+If you are not bound as the root DN, the server sets a time
+limit.
+
+
+
+#define LDAP_ADMINLIMIT_EXCEEDED 0x0b
+/* 11 */
+
+
+LDAP_AFFECTS_MULTIPLE_DSAS
+
+This result code indicates that the requested
+operation needs to be performed on multiple servers, where this operation
+is not permitted.
+#define LDAP_AFFECTS_MULTIPLE_DSAS 0x47
+ /* 71 */
+
+
+LDAP_ALIAS_DEREF_PROBLEM
+
+This result code indicates that a problem
+occurred when dereferencing an alias.
+&cnDirectoryServer; does not currently send this result code back
+to LDAP clients.
+
+#define LDAP_ALIAS_DEREF_PROBLEM 0x24
+ /* 36 */
+
+
+LDAP_ALIAS_PROBLEM
+
+This result code indicates that the alias
+is invalid.
+&cnDirectoryServer; does not currently send this result code back
+to LDAP clients.
+
+#define LDAP_ALIAS_PROBLEM 0x21 /*
+33 */
+
+
+LDAP_ALREADY_EXISTS
+
+This result code indicates that the request
+is attempting to add an entry that already exists in the directory. &cnDirectoryServer; sends
+this result code back to the client in the following situations:
+
+The request is an add request, and the entry already exists
+in the directory.
+The request is a modify DN request, and the new DN of the
+entry already identifies another entry.
+The request is adding an attribute to the schema, and an attribute
+with the specified name or object identifier (OID) already exists.
+
+
+
+#define LDAP_ALREADY_EXISTS 0x44 /*
+68 */
+
+
+LDAP_AUTH_UNKNOWN
+
+This result code indicates that an unknown
+authentication method was specified.
+&DirectorySDKForC; library sets this result code if ldap_bind or ldap_bind_s are
+called and an authentication method other than LDAP_AUTH_SIMPLE is
+specified. These functions only allow you to use simple authentication.
+
+
+#define LDAP_AUTH_UNKNOWN 0x56 /* 86
+*/
+
+
+LDAP_BUSY
+
+This result code indicates that the server
+is currently too busy to perform the requested operation.
+#define LDAP_BUSY 0x33 /* 51 */
+
+
+
+LDAP_CLIENT_LOOP
+
+This result code indicates that the LDAP
+client detected a loop, for example, when following referrals.
+
+#define LDAP_CLIENT_LOOP 0x60 /* 96
+*/
+
+
+LDAP_COMPARE_FALSE
+
+This result code is returned after an
+LDAP compare operation is completed. The result indicates that the specified
+attribute value is not present in the specified entry.
+#define LDAP_COMPARE_FALSE 0x05 /*
+5 */
+
+
+LDAP_COMPARE_TRUE
+
+This result code is returned after an
+LDAP compare operation is completed. The result indicates that the specified
+attribute value is present in the specified entry.
+#define LDAP_COMPARE_TRUE 0x06 /* 6
+*/
+
+
+LDAP_CONFIDENTIALITY_REQUIRED
+
+This result code indicates that confidentiality
+is required for the operation.
+#define LDAP_CONFIDENTIALITY_REQUIRED
+0x0d /* 13 */
+
+
+LDAP_CONNECT_ERROR
+
+This result code indicates that the LDAP
+client cannot establish a connection, or has lost the connection, with the
+LDAP server. &DirectorySDKForC; sets this result code. If you have not
+established an initial connection with the server, verify that you have specified
+the correct host name and port number and that the server is running.
+
+#define LDAP_CONNECT_ERROR 0x5b /* 91
+*/
+
+
+LDAP_CONSTRAINT_VIOLATION
+
+This result code indicates that a value
+in the request does not comply with certain constraints. &cnDirectoryServer; sends
+this result code back to the client in the following situations:
+
+The request adds or modifies the userpassword attribute,
+and one of the following is true:
+
+The server is configured to check the password syntax, and
+the length of the new password is less than the minimum password length.
+
+The server is configured to check the password syntax, and
+the new password is the same as one of the values of the uid,
+ cn, sn, givenname,
+ou, or mail attributes.
+The server is configured to keep a history of previous passwords,
+and the new password is the same as one of the previous passwords.
+
+
+The request is a bind request, and the user is locked out of the account.
+(For example, the server can be configured to lock a user out of the account
+after a given number of failed attempts to bind to the server.)
+
+
+
+#define LDAP_CONSTRAINT_VIOLATION 0x13
+ /* 19 */
+
+
+LDAP_CONTROL_NOT_FOUND
+
+This result code indicates that a requested
+LDAP control was not found. &DirectorySDKForC; sets this result code when
+parsing a server response for controls and not finding the requested controls.
+For example:
+
+ldap_parse_entrychange_control is
+called, but no entry change notification control is found in the server’s
+response.
+ldap_parse_sort_control is
+called, but no server-side sorting control is found in the server’s
+response.
+ldap_parse_virtuallist_control is
+called, but no virtual list view response control is found in the server’s
+response.
+
+
+#define LDAP_CONTROL_NOT_FOUND 0x5d
+/* 93 */
+
+
+LDAP_DECODING_ERROR
+
+This result code indicates that the LDAP
+client encountered an error when decoding the LDAP response received from
+the server.
+#define LDAP_DECODING_ERROR 0x54 /*
+84 */
+
+
+LDAP_ENCODING_ERROR
+
+This result code indicates that the LDAP
+client encountered an error when encoding the LDAP request to be sent to the
+server.
+#define LDAP_ENCODING_ERROR 0x53 /*
+83 */
+
+
+LDAP_FILTER_ERROR
+
+This result code indicates that an error
+occurred when specifying the search filter. &DirectorySDKForC; sets this
+result code if it cannot encode the specified search filter in an LDAP search
+request.
+#define LDAP_FILTER_ERROR 0x57 /* 87
+*/
+
+
+LDAP_INAPPROPRIATE_AUTH
+
+This result code indicates that the type
+of credentials are not appropriate for the method of authentication used. &cnDirectoryServer; sends
+this result code back to the client if simple authentication is used in a
+bind request, but the entry has no userpassword attribute;
+also, if LDAP_SASL_EXTERNAL is attempted on a non-SSL
+connection.
+#define LDAP_INAPPROPRIATE_AUTH 0x30
+ /* 48 */
+
+
+LDAP_INAPPROPRIATE_MATCHING
+
+This result code indicates that an extensible
+match filter in a search request contained a matching rule that does not apply
+to the specified attribute type.
+#define LDAP_INAPPROPRIATE_MATCHING
+0x12 /* 18 */
+
+
+LDAP_INDEX_RANGE_ERROR
+
+This result code indicates that the search
+results exceeded the range specified by the requested offsets. This result
+code applies to search requests that contain virtual list view controls.
+
+#define LDAP_INDEX_RANGE_ERROR 0x3D
+ /* 61 */
+
+
+LDAP_INSUFFICIENT_ACCESS
+
+This result code indicates that the client
+has insufficient access to perform the operation. Check that the user you
+are authenticating as has the appropriate permissions.
+#define LDAP_INSUFFICIENT_ACCESS 0x32
+ /* 50 */
+
+
+LDAP_INVALID_CREDENTIALS
+
+This result code indicates that the credentials
+provided in the request are invalid. &cnDirectoryServer; sends this result
+code back to the client if a bind request contains the incorrect credentials
+for a user or if a user’s password has already expired.
+#define LDAP_INVALID_CREDENTIALS 0x31
+ /* 49 */
+
+
+LDAP_INVALID_DN_SYNTAX
+
+This result code indicates than an invalid
+DN has been specified. &cnDirectoryServer; sends this result code back to
+the client if an add request or a modify DN request specifies an invalid DN.
+It also sends this code when an LDAP_SASL_EXTERNAL bind
+is attempted but certification to DN mapping fails.
+#define LDAP_INVALID_DN_SYNTAX 0x22
+ /* 34 */
+
+
+LDAP_INVALID_SYNTAX
+
+This result code indicates that the request
+contains invalid syntax. &cnDirectoryServer; sends this result code back to
+the client in the following situations:
+
+The server encounters an access control instruction (ACI)
+with invalid syntax.
+The request attempts to add or modify an aci attribute,
+and the value of the attribute is an ACI with invalid syntax.
+The request is a search request with a substring filter, and
+the syntax of the filter is invalid.
+The request is a modify request that is attempting to modify
+the schema, but no values are provided (for example, the request might be
+attempting to delete all values of the objectclass attribute).
+
+
+
+#define LDAP_INVALID_SYNTAX 0x15 /*
+21 */
+
+
+LDAP_IS_LEAF
+
+This result code indicates that the specified
+entry is a leaf entry.
+&cnDirectoryServer; does not currently send this result code back
+to LDAP clients.
+
+#define LDAP_IS_LEAF 0x23 /* 35 */
+
+
+
+LDAP_LOCAL_ERROR
+
+This result code indicates that an error
+occurred in the LDAP client, though it may also be returned by &cnDirectoryServer;.
+
+#define LDAP_LOCAL_ERROR 0x52 /* 82
+*/
+
+
+LDAP_LOOP_DETECT
+
+This result code indicates that the server
+was unable to perform the requested operation because of an internal loop.
+&cnDirectoryServer; does not currently send this result code back
+to LDAP clients.
+
+#define LDAP_LOOP_DETECT 0x36 /* 54
+*/
+
+
+LDAP_MORE_RESULTS_TO_RETURN
+
+This result code indicates that there
+are more results in the chain of results. The &DirectorySDKForC; sets this
+result code when the ldap_parse_sasl_bind_result function
+is called to retrieve the result code of an operation, and additional result
+codes from the server are available in the LDAP structure.
+
+#define LDAP_MORE_RESULTS_TO_RETURN
+0x5f /* 95 */
+
+
+LDAP_NAMING_VIOLATION
+
+This result code indicates that the request
+violates the structure of the DIT.
+&cnDirectoryServer; does not currently send this result code back
+to LDAP clients.
+
+#define LDAP_NAMING_VIOLATION 0x40
+/* 64 */
+
+
+LDAP_NO_MEMORY
+
+This result code indicates that no memory
+is available. &DirectorySDKForC; sets this result code if a function cannot
+allocate memory (for example, when creating an LDAP request or an LDAP control).
+
+#define LDAP_NO_MEMORY 0x5a /* 90 */
+
+
+
+LDAP_NO_OBJECT_CLASS_MODS
+
+This result code indicates that the request
+is attempting to modify an object class that should not be modified (for example,
+a structural object class).
+&cnDirectoryServer; does not currently send this result code back
+to LDAP clients.
+
+#define LDAP_NO_OBJECT_CLASS_MODS 0x45
+ /* 69 */
+
+
+LDAP_NO_RESULTS_RETURNED
+
+This result code indicates that no results
+were returned from the server. The &DirectorySDKForC; sets this result
+code when the ldap_parse_result function
+is called but no result code is included in the server’s response.
+
+#define LDAP_NO_RESULTS_RETURNED 0x5E
+ /* 94 */
+
+
+LDAP_NO_SUCH_ATTRIBUTE
+
+This result code indicates that the specified
+attribute does not exist in the entry. &cnDirectoryServer; might send this
+result code back to the client if, for example, a modify request specifies
+the modification or removal of a non-existent attribute or if a compare request
+specifies a non-existent attribute.
+#define LDAP_NO_SUCH_ATTRIBUTE 0x10
+ /* 16 */
+
+
+LDAP_NO_SUCH_OBJECT
+
+This result code indicates that the server
+cannot find an entry specified in the request. &cnDirectoryServer; sends this
+result code back to the client if it cannot find a requested entry and it
+cannot refer your client to another LDAP server.
+#define LDAP_NO_SUCH_OBJECT 0x20 /*
+32 */
+
+
+LDAP_NOT_ALLOWED_ON_NONLEAF
+
+This result code indicates that the requested
+operation is allowed only on entries that do not have child entries (leaf
+ entries as opposed to branch entries). &cnDirectoryServer; sends
+this result code back to the client if the request is a delete request or
+a modify DN request and the entry is a parent entry. You cannot delete or
+move a branch of entries in a single operation.
+#define LDAP_NOT_ALLOWED_ON_NONLEAF
+0x42 /* 66 */
+
+
+LDAP_NOT_ALLOWED_ON_RDN
+
+This result code indicates that the requested
+operation will affect the RDN of the entry. &cnDirectoryServer; sends this
+result code back to the client if the request is a modify request that deletes
+attribute values from the entry that are used in the RDN of the entry. (For
+example, the request removes the attribute value uid=bjensen from
+the entry uid=bjensen,ou=People,dc=example,dc=com.)
+
+#define LDAP_NOT_ALLOWED_ON_RDN 0x43
+ /* 67 */
+
+
+LDAP_NOT_SUPPORTED
+
+This result code indicates that the LDAP
+client is attempting to use functionality that is not supported. &DirectorySDKForC; sets
+this result code if the client identifies itself as an LDAP v2 client, and
+the client is attempting to use functionality available in LDAP v3. For example:
+
+You are passing LDAP controls to a function.
+You are calling ldap_extended_operation , ldap_extended_operation_s, or
+ldap_parse_extended_result to request an extended operation or to
+parse an extended response.
+You are calling ldap_rename or ldap_rename_s, and you are specifying a new superior
+DN as an argument.
+You are calling ldap_sasl_bind, ldap_sasl_bind_s, or ldap_parse_sasl_bind_result
+ to request Simple Authentication and Security Layer (SASL) authentication
+or to parse a SASL bind response.
+You are calling ldap_parse_virtuallist_control
+ to parse a virtual list control from the server’s response.
+If you want to use these features, make sure to specify that your LDAP
+client is an LDAP v3 client.
+
+
+#define LDAP_NOT_SUPPORTED 0x5c /* 92
+*/
+
+
+LDAP_OBJECT_CLASS_VIOLATION
+
+This result code indicates that the request
+specifies a new entry or a change to an existing entry that does not comply
+with the server’s schema. &cnDirectoryServer; sends this result code
+back to the client in the following situations:
+
+The request is an add request, and the new entry does not
+comply with the schema. For example, the new entry does not have all the required
+attributes, or the entry has attributes that are not allowed in the entry.
+
+The request is a modify request, and the change will make
+the entry non compliant with the schema. For example, the change removes a
+required attribute or adds an attribute that is not allowed.Check
+the server error logs for more information, and the schema for the type of
+entry that you are adding or modifying.
+
+
+#define LDAP_OBJECT_CLASS_VIOLATION
+0x41 /* 65 */
+
+
+LDAP_OPERATIONS_ERROR
+
+This is a general result code indicating
+that an error has occurred. &cnDirectoryServer; might send this code if, for
+example, memory cannot be allocated on the server. To troubleshoot this type
+of error, check the server’s error logs. You may need to increase the
+log level of the server to get additional information.
+#define LDAP_OPERATIONS_ERROR 0x01
+/* 1 */
+
+
+LDAP_OTHER
+
+This result code indicates than an unknown
+error has occurred. This error may be returned by &cnDirectoryServer; when
+an error occurs that is not better described using another LDAP error code.
+When this error occurs, check the server's error logs. You may need
+to increase the log level of the server to get additional information.
+
+#define LDAP_OTHER 0x50 /* 80 */
+
+
+
+LDAP_PARAM_ERROR
+
+This result code indicates that an invalid
+parameter was specified. &DirectorySDKForC; sets this result code if a
+function was called and invalid parameters were specified, for example, if
+the LDAP structure is NULL.
+
+#define LDAP_PARAM_ERROR 0x59 /* 89
+*/
+
+
+LDAP_PARTIAL_RESULTS
+
+&cnDirectoryServer; sends this result
+code to LDAP v2 clients to refer them to another LDAP server. When sending
+this code to a client, the server includes a new line-delimited list of LDAP
+URLs that identifies another LDAP server. If the client identifies itself
+as an LDAP v3 client in the request, an LDAP_REFERRAL result
+code is sent instead of this result code.
+#define LDAP_PARTIAL_RESULTS 0x09 /*
+9 */
+
+
+LDAP_PROTOCOL_ERROR
+
+This result code indicates that the LDAP
+client’s request does not comply with the LDAP. &cnDirectoryServer; sends
+this result code back to the client in the following situations:
+
+The server cannot parse the incoming request.
+The request specifies an attribute type that uses a syntax
+not supported by the server.
+The request is a SASL bind request, but your client identifies
+itself as an LDAP v2 client.
+The request is a bind request that specifies an unsupported
+version of the LDAP. Make sure to specify whether your LDAP client is an LDAP
+v2 client or an LDAP v3 client.
+The request is an add or a modify request that specifies the
+addition of an attribute type to an entry, but no values are specified.
+
+The request is a modify request, and one of the following
+is true:
+
+An unknown modify operation is specified (an operation other
+than LDAP_MOD_ADD, LDAP_MOD_DELETE,
+and LDAP_MOD_REPLACE).
+No modifications are specified.
+
+The request is a modify DN request, and one of the following is true:
+
+The new RDN is not a valid RDN.
+A new superior DN is specified, but your client identifies
+itself as an LDAP v2 client.
+
+The request is a search request, and one of the following is true:
+
+An unknown scope is specified, meaning a scope other than
+LDAP_SCOPE_BASE , LDAP_SCOPE_ONELEVEL, or LDAP_SCOPE_SUBTREE
+.
+An unknown filter type is specified.
+The filter type LDAP_FILTER_GE or LDAP_FILTER_LE
+ is specified, but the type of attribute contains values that cannot
+be ordered. (For example, if the attribute type uses a binary syntax, the
+values of the attribute contain binary data, which cannot be sorted.)
+
+The request contains an extensible filter (a filter using
+matching rules), but your client identifies itself as an LDAP v2 client.
+
+The request contains an extensible filter (a filter using
+matching rules), but the matching rule is not supported by the server.
+
+
+The request is a search request with a server-side sorting control,
+and one of the following is true:
+
+The server does not have a syntax plug-in that supports the
+attribute used for sorting.
+The syntax plug-in does not have a function for comparing
+values of the attribute. (This compare function is used for sorting.)
+
+The type of attribute specified for sorting contains values
+that cannot be sorted in any order. For example, if the attribute type uses
+a binary syntax, the values of the attribute contain binary data, which cannot
+be sorted.
+The server encounters an error when creating the sorting response
+control (the control to be sent back to the client).
+When sorting the results, the time limit or the look-through
+limit is exceeded. The look-through limit is the maximum number of entries
+that the server will check when gathering a list of potential search result
+candidates.
+
+The request is an extended operation request, and the server does not
+support the extended operation. In &cnDirectoryServer;, extended operations
+are supported through extended operation server plug-ins. Make sure that the
+server is loading a plug-in that supports the extended operation. Check the
+OID of the extended operation in your LDAP client to make sure that it matches
+the OID of the extended operation registered in the server plug-in.
+
+An authentication method other than LDAP_AUTH_SIMPLE or
+ LDAP_AUTH_SASL is specified.To troubleshoot
+this type of error, check the server’s error logs. You may need to increase
+the log level of the server to get additional information.
+
+
+
+#define LDAP_PROTOCOL_ERROR 0x02 /*
+2 */
+
+
+LDAP_REFERRAL
+
+This result code indicates that the server
+is referring the client to another LDAP server. When sending this code to
+a client, the server includes a list of LDAP URLs that identify another LDAP
+server. This result code is part of the LDAP v3. For LDAP v2 clients, &cnDirectoryServer; sends
+an LDAP_PARTIAL_RESULTS result code instead.
+
+#define LDAP_REFERRAL 0x0a /* 10 */
+
+
+
+LDAP_REFERRAL_LIMIT_EXCEEDED
+
+This result code indicates that the
+referral hop limit was exceeded. &DirectorySDKForC; sets this
+result code, when following referrals, if the client is referred to other
+servers more times than allowed by the referral hop limit.
+
+#define LDAP_REFERRAL_LIMIT_EXCEEDED
+0x61 /* 97 */
+
+
+LDAP_RESULTS_TOO_LARGE
+
+This result code indicates that the results
+of the request are too large.
+&cnDirectoryServer; does not currently send this result code back
+to LDAP clients.
+
+#define LDAP_RESULTS_TOO_LARGE 0x46
+ /* 70 */
+
+
+LDAP_SASL_BIND_IN_PROGRESS
+
+This result code is used in multi stage
+SASL bind operations. The server sends this result code back to the client
+to indicate that the authentication process has not yet completed.
+
+#define LDAP_SASL_BIND_IN_PROGRESS 0x0E
+ /* 14 */
+
+
+LDAP_SERVER_DOWN
+
+This result code indicates that &DirectorySDKForC; cannot
+establish a connection with, or lost the connection to, the LDAP server. If
+you have not established an initial connection with the server, verify that
+you have specified the correct host name and port number and that the server
+is running.
+#define LDAP_SERVER_DOWN 0x51 /* 81
+*/
+
+
+LDAP_SIZELIMIT_EXCEEDED
+
+This result code indicates that the maximum
+number of search results to return has been exceeded. This limit is specified
+in the search request. If you specify no size limit, the server will set one.
+When working with &cnDirectoryServer;, keep in mind the following:
+
+If you are bound as the root DN and specify no size limit,
+the server enforces no size limit at all.
+If you are not bound as the root DN and specify no size limit,
+the server sets the size limit to the value specified by the sizelimit directive
+in the server’s slapd.conf configuration file.
+
+If the size limit that you specify exceeds the value specified
+by the sizelimit directive in the server’s slapd.conf
+ configuration file, the server uses the size limit specified in
+the configuration file.
+
+
+#define LDAP_SIZELIMIT_EXCEEDED 0x04
+ /* 4 */
+
+
+LDAP_SORT_CONTROL_MISSING
+
+This result code indicates that server
+did not receive a required server-side sorting control. &cnDirectoryServer; sends
+this result code back to the client if the server receives a search request
+with a virtual list view control but no server-side
+sorting control as the virtual list view control requires
+a server-side sorting control.
+#define LDAP_SORT_CONTROL_MISSING 0x3C
+ /* 60 */
+
+
+LDAP_STRONG_AUTH_NOT_SUPPORTED
+
+This result code is returned as the result
+of a bind operation. It indicates that the server does not recognize or support
+the specified authentication method.
+#define LDAP_STRONG_AUTH_NOT_SUPPORTED
+0x07 /* 7 */
+
+
+LDAP_STRONG_AUTH_REQUIRED
+
+This result code indicates that a stronger
+method of authentication is required to perform the operation.
+
+#define LDAP_STRONG_AUTH_REQUIRED 0x08
+ /* 8 */
+
+
+LDAP_SUCCESS
+
+This result code indicates that the LDAP
+operation was successful.
+#define LDAP_SUCCESS 0x00 /* 0 */
+
+
+
+LDAP_TIMELIMIT_EXCEEDED
+
+This result code indicates that the time
+limit on a search operation has been exceeded. The time limit is specified
+in the search request. If you specify no time limit, the server will set one.
+When working with &cnDirectoryServer;, keep in mind the following:
+
+If you are bound as the root DN and specify no time limit,
+the server enforces no limit at all.
+If you are not bound as the root DN and specify no time limit,
+the server sets the time limit.
+If the time limit that you specify exceeds the time limit
+specified for the server configuration, the server uses the time limit specified
+in its configuration.
+
+
+#define LDAP_TIMELIMIT_EXCEEDED 0x03
+ /* 3 */
+
+
+LDAP_TIMEOUT
+
+This result code indicates that the LDAP
+client timed out while waiting for a response from the server. &DirectorySDKForC; sets
+this result code in the LDAP structure if
+the time-out period (for example, in a search request) has been exceeded and
+the server has not responded.
+#define LDAP_TIMEOUT 0x55 /* 85 */
+
+
+
+LDAP_TYPE_OR_VALUE_EXISTS
+
+This result code indicates that the request
+attempted to add an attribute type or value that already exists. &cnDirectoryServer; sends
+this result code back to the client in the following situations:
+
+The request attempts to add values that already exist in the
+attribute.
+The request is adding an attribute to the schema of the server,
+but the OID of the attribute is already used by an object class in the schema.
+
+The request is adding an object class to the schema of the
+server, and one of the following occurs:
+
+The object class already exists.
+The OID of the object class is already used by another object
+class or an attribute in the schema.
+The superior object class for this new object class does not
+exist.
+
+
+
+
+#define LDAP_TYPE_OR_VALUE_EXISTS 0x14
+ /* 20 */
+
+
+LDAP_UNAVAILABLE
+
+This result code indicates that the server
+is unavailable to perform the requested operation.
+At this point, neither &DirectorySDKForC; nor &cnDirectoryServer; return
+this result code.
+
+#define LDAP_UNAVAILABLE 0x34 /* 52
+*/
+
+
+LDAP_UNAVAILABLE_CRITICAL_EXTENSION
+
+This result code indicates that the specified
+control or matching rule is not supported by the server. &cnDirectoryServer; might
+send back this result code if the request includes an unsupported control
+or if the filter in the search request specifies an unsupported matching rule.
+
+#define LDAP_UNAVAILABLE_CRITICAL_EXTENSION
+0x0c /* 12 */
+
+
+LDAP_UNDEFINED_TYPE
+
+This result code indicates that the request
+specifies an undefined attribute type.
+&cnDirectoryServer; does not currently send this result code back
+to LDAP clients.
+
+#define LDAP_UNDEFINED_TYPE 0x11 /*
+17 */
+
+
+LDAP_UNWILLING_TO_PERFORM
+
+This result code indicates that the server
+is unwilling to perform the requested operation. &cnDirectoryServer; sends
+this result code back to the client in the following situations:
+
+The client has logged in for the first time and needs to change
+its password, but the client is requesting to perform other LDAP operations.
+In this situation, the result code is accompanied by an expired password control.
+
+The request is a modify DN request, and a superior DN is specified.
+
+The database is in read-only mode, and the request attempts
+to write to the directory.
+The request is a delete request that attempts to delete the
+root DSE.
+The request is a modify DN request that attempts to modify
+the DN of the root DSE.
+The request is a modify request to modify the schema entry,
+and one of the following occurs:
+
+The operation is LDAP_MOD_REPLACE. (The
+server does not allow you to replace schema entry attributes.)
+The request attempts to delete an object class that is the
+parent of another object class.
+The request attempts to delete a read-only object class or
+attribute.
+
+The server uses a database plug-in that does not implement the operation
+specified in the request. For example, if the database plug-in does not implement
+the add operation, sending an add request will return this result code.
+
+
+
+#define LDAP_UNWILLING_TO_PERFORM 0x35
+ /* 53 */
+
+
+LDAP_USER_CANCELLED
+
+This result code indicates that the user
+cancelled the LDAP operation.
+&cnDirectoryServer; does not currently send this result code back
+to LDAP clients.
+
+#define LDAP_USER_CANCELLED 0x58 /*
+88 */
+
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-sasl.sgm b/mozilla/directory/docs/ldapcsdk/csdk-sasl.sgm
new file mode 100644
index 00000000000..c20c7155402
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-sasl.sgm
@@ -0,0 +1,222 @@
+
+SASL Authentication With &DirectorySDKForC;
+
+C SDK
+Simple Authentication and Security Layer (SASL)
+
+This chapter describes the process of using a Simple Authentication
+and Security Layer (SASL) mechanism to authenticate an LDAP client to an LDAP
+server.
+
+This chapter covers the following topics:
+Understanding SASL and Directory
+SDK for C
+Determining Supported SASL Mechanisms
+With Directory SDK for C
+Authenticating Using SASL With Directory
+SDK for C
+
+
+Understanding SASL and &DirectorySDKForC;
+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.
+SASL is described in RFC 4422, Simple Authentication
+and Security Layer (SASL).
+Determining Supported SASL Mechanisms With &DirectorySDKForC;
+
+To determine the SASL mechanisms supported by an LDAP v3 server, get
+the root DSE of the server, and check the supportedSASLMechanisms attribute.
+The values of this attribute are the names of the SASL mechanisms supported
+by the server.
+If the root DSE does not have a supportedSASLMechanisms attribute,
+the server does not support any SASL mechanisms.
+For information about getting the root DSE, see To
+Get the Root DSE.
+Authenticating Using SASL With &DirectorySDKForC;
+
+To authenticate to the server with a SASL mechanism, call one of the
+following:
+The synchronous ldap_sasl_bind_s function
+
+The asynchronous ldap_sasl_bind function
+If you call the asynchronous function ldap_sasl_bind,
+you need to call the ldap_result and ldap_parse_sasl_bind_result
+ functions to get the result of the SASL bind operation.
+
+
+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
+challenges to the client. You might need to call ldap_sasl_bind_s
+ several times, or ldap_sasl_bind, ldap_result
+, and ldap_parse_sasl_bind_result several
+times in order to respond to each server challenge.
+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 LDAP_NOT_SUPPORTED
+ result code is returned. See Specifying
+the LDAP Version of Your Client.
+Synchronous SASL Bind Operation
+If you want to wait for the results of the SASL bind operation to complete
+before continuing, call the synchronous ldap_sasl_bind_s 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.
+
+ldap_sasl_bind_s returns one of the following values:
+LDAP_SUCCESS if your client has successfully
+authenticated.
+LDAP_SASL_BIND_IN_PROGRESS if the server
+sends a challenge to your client. If you receive this result code, check the
+servercredp argument for the berval structure
+that contains the server’s challenge. Call the ldap_sasl_bind function
+again to send a response to that challenge.
+An LDAP error code if a problem occurred or if authentication
+failed. See the ldap_sasl_bind_s function
+documentation for a list of the possible result codes.
+
+
+Asynchronous SASL Bind Operation
+If you want to perform other work in parallel while waiting for the
+SASL bind operation to complete, use the following procedure.
+To Bind Asynchronously Over SASL
+
+Call the asynchronous ldap_sasl_bind function
+to send an LDAP SASL bind request.This function returns an
+LDAP_SUCCESS 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 msgidp argument to point to a message
+ID identifying the SASL bind operation.
+Call the ldap_result function, passing in
+this message ID to determine whether the server sent a response for this operation
+to your client.The ldap_result function
+uses the message ID to determine if the server sent a SASL bind response.
+The function passes back the response in an LDAPMessage structure.
+
+Call the ldap_parse_sasl_bind_result function
+to parse the LDAPMessage structure and retrieve information
+from the server’s response.If the server sent a challenge
+to your client, the challenge is specified in the berval structure
+passed back as the servercredp argument.
+Call the ldap_get_lderrno function to get
+the LDAP result code for the operation.
+
+The function can return one of the following values:
+LDAP_SUCCESS if your client successfully
+authenticated to the server.
+LDAP_SASL_BIND_IN_PROGRESS if the server
+sent a challenge to your client.If the server returned an
+LDAP_SASL_BIND_IN_PROGRESS result code, check the servercredp
+ argument for the berval structure that
+contains the server’s challenge.
+An LDAP error code if a problem occurred or if authentication
+failed.See the ldap_sasl_bind function documentation
+for a list of result codes that the server can return for this operation.
+
+
+
+If the result code is LDAP_SASL_BIND_IN_PROGRESS and
+if the server passed back another challenge, determine the response to that
+challenge by calling the ldap_sasl_bind function again
+to send that response to the server.You can call ldap_result
+ and ldap_parse_sasl_bind_result again to
+get the next challenge sent from the server, if the result is again LDAP_SASL_BIND_IN_PROGRESS
+.
+
+
+Authenticating Over SASL
+This example shows an LDAP client that authenticates using the SASL
+mechanism that is named babsmechanism.
+#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 );
+}
+
+
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-search.sgm b/mozilla/directory/docs/ldapcsdk/csdk-search.sgm
new file mode 100644
index 00000000000..836f11dff38
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-search.sgm
@@ -0,0 +1,1738 @@
+
+Searching the Directory With &DirectorySDKForC;
+
+
+C SDK
+search LDAP directory
+
+searching the directory
+with C SDK
+
+This chapter explains how to use the LDAP C API to search the directory
+and to retrieve entries.
+
+This chapter covers the following topics:
+Overview of Search Functions for
+Directory SDK for C
+Sending a Search Request With Directory
+SDK for C
+Getting the Search Results With Directory
+SDK for C
+Sorting the Search Results With Directory
+SDK for C
+Freeing the Search Results With Directory
+SDK for C
+Examples of Search Operations With
+Directory SDK for C
+
+
+Overview of Search Functions for Directory SDK for
+C
+&DirectorySDKForC; provides functions that allow you to search a
+directory and to retrieve results from the server. For example, you can send
+a search request by calling the synchronous ldap_search_ext_s function
+or the asynchronous ldap_search_ext function and the
+server sends back matching results.
+
+In LDAP v3, a server can send three different types of results, represented
+by LDAPMessage structures, back to the client:
+Directory entries found by the search
+Search references found within the scope of the search
+A search reference is a reference to another
+LDAP server.
+An LDAP result code that specifies the result of the search
+operation
+
+To receive search references from LDAP v3 servers, you must identify
+your client as LDAP v3 enabled. If you do not, the server returns the LDAP
+error code LDAP_PARTIAL_RESULTS, and a set of referrals.
+See Specifying the LDAP Version of Your Client for
+details.
+
+These results can be processed based on the following guidelines:
+If you are retrieving the results sequentially, call ldap_result
+. This function returns each result, an LDAPMessage structure,
+and determines the type of result. A result can be either an entry or a search
+reference.
+If you are retrieving a chain of results, you can call
+ldap_first_message and ldap_next_message to
+iterate through the results in the chain.If you are just interested
+in entries, you can call ldap_first_entry and ldap_next_entry
+.If you are just interested in search references,
+you can call ldap_first_reference and ldap_next_refrence
+.
+To get an entry from a result, an LDAPMessage structure,
+call ldap_parse_entry.
+To get a search reference from a result, an LDAPMessage
+ structure, call ldap_parse_reference.
+
+To get the LDAP result code for the search operation from
+a result, an LDAPMessage structure, call ldap_parse_result
+.
+
+To access data from entries found by the search, you need to follow
+this general process in your code.
+
+Get each entry in the results.
+Get the attributes from each entry.
+Get the values from each attribute.
+
+
+
+Sending a Search Request With &DirectorySDKForC;
+
+C SDK
+search LDAP directory
+request
+
+To search the directory, call ldap_search_ext_s or
+ldap_search_ext. ldap_search_ext_s is a synchronous
+function that blocks other work until all results have been received from
+the server. The function is declared as shown here.
+ldap_search_ext_s Prototype
+
+LDAP_API(int) LDAP_CALL ldap_search_ext_s( LDAP *ld, const char *base,
+ int scope, const char *filter, char **attrs, int attrsonly,
+ LDAPControl **serverctrls, LDAPControl **clientctrls,
+ struct timeval *timeoutp, int sizelimit, LDAPMessage **res );
+
+ldap_search_ext is an asynchronous function that
+sends an LDAP search request to the server. You can do other work while checking
+to see if the server has returned any results. The function is declared as
+shown here.
+ldap_search_ext Prototype
+
+LDAP_API(int) LDAP_CALL ldap_search_ext( LDAP *ld, const char *base,
+ int scope, const char *filter, char **attrs, int attrsonly,
+ LDAPControl **serverctrls, LDAPControl **clientctrls,
+ struct timeval *timeoutp, int sizelimit, int *msgidp );
+
+Sample code for sending a search request can be found in Sending Search Request Using Directory SDK for C.
+Search Parameters for Directory SDK for C
+
+C SDK
+search LDAP directory
+parameters
+
+For either of the functions illustrated in Example 9–1 and Example 9–2, you specify
+the search criteria by using the parameters as detailed in the following table.
+
Search
+Criteria Parameters
+
+
+
+
+Parameter Name
+
+Description
+
+
+
+
+
+base
+
+Specifies the starting point in the directory, or the base DN, where
+the search begins. For example, to search entries under dc=example,dc=com
+, the base DN is dc=example,dc=com. See Specifying the Base DN and the Scope With Directory SDK
+for C.
+
+
+
+scope
+
+Specifies which entries to search. The search can address the base DN
+only, entries one level under the base DN, or all entries under the base DN.
+See Specifying the Base DN and the Scope With Directory
+SDK for C.
+
+
+
+filter
+
+Specifies a search filter by defining what to search for. A search filter
+can be as simple as “find entries with the last name of Jensen”
+or as complex as “find entries that belong to Dept. #17 and whose first
+names start with the letter F.” See Specifying
+a Search Filter With Directory SDK for C.
+
+
+
+attrsattrsonly
+
+Specify what to return. Options are the type of information to return,
+and the attributes to retrieve. Also, options include whether to return only
+attribute types, or both types and values. You can also specify to return
+the names of attributes only, and not the values, by passing a nonzero value
+for the attrsonly argument. See Specifying
+the Attributes to Retrieve With Directory SDK for C.
+
+
+
+serverctrlsclientctrls
+
+Specify the LDAP v3 controls that are associated with this search operation.
+For details on LDAP v3 controls, see Chapter 16,
+LDAP Controls With Directory SDK for C.
+
+
+
+timeoutpsizelimit
+
+Specify search constraints that you want applied to the search. For
+example, you can specify a different timeout period or maximum number of results
+from the values already defined for the current session. See Setting Search Preferences With Directory SDK for C.
+
+
+
+
+
+
+Specifying the Base DN and the Scope With &DirectorySDKForC;
+
+When sending a search request, you need to specify the base DN and the
+search scope to identify the entries that you want searched. The base DN,
+the root argument, is the DN of the entry that serves as the starting point
+for the search.
+
+To specify the scope of the search, pass one of the following values
+as the scope parameter:
+LDAP_SCOPE_SUBTREE searches the base entry
+and all entries at all levels under the base entry.
+LDAP_SCOPE_ONELEVEL searches all entries
+one level under the base entry. The base entry is not included in the search.
+Use this setting if you just want to list the entries under a given entry.
+
+LDAP_SCOPE_BASE searches only the base
+entry. Use this setting if you just want to read the attributes of the base
+entry.
+
+
+Specifying a Search Filter With Directory SDK for
+C
+
+C SDK
+search LDAP directory
+filters
+
+When you search the directory, you use a search filter to define the
+search. The following example illustrates the search filter syntax:
+
+(attributeoperator
+value)
+(cn=Barbara Jensen)
+
+
+
+Compare the syntax to the example. You see that cn is
+the attribute, that = is the operator, and that Barbara
+Jensen is the value. The filter finds entries with the common name
+Barbara Jensen. For a list of valid attributes for your search filter,
+see the LDAP schema for the directory server you are using. For a list of
+valid operators that you can use in your search filter, see the following
+table.
+
Basic
+Operators for Search Filters
+
+
+
+
+Operator
+
+Description
+
+Example
+
+
+
+
+
+=
+
+Returns entries whose attribute is equal to the value.
+
+(cn=Barbara Jensen) finds the entry with RDN cn=Barbara
+Jensen.
+
+
+
+>=
+
+Returns entries whose attribute is greater than or equal to the value.
+
+
+(sn >= jensen) finds all entries with surname (SN)
+from jensen to the end of the alphabetical list.
+
+
+
+
+<=
+
+Returns entries whose attribute is less than or equal to the value.
+
+
+(sn <= jensen) finds all entries with SN from
+the beginning of the alphabetical list to jensen.
+
+
+
+
+=*
+
+Returns entries that have a value set for that attribute.
+
+(sn =*) finds all entries that have the sn attribute.
+
+
+
+
+~=
+
+Returns entries whose attribute value approximately matches the specified
+value. Typically, the algorithm matches words that sound alike.
+
+(sn ~= jensen) finds entries with sn = jensen but
+also sn = jansen.
+
+
+
+
+With boolean operators and with parentheses, you can combine different
+sets of conditions into one filter. The following shows boolean search filter
+syntax for combining filters, and a simple example:
+
+(boolean-operator(filter1
+)(filter2)(filter3))
+
+(|(sn=Jensen)(sn=Johnson))
+
+
+
+The example uses the boolean or operator, |, to signify
+a search for all entries with the last name Jensen or the
+last name Johnson. The following table describes the valid
+boolean operators that you can use in your search filter.
+
Boolean
+Operators for Search Filters
+
+
+
+
+Operator
+
+Description
+
+
+
+
+
+&
+
+Returns entries that match all specified filter criteria.
+
+
+
+|
+
+Returns entries that match one or more of the filter criteria.
+
+
+
+
+!
+
+Returns entries for which the filter is not true. You can only apply
+this operator to a single filter. For example: You can use:
+(!(filter))
+You cannot use:
+(!(filter1)(filter2))
+
+
+
+
+
+
+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 this filter to search for all entries whose names begin with the
+letter F:
+(givenName=F*)
+When comparing values with letters, the value of the letter a is
+less than the value z. For example, the following filter
+finds all entries with last names beginning with a through
+Jensen:
+(sn<=jensen)
+
+Specifying the Attributes to Retrieve With Directory
+SDK for C
+
+C SDK
+search LDAP directory
+attributes
+
+With the attrs argument, you can retrieve all attributes
+in the entries returned by the search. Alternatively, you can specify the
+attributes from the search results.
+
+To specify attributes, use the following guidelines:
+To return selected attributes, pass an array of the attribute
+names as the attrs argument. For example, to return only
+email addresses and phone numbers, pass the NULL terminated
+array {"mail", "telephoneNumber", NULL} as the attrs argument.
+
+To return all attributes in an entry, pass NULL as
+the attrs argument.
+To return no attributes from an entry, pass LDAP_NO_ATTRS
+ as the attrs argument.
+
+Sorting Attributes
+If you plan to sort the results on your client, you need to 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. See Sorting the Search
+Results With Directory SDK for C.
+Operational Attributes
+Some attributes are used by servers for administering the directory.
+For example, the creatorsName attribute specifies the DN
+of the user who added the entry. These attributes are called operational
+attributes.
+Servers do not normally return operational attributes in search results
+unless you specify the attributes by name. For example, you can pass NULL
+ for the attrs argument to retrieve all of the
+attributes in entries found by the search. When you pass this value, the operational
+attribute creatorsName is not returned to your client.
+You need to explicitly specify the creatorsName attribute
+in the attrs argument. You can retrieve all attributes
+in an entry, as well as selected operational attributes. Pass a NULL terminated
+array that contains LDAP_ALL_USER_ATTRS. Also, pass the
+names of the operational attributes as the attrs argument.
+The following table lists operational attributes and explains the meaning
+of their values.
+
Operational
+Attributes and Descriptions of Their Values
+
+
+
+
+Attribute Name
+
+Description of Values
+
+
+
+
+
+createTimestamp
+
+The time that the entry was added to the directory
+
+
+
+modifyTimestamp
+
+The time that the entry was last modified
+
+
+
+creatorsName
+
+DN of the user who added the entry to the directory
+
+
+
+modifiersName
+
+DN of the user who last modified the entry
+
+
+
+subschemaSubentry
+
+DN of the subschema entry, which controls the schema for this entry
+
+
+
+
+
+
+
+Setting Search Preferences With &DirectorySDKForC;
+
+C SDK
+search LDAP directory
+preferences
+
+For a given search, you can specify the maximum number of results to
+be returned. Alternatively, you can specify the maximum amount of time to
+wait for a search.
+
+Use the timeoutp and sizelimit arguments
+of the ldap_search_ext_s or the ldap_search_ext functions
+with the following guidelines:
+To specify an infinite time limit, in other words, no limit,
+create a timeval structure with tv_sec = tv_usec
+= 0. Then pass a pointer to the structure as the timeoutp argument.
+
+To use the time limit specified by the LDAP_OPT_TIMELIMIT
+ option for this connection, pass NULL as the
+timeoutp argument.
+To specify an infinite size limit, in other words, no limit,
+pass LDAP_NO_LIMIT as the sizelimit argument.
+
+To use the size limit specified by the LDAP_OPT_SIZELIMIT
+ option for this connection, pass NULL as the
+sizelimit argument.
+To specify preferences for all searches under the current
+connection, call ldap_set_option and set the LDAP_OPT_SIZELIMIT
+ and LDAP_OPT_TIMELIMIT options. If
+you do not want to specify a limit, in other words, no limit, set the value
+of each option to LDAP_NO_LIMIT.
+
+The LDAP server administrator might already have configured time
+limits and size constraints that you cannot override.
+The following example sets these session preferences so that a search
+returns no more than 100 entries, and takes no more than 30 seconds.
+Sample Code to
+Set Session Search Preferences
+#include <stdio.h>
+#include "ldap.h"
+...
+LDAP *ld;
+int max_ret, max_tim;
+char *host = "ldap.example.com";
+...
+/* Initialize a session with the LDAP server ldap.example.com:389. */
+/* Use prldap_init() for IPv6 support. */
+if ( ( ld = ldap_init( host, LDAP_PORT ) ) == NULL ) {
+ perror( "ldap_init" );
+ return( 1 );
+}
+
+/* Set the maximum number of entries returned. */
+max_ret = 100;
+ldap_set_option(ld, LDAP_OPT_SIZELIMIT, (void *)&max_ret );
+
+
+/* Set the maximum number of seconds to wait. */
+max_tim = 30;
+ldap_set_option( ld, LDAP_OPT_TIMELIMIT, (void *)&max_tim );
+...
+
+
+
+Getting the Search Results With &DirectorySDKForC;
+
+C SDK
+search LDAP directory
+results
+
+
+In LDAP v3, the server returns search results as a chain of LDAPMessage
+ structures, with each structure containing the following:
+The directory entries found by the search. In other words,
+those entries that match the search criteria.
+Any search references found within the scope of the search.
+A search reference is a reference to another LDAP server.
+
+An LDAP result code that specifies the result of the search
+operation.
+
+Because results are represented as a chain, do not free individual
+LDAPMessage structures within the chain. When you are done working
+with the results, free the chain, rather than the individual structures. If
+you free individual LDAPMessage structures from memory,
+you might lose all of the results.
+
+To retrieve an individual result from a chain of LDAPMessage structures,
+you can call one of the following sets of functions:
+To get each entry and each search reference in the result,
+call ldap_first_message and ldap_next_message.
+Both of these functions return a pointer to an LDAPMessage structure
+that represents an entry, search reference, or LDAP result code. You can get
+the count of the structures in the chain by calling ldap_count_messages
+.
+If you want to retrieve just the entries from the chain, call
+ldap_first_entry and ldap_next_entry. Both
+of these functions return a pointer to an LDAPMessage structure
+that represents an entry. You can get the count of the entries in the chain
+by calling ldap_count_entries.
+If you want to retrieve just the search references from the
+chain, call ldap_first_reference and ldap_next_reference
+. Both of these functions return a pointer to an LDAPMessage
+ structure that represents a search reference. You can get the
+count of the search references in the chain by calling ldap_count_references
+.
+
+Getting Results Synchronously
+
+C SDK
+search LDAP directory
+synchronous functions
+
+If you call ldap_search_ext_s to search the directory
+synchronously, the function blocks processes until all results have been received.
+The function then returns a chain of results in the result parameter,
+a handle to an LDAPMessage structure. The following
+example prints the values of all attributes in the entries returned by a synchronous
+search.
+Synchronous Searching
+#include <stdio.h>
+#include "ldap.h"
+/* Change these as needed. */
+#define HOSTNAME "localhost"
+#define PORTNUMBER LDAP_PORT
+#define BASEDN "dc=example,dc=com"
+#define SCOPE LDAP_SCOPE_SUBTREE
+#define FILTER "(sn=Jensen)"
+int
+main( int argc, char **argv )
+{
+ LDAP *ld;
+ LDAPMessage *res, *msg;
+ LDAPControl **serverctrls;
+ BerElement *ber;
+ char *a, *dn, *matched_msg = NULL, *error_msg = NULL;
+ char **vals, **referrals;
+ int version, i, rc, parse_rc, msgtype, num_entries = 0,
+ num_refs = 0;
+ /* Get a handle to an LDAP connection. Use prldap_init() for IPv6. */
+ if ( (ld = ldap_init( HOSTNAME, PORTNUMBER )) == NULL ) {
+ perror( "ldap_init" );
+ return( 1 );
+ }
+ version = LDAP_VERSION3;
+ if ( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ) !=
+ LDAP_SUCCESS ) {
+ rc = ldap_get_lderrno( ld, NULL, NULL );
+ fprintf( stderr, "ldap_set_option: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+ /* Bind to the server anonymously. */
+ 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 search operation. */
+ rc = ldap_search_ext_s( ld, BASEDN, SCOPE, FILTER,
+ NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &res );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_search_ext_s: %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 );
+ }
+ ldap_unbind_s( ld );
+ return( 1 );
+ }
+ num_entries = ldap_count_entries( ld, res );
+ num_refs = ldap_count_references( ld, res );
+ /* Iterate through the results. An LDAPMessage structure sent back from
+ a search operation can contain either an entry found by the search,
+ a search reference, or the final result of the search operation. */
+ for ( msg = ldap_first_message( ld, res );
+ msg != NULL;
+ msg = ldap_next_message( ld, msg ) ) {
+ /* Determine what type of message was sent from the server. */
+ msgtype = ldap_msgtype( msg );
+ switch( msgtype ) {
+ /* If the result was an entry found by the search, get and print the
+ attributes and values of the entry. */
+ case LDAP_RES_SEARCH_ENTRY:
+ /* Get and print the DN of the entry. */
+ if (( dn = ldap_get_dn( ld, res )) != NULL ) {
+ printf( "dn: %s\n", dn );
+ ldap_memfree( dn );
+ }
+ /* Iterate through each attribute in the entry. */
+ for ( a = ldap_first_attribute( ld, res, &ber );
+ a != NULL; a = ldap_next_attribute( ld, res, ber ) ) {
+ /* Get and print all values for each attribute. */
+ if (( vals = ldap_get_values( ld, res, 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 );
+ }
+ printf( "\n" );
+ break;
+ case LDAP_RES_SEARCH_REFERENCE:
+ /* The server sent a search reference encountered during the
+ search operation. */
+ /* Parse the result and print the search references.
+ Ideally, rather than print them out, you would follow the
+ references. */
+ parse_rc = ldap_parse_reference( ld, msg, &referrals, NULL, 0 );
+ if ( parse_rc != LDAP_SUCCESS ) {
+ fprintf( stderr,
+ "ldap_parse_result: %s\n",
+ ldap_err2string( parse_rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+ if ( referrals != NULL ) {
+ for ( i = 0; referrals[ i ] != NULL; i++ ) {
+ printf( "Search reference: %s\n\n", referrals[ i ] );
+ }
+ ldap_value_free( referrals );
+ }
+ break;
+ case LDAP_RES_SEARCH_RESULT:
+ /* Parse the final result 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, msg, &rc,
+ &matched_msg, &error_msg, NULL, &serverctrls, 0 );
+ 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 search operation. */
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_search_ext: %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 );
+ }
+ } else {
+ printf( "Search completed successfully.\n"
+ "Entries found: %d\n"
+ "Search references returned: %d\n",
+ num_entries, num_refs );
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ }
+ /* Disconnect when done. */
+ ldap_unbind( ld );
+ return( 0 );
+}
+
+
+Getting Results Asynchronously
+
+C SDK
+search LDAP directory
+asynchronous functions
+
+If you use the asynchronous function ldap_search_ext,
+you first need to call ldap_result to determine if the
+server sent back any results.
+ldap_result Prototype
+LDAP_API(int) LDAP_CALL ldap_result( LDAP *ld, int msgid, int all,
+ struct timeval *timeout, LDAPMessage **result );
+
+You can specify how you want to get asynchronous results.
+Retrieving Search Results Individually
+To get the results individually as the client receives the results from
+the server, pass LDAP_MSG_ONE as the all argument.
+
+#include <stdio.h>
+#include "ldap.h"
+...
+#define BASEDN "dc=example,dc=com"
+#define SCOPE LDAP_SCOPE_SUBTREE
+#define FILTER "(sn=Jensen)"
+...
+LDAP *ld;
+LDAPMessage *res;
+int msgid, rc, parse_rc, finished = 0;
+struct timeval zerotime;
+zerotime.tv_sec = zerotime.tv_usec = 0L;
+...
+/* Send the LDAP search request. */
+rc = ldap_search_ext( ld, BASEDN, SCOPE, FILTER, NULL, 0, NULL, NULL,
+ NULL, LDAP_NO_LIMIT, &msgid );
+...
+/* Poll the server for the results of the search operation. */
+while ( !finished ) {
+ rc = ldap_result( ld, msgid, LDAP_MSG_ONE, &zerotime, &res );
+ switch ( rc ) {
+ case -1:
+ /* An error occurred. */
+ ...
+ case 0:
+ /* The timeout period specified by zerotime was exceeded. */
+ ...
+ case LDAP_RES_SEARCH_ENTRY:
+ /* The server sent one of the entries found by the search. */
+ ...
+ case LDAP_RES_SEARCH_REFERENCE:
+ /* The server sent a search reference .*/
+ ...
+ case LDAP_RES_SEARCH_RESULT:
+ /* Parse the final result received from the server. */
+ ...
+ }
+...
+}
+...
+
+To get the results all at once, in other words, to block processes
+until all results are received, pass LDAP_MSG_ALL as the
+all argument.
+To get the results received thus far, pass LDAP_MSG_RECEIVED
+ as the all argument.
+
+
+If you specify either LDAP_MSG_ALL or LDAP_MSG_RECEIVED
+, the function passes back a chain of search results as the result
+ argument. If you specify LDAP_MSG_ONE, the function
+passes back a single search result as the result argument.
+The function normally returns the type of the first search result. When the
+function returns the type, as only one result is returned, the function returns
+the type of that result.
+The following example prints the values of all attributes in the entries
+returned by an asynchronous search.
+Printing Results of an Asynchronous
+Search
+#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 BASEDN "dc=example,dc=com"
+#define SCOPE LDAP_SCOPE_SUBTREE
+#define FILTER "(sn=Jensen)"
+int
+main( int argc, char **argv )
+{
+ LDAP *ld;
+ LDAPMessage *res;
+ BerElement *ber;
+ LDAPControl **serverctrls;
+ char *a, *dn, *matched_msg = NULL, *error_msg = NULL;
+ char **vals, **referrals;
+ int version, i, msgid, rc, parse_rc, finished = 0,
+ num_entries = 0, num_refs = 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 );
+ }
+ version = LDAP_VERSION3;
+ if ( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ) !=
+ LDAP_SUCCESS ) {
+ rc = ldap_get_lderrno( ld, NULL, NULL );
+ fprintf( stderr, "ldap_set_option: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+ /* Bind to the server anonymously. */
+ 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 the server cannot find an entry,
+ print the portion of the DN that matches
+ 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_s( ld );
+ return( 1 );
+ }
+ /* Send the LDAP search request. */
+ rc = ldap_search_ext( ld, BASEDN, SCOPE, FILTER,
+ NULL, 0, NULL, NULL, NULL, LDAP_NO_LIMIT, &msgid );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_search_ext: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+ /* Poll the server for the results of the search operation.
+ Passing LDAP_MSG_ONE indicates that you want to receive
+ the entries one at a time, as they come in. If the next
+ entry that you retrieve is NULL, there are no more entries. */
+ while ( !finished ) {
+ rc = ldap_result( ld, msgid, LDAP_MSG_ONE, &zerotime, &res );
+ /* The server can return three types of results back to the client,
+ and the return value of ldap_result() indicates the result type:
+ LDAP_RES_SEARCH_ENTRY identifies an entry found by the search,
+ LDAP_RES_SEARCH_REFERENCE identifies a search reference returned
+ by the server, and LDAP_RES_SEARCH_RESULT is the last result
+ sent from the server to the client after the operation completes.
+ You need to check for each of these types of results. */
+ 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 the server has still not yet sent the
+ results of the search operation back to your client.
+ Break out of this switch statement, and continue calling
+ ldap_result() to poll for results. */
+ break;
+ case LDAP_RES_SEARCH_ENTRY:
+ /* The server sent one of the entries found by the search
+ operation. Print the DN, attributes, and values of the entry. */
+ /* Keep track of the number of entries found. */
+ num_entries++;
+ /* Get and print the DN of the entry. */
+ if (( dn = ldap_get_dn( ld, res )) != NULL ) {
+ printf( "dn: %s\n", dn );
+ ldap_memfree( dn );
+ }
+ /* Iterate through each attribute in the entry. */
+ for ( a = ldap_first_attribute( ld, res, &ber );
+ a != NULL; a = ldap_next_attribute( ld, res, ber ) ) {
+ /* Get and print all values for each attribute. */
+ if (( vals = ldap_get_values( ld, res, 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 );
+ }
+ printf( "\n" );
+ ldap_msgfree( res );
+ break;
+ case LDAP_RES_SEARCH_REFERENCE:
+ /* The server sent a search reference encountered during the
+ search operation. */
+ /* Keep track of the number of search references returned from
+ the server. */
+ num_refs++;
+ /* Parse the result and print the search references.
+ Ideally, rather than print them out, you would follow the
+ references. */
+ parse_rc = ldap_parse_reference( ld, res, &referrals, NULL, 1 );
+ if ( parse_rc != LDAP_SUCCESS ) {
+ fprintf( stderr,
+ "ldap_parse_result: %s\n",
+ ldap_err2string( parse_rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+ if ( referrals != NULL ) {
+ for ( i = 0; referrals[ i ] != NULL; i++ ) {
+ printf( "Search reference: %s\n\n", referrals[ i ] );
+ }
+ ldap_value_free( referrals );
+ }
+ break;
+ case LDAP_RES_SEARCH_RESULT:
+ /* Parse the final result 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().) */
+ finished = 1;
+ parse_rc = ldap_parse_result( ld, res, &rc, &matched_msg,
+ &error_msg, NULL, &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 search operation. */
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_search_ext: %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 );
+ }
+ } else {
+ printf( "Search completed successfully.\n"
+ "Entries found: %d\n"
+ "Search references returned: %d\n"
+ "Counted to %d while waiting for the search operation.\n",
+ num_entries, num_refs, global_counter );
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ /* Do other work here while waiting for the search operation
+ to complete. */
+ if ( !finished ) {
+ do_other_work();
+ }
+ }
+ /* Disconnect when done. */
+ ldap_unbind( ld );
+ return( 0 );
+}
+/*
+ * Perform other work while polling for results. This doesn't do
+ * anything useful, but it could.
+ */
+static void
+do_other_work()
+{
+ global_counter++;
+}
+
+
+Determining Search Result Types
+
+C SDK
+search LDAP directory
+result types
+
+To determine what type of result was returned, call the ldap_msgtype
+ function.
+
+A search result can be one of the following types:
+LDAP_RES_SEARCH_ENTRY indicates that the
+result is an entry that is found in the search. You can pass the LDAPMessage
+ structure that represents the entry to ldap_get_dn to
+get the DN of the entry. You can pass the structure to ldap_first_attribute
+ and ldap_next_attribute to get the attributes
+of the entry. For details, see Getting Distinguished
+Names for Each Entry and Getting Attribute
+Types From an Entry.
+LDAP_RES_SEARCH_REFERENCE indicates that
+the result is a search reference that is found within the scope of the search.
+You can pass the LDAPMessage structure representing
+the search reference to the ldap_parse_reference function
+to get the referrals, LDAP URLs, to other servers. For details, see Getting Referrals From Search References.To
+receive search references from an LDAP v3 server, you must identify your client
+as LDAP v3 enabled. If not, the server returns the error code LDAP_PARTIAL_RESULTS
+ and a set of referrals. See Specifying
+the LDAP Version of Your Client for details.
+LDAP_RES_SEARCH_RESULT indicates that the
+result is the final data sent by the server to indicate the end of the LDAP
+search operation. You can pass the LDAPMessage structure
+that represents the result to the ldap_parse_result function
+to get the LDAP result code for the search operation. For a list of possible
+result codes for an LDAP search operation, see the ldap_search_ext_s
+3ldap man page. For details on parsing the result, see Getting Information From an LDAPMessage Structure.
+
+
+Retrieving a Chain of Results
+This example retrieves each result in a chain. The example then determines
+its type.
+#include <stdio.h>
+#include "ldap.h"
+...
+#define BASEDN "dc=example,dc=com"
+#define SCOPE LDAP_SCOPE_SUBTREE
+#define FILTER "(sn=Jensen)"
+...
+LDAP *ld;
+LDAPMessage *res, *msg;
+BerElement *ber;
+char *matched_msg = NULL, *error_msg = NULL;
+int rc, msgtype, num_entries = 0, num_refs = 0;
+...
+/* Perform the search operation. */
+rc = ldap_search_ext_s( ld, BASEDN, SCOPE, FILTER, NULL, 0, NULL, NULL,
+ NULL, LDAP_NO_LIMIT, &res );
+if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_search_ext_s: %s\n", ldap_err2string( rc ) );
+ if ( error_msg != NULL && *error_msg != '\0' ) {
+ fprintf( stderr, "%s\n", error_msg );
+ }
+ /* If the server cannot find an entry and returns the portion of
+ the DN that can find an entry, print it out. */
+ 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 );
+}
+...
+num_entries = ldap_count_entries( ld, res );
+num_refs = ldap_count_references( ld, res );
+...
+/* Iterate through the results. */
+for ( msg = ldap_first_message( ld, res ); msg != NULL;
+ msg = ldap_next_message( ld, msg ) ) {
+
+ /* Determine what type of message was sent from the server. */
+ msgtype = ldap_msgtype( msg );
+ switch( msgtype ) {
+ case LDAP_RES_SEARCH_ENTRY:
+ /* The result is an entry. */
+ ...
+ case LDAP_RES_SEARCH_REFERENCE:
+ /* The result is a search reference. */
+ ...
+ case LDAP_RES_SEARCH_RESULT:
+ /* The result is the final result sent by the server. */
+ ...
+ }
+...
+}
+...
+
+
+Getting Distinguished Names for Each Entry
+
+C SDK
+search LDAP directory
+retrieving DNs
+
+Because the DN of an entry differentiates the entry from other entries,
+you might want to access the DN in search results. You might also want to
+parse the name into its individual components. The SDK provides functions
+for both of these tasks.
+Getting the Distinguished Name of an Entry
+To get the DN of an entry, call the ldap_get_dn function.
+When finished with the DN, free the DN from memory by calling the ldap_memfree
+ function.
+Obtaining the DN for Search Result
+Entries
+#include <stdio.h>
+#include "ldap.h"
+...
+LDAP *ld;
+LDAPMessage *result, *e;
+char *dn;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(sn=Jensen)";
+...
+/* Search the directory. */
+if ( ldap_search_s( ld, my_searchbase, LDAP_SCOPE_SUBTREE,
+ my_filter, NULL, 0, &result ) !=
+ LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+
+/* For each matching entry found, print the name of the entry.*/
+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 );
+ /* Free the memory used for the DN when done */
+ ldap_memfree( dn );
+ }
+}
+/* Free the result from memory when done. */
+ldap_msgfree( result );
+
+
+Getting the Components of a Distinguished Name
+If you want to access individual components of a DN or relative DN,
+call the ldap_explode_dn or ldap_explode_rdn function,
+respectively. Both functions return a NULL terminated array
+that contains the components of the DN. When you are done working with this
+array, free the array by calling the ldap_value_free function.
+
+You can also specify whether or not you want the attribute names included
+in the array, by using the notypes parameter.
+
+Set notypes to 0 if
+you want to include attribute names, as in this function call:
+
+ldap_explode_dn( "uid=bjensen,ou=People,dc=example,dc=com", 0 )
+This function then returns this array:
+{ "uid=bjensen", "ou=People", "dc=example,dc=com", NULL }
+
+Set notypes to 1 if
+you do not want to include the attribute names in the array, as in this function
+call:
+
+ldap_explode_dn( "uid=bjensen,ou=People,dc=example,dc=com", 1 )
+This function then returns this array:
+{ "bjensen", "People", "example.com", NULL }
+
+
+Getting Attribute Types From an Entry
+
+C SDK
+search LDAP directory
+retrieving attribute types
+
+To retrieve the type, also called the name, of the first attribute in
+an entry, call the ldap_first_attribute function. To
+get the type of the next attribute, call the ldap_next_attribute function.
+
+Operational attributes such as creatorsName and
+modifyTimestamp are not normally returned in search results. You
+must explicitly specify operational attibutes by type in the search request.
+For more details, see Operational Attributes.
+
+When you are finished iterating through the attributes, you need to
+free the BerElement structure allocated by the
+ldap_first_attribute function, if the structure is not NULL.
+To free this structure, call the ldap_ber_free function.
+You should also free the attribute type returned by the ldap_first_attribute
+ function. To free the attribute type, call the ldap_memfree
+ function. The following example shows how to do this.
+Retrieving Entry Attribute Types
+#include <stdio.h>
+#include "ldap.h"
+...
+LDAP *ld;
+LDAPMessage *result, *e;
+BerElement *ber;
+char *a;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(sn=Jensen)";
+...
+/* Search the directory. */
+if ( ldap_search_s( ld, my_searchbase, LDAP_SCOPE_SUBTREE, my_filter,
+ NULL, 0, &result ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+
+/* Get the first matching entry.*/
+e = ldap_first_entry( ld, result );
+
+/* Retrieve the attributes of the entry. */
+ for (a = ldap_first_attribute(ld, e, &ber); a != NULL;
+ a = ldap_next_attribute(ld, e, ber)){
+ ...
+ /* Code to get and manipulate attribute values */
+ ...
+ }
+ ldap_memfree( a );
+ }
+ /* Free the BerElement structure from memory when done. */
+ if ( ber != NULL ) {
+ ldap_ber_free( ber, 0 );
+ }
+...
+
+
+Getting the Values of an Attribute
+
+C SDK
+search LDAP directory
+retrieving attribute values
+
+The values of an attribute are represented by a NULL terminated
+array. If the attribute contains string data, such as a name or phone number,
+the values are a list of strings. If the attribute contains binary data, the
+values are a list of berval structures, such as JPEG
+files or audio files. Use the following guidelines to retrieve the values
+of an attribute:
+
+To get the values of an attribute that contains string data,
+call the ldap_get_values function. The ldap_get_values
+ function returns a NULL terminated array of
+strings that represent the value of the attribute.
+To get the values of an attribute that contains binary data,
+call the ldap_get_values_len function. The ldap_get_values_len
+ function returns a NULL terminated array of
+berval structures that represent the value of the attribute.
+
+To get the number of values in an attribute, call either the
+ldap_count_values or ldap_count_values_len function.
+Both functions return the number of values in the attribute.
+
+When you have finished working with the values of the attribute, you
+need to free the values from memory. To free the values, call ldap_free_value
+ or ldap_free_value_len. The following example
+gets, then prints the values of an attribute in an entry. The function assumes
+that all attributes have string values.
+Retrieving Attribute Values
+#include <stdio.h>
+#include "ldap.h"
+...
+LDAP *ld;
+LDAPMessage *result, *e;
+BerElement *ber;
+char *a;
+char **vals;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(sn=Jensen)";
+int i;
+...
+/* Search the directory. */
+if ( ldap_search_s( ld, my_searchbase, LDAP_SCOPE_SUBTREE,
+ my_filter, NULL, 0, &result ) !=
+ LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+
+/* Get the first matching entry.*/
+e = ldap_first_entry( ld, result );
+
+/* Get the first matching attribute. */
+a = ldap_first_attribute( ld, e, &ber );
+
+/* Get the values of the attribute. */
+if ( ( vals = ldap_get_values( ld, e, a ) ) != NULL ) {
+ for ( i = 0; vals[i] != NULL; i++ ) {
+ /* Print the name of the attribute and each value */
+ printf( "%s: %s\n", a, vals[i] );
+ }
+ /* Free the attribute values from memory when done. */
+ ldap_value_free( vals );
+}
+...
+
+The following example gets the first value of the jpegPhoto attribute
+and saves the JPEG data to a file.
+Getting and Saving an Attribute
+Value
+#include <stdio.h>
+#include "ldap.h"
+...
+LDAP *ld;
+LDAPMessage *result, *e;
+BerElement *ber;
+char *a;
+struct berval photo_data;
+struct berval **list_of_photos;
+FILE *out;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(sn=Jensen)";
+...
+/* Search the directory. */
+if ( ldap_search_s( ld, my_searchbase, LDAP_SCOPE_SUBTREE,
+ my_filter, NULL, 0, &result ) !=
+ LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+
+/* Get the first matching entry.*/
+e = ldap_first_entry( ld, result );
+
+/* Find the jpegPhoto attribute. */
+a = ldap_first_attribute( ld, e, &ber );
+while ( strcasecmp( a, "jpegphoto" ) != 0 ) {
+ a = ldap_next_attribute( ld, e, ber );
+}
+
+/* Get the value of the attribute. */
+if ( ( list_of_photos = ldap_get_values_len( ld, e, a ) ) !=
+ NULL ) {
+ /* Prepare to write the JPEG data to a file */
+ if ( ( out = fopen( "photo.jpg", "wb" ) ) == NULL ) {
+ perror( "fopen" );
+ return( 1 );
+ }
+ /* Get the first JPEG. */
+ photo_data = *list_of_photos[0];
+ /* Write the JPEG data to a file */
+ fwrite( photo_data.bv_val, photo_data.bv_len, 1, out );
+ fclose( out );
+ /* Free the attribute values from memory when done. */
+ ldap_value_free_len( list_of_photos );
+}
+...
+
+
+Getting Referrals From Search References
+
+C SDK
+search LDAP directory
+retrieving referrals
+
+C SDK
+search LDAP directory
+retrieving search references
+
+A search reference returned from the server contains one or more
+referrals, which are LDAP URLs that identify other LDAP servers.
+To retrieve these referrals, you need to call the ldap_parse_reference function.
+The following example gets and prints the referrals from a search reference.
+Obtaining a Referral
+#include <stdio.h>
+#include "ldap.h"
+...
+LDAP *ld;
+LDAPMessage *msg;
+char **referrals;
+int i, rc, parse_rc;
+...
+parse_rc = ldap_parse_reference( ld, msg, &referrals, NULL, 0 );
+if ( parse_rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_parse_result: %s\n",
+ ldap_err2string( parse_rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+}
+if ( referrals != NULL ) {
+ for ( i = 0; referrals[ i ] != NULL; i++ ) {
+ printf( "Search reference: %s\n\n", referrals[ i ] );
+ }
+ ldap_value_free( referrals );
+}
+...
+
+
+
+Sorting the Search Results With &DirectorySDKForC;
+
+C SDK
+search LDAP directory
+client-side sorting
+
+C SDK
+search LDAP directory
+server-side sorting
+
+&DirectorySDKForC; offers functions to sort entries and values in
+the search results. You can either specify that the server return sorted results
+or you can sort entries on your client.
+Server-Side Sorting
+To sort results on the server, you need to send a server-side sorting
+control with the search request. For details, see Using
+the Server-Side Sorting Control With Directory SDK for C for details.
+
+Client-Side Sorting
+First, you need to retrieve the attributes that you plan to use for
+sorting. For example, you might plan to sort the results by email address.
+Make sure that the mail attribute is one of the attributes
+returned in the search.
+Sorting Entries by an Attribute
+To sort the search results by a particular attribute, call the ldap_sort_entries
+ function. If you do no’t specify an attribute for sorting,
+that is, if you pass NULL for the attr parameter,
+the entries are sorted by DN.
+Sorting Entries
+by an Attribute
+This example sorts entries by the roomNumber attribute.
+#include <stdio.h>
+#include <string.h>
+#include "ldap.h"
+...
+LDAP *ld;
+LDAPMessage *result;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(sn=Jensen)";
+char *sortby = "roomNumber";
+...
+/* Search the directory. */
+if ( ldap_search_s( ld, my_searchbase, LDAP_SCOPE_SUBTREE,
+ my_filter, NULL, 0, &result ) !=
+ LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+
+/* Sort the results by room number, using strcasecmp. */
+if ( ldap_sort_entries(ld, &result, sortby, strcasecmp) !=
+ LDAP_SUCCESS ){
+ ldap_perror( ld, "ldap_sort_entries" );
+ return( 1 );
+}
+...
+
+
+Sorting Entries by Multiple Attributes
+To sort the search results by multiple attributes, call the ldap_multisort_entries
+ function. If you do not specify a set of attributes for sorting,
+the entries are sorted by DN. To sort entries by DN, pass NULL for
+the attr parameter.
+Sorting
+Entries by Multiple Attributes
+This example sorts entries first by the roomNumber attribute,
+then by the telephoneNumber attribute.
+#include <stdio.h>
+#include <string.h>
+#include "ldap.h"
+LDAP *ld;
+LDAPMessage *res;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(sn=Jensen)";
+char *attrs[2];
+attrs[0] = "roomNumber";
+attrs[1] = "telephoneNumber";
+attrs[2] = NULL;
+...
+/* Search the directory. */
+if ( ldap_search_s( ld, my_searchbase, LDAP_SCOPE_SUBTREE,
+ my_filter, NULL, 0, &res ) !=
+ LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+
+/* Sort the results, using strcasecmp. */
+if ( ldap_multisort_entries(ld,&res,attrs, strcasecmp) !=
+ LDAP_SUCCESS ){
+ ldap_perror( ld, "ldap_sort_entries" );
+ return( 1 );
+}
+
+
+Sorting the Values of an Attribute
+You can also sort the values of a particular attribute. To sort the
+values, call the ldap_sort_strcasecmp function. In this
+function, the comparison function must pass parameters of the type char
+**. You should use the ldap_sort_strcasecmp function,
+rather than a function like strcasecmp, which passes
+parameters of the type char *. The following example sorts
+the values of attributes before printing the values.
+Sorting Attribute
+Values
+#include <stdio.h>
+#include <string.h>
+#include "ldap.h"
+LDAP *ld;
+LDAPMessage *result, *e;
+BerElement *ber;
+char *a, *dn;
+char **vals;
+int i;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(sn=Jensen)";
+...
+ if ( ( vals = ldap_get_values( ld, e, a ) ) != NULL ) {
+ /* Sort the values of the attribute */
+ if ( ldap_sort_values(ld, vals, strcasecmp)) !=
+ LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_sort_values" );
+ return( 1 );
+ }
+ /* Print the values of the attribute. */
+ for ( i = 0; vals[i] != NULL; i++ ) {
+ printf( "%s: %s\n", a, vals[i] );
+ }
+ /* Free the values from memory. */
+ ldap_value_free( vals );
+ }
+...
+
+
+
+
+Freeing the Search Results With &DirectorySDKForC;
+
+C SDK
+search LDAP directory
+freeing results
+
+The results of the search are returned in an LDAPMessage structure.
+After you are done working with the search results, you should free this structure
+from memory. To free the search results, call the ldap_msgfree function,
+which returns the type of the last message freed from memory.
+Examples of Search Operations With &DirectorySDKForC;
+
+
+C SDK
+search LDAP directory
+examples
+
+This section contains sample code for various search operations.
+Reading an Entry With a Search
+You can use the search functions to read a specific entry in the directory.
+To read an entry, set the starting point of the search to the entry. Also,
+set the scope of the search to LDAP_SCOPE_BASE, specifying
+(objectclass=*) as the search filter, as shown in the following
+example.
+Reading a Specific Entry With
+a Search
+#include <stdio.h>
+#include "ldap.h"
+/* Change these as needed. */
+#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. Use prldap_init() for IPv6. */
+ if ( (ld = ldap_init( HOSTNAME, PORT_NUMBER )) == NULL ) {
+ perror( "ldap_init" );
+ return( 1 );
+ }
+ /* Bind anonymously to the LDAP server. */
+ if ( ( rc = ldap_simple_bind_s( ld, NULL, NULL ) ) !=
+ 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 this is 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 );
+}
+
+
+Listing Subentries With a Search
+You can use the search functions to list the subentries under a specific
+entry in the directory. To list the subentries, set the starting point of
+the search to the entry. Also, set the scope of the search to LDAP_SCOPE_ONELEVEL
+. The following lists all entries one level under the dc=example,dc=com
+ entry in the directory hierarchy.
+Listing Subentries
+#include <stdio.h>
+#include "ldap.h"
+
+LDAP *ld;
+LDAPMessage *result, *e;
+BerElement *ber;
+char *a, *dn;
+char **vals;
+char *my_searchbase = "dc=example,dc=com";
+char *my_filter = "(objectclass=*)"
+
+/* Search one level under the starting point. */
+if ( ldap_search_s( ld, my_searchbase, LDAP_SCOPE_ONELEVEL, my_filter,
+ NULL, 0, &result ) != LDAP_SUCCESS ) {
+ ldap_perror( ld, "ldap_search_s" );
+ return( 1 );
+}
+/* For each matching entry, print the entry name and its attributes. */
+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 );
+ }
+ for ( a = ldap_first_attribute( ld, e, &ber ); a != NULL;
+ a = ldap_next_attribute( ld, e, ber ) ) {
+ 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 ) {
+ ldap_ber_free( ber, 0 );
+ }
+ printf( "\n" );
+}
+ldap_msgfree( result );
+...
+
+
+Sending Search Request Using &DirectorySDKForC;
+The following sample code shows how to search for all entries with the
+last name (surname) Jensen in the example.com organization.
+
+Sending a Search Request
+#include <stdio.h>
+#include "ldap.h"
+...
+#define BASEDN "dc=example,dc=com"
+#define SCOPE LDAP_SCOPE_SUBTREE
+#define FILTER "(sn=Jensen)"
+...
+LDAP *ld;
+int msgid, rc;
+...
+/* Send the search request. */
+rc = ldap_search_ext( ld, BASEDN, SCOPE, FILTER, NULL, 0, NULL,
+ NULL, NULL, LDAP_NO_LIMIT, &msgid );
+if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_search_ext: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+}
+...
+
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-server-info.sgm b/mozilla/directory/docs/ldapcsdk/csdk-server-info.sgm
new file mode 100644
index 00000000000..1d0e23bd92c
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-server-info.sgm
@@ -0,0 +1,374 @@
+
+Getting Server Information With &DirectorySDKForC;
+
+
+C SDK
+getting server information
+
+This chapter explains how to access and modify information about your
+LDAP server over the LDAP protocol.
+
+This chapter covers the following topics:
+Reading DSEs With Directory SDK for
+C
+Determining LDAP v3 Support With
+Directory SDK for C
+Getting Schema Information With Directory
+SDK for C
+
+
+Reading DSEs With &DirectorySDKForC;
+
+C SDK
+getting server information
+DSE
+
+A DSA-specific entry, DSE, 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 dc=example,dc=com in the directory tree.
+The root DSE is specified as part of LDAP v3. Note that LDAP v2 servers
+do not necessarily have a root DSE.
+
+The root DSE can contain the following information:
+The naming contexts of this server such as, dc=example,dc=com
+
+URLs of alternate servers to contact if this server is unavailable
+
+The versions of LDAP supported by this server, version 2 or
+version 3
+The LDAP v3 controls supported by the serverSee Chapter 16, LDAP Controls With Directory SDK
+for C for details.
+The SASL mechanisms supported by the serverSee Chapter 17, SASL Authentication With Directory
+SDK for C for details.
+The LDAP v3 extended operations supported by the server
+See Chapter 18, Extended Operations
+With Directory SDK for C for details.
+
+The following lists root DSE attributes and explains the meaning of
+their values.
+
Root DSE
+Attributes and Descriptions of Their Values
+
+
+
+
+Attribute Name
+
+Description of Values
+
+
+
+
+
+namingContexts
+
+The naming contexts supported by this server, such dc=example,dc=com
+.
+
+
+
+altServer
+
+LDAP URLs that identify other servers to contact if this server is unavailable.
+
+
+
+
+supportedExtension
+
+The object identifiers (OIDs) of the LDAP v3 extended operations supported
+by this server.
+If this attribute is not in the root DSE, the server does not support
+any extended operations.
+
+
+
+supportedControl
+
+The OIDs of the LDAP v3 controls supported by this server.
+If this attribute is not in the root DSE, the server does not support
+any LDAP v3 controls.
+
+
+
+supportedSASLMechanisms
+
+The names of the SASL mechanisms supported by the server.
+If this attribute is not in the root DSE, the server does not support
+any SASL mechanisms.
+
+
+
+supportedLDAPVersion
+
+The value of this attribute is the version of LDAP supported by this
+server, such as 2 or 3.
+
+
+
+
+To Get the Root DSE
+
+Initialize an LDAP session by calling the ldap_init or
+prldap_init function.
+Turn off automatic referral handling by calling the ldap_set_option
+ function and setting the LDAP_OPT_REFERRALS option
+to LDAP_OPT_OFF.
+Search the directory with the following criteria:
+
+Set the search scope to a base search.
+
+Specify an empty string for the base DN.
+Use the search filter (objectclass=*).
+
+
+Check the results of the search.If the server returns
+a result code, such as LDAP_OPERATIONS_ERROR, LDAP_PROTOCOL_ERROR
+, LDAP_REFERRAL, or LDAP_NO_SUCH_OBJECT
+, the LDAP server probably does not support LDAP v3.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 LDAP structure, you have created
+by calling ldap_init or prldap_init.
+The function returns 0 if successful or 1 if
+an error occurred.
+
+
+Getting the Root DSE and Printing its Attribute Values
+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 );
+}
+
+
+
+Determining LDAP v3 Support With &DirectorySDKForC;
+
+C SDK
+getting server information
+LDAP v3 support
+
+You can determine what version an LDAP server supports by getting the
+supportedLDAPVersion attribute from the root DSE. This attribute
+could contain the value 2 or 3.
+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.
+The following example connects to an LDAP server. The example code then
+determines whether the server supports LDAP v3.
+Determining the Supported
+LDAP Version
+/* 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 );
+}
+...
+
+
+Getting Schema Information With &DirectorySDKForC;
+
+C SDK
+getting server information
+schema
+
+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 subschema entry. To find the DN of the
+subschema entry, get the subschemaSubentry operational
+attribute from the root DSE or any entry.
+
+The subschema entry can have the following attributes:
+objectClasses specifies the object class
+definitions in the schema. Each value of this attribute is an object class
+that is known to the server.
+attributeTypes specifies the attribute
+type definitions in the schema. Each value of this attribute is an attribute
+type that is known to the server.
+matchingRules specifies the matching rule
+definitions in the schema. Each value of this attribute is a matching rule
+that is known to the server.
+matchingRuleUse 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.
+
+For information about the format of the attribute values, see RFC
+4517, Lightweight Directory Access Protocol (v3): Attribute
+Syntax Definitions.
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-ssl.sgm b/mozilla/directory/docs/ldapcsdk/csdk-ssl.sgm
new file mode 100644
index 00000000000..a9cb35954f7
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-ssl.sgm
@@ -0,0 +1,382 @@
+
+SSL Connections With &DirectorySDKForC;
+
+C SDK
+Secure Sockets Layer (SSL)
+
+This chapter describes the process of enabling an LDAP client to connect
+to an LDAP server over the Secure Sockets Layer (SSL) protocol.
+
+This chapter covers the following topics:
+How SSL Works With Directory SDK
+for C
+Connecting to a Server Over SSL With
+Directory SDK for C
+Handling Errors With Directory SDK
+for C
+Starting Transport Layer
+Security With Directory SDK for C
+Installing Your Own SSL I/O Functions
+With Directory SDK for C
+Using Certificate-Based Client Authentication
+With Directory SDK for C
+
+
+How SSL Works With &DirectorySDKForC;
+The primary goal of the SSL protocol is to provide privacy and reliability
+between two communicating applications.
+SSL is not supported on all LDAP servers.SSL communication
+must take place on a separate TCP port unless the server supports Start TLS.
+
+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
+not trusted, the client also refuses to connect to the server.
+The LDAP server can also request that the client send a certificate
+to authenticate itself. This part of the process is called certificate-based
+client authentication. 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 not
+trusted, 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.
+
+&DirectorySDKForC; includes functions that allow you to connect an
+LDAP client to an LDAP server over SSL. The functions make the following assumptions:
+
+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.Different certificate database
+versions can be incompatible, which might result in database errors.
+
+
+
+The database used contains any one of the following:
+The certificate of the CA that issued the server’s certificate
+
+If the CAs are organized in a hierarchy, the certificate of
+any of the CAs in the hierarchy
+The certificate of the LDAP server
+
+
+The CA certificate is marked as trusted in
+the certificate database.
+
+
+If you plan to use certificate-based client authentication, you also
+need the following:
+A client certificate in the certificate database issued by
+a CA that is trusted by the LDAP server
+A public-private key pair in a key file
+
+
+
+
+The functions allow you to do the following:
+Set the session option for communicating with the server over
+SSL.See Connecting to a Server Over
+SSL With Directory SDK for C for details.
+Start transport layer security by using the Start TLS extended
+operationSee Starting Transport
+Layer Security With Directory SDK for C for details.
+Replace the default I/O functions with your own I/O functions
+for communicating over SSLSee Installing
+Your Own SSL I/O Functions With Directory SDK for C for details.
+
+Enable your client to send certificates to authenticate itself
+See Using Certificate-Based Client Authentication
+With Directory SDK for C for details.
+
+
+Connecting to a Server Over SSL With &DirectorySDKForC;
+
+C SDK
+Secure Sockets Layer (SSL)
+connecting to the server
+
+To enable your LDAP client to connect to an LDAP server with SSL, you
+need to perform the following procedure.
+To Initialize a Client SSL Connection by Using ldapssl_init
+
+
+Initialize your client by calling one of the following functions:
+
+Call ldapssl_client_init if you do not plan
+to use certificate-based client authentication.
+Call ldapssl_clientauth_init if you plan
+to use certificate-based client authentication.
+Call ldapssl_advclientauth_init.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.
+You must initialize your client before initializing the LDAP session.
+The process of initializing the client opens the certificate database.
+
+Initialize an LDAP session with the secure server by calling the
+ldapssl_init function.For an alternative way to accomplish
+this step, see Alternative to ldapssl_init.
+
+
+
+To Initialize a Client SSL Connection by using ldapssl_init
+This example initializes a client to connect to a secure LDAP server
+over SSL.
+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. */
+...
+
+
+Alternative to ldapssl_init
+As an alternative to calling the ldapssl_init function,
+you can use the following procedure.
+To Initialize a Client SSL Connection (Alternative Method Using
+ldap_init
+
+After initializing your client, initialize an LDAP session with
+the server by calling the standard initialization function ldap_init.
+
+Install the standard SSL I/O functions by calling ldapssl_install_routines
+.
+Set the SSL option in the LDAP structure by calling ldap_set_option
+.
+
+
+Initializing a Client SSL Initialization (Alternative Method Using
+ldap_init)
+This example prepares a client to connect to a secure LDAP server over
+SSL using ldap_init.
+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. */
+...
+
+
+
+
+Handling Errors With &DirectorySDKForC;
+
+C SDK
+Secure Sockets Layer (SSL)
+handling errors
+
+After calling any of the SSL initialization functions, you can convert
+SSL-specific error codes to text strings by calling ldapssl_err2string.
+The ldapssl_err2string function provides support for
+special SSL error messages that are not handled by the normal error conversion
+routine ldap_err2string.
+Starting Transport Layer Security With &DirectorySDKForC;
+
+C SDK
+Secure Sockets Layer (SSL)
+start TLS
+
+RFC
+4513, Lightweight Directory Access Protocol (LDAP): Authentication
+Methods and Security Mechanisms, describes the extended operation.
+Start TLS allows you to connect to a nonsecure port, and then request transport
+layer security.
+To Use Start TLS
+
+Initialize your client with ldapssl_client_init.
+The process of initializing the client opens the certificate
+database.
+Get a handle to an LDAP connection.
+Request Start TLS with ldap_start_tls_s.
+
+Authenticate to the directory to perform additional operations.
+
+
+
+Using Start TLS
+This example connects and uses Start TLS, then requests the Who am I?
+extended operation. The example relies on a certificate database directory, /local/examples/alias/.
+/*
+ * 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 );
+}
+See Performing a Who Am I? Extended
+Operation With Directory SDK for C for details on using the “Who
+am I?” extended operation.
+
+To troubleshoot Start TLS problems, call the PR_GetError function.
+This function gives you access to many Network Security Services (NSS) errors
+further documented in the Mozilla.org SSL Reference.
+
+
+Installing Your Own SSL I/O Functions With &DirectorySDKForC;
+
+C SDK
+Secure Sockets Layer (SSL)
+custom I/O functions
+
+The ldapssl_init and ldapssl_install_routines
+ 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 ldap_x_ext_io_fns structure.
+To Install Your Own SSL I/O Functions
+
+Create an ldap_x_ext_io_fns structure,
+and set the fields to point to your I/O functions.
+Call ldap_set_option to point to that structure.
+
+if (ldap_set_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS, &my_io_struct) != 0 ) {
+ ldap_perror( ld, "ldap_set_option" );
+ return( 1 );
+}
+
+
+
+
+Using Certificate-Based Client Authentication With &DirectorySDKForC;
+
+C SDK
+Secure Sockets Layer (SSL)
+certificate-based authentication
+
+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.
+To Use Certificate-Based Client Authentication
+
+Initialize your LDAP client by calling either ldapssl_clientauth_init
+ or ldapssl_advclientauth_init, not ldapssl_client_init
+.Use ldapssl_advclientauth_init if
+you want to specify the path of a security module database, or to specify
+the method used to verify the server certificate.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 ldapssl_client_init.
+Initialize an LDAP session with the secure server by calling
+ldapssl_init.
+Enable your client to authenticate with the secure server by calling
+ldapssl_enable_clientauth.
+Perform a Simple Authentication and Security Layer (SASL) bind
+operation by using the mechanism EXTERNAL. This mechanism
+indicates to the directory server that certificates should be used to authenticate
+clients.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 LDAP_INVALID_CREDENTIALS result
+code with the error message Client Certificate Mapping Failed.
+
+
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-understanding.sgm b/mozilla/directory/docs/ldapcsdk/csdk-understanding.sgm
new file mode 100644
index 00000000000..cbc56096b51
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-understanding.sgm
@@ -0,0 +1,970 @@
+
+About &DirectorySDKForC;
+
+
+This chapter introduces &DirectorySDKForC; and covers the following
+topics:
+Overview of Directory SDK for C
+
+Files Provided With Directory SDK
+for C
+Compiling Applications with Directory
+SDK for C
+Sample Programs for Directory SDK
+for C
+
+
+Overview of &DirectorySDKForC;
+
+C SDK
+overview of
+
+&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.
+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 The C LDAP
+Application Programming Interface.
+LDAP API
+
+LDAP Application Programming Interface (API)
+LDAP API
+LDAP API
+
+APIs
+LDAP
+
+RFC
+4511, Lightweight Directory Access Protocol (v3),
+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.
+
+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:
+Search for and retrieve a list of entries.
+Add new entries to the database.
+Update existing directory entries.
+Delete entries.
+Rename entries.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.
+
+
+Synchronous and Asynchronous Operations
+
+C SDK
+synchronous functions
+
+C SDK
+asynchronous functions
+
+operations
+asynchronous
+
+operations
+synchronous
+
+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.
+
+Call a synchronous function to wait for the operation to complete
+before receiving the return value of a function.
+Call an asynchronous function to perform other work while
+waiting for an operation to complete. Your application must then poll for
+results.For more information, see Synchronous
+Examples, and Asynchronous Examples.
+
+
+
+Files Provided With Directory SDK for C
+
+C SDK
+files installed
+
+&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.
+
&DirectorySDKForC; Content
+
+
+
+
+Directory Location
+
+Description
+
+
+
+
+
+etc/
+
+Contains miscellaneous files for you to use. The files are described
+in Miscellaneous Files
+
+
+
+examples/
+
+Contains sample source code and Makefiles for LDAP clients. See the
+README file in this directory for more information.
+
+
+
+include/
+
+Contains the header files. You must include the files in this directory
+in your client source files. The header files are described in Directory SDK for C Header Files
+
+
+
+include-nspr/
+
+Contains Netscape Portable Runtime (NSPR) header files. NSPR provides
+a platform-neutral API for system—level and libc—style
+functions.
+
+
+
+include-private/
+
+Contains private header files that are not documented in this guide.
+
+
+
+
+lib/
+
+Contains the C library files. The specific library used is dependent
+on the type of application you are building. For details see Directory SDK for C Libraries.
+
+
+
+lib-private/
+
+Contains private libraries that are not documented in this guide.
+
+
+
+
+tools/
+
+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.
+
+
+
+
+&DirectorySDKForC; Header Files
+
+C SDK
+header files
+
+header files
+C SDK
+
+The following table describes &DirectorySDKForC; header files that
+are in the include/ directory.
+All locations are relative to the directory where the software
+is installed, which depends on your operating system.
+
&DirectorySDKForC; Header
+Files
+
+
+
+
+Header File
+
+Description
+
+
+
+
+
+disptmpl.h
+
+A header file related to the templates (ldaptemplates.conf).
+
+
+
+
+lber.h
+
+Contains prototypes for the standard Basic Encoding Rules (BER) functions,
+structures, and defines. For details see lber.h Header
+File
+
+
+
+ldap-deprecated.h
+
+Contains deprecated functions that should not be used. This header is
+included in ldap.h.
+
+
+
+ldap-extension.h
+
+Contains functions, structures, and defines that extend the standard
+LDAP C API specification. This header is included in ldap.h.
+
+
+
+
+ldap-platform.h
+
+A private header file that contains platform-specific definitions, which
+allow abstraction from the underlying system.
+
+
+
+ldap-standard.h
+
+Contains the standard LDAP functions, structures, and defines. This
+header is included in ldap.h.
+
+
+
+ldap-to-be-deprecated.h
+
+Contains functions, structures, and defines that might be deprecated
+in future releases. This header is included in ldap.h.
+
+
+
+
+ldap.h
+
+This base header contains LDAP functions, structures, and defines to
+mirror the latest LDAP C API specifications.
+
+This header also includes the following header files:
+ldap-deprecated.h
+ldap-extension.h
+ldap-standard.h
+ldap-to-be-deprecated.h
+
+For details, see ldap.h Header File.
+
+
+
+
+ldap_ssl.h
+
+Contains prototypes for LDAP over SSL functions, structures, and defines.
+For details, see ldap_ssl.h Header File
+
+
+
+
+ldappr.h
+
+Contains prototypes for the functions, structures, and defines that
+are contained in the Netscape Portable Runtime (NSPR) API. For details seeldappr.h Header File
+
+
+
+srchpref.h
+
+A header file related to the search preferences (ldapsearchprefs.conf
+ ).
+
+
+
+
+ldap.h Header File
+
+ldap.h header file
+including
+To make use of the &DirectorySDKForC; functions, include the
+ldap.h header file in your C source files as shown in this line
+of code:
+#include "ldap.h"
+
+By including this file, you also include the following header files:
+ldap-deprecated.h
+ldap-extension.h
+ldap-standard.h
+ldap-platform.h
+ldap-to-be-deprecated.h
+
+
+lber.h Header File
+
+lber.h header file
+including
+
+lber.h is included in ldap-standard.h.
+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.
+
+ldap_ssl.h Header File
+
+ldap_ssl.h header file
+including
+If you are calling LDAP over SSL functions, you also need to include
+the ldap_ssl.h header file, as follows:
+#include "ldap_ssl.h"
+
+ldappr.h Header File
+
+ldappr.h header file
+including
+
+To make use of the Netscape Portable Runtime (NSPR) API with your LDAP
+applications, you must include the ldappr.h 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:
+#include "ldappr.h"
+For more information about NSPR, see the ldappr.h header
+file and the Netscape Portable Runtime project page at http://www.mozilla.org/projects/nspr/
+.
+
+Miscellaneous Files
+
+ldapfilter.confsample file
+
+ldapfriendlysample file
+
+ldapsearchprefs.confsample file
+
+ldaptemplates.confsample file
+
+C SDK
+sample files
+
+&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 etc/ directory. All locations are
+relative to the directory where the software is installed, which depends on
+your operating system.
+
Sample Configuration
+Files
+
+
+
+
+File Name
+
+Description
+
+
+
+
+
+ldapfilter.conf
+
+This filter configuration file can be used in context with ldap_init_getfilter
+.
+
+
+
+ldapfriendly
+
+This file is used to map the two—letter country codes to their
+full names by ldap_friendly_name.
+
+
+
+ldapsearchprefs.conf
+
+This configuration file was used in context with a deprecated function.
+
+
+
+
+ldaptemplates.conf
+
+This configuration file was used in context with a deprecated function.
+
+
+
+
+
+
+&DirectorySDKForC; Libraries
+
+C SDK
+libraries
+
+libraries
+C SDK
+
+&DirectorySDKForC; includes several different libraries. A library
+is a set of ready-made functions that are linked into a program. &DirectorySDKForC; uses
+shared libraries. Shared libraries are dynamically loaded into
+memory when needed, reducing the size of the executable.
+Library Naming Conventions
+Libraries on different systems have different naming conventions. The
+following table shows the&DirectorySDKForC; naming conventions.
+
Library
+Naming Convention by Operating System
+
+
+
+
+
+
+
+Operating System
+
+Static Library Name
+
+Shared Library Name
+
+
+
+
+
+Solaris and Red Hat systems
+
+liblibraryname.a
+
+
+liblibraryname.so.versionnumber
+
+
+
+
+HP-UX systems
+
+liblibraryname.a
+
+
+liblibraryname.sl
+
+
+
+
+Windows systems
+
+nslibraryname.lib
+
+
+nslibraryname.dll
+
+
+
+
+
+On UNIX systems, the shared
+library file name can be fully qualified by prefixing path information.
+
+Installed Shared Libraries
+The following table describes the installed libraries that are in the
+lib/ directory. All locations are relative to the directory where
+the software is installed, which depends on your operating system.
+
Shared Libraries
+
+
+
+
+UNIX Library
+
+Windows Library
+
+Description
+
+
+
+
+
+libldap60.so
+
+nsldap32v60.dll
+
+LDAP library.
+
+
+
+libprldap60.so
+
+nsldappr32v60.dll
+
+LDAP library built with NSPR.
+This library requires the libnspr4.so library in
+the lib-private/ directory.
+
+
+
+libssldap60.so
+
+nsldapssl32v60.dll
+
+LDAP library that is built with support for the Secure Sockets Layer
+protocol.
+This library depends on the libnss3.so and libnspr4.so
+ libraries in the lib-private/ directory.
+
+
+
+
+
+
+&DirectorySDKForC; Dependencies
+
+&DirectorySDKForC; resolves dependencies for the following APIs at
+run—time:
+Netscape Portable Runtime (NSPR) provides core cross-platform
+functions.
+Netscape Security Services (NSS) provides encryption, cryptographic,
+Secure Sockets Layer (SSL), and Public Key Infrastructure (PKI) support.
+
+Simple Authentication and Security Layer (SASL) provides support
+for applications that require SASL.
+
+
+
+LDAP Tools
+
+LDAP tools
+
+&DirectorySDKForC; includes several utilities to help you work with
+LDAP data sets. These utilities are installed in the tools/ 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.
+
&DirectorySDKForC; LDAP
+Tools
+
+
+
+
+Command
+
+Description
+
+
+
+
+
+ldapcmp
+
+Compares the contents of a single LDAP entry or subtree in two directories.
+
+
+
+
+ldapcompare
+
+Compares an attribute value against the contents of a given LDAP entry.
+
+
+
+
+ldapdelete
+
+Deletes existing LDAP entries.
+
+
+
+ldapmodify
+
+Edits the contents of an LDAP directory, either by adding new entries
+or modifying existing ones.
+
+
+
+ldappasswd
+
+Changes user passwords on LDAP entries.
+
+
+
+ldapsearch
+
+Issues search requests to an LDAP directory, then displays the result
+as LDAP Data Interchange Format (LDIF) text.
+
+
+
+
+
+
+Compiling Applications with Directory SDK for C
+
+C SDK
+compiling applications
+
+When compiling applications, you must include the header files and link
+to the libraries required. Information about including the header files is
+in Directory SDK for C Header Files. Linking
+to shared libraries is covered in this section. &DirectorySDKForC; is qualified
+to work with C compilers.
+&DirectorySDKForC; is not guaranteed to work with C++ compilers.
+
+Compiling on UNIX Platforms
+When compiling clients on UNIX platforms, specify link options correctly
+to link the application to the appropriate shared libraries. See the Makefile
+ in the examples/ directory for details on
+compiling your applications on UNIX platforms.
+Compiling on Windows Systems With &DirectorySDKForC;
+
+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 FILE pointer as found in UNIX systems.
+Given this difference, make sure that you define the following:
+_CONSOLE if you are writing a console application
+
+_WINDOWS if you are writing a standard
+Windows GUI application
+
+
+Linking Dependencies
+
+libraries
+runtime
+
+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 runtime libraries.
+Any of the following options ensure that the operating system can find the
+shared libraries.
+
+Make sure that the shared library file, such as libldap60.so
+, is in a location specified by environment variables.
+
+On some platforms, clients can be complied with flags that
+let you set the runtime path to load libraries as an environment variable.
+
+On Solaris and Red Hat systems, you
+can use the LD_LIBRARY_PATH environment variable if you use
+the -Wl,+s+b flag when compiling and linking.
+
+On HP-UX system, use the SHLIB_PATH environment
+variable.
+
+
+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
+system32\ directory. Make sure that your client finds the DLLs
+included with &DirectorySDKForC; before your client finds the version in
+the system32\ directory. At runtime, your client searches
+for the DLL in the following locations in the order shown:
+The directory from which the application loaded
+
+The current directory
+The Windows system directory, typically winnt\system32\
+To avoid potential conflicts, do not copy the DLL
+to this directory
+The directories listed in the PATH environment
+variable
+
+
+
+
+Use a link flag that specifies the path where the executable
+can find the library. For example, on Solaris systems, you can use the -R
+ flag to specify the path where the executable can find the library.
+See the Makefile in the examples/ directory
+for examples of additional settings for compiling and linking your LDAP client.
+Different platforms might require different sets of define statements.
+
+
+
+
+Sample Programs for Directory SDK for C
+
+C SDK
+sample programs
+
+example programs
+C SDK
+
+&DirectorySDKForC; includes several examples that demonstrate the
+use of the functions that the SDK provides. The examples are located in the
+examples/ 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 README in the examples/
+ directory.
+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.
+Synchronous Examples
+
+C SDK
+synchronous examples
+
+example programs
+C SDK
+synchronous
+
+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.
+
Synchronous
+Example Programs
+
+
+
+
+Example Source
+
+Description
+
+
+
+
+
+authzid.c
+
+Shows how to use the authorization ID control, which allows you to get
+the authorization ID for an LDAP operation.
+
+
+
+compare.c
+
+Shows how to use ldap_compare_s, which allows you
+to test if a particular value is contained in an attribute of an entry.
+
+
+
+
+crtfilt.c
+
+Shows how to use the ldap_create_filter function
+to generate LDAP filters.
+
+
+
+csearch.c
+
+Like search.c, but enables an in-memory cache.
+
+
+
+
+effright.c
+
+Shows how to use the get effective rights control, which allows you
+to determine access rights to entries and their attributes.
+
+
+
+getattrs.c
+
+Retrieves specific attributes from an entry.
+
+
+
+getfilt.c
+
+Shows how to use the ldap_getfilter* family of
+functions, which generate LDAP filters that are based on an arbitrary search
+string provided by a user.
+
+
+
+modattrs.c
+
+Shows how to use ldap_modify_s to replace and add
+to values in an attribute.
+
+
+
+modrdn.c
+
+Shows how to use ldap_modrdn2_s to change the relative
+distinguished name (RDN) of an entry.
+
+
+
+pwdextop.c
+
+Shows how to use the LDAP password modify extended operation to change
+a password.
+
+
+
+pwdpolicy.c
+
+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.
+
+
+
+rdentry.c
+
+Shows how to use ldap_search_s to retrieve a particular
+entry from the directory.
+
+
+
+realattr.c
+
+Shows how to use the control to retrieve only real attributes during
+a search.
+
+
+
+search.c
+
+Shows how to use ldap_search_s to search for all
+entries that have an attribute value that exactly matches what you search
+for.
+
+
+
+srvrsort.c
+
+Shows how to use server-side sorting in conjunction with the ldap_search_ext_s
+ function.
+
+
+
+ssearch.c
+
+Like ssnoauth.c, but includes certificate-based
+authentication.
+
+
+
+ssnoauth.c
+
+Like search.c, but the search is done over an SSL-protected
+TCP connection.
+
+
+
+starttls.c
+
+Shows how to use the Start TLS extended operation.
+
+
+
+userstatus.c
+
+Shows how to use the account status control to retrieve information
+about the account of the user binding to the directory.
+
+
+
+virtattr.c
+
+Shows how to use the control to retrieve only virtual attributes during
+a search.
+
+
+
+whoami.c
+
+Shows how to use the Who am I? extended operation to retrieve the authorization
+ID.
+
+
+
+
+
+Asynchronous Examples
+
+C SDK
+asynchronous examples
+
+example programs
+C SDK
+asynchronous programs
+
+These examples use the asynchronous LDAP calls. You begin an operation.
+You then periodically poll to see if any results have been returned.
+
Asynchronous
+Example Programs
+
+
+
+
+Example Source
+
+Description
+
+
+
+
+
+add.c
+
+Adds an entry to the directory.
+
+
+
+asearch.c
+
+Initiates a search for entries, printing the results on arrival.
+
+
+
+
+del.c
+
+Deletes an entry from the directory.
+
+
+
+nsprio.c
+
+Like asearch. but uses the PerLDAP routines to incorporate
+the Netscape Portable Runtime (NSPR) API.
+
+
+
+ppolicy.c
+
+Attempts to bind to the directory and reports back any password expiration
+information received. This program demonstrates how clients can process password
+policy information.
+
+
+
+psearch.c
+
+Shows how to use Persistent Search, an LDAP v3 extension, to monitor
+a directory for changes.
+
+
+
+
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-whatsnew.sgm b/mozilla/directory/docs/ldapcsdk/csdk-whatsnew.sgm
new file mode 100644
index 00000000000..3937ed0d75c
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-whatsnew.sgm
@@ -0,0 +1,178 @@
+
+What's New In &DirectorySDKForC;
+
+upgrading
+C SDK
+
+This chapter compares the current version of &DirectorySDKForC; API
+with the previous version.
+
+This chapter covers the following topics:
+Deprecated and Changed
+Directory SDK for C Features
+New Directory SDK for
+C Features
+
+
+Deprecated and Changed &DirectorySDKForC; Features
+
+
+deprecated features
+C SDK
+
+This section covers the following changes and deprecated features in
+this release. Where possible, &DirectorySDKForC; provides replacement features
+for deprecated features.
+
+liblber API
+File layout
+IPv6 support
+NSS and NSPR version updates
+NSS security tools
+
+liblber API
+
+
+APIs
+liblber
+
+libraries
+liblber
+
+The Basic Encoding Rules library, liblber,
+changed for portability reasons and to comply with The C LDAP Application
+Program Interface Internet draft. In particular, according to
+section 17.1., BER Data Structures and Types, the following
+structures have changed.
+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.
+Programs that do not use the liblber API
+directly need not be changed. You can continue to build and use those applications
+as before.
+If, however, your programs call the liblber API
+directly, you must change your application code to reflect the type definitions
+in include/lber.h. Compilers typically issue type mismatch
+warnings when compiling old code that has not been fixed.
+File Layout
+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 Files Provided With Directory SDK for C.
+
+IPv6 Support
+IPv6 support is provided by means of the NSPR library. Therefore, to
+use LDAP over IPv6, use prldap_init instead of ldap_init
+.
+NSS and NSPR Version Updates
+This version of &DirectorySDKForC; uses NSS 3.11and NSPR 4.6. Both
+components are included in binary form for your convenience.
+NSS Security Tools
+NSS security tools, used to maintain NSS databases so your application
+can do LDAP over SSL, are not delivered with &DirectorySDKForC;.
+For access to NSS security tools, refer to the NSS
+security tools project.
+
+New &DirectorySDKForC; Features
+
+new features
+C SDK
+
+C SDK
+new features of
+
+
+This section describes the features introduced in this release:
+LDAP Version 3 Default
+
+Supported
+Controls
+Supported Extended
+Operations
+Additional Directory
+SDK for C Examples
+
+LDAP Version 3 Default
+&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.
+Supported Controls
+This version of &DirectorySDKForC; adds support for developing client
+applications, including more than 10 LDAP v3 controls. See Table 16–1 for a complete list.
+For instructions on using controls supported by &DirectorySDKForC;,
+see Chapter 16, LDAP Controls With Directory
+SDK for C.
+Supported Extended Operations
+
+extended operations
+C SDK support of
+
+This version of &DirectorySDKForC; adds support for developing client
+applications that use the following extended operations.
+
+LDAP Password Modify Extended Operation
+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 RFC 3062.
+The extended operation has identifier 1.3.6.1.4.1.4203.1.11.1.
+
+
+
+Start TLS Extended Operation
+The Start TLS extended operation lets your client application
+connect to a nonsecure port, and then request transport layer security.
+The extended operation has identifier 1.3.6.1.4.1.1466.20037.
+
+
+
+Who Am I? Extended Operation
+The “Who am I?” extended operation lets your client
+application determine the authorization identity that the server currently
+associates with your client.
+The extended operation has identifier 1.3.6.1.4.1.4203.1.11.3.
+
+
+
+
+For instructions on using extended operations supported by &DirectorySDKForC;,
+see Chapter 18, Extended Operations With
+Directory SDK for C.
+Additional &DirectorySDKForC; Examples
+
+
+example programs
+C SDK
+
+More sample code is provided in the examples/ directory.
+The additional samples demonstrate newly supported controls and extended operations.
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/csdk-write.sgm b/mozilla/directory/docs/ldapcsdk/csdk-write.sgm
new file mode 100644
index 00000000000..f6e5ea5c20d
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/csdk-write.sgm
@@ -0,0 +1,2118 @@
+
+Adding, Updating, and Deleting Entries With &DirectorySDKForC;
+
+
+C SDK
+writing to directory entries
+
+This chapter explains how to use LDAP C API functions to add, update,
+delete, and rename entries.
+
+This chapter covers the following topics:
+Specifying Entry Information With
+Directory SDK for C
+Adding an Entry With Directory SDK
+for C
+Modifying an Entry With Directory
+SDK for C
+Deleting an Entry With Directory
+SDK for C
+Changing the DN of an Entry With
+Directory SDK for C
+
+
+Specifying Entry Information With &DirectorySDKForC;
+
+To add or modify an entry in the directory, you need to specify information
+about the entry’s attributes. In most cases, you must specify the following:
+
+The type of attribute that you are working with. For example,
+the sn attribute or the telephoneNumber attribute.
+
+The values that you are adding, or replacing in the attribute.
+
+The operation that you are performing when modifying an existing
+entry. In other words, determine whether you are adding, modifying, or deleting
+the attribute in the existing entry.
+
+To specify this information, you use an LDAPMod structure
+as shown here.
+LDAPMod Structure
+
+typedef struct ldapmod {
+ int mod_op;
+ char *mod_type;
+ union {
+ char **modv_strvals;
+ struct berval **modv_bvals;
+ } mod_vals;
+#define mod_values mod_vals.modv_strvals
+#define mod_bvalues mod_vals.modv_bvals
+} LDAPMod;
+
+The following table details the fields in the LDAPMod data
+structure.
+
LDAPMod
+ Field Descriptions
+
+
+
+
+Field
+
+Description
+
+
+
+
+
+
+mod_op
+
+
+The operation to be performed on the attribute and the type of data
+that is specified as the attribute values. This field can have one of the
+following values:
+LDAP_MOD_ADD adds a value to the attribute.
+
+LDAP_MOD_DELETE removes a value from the
+attribute.
+LDAP_MOD_REPLACE replaces all existing
+values of the attribute.Furthermore, if you specify binary values
+in the mod_bvalues field, use the bitwise or operator,
+|, to combine LDAP_MOD_BVALUES with the operation
+type:
+mod->mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES
+If you are using the structure to add a new entry, you can specify
+0 for the mod_op field, unless you are adding
+binary values and need to specify LDAP_MOD_BVALUES. See Adding an Entry With Directory SDK for C for details.
+
+
+
+
+
+
+mod_type
+
+Attribute type that you want to add, delete, or replace, such as sn
+ or telephoneNumber.
+
+
+
+mod_values
+
+Pointer to a NULL terminated array of string values
+for the attribute.
+
+
+
+mod_bvalues
+
+Pointer to a NULL terminated array of berval
+ structures for the attribute.
+
+
+
+
+The following precautions pertain to entry modifications and
+the fields detailed in Table 11–1.
+
+
+If you specify LDAP_MOD_DELETE in the
+mod_op field to remove all values in an attribute, the attribute
+is removed from the entry.
+If you specify LDAP_MOD_DELETE in the
+mod_op field and NULL in the mod_values field,
+the attribute is removed from the entry.
+If you specify LDAP_MOD_REPLACE in the
+mod_op field and NULL in the mod_values field,
+the attribute is removed from the entry.
+If you specify LDAP_MOD_REPLACE in the
+mod_op field, but the attribute does not exist in the entry, the
+attribute is added to the entry.
+If you specify LDAP_MOD_ADD in the mod_op
+ field, but the attribute does not exist in the entry, the attribute
+is added to the entry.
+
+If you allocate memory for the structures yourself, free the structures
+when you finish by calling the ldap_mods_free function.
+
+Adding an Entry With &DirectorySDKForC;
+
+LDAP entries
+adding
+
+entries
+adding
+
+adding
+LDAP entries
+
+The following procedure provides the general steps for adding a new
+entry to the directory.
+To Add a New Entry
+
+Use the LDAPMod structure to specify
+the name and values of each attribute.
+Create an array of LDAPMod structures
+to represent the attributes in the entry.
+Call the ldap_add_ext or ldap_add_ext_s
+ function, passing in the array of LDAPMod structures
+and a distinguished name (DN) for the entry.
+Call the ldap_mods_free function to free
+any LDAPMod structures that you allocated.
+
+
+
+Specifying Values for Attributes
+You can specify a value for an attribute in three ways. You can specify
+a single value. You can specify multiple values. You can add binary data as
+the value of an attribute.
+Specifying a Single Value in an Attribute
+To specify a value in an attribute, set the mod_op,
+mod_type, and mod_values fields in an LDAPMod
+ structure. This example sets up the structure for the sn attribute.
+
+Setting Up an Attribute Structure
+#include "ldap.h"
+…
+LDAPMod attribute1;
+char *sn_values[] = { "Jensen", NULL };
+…
+attribute1.mod_op = 0;
+attribute1.mod_type = "sn";
+attribute1.mod_values = sn_values;
+…
+
+Because you are specifying an attribute for a new entry, rather than
+for an existing entry, you can set the mod_op field to
+0. For an existing entry, the mod_op field identifies
+the type of change you are making to the entry.
+Specifying Multiple Values in an Attribute
+If an attribute has more than one value, specify the values in the
+mod_values array. This example specifies two values for the cn
+ attribute.
+Specifying Multiple
+Values in an Attribute
+#include "ldap.h"
+…
+LDAPMod attribute2, attribute3;
+char *cn_values[] = { "Barbara Jensen", "Babs Jensen", NULL };
+char *objectClass_values[] = { "top", "person",
+ "organizationalPerson", "inetOrgPerson", NULL };
+…
+attribute2.mod_op = 0;
+attribute2.mod_type = "cn";
+attribute2.mod_values = cn_values;
+attribute3.mod_op = 0;
+attribute3.mod_type = "objectClass";
+attribute3.mod_values = objectClass_values;
+…
+
+
+Specifying Binary Data as the Value of an Attribute
+If the attribute contains binary data rather than string values, specify
+the data in a berval structure similar to this.
+berval Structure
+
+struct berval {
+ unsigned long bv_len;
+ char *bv_val;
+}
+
+The berval structure fields and field descriptions
+are as follows:
+
+bv_len
+The length of the data
+
+
+bv_val
+A pointer to the binary data
+
+
+
+After creating the berval structures for the
+binary data, you may use the structures.
+To Use berval Structures
+
+Add the berval structures to the mod_bvalues
+ field in the LDAPMod structure.
+
+Use the bitwise or operator, |, to combine
+the value of the mod_op field with LDAP_MOD_BVALUES.
+When adding a new entry, you set the mod_op field
+to LDAP_MOD_BVALUES because the mod_op field
+is 0 in this case.For example, suppose the
+file my_photo.jpg contains a JPEG photograph of Barbara
+Jensen. The following example sets the jpegPhoto attribute
+to the JPEG data of the photograph.
+
+
+Adding a Value to an Attribute
+#include <stdio.h>
+#include <sys/stat.h>
+#include "ldap.h"
+…
+char *photo_data;
+FILE *fp;
+struct stat st;
+LDAPMod attribute4;
+struct berval photo_berval;
+struct berval *jpegPhoto_values[2];
+/* Get information about the JPEG file, including its size. */
+if ( stat( "my_photo.jpg", &st ) != 0 ) {
+ perror( "stat" );
+ return( 1 );
+}
+
+/* Open the JPEG file and read it into memory. */
+if ( ( fp = fopen( "my_photo.jpg", "rb" ) ) == NULL ) {
+ perror( "fopen" );
+ return( 1 );
+}
+if ( ( ( photo_data = ( char * )malloc( st.st_size ) ) == NULL ) ||
+ ( fread ( photo_data, st.st_size, 1, fp ) != 1 ) ) {
+ perror( photo_data ? "fread" : "malloc" );
+ return( 1 );
+}
+
+fclose( fp );
+
+attribute4.mod_op = LDAP_MOD_BVALUES;
+attribute4.mod_type = "jpegPhoto";
+photo_berval.bv_len = st.st_size;
+photo_berval.bv_val = photo_data;
+jpegPhoto_values[0] = &photo_berval;
+jpegPhoto_values[1] = NULL;
+attribute4.mod_values = jpegPhoto_values;
+
+
+
+
+Specifying Attributes in the Entry
+After specifying values for attributes in LDAPMod structures,
+as described in Specifying Values for Attributes,
+you need to construct an array of these structures. You then pass a pointer
+to this array as a parameter to the function for creating a new entry.
+Make sure you create LDAPMod structures for
+all required attributes in the new entry.
+ The following example creates an array of LDAPMod structures.
+
+Adding an Array of
+Structures to an Attribute
+#include "ldap.h"
+LDAPMod *list_of_mods[5]
+LDAPMod attribute1, attribute2, attribute3, attribute4;
+…
+/* Code for filling the LDAPMod structures with values */
+…
+list_of_mods[0] = &attribute1;
+list_of_mods[1] = &attribute2;
+list_of_mods[2] = &attribute3;
+list_of_mods[3] = &attribute4;
+list_of_mods[4] = NULL;
+…
+
+
+Adding the Entry to the Directory
+
+To add the entry to the directory, call one of the following:
+The synchronous ldap_add_ext_s function
+
+The asynchronous ldap_add_ext function
+
+
+If you have allocated LDAPMod structures yourself,
+you should free the structures when you are done. Call the ldap_mods_free
+ function to free LDAPMod structures.
+Synchronous Add Operation
+
+synchronous functions
+add operation
+
+If you want to wait for the results of the add operation to complete
+before continuing, call the synchronous ldap_add_ext_s function.
+This function sends an LDAP add request to the server. The function also blocks
+other work until the server sends the results of the operation back to your
+client. The ldap_add_ext_s function returns LDAP_SUCCESS
+ if the operation completed successfully, or an error code if
+a problem occurred.
+The following example calls the synchronous ldap_add_ext_s function
+to add the user William Jensen to the directory.
+Performing a Synchronous Add Operation
+
+#include <stdio.h>
+#include "ldap.h"
+…
+#define NEW_DN "uid=wbjensen,ou=People,dc=example,dc=com"
+…
+LDAP *ld;
+LDAPMod **mods;
+char *matched_msg = NULL, *error_msg = NULL;
+int rc;
+…
+/* Perform the add operation. */
+rc = ldap_add_ext_s( ld, NEW_DN, mods, NULL, NULL );
+if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_add_ext_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 );
+ }
+} else {
+ printf( "%s added successfully.\n", NEW_DN );
+}
+…
+
+The following sample program calls the synchronous ldap_add_ext_s
+ function to add a new user to the directory.
+Sample Synchronous Add Program
+#include <stdio.h>
+#include "ldap.h"
+/* Change these as needed. */
+#define HOSTNAME "localhost"
+#define PORTNUMBER LDAP_PORT
+#define BIND_DN "cn=Directory Manager"
+#define BIND_PW "23skidoo"
+#define NEW_DN "uid=wbjensen,ou=People,dc=example,dc=com"
+#define NUM_MODS 5
+int
+main( int argc, char **argv )
+{
+ LDAP *ld;
+ LDAPMod **mods;
+ char *matched_msg = NULL, *error_msg = NULL;
+ int i, rc;
+ char *object_vals[] = { "top", "person", "organizationalPerson",
+ "inetOrgPerson", NULL };
+
+char *cn_vals[] = { "William B Jensen", "William Jensen", "Bill Jensen",
+ NULL };
+ char *sn_vals[] = { "Jensen", NULL };
+ char *givenname_vals[] = { "William", "Bill", NULL };
+ char *telephonenumber_vals[] = { "+1 415 555 1212", NULL };
+ /* 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 to the server as the Directory Manager. */
+ rc = ldap_simple_bind_s( ld, BIND_DN, BIND_PW );
+ 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 );
+ }
+ /* Construct the array of LDAPMod structures representing the attributes
+ of the new entry. */
+ mods = ( LDAPMod ** ) malloc(( NUM_MODS + 1 ) * sizeof( LDAPMod * ));
+ if ( mods == NULL ) {
+ fprintf( stderr, "Cannot allocate memory for mods array\n" );
+ exit( 1 );
+ }
+ for ( i = 0; i < NUM_MODS; i++ ) {
+ if (( mods[ i ] = ( LDAPMod * ) malloc( sizeof( LDAPMod ))) == NULL ) {
+ fprintf( stderr, "Cannot allocate memory for mods element\n" );
+ exit( 1 );
+ }
+ }
+ mods[ 0 ]->mod_op = 0;
+ mods[ 0 ]->mod_type = "objectclass";
+ mods[ 0 ]->mod_values = object_vals;
+ mods[ 1 ]->mod_op = 0;
+ mods[ 1 ]->mod_type = "cn";
+ mods[ 1 ]->mod_values = cn_vals;
+ mods[ 2 ]->mod_op = 0;
+ mods[ 2 ]->mod_type = "sn";
+ mods[ 2 ]->mod_values = sn_vals;
+ mods[ 3 ]->mod_op = 0;
+ mods[ 3 ]->mod_type = "givenname";
+ mods[ 3 ]->mod_values = givenname_vals;
+ mods[ 4 ]->mod_op = 0;
+ mods[ 4 ]->mod_type = "telephonenumber";
+ mods[ 4 ]->mod_values = telephonenumber_vals;
+ mods[ 5 ] = NULL;
+ /* Perform the add operation. */
+ rc = ldap_add_ext_s( ld, NEW_DN, mods, NULL, NULL );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_add_ext_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 );
+ }
+ } else {
+ printf( "%s added successfully.\n", NEW_DN );
+ }
+ ldap_unbind_s( ld );
+ for ( i = 0; i < NUM_MODS; i++ ) {
+ free( mods[ i ] );
+ }
+ free( mods );
+ return 0;
+}
+
+
+Asynchronous Add Operation
+
+asynchronous functions
+add operation
+
+If you want to perform other work while waiting for the entry to be
+added, call the asynchronous ldap_add_ext function. This
+function sends an LDAP add request to the server and returns an LDAP_SUCCESS
+ result code if the request was successfully sent, or an LDAP
+result code if an error occurred.
+The ldap_add_ext function passes back a message
+ID identifying the add operation. To determine whether the server sent a response
+for this operation to your client, call the ldap_result function
+and pass in this message ID. The ldap_result function
+uses the message ID to determine if the server sent the results of the add
+operation. The ldap_result function passes back the results
+in an LDAPMessage structure. You can call the
+ldap_parse_result function to parse the LDAPMessage structure
+to determine if the operation was successful.
+The following example calls the asynchronous ldap_add_ext function
+to add the user William Jensen to the directory.
+Performing an Asynchronous Add
+Operation
+#include <stdio.h>
+#include "ldap.h"
+…
+#define NEW_DN "uid=wbjensen,ou=People,dc=example,dc=com"
+
+…
+LDAP *ld;
+LDAPMessage *res;
+LDAPControl **serverctrls;
+char *matched_msg = NULL, *error_msg = NULL;
+char **referrals;
+int i, rc, parse_rc, msgid, finished = 0;
+
+/* Timeout period for the ldap_result() function to wait for results. */
+struct timeval zerotime;
+zerotime.tv_sec = zerotime.tv_usec = 0L;
+…
+/* Send the LDAP add request. */
+rc = ldap_add_ext( ld, NEW_DN, mods, NULL, NULL, &msgid );
+if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_add_ext: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+}
+…
+/* Poll the server for the results of the add 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 polling. */
+ break;
+ default:
+ /* The function has retrieved the results of the add operation. */
+ finished = 1;
+
+ /* Parse the result to determine the result of
+ the add operation. */
+ 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 add operation. */
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_add_ext: %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 );
+ }
+ } else {
+ printf( "%s added successfully.\n", NEW_DN );
+ }
+ }
+}
+…
+
+The following sample program calls the asynchronous ldap_add_ext function
+to add a new user to the directory.
+Sample Asynchronous Add
+Program
+#include <stdio.h>
+#include "ldap.h"
+void do_other_work();
+int global_counter = 0;
+void free_mods( LDAPMod **mods );
+/* Change these as needed. */
+#define HOSTNAME "localhost"
+#define PORTNUMBER LDAP_PORT
+#define BIND_DN "cn=Directory Manager"
+#define BIND_PW "23skidoo"
+#define NEW_DN "uid=wbjensen,ou=People,dc=example,dc=com"
+#define NUM_MODS 5
+int
+main( int argc, char **argv )
+{
+ LDAP *ld;
+ LDAPMessage *res;
+ LDAPMod **mods;
+ LDAPControl **serverctrls;
+ char *matched_msg = NULL, *error_msg = NULL;
+ char **referrals;
+ int i, rc, parse_rc, msgid, finished = 0;
+ struct timeval zerotime;
+ char *object_vals[] = { "top", "person", "organizationalPerson",
+ "inetOrgPerson", NULL };
+ char *cn_vals[] = { "William B Jensen", "William Jensen",
+ "Bill Jensen", NULL };
+ char *sn_vals[] = { "Jensen", NULL };
+ char *givenname_vals[] = { "William", "Bill", NULL };
+ char *telephonenumber_vals[] = { "+1 415 555 1212", NULL };
+ 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 to the server as the Directory Manager. */
+ rc = ldap_simple_bind_s( ld, BIND_DN, BIND_PW );
+ 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 );
+ }
+ /* Construct the array of LDAPMod structures representing the attributes
+ of the new entry. */
+ mods = ( LDAPMod ** ) malloc(( NUM_MODS + 1 ) * sizeof( LDAPMod * ));
+ if ( mods == NULL ) {
+ fprintf( stderr, "Cannot allocate memory for mods array\n" );
+ exit( 1 );
+ }
+ for ( i = 0; i < NUM_MODS; i++ ) {
+ if (( mods[ i ] = ( LDAPMod * ) malloc( sizeof( LDAPMod ))) == NULL ) {
+ fprintf( stderr, "Cannot allocate memory for mods element\n" );
+ exit( 1 );
+ }
+ }
+ mods[ 0 ]->mod_op = 0;
+ mods[ 0 ]->mod_type = "objectclass";
+ mods[ 0 ]->mod_values = object_vals;
+ mods[ 1 ]->mod_op = 0;
+ mods[ 1 ]->mod_type = "cn";
+ mods[ 1 ]->mod_values = cn_vals;
+ mods[ 2 ]->mod_op = 0;
+ mods[ 2 ]->mod_type = "sn";
+ mods[ 2 ]->mod_values = sn_vals;
+ mods[ 3 ]->mod_op = 0;
+ mods[ 3 ]->mod_type = "givenname";
+ mods[ 3 ]->mod_values = givenname_vals;
+ mods[ 4 ]->mod_op = 0;
+ mods[ 4 ]->mod_type = "telephonenumber";
+ mods[ 4 ]->mod_values = telephonenumber_vals;
+ mods[ 5 ] = NULL;
+ /* Send the LDAP add request. */
+ rc = ldap_add_ext( ld, NEW_DN, mods, NULL, NULL, &msgid );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_add_ext: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ free_mods( mods );
+ return( 1 );
+ }
+ /* Poll the server for the results of the add 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 );
+ free_mods( mods );
+ return( 1 );
+ case 0:
+ /* The timeout period specified by zerotime was exceeded.
+ This means that the server has still not yet sent the
+ results of the add operation back to your client.
+ Break out of this switch statement, and continue calling
+ ldap_result() to poll for results. */
+ break;
+ default:
+ /* The function has retrieved the results of the add 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 );
+ free_mods( mods );
+ return( 1 );
+ }
+ /* Check the results of the LDAP add operation. */
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_add_ext: %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 );
+ }
+ } else {
+ printf( "%s added successfully.\n"
+ "Counted to %d while waiting for the add operation.\n",
+ NEW_DN, global_counter );
+ }
+ }
+ /* Do other work while waiting for the results of the add operation. */
+ if ( !finished ) {
+ do_other_work();
+ }
+ }
+ ldap_unbind( ld );
+ free_mods( mods );
+ return 0;
+}
+/*
+ * Free a mods array.
+ */
+void
+free_mods( LDAPMod **mods )
+{
+ int i;
+ for ( i = 0; i < NUM_MODS; i++ ) {
+ free( mods[ i ] );
+ }
+ free( mods );
+}
+
+/*
+ * Perform other work while polling for results.
+ * This doesn't do anything useful, but it could.
+ */
+void
+do_other_work()
+{
+ global_counter++;
+}
+
+
+
+
+Modifying an Entry With &DirectorySDKForC;
+
+LDAP entries
+modifying
+
+modifying
+LDAP entries
+
+entries
+modifying
+
+The following procedure provides the general steps for modifying an
+entry.
+To Modify an Entry
+
+Use the LDAPMod structure to specify
+a change to an attribute.
+Create an array of LDAPMod structures
+that represent the changes that need to be made.
+Call the ldap_modify_ext or ldap_modify_ext_s
+ function, passing in the array of LDAPMod structures
+and the DN of the entry that you want modified.
+Call the ldap_mods_free function to free
+any LDAPMod structures that you allocated.
+
+
+
+Types of Modifications
+You can modify an entry in various ways. The following sections explain
+the types of modifications.
+Replacing the Values of an Attribute
+
+To replace all existing values of an attribute, create an LDAPMod
+ structure with the following values.
+Set the mod_type field to the attribute
+type that you want to change, such as telephoneNumber.
+
+Set the mod_values field to the new values
+of the attribute.
+Set the value of the mod_op field to
+LDAP_MOD_REPLACE.
+
+The following code specifies a change that replaces the values of the
+telephoneNumber attribute.
+#include "ldap.h"
+LDAPMod attribute1;
+char *telephoneNumber_values[] = { "+1 800 555 1212", NULL };
+attribute1.mod_type = "telephoneNumber";
+attribute1.mod_op = LDAP_MOD_REPLACE;
+attribute1.mod_values = telephoneNumber_values;
+
+If you want to specify binary data as berval structures
+as opposed to string values, you need to do the following:
+Use the mod_bvalues field rather than the
+mod_values field.
+Use the bitwise or operator, |, to combine
+the value LDAP_MOD_BVALUES with the value of the mod_op
+ field.
+
+If you specify an attribute that does not exist in the entry,
+the attribute is added to the entry.You can set a NULL value
+for the attribute either by setting the mod_values field
+to NULL or by setting the mod_bvalues field
+to NULL. When the mod_op field also
+contains LDAP_MOD_BVALUES, the attribute is removed from
+the entry.
+
+Removing Values From an Attribute
+
+To remove values from an attribute, create an LDAPMod structure
+with the following values:
+Set the mod_type field to the attribute
+type that contains the values to remove such as facsimileTelephoneNumber
+.
+Set the mod_values field to the values
+that you want removed from the attribute.
+Set the value of the mod_op field to
+LDAP_MOD_DELETE.The following code specifies the removal
+of one of the values of the facsimileTelephoneNumber attribute
+in the entry.
+#include "ldap.h"
+LDAPMod attribute2;
+char *fax_values[] = { "+1 800 555 1212", NULL };
+attribute2.mod_type = "facsimileTelephoneNumber";
+attribute2.mod_op = LDAP_MOD_DELETE;
+attribute2.mod_values = fax_values;
+…
+
+
+
+If you want to specify binary data as berval structures
+as opposed to string values, you need to do the following:
+Use the mod_bvalues field rather than the
+mod_values field.
+Use the bitwise or operator, |, to combine
+the value LDAP_MOD_BVALUES with the value of the mod_op
+ field.
+
+If you remove all values from the attribute, the attribute
+is removed from the entry.You can set a NULL value
+for the attribute either by setting the mod_values field
+to NULL, or by setting the mod_bvalues field
+to NULL. When the mod_op field then
+contains LDAP_MOD_BVALUES, the attribute is removed from
+the entry.
+
+Adding Values to an Attribute
+
+To add values to an attribute in an entry, create an LDAPMod structure
+with the following:
+Set the mod_type field to the attribute
+type that you want to add values to, such as audio.
+
+Set the mod_values field to the new values
+of the attribute.
+Set the value of the mod_op field to
+LDAP_MOD_ADD.
+
+
+If the attribute contains binary data as opposed to string values, you
+need to do the following values:
+Use the mod_bvalues field rather than the
+mod_values field, and put the values in berval structures.
+
+Use the bitwise or operator, |, to combine
+the value LDAP_MOD_BVALUES with the value of the mod_op
+ field.
+
+If the attribute does not already exist in the entry, the attribute
+is added to the entry.
+The following code adds values to the audio attribute
+of an entry.
+#include <stdio.h>
+#include <sys/stat.h>
+#include "ldap.h"
+…
+char *audio_data;
+FILE *fp;
+struct stat st;
+LDAPMod attribute3;
+struct berval audio_berval;
+struct berval *audio_values[2];
+…
+/* Get information about the audio file, including its size. */
+if ( stat( "my_sounds.au", &st ) != 0 ) {
+ perror( "stat" );
+ return( 1 );
+}
+
+/* Open the audio file and read it into memory. */
+if ( ( fp = fopen( "my_sounds.au", "rb" ) ) == NULL ) {
+ perror( "fopen" );
+ return( 1 );
+}
+
+if ( ( ( audio_data = ( char * )malloc( st.st_size ) ) == NULL ) ||
+ ( fread ( audio_data, st.st_size, 1, fp ) != 1 ) ) {
+ perror( audio_data ? "fread" : "malloc" );
+ return( 1 );
+}
+
+fclose( fp );
+attribute3.mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
+attribute3.mod_type = "audio";
+audio_berval.bv_len = st.st_size;
+audio_berval.bv_val = audio_data;
+audio_values[0] = &audio_berval;
+audio_values[1] = NULL;
+attribute3.mod_values = audio_values;
+…
+
+Removing an Attribute With &DirectorySDKForC;
+
+You can remove an attribute from an entry in either of the following
+ways:
+Remove all values from the attribute.
+Set the mod_op field to LDAP_MOD_REPLACE
+ or LDAP_MOD_DELETE, and specify NULL for
+the mod_values field.
+
+
+Adding an Attribute With &DirectorySDKForC;
+If you add or replace values in an attribute that does not yet exist
+in the entry, the attribute is added to the entry.
+
+Creating an Array of Changes
+After specifying the changes to attribute values in LDAPMod structures,
+you need to construct an array of these structures. You pass a pointer to
+this array as a parameter to the function for modifying the entry. The following
+example creates an array of LDAPMod structures.
+Assembling an Array of
+LDAPMod Structures
+#include "ldap.h"
+…
+LDAPMod *list_of_mods[4]
+LDAPMod attribute1, attribute2, attribute3;
+…
+/* Code for filling the LDAPMod structures with values */
+…
+list_of_mods[0] = &attribute1;
+list_of_mods[1] = &attribute2;
+list_of_mods[2] = &attribute3;
+list_of_mods[3] = NULL;
+…
+
+
+Modifying an Entry in the Directory With &DirectorySDKForC;
+
+
+To modify an entry in the directory, call one of the following functions:
+The synchronous ldap_modify_ext_s function
+
+The asynchronous ldap_modify_ext function
+
+
+Synchronous Modify Operation
+If you want to wait for the results of the modify operation to complete
+before continuing, call the synchronous ldap_modify_ext_s function.
+The function sends a modify request to the server. Also, the function blocks
+all work until the server sends the results of the operation back to your
+client. The function returns LDAP_SUCCESS if the operation
+completed successfully, or an error code if a problem occurred.
+The following example calls the synchronous ldap_modify_ext_s function
+to modify the entry for the user William Jensen in the
+directory.
+Performing a Synchronous Modify
+Operation
+#include <stdio.h>
+#include "ldap.h"
+
+#define MODIFY_DN "uid=wbjensen,ou=People,dc=example,dc=com"
+…
+LDAP *ld;
+LDAPMod *mods[ 3 ];
+char *matched_msg = NULL, *error_msg = NULL;
+int rc;
+…
+/* Perform the modify operation. */
+rc = ldap_modify_ext_s( ld, MODIFY_DN, mods, NULL, NULL );
+if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_modify_ext_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 );
+ }
+} else {
+ printf( "%s modified successfully.\n", MODIFY_DN );
+}
+ldap_unbind_s( ld );
+…
+
+The following sample program calls the synchronous ldap_modify_ext_s
+ function to modify a user entry in the directory. The program
+replaces the values of the mail attribute and adds a
+description attribute to the entry.
+Sample Synchronous Modify
+Program
+#include <stdio.h>
+#include <time.h>
+#include "ldap.h"
+/* Change these as needed. */
+#define HOSTNAME "localhost"
+#define PORTNUMBER LDAP_PORT
+#define BIND_DN "cn=Directory Manager"
+#define BIND_PW "23skidoo"
+#define MODIFY_DN "uid=wbjensen,ou=People,dc=example,dc=com"
+int
+main( int argc, char **argv )
+{
+ LDAP *ld;
+ LDAPMod mod0, mod1;
+ LDAPMod *mods[ 3 ];
+ char *matched_msg = NULL, *error_msg = NULL;
+ char *vals0[ 2 ], *vals1[ 2 ];
+ time_t now;
+ char buf[ 128 ];
+ 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 to the server as the Directory Manager. */
+ rc = ldap_simple_bind_s( ld, BIND_DN, BIND_PW );
+ 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 );
+ }
+/* Construct the array of LDAPMod structures representing the
+ changes that you want to make to attributes in the entry. */
+/* Specify the first modification, which replaces all values of the
+mail attribute with the value "wbj@example.com". */
+ mod0.mod_op = LDAP_MOD_REPLACE;
+ mod0.mod_type = "mail";
+ vals0[0] = "wbj@example.com";
+ vals0[1] = NULL;
+ mod0.mod_values = vals0;
+/* Specify the second modification, which adds a value to the
+ description attribute. If this attribute does not yet exist,
+ the attribute ia added to the entry. */
+ 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;
+/* Perform the modify operation. */
+ rc = ldap_modify_ext_s( ld, MODIFY_DN, mods, NULL, NULL );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_modify_ext_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 );
+ }
+ } else {
+ printf( "%s modified successfully.\n", MODIFY_DN );
+ }
+ ldap_unbind_s( ld );
+ return 0;
+}
+
+
+Asynchronous Modify Operation
+
+asynchronous functions
+modify operation
+
+If you want to perform other work in parallel while waiting for the
+entry to be modified, call the asynchronous ldap_modify_ext function.
+This function sends a modify request to the server and returns an LDAP_SUCCESS
+ result code if the request was successfully sent, or an LDAP
+result code if an error occurred.
+The ldap_modify_ext function passes back a message
+ID identifying the modify operation. To determine whether the server sent
+a response for this operation to your client, call the ldap_result function
+and pass in this message ID. The ldap_result function
+uses the message ID to determine if the server sent the results of the modify
+operation. The ldap_result function passes back the results
+in an LDAPMessage structure. You can call the
+ldap_parse_result function to parse the LDAPMessage structure
+to determine if the operation was successful.
+The following example calls the asynchronous ldap_modify_ext function
+to modify the entry for the user William Jensen in the
+directory.
+Performing an Asynchronous Modify
+Operation
+#include <stdio.h>
+#include "ldap.h"
+…
+#define MODIFY_DN "uid=wbjensen,ou=People,dc=example,dc=com"
+…
+LDAP *ld;
+LDAPMessage *res;
+LDAPMod *mods[ 3 ];
+LDAPControl **serverctrls;
+char *matched_msg = NULL, *error_msg = NULL;
+char **referrals;
+int rc, parse_rc, msgid, finished = 0;
+
+/* Timeout period for the ldap_result() function to wait for results. */
+struct timeval zerotime;
+zerotime.tv_sec = zerotime.tv_usec = 0L;
+…
+/* Send the LDAP modify request. */
+rc = ldap_modify_ext( ld, MODIFY_DN, mods, NULL, NULL, &msgid );
+if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_modify_ext: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+}
+
+/* Poll the server for the results of the modify 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 polling. */
+ break;
+ default:
+ /* The function has retrieved the results of the
+ modify operation. */
+ 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 modify operation. */
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_modify_ext: %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 );
+ }
+ } else {
+ printf( "%s modified successfully.\n", MODIFY_DN );
+ }
+ }
+}
+ldap_unbind( ld );
+…
+
+The following sample program calls the asynchronous ldap_modify_ext
+ function to modify a user entry in the directory. The program
+replaces the values of the mail attribute and adds a
+description attribute to the entry.
+Sample Asynchronous Modify
+Program
+#include <stdio.h>
+#include <time.h>
+#include "ldap.h"
+void do_other_work();
+int global_counter = 0;
+/* Change these as needed. */
+#define HOSTNAME "localhost"
+#define PORTNUMBER LDAP_PORT
+#define BIND_DN "cn=Directory Manager"
+#define BIND_PW "23skidoo"
+#define MODIFY_DN "uid=wbjensen,ou=People,dc=example,dc=com"
+int
+main( int argc, char **argv )
+{
+ LDAP *ld;
+ LDAPMessage *res;
+ LDAPMod mod0, mod1;
+ LDAPMod *mods[ 3 ];
+ LDAPControl **serverctrls;
+ char *matched_msg = NULL, *error_msg = NULL;
+ char **referrals;
+ char *vals0[ 2 ], *vals1[ 2 ];
+ time_t now;
+ char buf[ 128 ];
+ 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 to the server as the Directory Manager. */
+ rc = ldap_simple_bind_s( ld, BIND_DN, BIND_PW );
+ 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 );
+ }
+/* Construct the array of LDAPMod structures representing the changes
+ that you want to make to attributes in the entry. */
+/* Specify the first modification, which replaces all values of the
+ mail attribute with the value "wbj@example.com". */
+ mod0.mod_op = LDAP_MOD_REPLACE;
+ mod0.mod_type = "mail";
+ vals0[0] = "wbj@example.com";
+ vals0[1] = NULL;
+ mod0.mod_values = vals0;
+/* Specify the second modification, which adds a value to the description
+ attribute. If this attribute does not yet exist, the attribute ia added
+ to the entry. */
+ 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;
+/* Send the LDAP modify request. */
+ rc = ldap_modify_ext( ld, MODIFY_DN, mods, NULL, NULL, &msgid );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_modify_ext: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+/* Poll the server for the results of the modify 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 the server has still not yet sent the
+ results of the modify operation back to your client.
+ Break out of this switch statement, and continue calling
+ ldap_result() to poll for results. */
+ break;
+ default:
+ /* The function has retrieved the results of the modify
+ 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 add operation. */
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_modify_ext: %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 );
+ }
+ } else {
+ printf( "%s modified successfully.\n"
+ "Counted to %d while waiting for the modify operation.\n",
+ MODIFY_DN, global_counter );
+ }
+ }
+/* Do other work while waiting for the results of the modify 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++;
+}
+
+
+
+
+Deleting an Entry With &DirectorySDKForC;
+
+LDAP entry
+delete
+
+deleting
+LDAP entry
+
+entries
+deleting
+
+
+To remove an entry from the directory, call one of the following functions:
+
+The synchronous ldap_delete_ext_s function
+
+The asynchronous ldap_delete_ext function
+
+
+Synchronous Delete Operation
+
+synchronous functions
+delete operation
+
+If you want to wait for the results of the delete operation to complete
+before continuing, call the synchronous ldap_delete_ext_s function.
+This function sends a delete request to the server. The function also blocks
+all other processes until the server sends the results of the operation back
+to your client. The ldap_delete_ext_s function returns
+LDAP_SUCCESS if the operation completed successfully, or an error
+code if a problem occurred.
+The following example calls the synchronous ldap_delete_ext_s function
+to remove the entry for user William Jensen from the directory.
+
+Performing a Synchronous Delete
+Operation
+#include <stdio.h>
+#include "ldap.h"
+…
+#define DELETE_DN "uid=wjensen,ou=People,dc=example,dc=com"
+…
+LDAP *ld;
+char *matched_msg = NULL, *error_msg = NULL;
+int rc;
+…
+/* Perform the delete operation. */
+rc = ldap_delete_ext_s( ld, DELETE_DN, NULL, NULL );
+if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_delete_ext_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 );
+ }
+} else {
+ printf( "%s deleted successfully.\n", DELETE_DN );
+}
+ldap_unbind_s( ld );
+…
+
+The following sample program calls the synchronous ldap_delete_ext_s
+ function to delete a user entry from the directory.
+Sample Synchronous Delete
+Program
+#include <stdio.h>
+#include "ldap.h"
+/* Change these as needed. */
+#define HOSTNAME "localhost"
+#define PORTNUMBER LDAP_PORT
+#define BIND_DN "cn=Directory Manager"
+#define BIND_PW "23skidoo"
+#define DELETE_DN "uid=wjensen,ou=People,dc=example,dc=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 to the server as the Directory Manager. */
+ rc = ldap_simple_bind_s( ld, BIND_DN, BIND_PW );
+ 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 delete operation. */
+ rc = ldap_delete_ext_s( ld, DELETE_DN, NULL, NULL );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_delete_ext_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 );
+ }
+ } else {
+ printf( "%s deleted successfully.\n", DELETE_DN );
+ }
+ ldap_unbind_s( ld );
+ return 0;
+}
+
+
+Asynchronous Delete Operation
+
+asynchronous functions
+delete operation
+
+If you want to perform other work in parallel while waiting for the
+entry to be deleted, call the asynchronous ldap_delete_ext function.
+This function sends a delete request to the server and returns an LDAP_SUCCESS
+ result code if the request was successfully sent, an LDAP result
+code if an error occurred.
+The ldap_delete_ext function passes back a message
+ID identifying the delete operation. To determine whether the server sent
+a response for this operation to your client, call the ldap_result function
+and pass in this message ID. The ldap_result function
+uses the message ID to determine if the server sent the results of the delete
+operation. The ldap_result function passes back the results
+in an LDAPMessage structure. You can call the
+ldap_parse_result function to parse the LDAPMessage structure
+to determine if the operation was successful.
+The following example calls the asynchronous ldap_delete_ext function
+to remove the user William Jensen from the directory.
+Performing an Asynchronous Delete
+Operation
+#include <stdio.h>
+#include "ldap.h"
+…
+#define DELETE_DN "uid=wjensen,ou=People,dc=example,dc=com"
+…
+LDAP *ld;
+LDAPMessage *res;
+LDAPControl **serverctrls;
+char *matched_msg = NULL, *error_msg = NULL;
+char **referrals;
+int rc, parse_rc, msgid, finished = 0;
+
+/* Timeout period for the ldap_result() function to wait for results. */
+struct timeval zerotime;
+zerotime.tv_sec = zerotime.tv_usec = 0L;
+…
+/* Send the LDAP delete request. */
+rc = ldap_delete_ext( ld, DELETE_DN, NULL, NULL, &msgid );
+if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_delete_ext: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+}
+
+/* Poll the server for the results of the delete 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 polling. */
+ break;
+ default:
+ /* The function has retrieved the results of the
+ delete operation. */
+ 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 delete operation. */
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_delete_ext: %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 );
+ }
+ } else {
+ printf( "%s deleted successfully.\n", DELETE_DN );
+ }
+ }
+}
+ldap_unbind( ld );
+…
+
+The following sample program calls the asynchronous ldap_delete_ext
+ function to delete a user entry from the directory.
+Sample Asynchronous Delete
+Program
+#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 BIND_DN "cn=Directory Manager"
+#define BIND_PW "23skidoo"
+#define DELETE_DN "uid=wjensen,ou=People,dc=example,dc=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 to the server as the Directory Manager. */
+ rc = ldap_simple_bind_s( ld, BIND_DN, BIND_PW );
+ 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 );
+ }
+/* Send the LDAP delete request. */
+ rc = ldap_delete_ext( ld, DELETE_DN, NULL, NULL, &msgid );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_delete_ext: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+/* Poll the server for the results of the delete 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 the server has still not yet sent the
+ results of the delete operation back to your client.
+ Break out of this switch statement, and continue calling
+ ldap_result() to poll for results. */
+ break;
+ default:
+ /* The function has retrieved the results of the delete 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 delete operation. */
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_delete_ext: %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 );
+ }
+ } else {
+ printf( "%s deleted successfully.\n"
+ "Counted to %d while waiting for the delete operation.\n",
+ DELETE_DN, global_counter );
+ }
+ }
+ /* Do other work while waiting for the results of the
+ delete 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++;
+}
+
+
+
+Changing the DN of an Entry With &DirectorySDKForC;
+
+LDAP entry
+change DN
+
+changing
+DN of entry
+
+entries
+changing DN of
+
+
+To change the distinguished name (DN) of an entry, call one of the following
+functions:
+The synchronous ldap_rename_s function
+
+The asynchronous ldap_rename function
+
+
+For both functions, you can choose to delete the attribute that represents
+the old relative distinguished name (RDN). You can also change the location
+of the entry in the directory tree.
+Synchronous Renaming Operation
+
+synchronous functions
+renaming operation
+
+If you want to wait for the results of the modify DN operation to complete
+before continuing, call the synchronous ldap_rename_s function.
+This function sends a modify DN request to the server. The function also blocks
+other work until the server sends the results of the operation back to your
+client. The ldap_rename_s function returns LDAP_SUCCESS
+ if the operation completed successfully, or an error code if
+a problem occurred.
+The following calls the synchronous ldap_rename_s function
+to change the RDN of the entry for the user William Jensen in
+the directory.
+Performing a Synchronous Rename
+Operation
+#include <stdio.h>
+#include "ldap.h"
+…
+#define OLD_DN "uid=wbjensen,ou=People,dc=example,dc=com"
+#define NEW_RDN "uid=wjensen"
+…
+LDAP *ld;
+char *matched_msg = NULL, *error_msg = NULL;
+int rc;
+…
+/* Perform the modify DN operation. */
+rc = ldap_rename_s( ld, OLD_DN, NEW_RDN, NULL, 1, NULL, NULL );
+if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_rename_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 );
+ }
+} else {
+ printf( "%s renamed successfully.\n", OLD_DN );
+}
+ldap_unbind_s( ld );
+…
+
+
+Asynchronous Renaming Operation
+
+asynchronous functions
+renaming operation
+
+If you want to perform other work in parallel while waiting for the
+entry to be renamed, call the asynchronous ldap_rename function.
+This function sends a modify DN request to the server and returns an LDAP_SUCCESS
+ result code if the request was successfully sent, or an LDAP
+result code if an error occurred.
+The ldap_rename function passes back a message
+ID identifying the modify DN operation. To determine whether the server sent
+a response for this operation to your client, call the ldap_result function
+and pass in this message ID. The ldap_result function
+uses the message ID to determine if the server sent the results of the modify
+DN operation. The ldap_result function passes back the
+results in an LDAPMessage structure. You can call
+the ldap_parse_result function to parse the LDAPMessage
+ structure to determine if the operation was successful.
+The following example calls the asynchronous ldap_rename function
+to change the RDN of the user William Jensen in the directory.
+
+Performing an Asynchronous
+Rename Operation
+#include <stdio.h>
+#include "ldap.h"
+…
+#define OLD_DN "uid=wbjensen,ou=People,dc=example,dc=com"
+#define NEW_RDN "uid=wjensen"
+…
+LDAP *ld;
+LDAPMessage *res;
+LDAPControl **serverctrls;
+char *matched_msg = NULL, *error_msg = NULL;
+char **referrals;
+int rc, parse_rc, msgid, finished = 0;
+
+/* Timeout period for the ldap_result() function to wait
+ for results. */
+struct timeval zerotime;
+zerotime.tv_sec = zerotime.tv_usec = 0L;
+…
+/* Send the LDAP modify DN request. */
+rc = ldap_rename( ld, OLD_DN, NEW_RDN, NULL, 1, NULL, NULL, &msgid );
+if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_rename: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+}
+
+/* Poll the server for the results of the modify DN 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 polling. */
+ break;
+ default:
+ /* The function has retrieved the results of the
+ modify DN operation. */
+ 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 modify DN operation. */
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_rename: %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 );
+ }
+ } else {
+ printf( "%s renamed successfully.\n", OLD_DN );
+ }
+ }
+}
+ldap_unbind( ld );
+…
+
+
+Deleting the Attribute From the Old RDN
+Both ldap_rename and ldap_rename_s have
+a deleteoldrdn parameter that allows you to remove the
+old RDN from the entry. For example, suppose an entry has the following values
+for the cn attribute:
+cn: Barbara Jensen
+cn: Babs Jensen
+Then the following function adds the second name and removes the first:
+ldap_modrdn2( "cn=Barbara Jensen", "cn=Barbie Jensen", 1 );
+The function adds Barbie Jensen to the list of values.
+The function removes the Barbara Jensen value. The resulting
+entry has the following values:
+cn: Barbie Jensen
+cn: Babs Jensen
+Suppose 0 is passed for the deleteoldrdn parameter
+instead of 1:
+ldap_modrdn2( "cn=Barbara Jensen", "cn=Barbie Jensen", 0 );
+The Barbara Jensen value is not removed from the
+entry. The resulting entry has the following values:
+cn: Barbie Jensen
+cn: Babs Jensen
+cn: Barbara Jensen
+
+Changing the Location of the Entry
+Both ldap_rename and ldap_rename_s have
+a newparent parameter that allows you to specify a new
+location for the entry in the directory tree. For example, if you pass ou=Contractors,dc=example,dc=com
+ as the newparent parameter when renaming the
+entry uid=bjensen,ou=People,dc=example,dc=com, the entry
+is moved under ou=Contractors,dc=example,dc=com. The new
+DN for the entry is uid=bjensen,ou=Contractors,dc=example,dc=com.
+
+Some LDAP servers do not support this feature. When you specify
+this argument, a server might return the LDAP result code LDAP_UNWILLING_TO_PERFORM
+, with the error message Server does not support moving
+of entries.
+Synchronous Relocation of an Entry
+The following example calls the synchronous ldap_rename_s function
+to change the RDN of a user entry in the directory.
+Performing a Synchronous Relocation
+of an Entry
+#include <stdio.h>
+#include "ldap.h"
+/* Change these as needed. */
+#define HOSTNAME "localhost"
+#define PORTNUMBER LDAP_PORT
+#define BIND_DN "cn=Directory Manager"
+#define BIND_PW "23skidoo"
+#define OLD_DN "uid=wbjensen,ou=People,dc=example,dc=com"
+#define NEW_RDN "uid=wjensen"
+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 to the server as the Directory Manager. */
+ rc = ldap_simple_bind_s( ld, BIND_DN, BIND_PW );
+ 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 modify DN operation. */
+ rc = ldap_rename_s( ld, OLD_DN, NEW_RDN, NULL, 1, NULL, NULL );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_rename_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 );
+ }
+ } else {
+ printf( "%s renamed successfully.\n", OLD_DN );
+ }
+ ldap_unbind_s( ld );
+ return 0;
+}
+
+
+Asynchronous Relocation of an Entry
+The following example calls the asynchronous ldap_rename function
+to change the RDN of a user entry in the directory.
+Performing an Asynchronous
+Relocation of an Entry
+#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 BIND_DN "cn=Directory Manager"
+#define BIND_PW "dougy4444"
+#define OLD_DN "uid=wbjensen,ou=People,dc=example,dc=com"
+#define NEW_RDN "uid=wjensen"
+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 to the server as the Directory Manager. */
+ rc = ldap_simple_bind_s( ld, BIND_DN, BIND_PW );
+ 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 );
+ }
+/* Send the LDAP modify DN request. */
+ rc = ldap_rename( ld, OLD_DN, NEW_RDN, NULL, 1, NULL, NULL, &msgid );
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_rename: %s\n", ldap_err2string( rc ) );
+ ldap_unbind( ld );
+ return( 1 );
+ }
+/* Poll the server for the results of the modify DN 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 the server has still not yet sent the
+ results of the modify DN operation back to your client.
+ Break out of this switch statement, and continue calling
+ ldap_result() to poll for results. */
+ break;
+ default:
+ /* The function has retrieved the results of the modify DN 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 modify DN operation. */
+ if ( rc != LDAP_SUCCESS ) {
+ fprintf( stderr, "ldap_rename: %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 );
+ }
+ } else {
+ printf( "%s renamed successfully.\n"
+ "Counted to %d while waiting for the modify DN operation.\n",
+ OLD_DN, global_counter );
+ }
+ }
+ /* Do other work while waiting for the results of the
+ modify DN 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++;
+}
+
+
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/figures/hierovrw.eps b/mozilla/directory/docs/ldapcsdk/figures/hierovrw.eps
new file mode 100644
index 00000000000..01fe4cba0b4
Binary files /dev/null and b/mozilla/directory/docs/ldapcsdk/figures/hierovrw.eps differ
diff --git a/mozilla/directory/docs/ldapcsdk/legal.sgm b/mozilla/directory/docs/ldapcsdk/legal.sgm
new file mode 100644
index 00000000000..127dc0071c8
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/legal.sgm
@@ -0,0 +1,113 @@
+
+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.
+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.
+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.
+This distribution may include materials developed by third
+parties.
+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.
+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.
+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.
+Mozilla, Netscape, and Netscape Navigator are trademarks or
+registered trademarks of Netscape Communications Corporation in the
+United States and other countries.
+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.
+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.
+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.
+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.
+Cette distribution peut comprendre des composants
+développés par des tierces parties.
+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.
+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.
+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.
+Mozilla, Netscape, et Netscape Navigator sont des marques de
+Netscape Communications Corporation aux Etats-Unis et dans d'autres
+pays.
+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.
+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.
diff --git a/mozilla/directory/docs/ldapcsdk/license.txt b/mozilla/directory/docs/ldapcsdk/license.txt
new file mode 100644
index 00000000000..92f23fd1acf
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/license.txt
@@ -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/.
diff --git a/mozilla/directory/docs/ldapcsdk/preface.sgm b/mozilla/directory/docs/ldapcsdk/preface.sgm
new file mode 100644
index 00000000000..e9e09ad0af6
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/preface.sgm
@@ -0,0 +1,375 @@
+
+Preface
+&abstract;
+
+Who Should Use This Book
+This guide is intended for developers creating directory client applications.
+
+
+Before using this guide, you must be familiar with the following:
+&cnDirectoryServer; functionality
+Developing programs in the C programming
+language
+Specifications for LDAP and related protocols, such as DSML
+v2
+Internet and World Wide Web technologies
+
+
+Before You Read This Book
+Before developing directory client applications, install &DirectorySDKForJava;.
+
+
+
+Additional Recommended Reading
+
+Directory client application developers might benefit from reading the
+following books:
+LDAP Programming with Java by Weltman
+and Dabhura (ISBN 0-201-65758-96)
+LDAP Programming, Management and Integration by
+Donley (ISBN 1930110405)
+LDAP: Programming Directory-Enabled Applications
+with Lightweight Directory Access Protocol by Howes and Smith
+(ISBN 1-57870-000-00)
+Understanding and Deploying LDAP Directory Services by
+Howes, et al. (ISBN 1-57870-070-10)
+
+
+In addition, keep bookmarks to the following IETF documents:
+
+RFC 2251, Lightweight Directory Access Protocol (v3)
+
+
+RFC 2252, Lightweight Directory Access Protocol (v3): Attribute
+Syntax Definitions
+
+RFC 2253, Lightweight Directory Access Protocol (v3): UTF-8
+String Representation of Distinguished Names
+
+RFC 2254, The String Representation of LDAP Search Filters
+
+
+RFC 2255, The LDAP URL Format
+
+RFC 2256, A Summary of the X.500(96) User Schema for use
+with LDAPv3
+
+RFC 2829, Authentication Methods for LDAP
+
+
+RFC 2830, Lightweight Directory Access Protocol (v3): Extension
+for Transport Layer Security
+
+RFC 2849, The LDAP Data Interchange Format (LDIF) - Technical
+Specification
+
+RFC 3377, Lightweight Directory Access Protocol (v3): Technical
+Specification
+
+
+How This Book Is Organized
+
+This guide includes the following chapters.
+Chapter 1, Understanding
+LDAP describes LDAP and directory concepts.
+Chapter 2, Choosing
+a Client SDK covers what to consider when choosing a software development
+kit for building directory client applications.
+Chapter 3,
+Best Practices for Writing Client Applications reviews what and what
+not to do when building directory client applications.
+Chapter 4, About Directory
+SDK for C describes what &DirectorySDKForC; offers you as a directory
+client developer.
+Chapter 5, Getting
+Started With Directory SDK for C gets you started using &DirectorySDKForC;.
+
+Chapter 6, What's New
+In Directory SDK for C presents new features, and changes from previous
+versions of &DirectorySDKForC;.
+Chapter 7, Writing an
+LDAP Client With Directory SDK for C covers the basics of writing
+a directory client application.
+Chapter 8, Using the LDAP
+C API shows how to write an application with &DirectorySDKForC;.
+
+Chapter 9, Searching
+the Directory With Directory SDK for C shows how to write client application
+code for searching a directory.
+Chapter 10, Using Filter
+Configuration Files With Directory SDK for C shows how to write code
+to search a directory using filter configuration files.
+Chapter 11, Adding, Updating,
+and Deleting Entries With Directory SDK for C shows how to write client
+application code for changing directory entries.
+Chapter 12, Comparing
+Attribute Values With Directory SDK for C shows how to compare attribute
+values in a directory with known values.
+Chapter 13, LDAP URLs With
+Directory SDK for C shows how to handle LDAP URLs.
+Chapter 14, Getting
+Server Information With Directory SDK for C shows how to retrieve
+information about the directory and directory service.
+Chapter 15, SSL Connections
+With Directory SDK for C shows how to write client application code
+that connects to the directory over SSL.
+Chapter 16, LDAP Controls
+With Directory SDK for C shows how to handle supported LDAP controls.
+
+Chapter 17, SASL Authentication
+With Directory SDK for C shows how to connect to the directory by
+using SASL.
+Chapter 18, Extended Operations
+With Directory SDK for C shows how to write client application code
+for handling LDAP v3 extended operations.
+Chapter 19, Writing
+Multithreaded Clients With Directory SDK for C shows how to write
+multithreaded client application code.
+Chapter 20, Directory SDK for C Data Type Reference covers &DirectorySDKForC; data types
+
+Chapter 21, Directory SDK for C Function Reference covers &DirectorySDKForC; functions
+
+Chapter 22, Directory SDK for C Result Codes covers &DirectorySDKForC; function result codes
+
+Appendix A, Creative Commons Attribution-ShareAlike 2.5 provides the full text of the license governing this guide
+
+
+
+Related Reading
+
+SLAMD Distributed Load Generation Engine
+The SLAMD Distributed Load Generation Engine (SLAMD) is a
+Java 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 . SLAMD
+is also available as a java.net project. See .
+
+Java Naming and Directory Interface
+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 . The JNDI Tutorial contains detailed
+descriptions and examples of how to use JNDI. This tutorial is at .
+
+Typographic Conventions
+The following table describes the typographic changes that are used
+in this book.
+
Typographic Conventions
+
+
+
+
+Typeface
+
+Meaning
+
+Example
+
+
+
+
+
+AaBbCc123
+
+The names of commands, files, and directories, and onscreen computer
+output
+
+Edit your .login file.
+Use ls to list all files.
+machine_name% you have mail.
+
+
+
+
+AaBbCc123
+
+What you type, contrasted with onscreen computer output
+
+machine_name%su
+Password:
+
+
+
+AaBbCc123
+
+A placeholder to be replaced with a real name or value
+
+The command to remove a file is rmfilename
+.
+
+
+
+AaBbCc123
+
+Book titles, new terms, and terms to be emphasized (note that some emphasized
+items appear bold online)
+
+Read Chapter 6 in the User's Guide.
+A cache is a copy that is stored locally.
+Do not save the file.
+
+
+
+
+
+Shell Prompts in Command Examples
+The following table shows default system prompts and superuser prompts.
+
Shell Prompts
+
+
+
+
+Shell
+
+Prompt
+
+
+
+
+
+C shell on UNIX and Linux systems
+
+machine_name%
+
+
+
+C shell superuser on UNIX and Linux systems
+
+machine_name#
+
+
+
+Bourne shell and Korn shell on UNIX and Linux systems
+
+$
+
+
+
+Bourne shell and Korn shell superuser on UNIX and Linux systems
+
+
+#
+
+
+
+Microsoft Windows command line
+
+C:\
+
+
+
+
+
+Symbol Conventions
+The following table explains symbols that might be used in this book.
+
Symbol Conventions
+
+
+
+
+Symbol
+
+Description
+
+Example
+
+Meaning
+
+
+
+
+
+[ ]
+
+Contains optional arguments and command options.
+
+ls [-l]
+
+The -l option is not required.
+
+
+
+{ | }
+
+Contains a set of choices for a required command option.
+
+-d {y|n}
+
+The -d option requires that you use either the
+y argument or the n argument.
+
+
+
+${ }
+
+Indicates a variable reference.
+
+${com.sun.javaRoot}
+
+References the value of the com.sun.javaRoot variable.
+
+
+
+
+-
+
+Joins simultaneous multiple keystrokes.
+
+Control-A
+
+Press the Control key while you press the A key.
+
+
+
++
+
+Joins consecutive multiple keystrokes.
+
+Ctrl+A+N
+
+Press the Control key, release it, and then press the subsequent keys.
+
+
+
+
+→
+
+Indicates menu item selection in a graphical user interface.
+
+
+File → New → Templates
+
+From the File menu, choose New. From the New submenu, choose Templates.
+
+
+
+
+
+
+
+
diff --git a/mozilla/directory/docs/ldapcsdk/understanding-ldap.sgm b/mozilla/directory/docs/ldapcsdk/understanding-ldap.sgm
new file mode 100644
index 00000000000..c438e95e1bc
--- /dev/null
+++ b/mozilla/directory/docs/ldapcsdk/understanding-ldap.sgm
@@ -0,0 +1,274 @@
+
+Understanding LDAP
+
+LDAP
+
+Lightweight Directory Access Protocol
+LDAP
+Lightweight Directory Access Protocol (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.
+
+This chapter explains the LDAP protocol, and the concepts behind LDAP.
+This chapter covers the following topics:
+How Directory Services Work
+
+How LDAP Servers
+Organize Directories
+How LDAP
+Clients and Servers Work
+Understanding LDAP
+v3
+
+
+How Directory Services Work
+
+directory
+definition of
+
+entries
+definition of
+
+attributes
+definition of
+
+A directory consists of entries that
+contain descriptive information. For example, a directory might contain entries
+that describe people or network resources, such as printers or fax machines.
+The descriptive information is stored in the attributes 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.
+
+entries
+example of
+
+attributes
+example of
+The entry for Barbara Jensen might have the
+following attributes:
+cn: Barbara Jensen
+mail: babs@example.com
+telephoneNumber: 555-1212
+roomNumber: 3995
+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:
+cn: Barbara Jensen
+cn: Babs Jensen
+mail: babs@example.com
+telephoneNumber: 555-1212
+roomNumber: 3995
+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.
+
+directory service
+definition of
+A directory service 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.
+&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.
+
+LDAP servers
+
+LDAP clients
+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.
+
+LDAP servers
+example of
+
+LDAP clients
+example of
+&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, Solaris naming
+services, Messaging Server, Portal Server, NameFinder, and the Mozilla mail
+client. Such clients use &cnDirectoryServer; to find, update, and add information
+about users.
+How LDAP Servers Organize Directories
+
+LDAP
+organization of data
+
+entries
+organization in LDAP
+
+LDAP servers
+how data is organized
+
+Because LDAP is intended to be a global directory service, data is organized
+hierarchically, starting at a root and branching down into individual entries.
+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.
+Hierarchy of Entries in a Directory
+
+
+Simple directory information tree with two organizational
+unit entries and two user entries
+
+
+
+relative distinguished names (RDNs)
+definition of
+
+RDNs
+relative distinguished names (RDNs)
+distinguished names (DNs)
+definition of
+
+CNs
+common names (CNs)
+DNs
+distinguished names (DNs)
+common names (CNs)
+Each entry is uniquely identified by a distinguished
+name (DN). A DN includes a relative distinguished name (RDN),
+that uniquely identifies the entry at that hierarchical level. For example,
+bjensen and kjensen 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 ou=People,dc=example,dc=com
+. DC is short for domain component. The full
+DN for this example would be uid=bjensen,ou=People,dc=example,dc=com.
+Here, uid is the user ID of the entry. ou is
+short for organizational unit.
+
+LDAP servers
+how data is distributed
+The data stored in a directory can be distributed among several
+LDAP servers. For example, one LDAP server at Example.com might
+contain entries representing North American organizational units and employees,
+while another LDAP server might contain entries representing European organizational
+units and employees.
+
+LDAP servers
+how referrals work
+
+referrals
+Some LDAP servers are set up to refer requests to other LDAP servers.
+For example, if the LDAP server at Example.com 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.
+
+How LDAP Clients and Servers
+Work
+
+LDAP servers
+LDAP clients and
+
+LDAP clients
+LDAP servers and
+
+LDAP clients
+operations performed by
+
+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.
+
+An LDAP client can perform these operations, among others:
+Search for and retrieve entries from the directory
+
+Add new entries to the directory
+Update entries in the directory
+Delete entries from the directory
+Rename entries in the directory
+
+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.
+
+LDAP servers
+connecting with LDAP clients
+
+LDAP clients
+connecting with LDAP servers
+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.
+
+LDAP servers
+authentication
+
+LDAP clients
+authentication
+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.
+Understanding LDAP v3
+
+LDAP
+version 3
+
+RFC
+4511 specifies LDAP version 3. Use this version of the protocol when
+writing new client applications.
+Many LDAP servers continue to support LDAP version 2 for use with legacy
+clients. This version of the protocol is specified in RFC 1777.
+
+LDAP v3 includes new features not present in version 2:
+Clients and servers can specify controls that
+extend the functionality of an LDAP operation.
+Clients can request that the server perform extended
+operations, operations not included in the list of standard LDAP
+operations.
+Clients can use Simple Authentication and Security
+Layer (SASL) mechanisms to authenticate to the directory. SASL
+is specified in
+RFC 4422.
+Servers, known as Directory System Agents (DSAs),
+have DSA-specific entries (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.
+
+Servers make their schemas, which define
+the object classes, attributes, syntaxes, and matching rules enforced by the
+directory, available to clients through the root DSE.
+
+UTF-8
+support of
+Both client and server applications can support data in UTF-8.
+UTF-8 is a transformation format of the Universal Character Set
+standard. UTF-8 is specified in RFC 3269. With UTF-8, clients can request and receive
+data that is tagged with language information.
+
+
+
diff --git a/mozilla/directory/docs/ldapjdk/00-Programmers-Guide.book b/mozilla/directory/docs/ldapjdk/00-Programmers-Guide.book
new file mode 100644
index 00000000000..993bcde7019
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/00-Programmers-Guide.book
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+]>
+
+Programmer's Guide for LDAP Java SDK
+
+MarkCraig
+
+June 2007
+
+Sun Microsystems, Inc.
+
+4150 Network Circle
+Santa ClaraCA95054
+U.S.A.
+
+2000-2007Sun Microsystems, Inc. All Rights Reserved.
+License -
+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. The full text of the
+License is provided at the end of this
+document.&legal;
+
+&abstract;
+
+&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;
+
+Creative Commons Attribution-ShareAlike 2.5
+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.
+See the License for the specific language governing permissions
+and limitations under the License. The full text of the License is as
+follows.
+&license;
+
+Index
+
+
diff --git a/mozilla/directory/docs/ldapjdk/abstract.sgm b/mozilla/directory/docs/ldapjdk/abstract.sgm
new file mode 100644
index 00000000000..5682faae336
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/abstract.sgm
@@ -0,0 +1,20 @@
+
+This &BookTitle; 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.
diff --git a/mozilla/directory/docs/ldapjdk/best-practices.sgm b/mozilla/directory/docs/ldapjdk/best-practices.sgm
new file mode 100644
index 00000000000..8f96271f1d6
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/best-practices.sgm
@@ -0,0 +1,378 @@
+
+Best Practices for
+Writing Client Applications
+
+
+This chapter includes best practices for developing client applications
+and cover the following topics:
+Creating Your Application
+
+Troubleshooting Problems
+
+
+
+Creating Your Application
+
+This section identifies practices to observe when creating directory
+client applications.
+Specify LDAP v3
+
+Authenticate Correctly
+
+Limit Connection Overhead
+
+Handle Potential
+Inactivity Timeouts
+Retrieve Entries Intelligently
+
+Write Simple, Conforming LDAP
+Filters
+Performing Specific Modifications
+
+Trust Result Codes
+
+Limit Dealings With Groups
+and Roles
+Read the DSE
+
+Use Resource-Intensive Features Sparingly
+Avoid Hard Coding Certain Information
+
+Define Schemas Only When Necessary
+
+Handle Referrals
+
+Treat a Directory as a Directory
+
+
+Specify LDAP v3
+
+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.
+With JNDI, you could use LDAP v3 as shown here.
+import java.util.Hashtable;
+import javax.naming.ldap.InitialLdapContext;
+
+Hashtable env = new Hashtable();
+env.put("java.naming.ldap.version", "3");
+InitialLdapContext ctx = new InitialLdapContext(env, null);
+
+With &DirectorySDKForC;, you could use LDAP v3 as shown
+here.
+#include "ldap.h"
+
+int version = LDAP_VERSION3;
+ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version );
+&DirectorySDKForC; uses LDAP v3 by default.
+With &DirectorySDKForJava;, you could use LDAP v3 as shown
+here.
+import netscape.ldap.LDAPConnection;
+
+LDAPConnection ld = new LDAPConnection();
+ld.setOption(LDAPv3.PROTOCOL_VERSION, new Integer(3));
+
+
+
+
+
+Authenticate Correctly
+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.
+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).
+If your application needs to authenticate, obtain a regular account
+to authenticate with the directory, rather than using the directory superuser
+account such as cn=Directory Manager. When you authenticate
+as directory superuser, you often bypass normal access control mechanisms.
+Bypassing normal access control renders auditing directory access more difficult.
+
+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.
+
+Limit Connection Overhead
+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.
+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.
+When finished with a connection, your application should perform an
+unbind.
+Handle Potential Inactivity Timeouts
+Most network equipment can use timeouts to drop stale connections, ensuring
+the equipment keeps a maximum number of connections that are available.
+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.
+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.
+
+Retrieve Entries Intelligently
+&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.
+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.
+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 USAGE, which is directoryOperation
+ or dsaOperation.
+When retrieving entries and attributes, recognize that you might not
+have access to all the attributes that exist.
+Write Simple, Conforming LDAP Filters
+
+LDAP filters
+writing
+
+The best filters use attributes that are indexed according to the way
+the attributes are indexed. For example, if employeeNumber is
+indexed for equality, your filter should be an equality filter such as (employeeNumber=123456)
+. Do not use a substring filter instead.
+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 not
+, !, only with and, &
+, for example (&(cn=Barbara)(!(sn=Jensen))).
+When you use not with or in a filter,
+the directory must construct a candidate list of everything except what your
+filter specifies.
+Performing Specific Modifications
+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.
+Moreover, when you have large values to store in an attribute, store
+a reference to the data instead of storing the data object.
+Trust Result Codes
+
+result codes
+trust
+
+&cnDirectoryServer; trades tight consistency across replica servers
+for very high performance, availability, and scalability. By allowing
+loose consistency 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.
+
+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.
+
+Limit Dealings With Groups and Roles
+
+groups
+working with
+
+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.
+
+For dynamic groups, do the following:
+Read the URL from the group definition.
+Examine the host, DN, and scope of the URL.
+Apply the filter part of the URL to the entry for the account.
+
+
+
+roles
+working with
+For roles, compare the DN of the role to the
+nsRole attribute of the entry for the account, such as (nsrole=cn=management,ou=people,dc=example,dc=com)
+. You can then retrieve all the values of the nsRole attribute
+for the account.
+Read the DSE
+
+DSE, root
+reading
+
+The root DSE is the entry that is retrieved by ldapsearch -b
+"" -s base "(objectclass=*)". 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.
+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.
+Use Resource-Intensive Features Sparingly
+Directories offer powerful features that can nevertheless place a heavy
+load on the server. Two such features are persistent search, and server-side
+sorting.
+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.
+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.
+
+Avoid Hard Coding Certain Information
+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.
+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.
+Be aware as well that object class and attribute type identifiers are
+not case-sensitive in LDAP. Your application should therefore recognize
+that inetOrgPerson and inetorgperson are
+equivalent, as are isMemberOf and ismemberof.
+
+Define Schemas Only When Necessary
+
+schema
+defining
+
+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.
+
+When you must define your own schema objects, follow these guidelines:
+Extend existing object classes by using AUXILIARY classes.
+
+Create new attributes rather than redefining existing attributes.
+Other applications might depend on existing attributes to keep
+their existing semantics.
+Obtain new object identifiers for the schema elements you
+define, rather than reusing existing object identifiers.
+Obtain new names for the schema elements you define, rather
+than reusing existing names.
+Update &cnDirectoryServer; schema over LDAP if you can.
+
+
+
+Handle Referrals
+
+referrals
+following
+
+LDAP v3 allows directories that are unable to handle your request to
+refer your application to other directories. Your application should follow
+those referrals.
+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.
+Treat a Directory as a Directory
+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.
+
+Troubleshooting Problems
+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.
+Check Result Codes
+
+troubleshooting
+result codes
+
+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.
+
+1
+LDAP operations error. The server encountered an error while
+processing your request.
+
+
+32
+No such object. The entry is not present on the server. Also,
+no referral is defined for the entry.
+
+
+49
+Invalid credentials. Your application failed to authenticate
+properly.
+
+
+53
+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.
+
+
+65
+Object class violation. Your write request would cause an
+entry to no longer conform to the schema defined for the directory.
+
+
+68
+Already exists. Your application is requesting to add an entry
+that has the same DN as an entry already present in the directory.
+
+
+
+RFC 4511 defines
+LDAP error codes, as does Chapter 22, Directory
+SDK for C Result Codes.
+Check Server Log Files
+
+troubleshooting
+log files
+
+&cnDirectoryServer; logs messages related to server operation in its
+logs/errors file. If you have access to this file, you might find
+useful troubleshooting information there.
+When debugging your application against &cnDirectoryServer;, you can
+adjust the log level, as well. See the server documentation for instructions.
+
+Inspect Network Packets
+
+troubleshooting
+decoding packets
+
+Although LDAP is not a textual protocol, tools such as
+snoop1M,
+ethereal, and tcpdump can decode the packets,
+sometimes providing you with important debugging information.
+
+
diff --git a/mozilla/directory/docs/ldapjdk/choose-api.sgm b/mozilla/directory/docs/ldapjdk/choose-api.sgm
new file mode 100644
index 00000000000..9db9908e1ee
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/choose-api.sgm
@@ -0,0 +1,98 @@
+
+Choosing a Client
+SDK
+
+This chapter discusses software development kits to help you select
+the appropriate directory SDK for your particular situation.
+
+This chapter covers the following topics:
+Java Naming and Directory Interface
+
+Directory SDK for Java
+
+Directory SDK for C
+
+Operating System libldap Library
+Support for Other Programming
+Languages
+
+
+Java Naming and Directory Interface
+
+Java Naming and Directory Interface
+
+JNDI
+Java Naming and Directory Interface
+Java Naming and Directory Interface (JNDI) technology supports directory
+access through LDAP and DSML v2 from Java 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.
+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.
+For information about JNDI, see . The JNDI
+Tutorial contains descriptions and examples of how to use JNDI.
+The tutorial is at .
+&DirectorySDKForC;
+&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.
+&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;.
+
+This document demonstrates how to use &DirectorySDKForC;. &DirectorySDKForC; code
+is published in open source form as part of the Mozilla Directory SDK project.
+
+&DirectorySDKForJava;
+&DirectorySDKForJava; lets you access LDAP directories from Java
+applications, but it is not part of the Java platform.
+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.
+This document demonstrates how to use &DirectorySDKForJava;. &DirectorySDKForJava; code
+is published in open source form as part of the Mozilla Directory SDK project.
+
+Operating System libldap Library
+
+
+libraries
+libldap
+
+libldap
+
+The native LDAP library on Solaris systems provides
+essentially the same API as &DirectorySDKForC;. Many &DirectorySDKForC; need
+only be recompiled to work with libldap.
+The LDAP library is sometimes not compatible with libldap on
+many GNU/Linux distributions. Many GNU/Linux distributions provide OpenLDAP
+support by default.
+Support for Other Programming Languages
+Support for directory access is available in a number of contexts where
+you do not choose to use the C or Java languages.
+For example, Perl has the PerLDAP module and the Net::LDAP collection
+of modules. Python has the python-ldap 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.
+
diff --git a/mozilla/directory/docs/ldapjdk/figures/entries.eps b/mozilla/directory/docs/ldapjdk/figures/entries.eps
new file mode 100644
index 00000000000..4081f95c968
Binary files /dev/null and b/mozilla/directory/docs/ldapjdk/figures/entries.eps differ
diff --git a/mozilla/directory/docs/ldapjdk/figures/hier1lvl.eps b/mozilla/directory/docs/ldapjdk/figures/hier1lvl.eps
new file mode 100644
index 00000000000..136c3353dc6
Binary files /dev/null and b/mozilla/directory/docs/ldapjdk/figures/hier1lvl.eps differ
diff --git a/mozilla/directory/docs/ldapjdk/figures/hierbase.eps b/mozilla/directory/docs/ldapjdk/figures/hierbase.eps
new file mode 100644
index 00000000000..ea7c7cb3fee
Binary files /dev/null and b/mozilla/directory/docs/ldapjdk/figures/hierbase.eps differ
diff --git a/mozilla/directory/docs/ldapjdk/figures/hierovrw.eps b/mozilla/directory/docs/ldapjdk/figures/hierovrw.eps
new file mode 100644
index 00000000000..01fe4cba0b4
Binary files /dev/null and b/mozilla/directory/docs/ldapjdk/figures/hierovrw.eps differ
diff --git a/mozilla/directory/docs/ldapjdk/figures/hiersrch.eps b/mozilla/directory/docs/ldapjdk/figures/hiersrch.eps
new file mode 100644
index 00000000000..9bffb67d1c0
Binary files /dev/null and b/mozilla/directory/docs/ldapjdk/figures/hiersrch.eps differ
diff --git a/mozilla/directory/docs/ldapjdk/jdk-adding.sgm b/mozilla/directory/docs/ldapjdk/jdk-adding.sgm
new file mode 100644
index 00000000000..5834402aed7
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/jdk-adding.sgm
@@ -0,0 +1,677 @@
+
+Adding, Updating, and Deleting Entries With &DirectorySDKForJava;
+
+This chapter explains how to use the LDAP Java classes to add, modify,
+delete, and rename entries in the directory.
+
+This chapter covers the following topics:
+Adding an Entry With Directory
+SDK for Java
+Modifying an Entry With Directory SDK for Java
+Deleting an Entry With Directory
+SDK for Java
+Renaming an Entry With Directory
+SDK for Java
+
+
+Adding an Entry With &DirectorySDKForJava;
+
+adding
+entries
+
+entries
+adding
+
+
+To add an entry to the directory, follow this general procedure:
+Create individual attributes for the entry.
+Create the set of attributes that make up the entry and add
+each of the attributes to this set.
+Create the new entry, specifying a unique distinguished name
+(DN) to identify the entry and the set of attributes that make up the entry.
+
+Add the new entry to directory.
+Creating a New Attribute
+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 LDAPAttribute object.
+To create a new attribute, use the LDAPAttribute constructor.
+You can specify a single string value, multiple string values, or a binary
+value when constructing the object.
+For example, the following section of code creates a new object for
+the attribute cn with the value Jane St. Clair.
+
+LDAPAttribute attr = new LDAPAttribute("cn", "Jane St. Clair");
+The following section of code creates an attribute objectclass with
+the values top, person, organizationalPerson
+, and inetOrgPerson.
+String objectclasses[] = {"top", "person", "organizationalPerson",
+ "inetOrgPerson"};
+LDAPAttribute attr = new LDAPAttribute("objectclass", objectclasses);
+You can also add string or binary values to an LDAPAttribute object
+by invoking the addValue method.
+Creating a New Attribute Set
+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 LDAPAttributeSet object.
+To create a new attribute set, use the LDAPAttributeSet constructor.
+Invoke the add method to add LDAPAttribute objects
+to the set.
+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);
+
+Creating a New Entry
+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 LDAPEntry object.
+To create a new entry, use the LDAPEntry constructor.
+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);
+
+Adding the New Entry to the Directory
+
+Before you add an entry to the directory, make sure that you have done
+the following:
+You have specified the object classes of the entry using the
+objectclass attribute, and have specified the required attributes
+for those object classes.
+
+For example, organizational units might be represented by entries of
+the organizationalUnit object class. To add an entry for
+an organizational unit, you need to specify the following attributes in the
+entry:
+objectclass with value top
+
+objectclass with value organizationalUnit
+
+ou with the value for the organizational
+unit, such as People
+
+
+You have authenticated as a user who has the access permissions
+to add the entry to the directory.If you do not have permission
+to add the entry, an LDAPException is returned with
+result code LDAPException.INSUFFICIENT_ACCESS_RIGHTS.
+
+
+To add the entry to the directory, invoke the add method
+of the LDAPConnection object.
+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());
+}
+
+Example of Adding an Entry
+The following example adds a new entry to the directory for the user
+who is named William Jensen.
+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());
+ }
+ }
+ }
+}
+
+
+Modifying an Entry With &DirectorySDKForJava;
+
+modifying
+entries
+
+entries
+modifying
+
+attributes
+modifying
+
+
+To modify an entry in the directory, follow this general procedure:
+Specify each attribute change to make.
+
+If you are making only one change to the entry, construct
+an LDAPModification object that specifies the change
+that needs to be made.
+If you are making more than one change, you need to construct
+an LDAPModificationSet object that specifies the changes
+that need to be made.
+
+
+Use the DN of the entry to find and update the
+entry in the directory.
+Specifying Attribute Changes
+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.
+Adding New Attribute Values
+
+attributes
+adding values to
+
+adding
+values to an attribute
+
+
+To add new values to an attribute in an entry, construct a new LDAPAttribute
+ object. Specify the name of the attribute. Also, specify the
+values to add. Then, perform one of the following operations:
+If you are making a single change to the entry, construct
+a new LDAPModification object to specify that change.
+Pass LDAPModification.ADD and the LDAPAttribute object
+as arguments to the LDAPModification constructor.
+
+If you are collecting multiple changes to an entry in an
+LDAPModificationSet object, invoke the add method.
+This method adds the change to the set of modifications. Pass LDAPModification.ADD
+ and the LDAPAttribute object as arguments
+to this method.
+
+For example, the following code excerpt adds the value babs@example.com
+ to the mail attribute:
+LDAPModificationSet mods = new LDAPModificationSet();
+LDAPAttribute attrMail = new LDAPAttribute("mail", "babs@example.com");
+mods.add(LDAPModification.ADD, attrMail);
+If the specified attribute does not exist in the entry, the attribute
+is created for the entry.
+Deleting Attribute Values
+
+attributes
+removing values from
+
+deleting
+values from an attribute
+
+removing
+values from an attribute
+
+
+To remove values from an attribute in an entry, construct a new
+LDAPAttribute object, specifying the name of the attribute and
+the values to remove. Then, perform one of the following operations:
+If you are making a single change to the entry, construct
+a new LDAPModification object to specify that change.
+Pass LDAPModification.DELETE and the LDAPAttribute
+ object as arguments to the LDAPModification constructor.
+
+If you are collecting multiple changes to an entry in an
+LDAPModificationSet object, invoke the add method.
+The method adds the change to the set of modifications. Pass LDAPModification.DELETE
+ and the LDAPAttribute object as arguments
+to this method.
+
+For example, the following code excerpt removes the value babs@example.com
+ from the mail attribute:
+LDAPModificationSet mods = new LDAPModificationSet();
+LDAPAttribute attrMail = new LDAPAttribute("mail", "babs@example.com");
+mods.add(LDAPModification.DELETE, attrMail);
+If you remove all values from an attribute, the attribute is removed
+from the entry. If you do not specify any values in the LDAPAttribute object,
+the attribute is also removed from the entry.
+Replacing Attribute Values
+
+attributes
+replacing values of
+
+changing
+values of an attribute
+
+modifying
+values of an attribute
+
+replacing
+values of an attribute
+
+
+To replace values for an attribute in an entry, construct a new
+LDAPAttribute object, specifying the name of the attribute and
+the values to replace. Then, perform one of the following operations:
+If you are making a single change to the entry, construct
+a new LDAPModification object to specify that change.
+Pass LDAPModification.REPLACE and the LDAPAttribute
+ object as arguments to the LDAPModification constructor.
+
+If you are collecting multiple changes to an entry in an
+LDAPModificationSet object, invoke the add method.
+The method adds the change to the set of modifications. Pass LDAPModification.REPLACE
+ and the LDAPAttribute object as arguments
+to this method.
+
+For example, the following code excerpt replaces the existing value
+of the mail attribute with babs@example.com:
+
+LDAPModificationSet mods = new LDAPModificationSet();
+LDAPAttribute attrMail = new LDAPAttribute("mail", "babs@example.com");
+mods.add(LDAPModification.REPLACE, attrMail);
+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 LDAPAttribute
+ object, the attribute is removed from the entry.
+Removing an Attribute
+
+attributes
+removing from an entry
+
+entries
+removing attributes from
+
+
+To remove an attribute from an entry, perform one of the following operations:
+
+Replace the values of the attribute with an LDAPAttribute
+ object that contains no values.
+Remove the values of the attribute with an LDAPAttribute
+ object that contains no values.
+Remove all values for the attribute.
+
+For example, the following code excerpt demonstrates the first two options
+by preparing an LDAPModificationSet object to remove
+the mail and description attributes:
+LDAPModificationSet mods = new LDAPModificationSet();
+LDAPAttribute attrMail = new LDAPAttribute("mail");
+LDAPAttribute attrDesc = new LDAPAttribute("description");
+mods.add(LDAPModification.REPLACE, attrMail);
+mods.add(LDAPModification.DELETE, attrDesc);
+
+
+Modifying the Entry in the Directory
+
+Before you modify an entry, make sure of the following:
+You have not removed any of the required attributes for that
+object class.
+You have authenticated as a user who has the access permissions
+to modify the entry in the directory.If you do not have permission
+to modify the entry, an LDAPException is returned with
+the result code LDAPException.INSUFFICIENT_ACCESS_RIGHTS.
+
+
+You specify the change with an LDAPModification object.
+You specify a list of changes with an LDAPModificationSet object.
+When finished specifying the change, pass the object with the DN of the entry
+to the modify method of the LDAPConnection object.
+
+Example of Modifying an Entry
+The following example modifies an entry in the directory.
+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());
+ }
+ }
+ }
+}
+
+
+Deleting an Entry With &DirectorySDKForJava;
+
+deleting an entry
+
+entries
+deleting
+
+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 LDAPException is returned with
+result code LDAPException.INSUFFICIENT_ACCESS_RIGHTS.
+To remove an entry from the directory, invoke the delete method
+of the LDAPConnection object. Specify the DN of the
+entry that you want to remove.
+The following example deletes the entry that is added in Example of Adding an Entry.
+
+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());
+ }
+ }
+ }
+}
+
+Renaming an Entry With &DirectorySDKForJava;
+
+changing the name of an entry
+
+moving an entry
+
+renaming an entry
+
+entries
+renaming
+
+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 LDAPException is returned with result
+code LDAPException.INSUFFICIENT_ACCESS_RIGHTS.
+
+To rename an entry, invoke the rename method of the
+LDAPConnection object. With this method, you can change the following:
+
+The relative distinguished name (RDN) of the entry
+
+The location of the entry in the directory by changing the
+DN and not just the RDNSome LDAP servers do not support moving
+entries by changing their DNs. Check your LDAP server documentation for further
+information.
+
+Changing the Relative Distinguished
+Name
+When invoking the rename method of the LDAPConnection
+ object, you can specify a deleteoldrdn parameter.
+The parameter allows you to remove the old RDN from the entry. Suppose an
+entry has the following values for the uid attribute:
+uid: wbjensen
+uid: wbj
+The following code excerpt changes the user ID value wbjensen to
+wjensen and removes the wbjensen value:
+ld.rename("uid=wbjensen,ou=People,dc=example,dc=com", "uid=wjensen", true);
+
+The resulting values in the entry do not include the old RDN:
+uid: wbjensen
+uid: wbj
+The following code excerpt retains the existing user ID value after
+the rename operation:
+ld.rename("uid=wbjensen,ou=People,dc=example,dc=com", "uid=wjensen", false);
+
+In this case, the resulting values in the entry do include
+the old RDN:
+uid: wbjensen
+uid: wjensen
+uid: wbj
+The DN after the rename operation is, however, uid=wjensen,ou=People,dc=example,dc=com
+.
+The following example creates an entry and then renames it:
+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());
+ }
+ }
+ }
+}
+
+Changing the Distinguished Name
+When invoking the rename method of the LDAPConnection
+ object, you can specify a newParentDN 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.
+The following example moves Sam Carter's entry from the organizational
+unit People, to the organizational unit Special Users:
+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());
+ }
+ }
+}
+
+
+
diff --git a/mozilla/directory/docs/ldapjdk/jdk-asynchronous.sgm b/mozilla/directory/docs/ldapjdk/jdk-asynchronous.sgm
new file mode 100644
index 00000000000..b63584ddc37
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/jdk-asynchronous.sgm
@@ -0,0 +1,277 @@
+
+Writing Asynchronous Clients With &DirectorySDKForJava;
+
+This chapter shows how to use the asynchronous interface to LDAP in
+Java applications.
+
+This chapter covers the following topics:
+Synchronous and Asynchronous Connections With Directory SDK for Java
+Common Uses for the Asynchronous Interface With Directory SDK for Java
+Classes in the Asynchronous Interface for Directory SDK for Java
+Performing Asynchronous Searches With Directory SDK for Java
+
+Further Reading About the Asynchronous Interface for Directory SDK for Java
+
+
+Synchronous and Asynchronous Connections
+With Directory SDK for Java
+
+asynchronous interface
+explained
+
+synchronous interface
+explained
+
+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.
+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.
+LDAPConnection 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.
+Common Uses for the Asynchronous Interface
+With Directory SDK for Java
+
+asynchronous interface
+common uses
+
+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 multiplexing.
+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.
+The following example illustrates a practical use of multiplexed searches
+and the asynchronous interface.
+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.
+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.
+Classes in the Asynchronous Interface for Directory
+SDK for Java
+
+asynchronous interface
+classes
+
+&DirectorySDKForJava; handles asynchronous communication through
+the LDAPAsynchronousConnection interface and its dependent
+classes. These files collectively form the asynchronous extensions to the
+LDAP API.
+LDAPAsynchronousConnection defines methods for
+authenticating to a server, as well as for searching, modifying, comparing,
+and deleting entries in the directory.
+When you call a method of LDAPAsynchronousConnection,
+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.
+
+LDAPAsynchronousConnection incorporates the following
+classes for handling asynchronous client-server interactions:
+LDAPMessage, which is the base class
+for LDAP request and response messages.
+LDAPResponse, which extends LDAPMessage
+, represents a message received from an LDAP server in response
+to a request.
+LDAPExtendedResponse, which extends
+LDAPResponse. This response is the response that an LDAP server
+returns when handling an extended operation request.
+LDAPResponseListener queues LDAPResponse
+ messages.
+LDAPSearchResult, which extends
+LDAPMessage. The response contains a single LDAP entry. The response
+is one of the responses an LDAP server can return when handling a search request.
+
+LDAPSearchResultReference, which extends
+LDAPMessage. The response contains a referral. The response is
+one of the responses that an LDAP server can return when handling a search
+request.
+LDAPSearchListener queues search results
+and references.
+
+
+Performing Asynchronous Searches With Directory
+SDK for Java
+One of the most common uses of the asynchronous interface is for performing
+multiplexed searches using more than one server or suffix.
+To Search Across Multiple Servers
+
+asynchronous interface
+search multiple servers
+
+
+To search on more than one server, perform the following steps.
+
+
+Connect to all the servers.
+Create a response listener for one search.
+Share the response listener with all the other searches.
+
+Obtain and process the results.
+Disconnect from the servers.
+
+
+Searching Across Multiple Servers
+This example demonstrates how to search on two servers at the same time.
+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());
+ }
+ }
+}
+
+
+To Search Across Multiple Suffixes
+on a Single Server
+
+asynchronous interface
+search multiple suffixes
+
+
+To search on more than one suffix, perform the following steps.
+
+
+Connect to the server.
+Create a response listener for one search.
+Share (multiplex) the response listener with the other searches.
+
+Obtain and process the results.
+Disconnect from the server.
+
+
+Searching Across Multiple Suffixes
+This example demonstrates how to search across two suffixes at the same
+time.
+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());
+ }
+ }
+}
+
+
+
+Further Reading About the Asynchronous Interface
+for Directory SDK for Java
+The asynchronous interface is defined in an Internet Draft, The
+Java LDAP Application Programming Interface.
+
diff --git a/mozilla/directory/docs/ldapjdk/jdk-common-classes.sgm b/mozilla/directory/docs/ldapjdk/jdk-common-classes.sgm
new file mode 100644
index 00000000000..07df5f50f07
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/jdk-common-classes.sgm
@@ -0,0 +1,617 @@
+
+Using the LDAP Java Classes
+
+This chapter covers general LDAP Java classes that are commonly used
+when writing LDAP clients.
+
+This chapter covers the following topics:
+Getting Information About Directory
+SDK for Java
+Handling Exceptions
+With Directory SDK for Java
+Handling Referrals With
+Directory SDK for Java
+Using In-Memory Cache With
+Directory SDK for Java
+Cloning a Connection
+With Directory SDK for Java
+Manipulating Distinguished
+Names With Directory SDK for Java
+
+
+Getting Information About &DirectorySDKForJava;
+
+&DirectorySDKForJava;
+getting information about
+
+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.
+To get this information, use the getProperty method
+of the LDAPConnection object.
+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());
+}
+Although a setProperty method is provided, currently
+no properties exist that you can set. If you invoke the setProperty method,
+the method returns an LDAPException.
+Handling Exceptions With &DirectorySDKForJava;
+
+exceptions
+handling
+
+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 0 indicates
+that the operation was successful. A non zero result code usually indicates
+that an error occurred.
+Getting Information About the Error
+
+exceptions
+getting information about
+
+LDAP result code
+
+In the LDAP Java classes, when an error occurs, an LDAPException
+ is returned. Referrals cause an LDAPReferralException to
+be returned as described in Handling
+Referrals With Directory SDK for Java.
+
+An LDAPException contains the following information:
+
+The LDAP result code for the error that occurred
+
+A message that contains any additional information about the
+error from the server
+
+An error can occur when an entry specified by a DN cannot be found.
+The LDAPException then also contains the DN of the
+closest matching entry that can be found.
+
+To get information from the LDAPException, use
+one of the following methods:
+To get the string representation of the exception, use the
+toString method.
+To get the LDAP result code, use the getLDAPResultCode method.
+
+To get any additional information sent by the server, use
+the getLDAPErrorMessage method.
+To get the closest matching DN in cases where your client
+specified a DN to a nonexistent entry, use the getMatchedDN method.
+
+
+To get the error message describing the LDAP result code, use the
+errorCodeToString method, as described in Getting the Error Message.
+The following section of code gets and prints information about an
+LDAPException.
+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;
+ }
+}
+
+Getting the Error Message
+
+LDAP result code
+string description for
+
+To get the error message for an LDAP result code, use the errorCodeToString
+ method.
+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));
+}
+Error messages corresponding to each LDAP result code are located either
+inside the ldapjdk.jar file or under another directory
+in your CLASSPATH, in a properties file named netscape/ldap/errors/ErrorCodes.props
+ or netscape/ldap/errors/ErrorCodes_locale.props
+. locale can be a two-letter version
+of the locale, such as de, fr, or
+ja, or it can be a full version of the locale, such as en_US.
+
+When you invoke the errorCodeToString method of an
+LDAPException, 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 errorCodeToString method
+looks for locale-specific properties files in the following order, retrieving
+the first property that is found:
+netscape/ldap/error/ErrorCodes_language_
+country.props
+netscape/ldap/error/ErrorCodes_language.props
+netscape/ldap/error/ErrorCodes.props
+
+
+Handling Referrals With &DirectorySDKForJava;
+
+referrals
+
+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 referral.
+This section explains how to set up your LDAP client to handle referrals automatically.
+
+Understanding Referrals
+
+Suppose an LDAP server has a directory that starts under dc=example,dc=com
+. Your client might send the server a request to modify the entry
+with the DN uid=bjensen,ou=People,o=example.com. The entry
+is not under dc=example,dc=com. One of the following can
+occur.
+If the server is not configured to send a referral, an
+LDAPException is returned with the LDAP result code LDAPException.NO_SUCH_OBJECT
+.
+If the server is configured to refer you to another LDAP server,
+the server sends a referral back to your client.
+
+Depending on how your LDAP client is configured, one of the following
+can occur:
+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 Enabling or Disabling
+Referral Handling.
+If your client does not handle referrals automatically, an
+LDAPReferralException is returned. You can get the LDAP URL specified
+in the referral by catching the exception, and then invoking the getURLs
+ method.
+
+By default, clients built with &DirectorySDKForJava; are configured
+to follow referrals automatically.
+
+Another concept that is similar to a referral is a search reference.
+A search reference is an entry with the object class
+referral. The ref attribute of this object contains
+an LDAP URL that points to another LDAP server.
+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 LDAPReferralException is then returned.
+Enabling or Disabling Referral Handling
+
+referrals
+handling automatically
+
+By default, clients built with &DirectorySDKForJava; automatically
+follow referrals to other servers.
+
+To change the way your client handles referrals, use one of two methods.
+Use the setOption method of the LDAPConnection object
+to change the behavior for all LDAP operations. Alternatively, use the setReferrals
+ method of the LDAPConstraints object to
+change the behavior for a specific search request.
+To prevent the client from automatically following referrals,
+pass LDAPv3.REFERRALS and false as arguments
+to the setOption method. Alternatively, pass false as
+the argument to the setReferrals method.
+To enable the client to follow referrals automatically again,
+pass LDAPv3.REFERRALS and true as arguments
+to the setOption method. Alternatively, pass true as
+the argument to the setReferrals method.
+
+
+Limiting Referral Hops
+
+referrals
+specifying maximum hops
+
+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 referral hop limit.
+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.
+If the referral hop limit is exceeded, an LDAPReferralException is
+returned.
+To set the referral hop limit, use either of two methods. Use the
+LDAPv3.REFERRALS_HOP_LIMIT preference with the setOption method
+of the LDAPConnection object to change the behavior
+for all LDAP operations. Alternatively, use the setHopLimit method
+of the LDAPConstraints object to change the behavior
+for a specific search request.
+By default, the maximum number of referral hops is 10.
+Binding When Following Referrals
+
+authentication
+authenticating during referrals
+
+referrals
+authenticating
+
+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.
+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 LDAPRebind interface. Then, specify
+an object of this new class with either of two methods. Use the LDAPv3.REFERRALS_REBIND_PROC
+ preference with the setOption method of the
+LDAPConnection object to set the preference for all LDAP operations.
+Alternatively, use the setRebindProc method of the
+LDAPConstraints object to change the behavior for a specific search
+request.
+The LDAPRebind interface specifies a getRebindAuthentication
+ method that returns an LDAPRebindAuth object.
+The getRebindAuthentication method and the LDAPRebindAuth
+ object that the method returns are used to get the DN and password
+for authentication.
+
+The following steps explain how this works.
+The LDAP server sends a referral back to the client. The referral
+contains an LDAP URL that points to another LDAP server.
+The client creates a new LDAPConnection object.
+
+The client connects to the host and port specified in the
+LDAP URL.
+You can use the getRebindProc method to
+find your object, the object that implements the LDAPRebind interface.
+The client then invokes the getRebindAuthentication method,
+passing in the host and port specified in the LDAP URL.
+The getRebindAuthentication method in your
+object returns an LDAPRebindAuth object.
+
+The client invokes the getDN and getPassword
+ methods of the returned LDAPRebindAuth object
+to get the DN and password to use for authentication.
+The client invokes the authenticate method of the LDAPConnection
+ object and passes the DN and password to authenticate to the
+server.
+
+
+Basically, you need to define the following:
+A class that implements the LDAPRebind interface
+
+A getRebindAuthentication that takes a
+host name and port number.
+This method creates an LDAPRebindAuth object
+that specifies the DN and password to use for authentication.
+
+
+
+Using In-Memory Cache With &DirectorySDKForJava;
+
+cache
+
+in-memory cache
+
+connection
+caching results
+
+LDAP session
+caching results
+
+search results
+caching
+
+&DirectorySDKForJava; includes an LDAPCache 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.
+How the Cache Operates
+
+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.
+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.
+
+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.
+
+
+Each item is uniquely identified by the search criteria, which includes
+the following:
+Host name and port number of the LDAP server
+Base DN of the search
+Search filter
+Scope of the search
+Attributes to be returned in the search results
+
+DN used to authenticate the client when binding to the server
+
+LDAP v3 controls specified in the search request
+
+
+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.
+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.
+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
+ou=People,dc=example,dc=com as a base DN to cache, your client caches
+search requests where the base DN is ou=People,dc=example,dc=com.
+
+Setting Up an In-Memory Cache
+
+cache
+setting up
+
+
+To set up a cache for your connection, do the following:
+Construct a new LDAPCache object that
+represents the cache.
+Invoke the setCache method of an LDAPConnection
+ object to associate the cache with the connection.
+
+
+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.
+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());
+}
+
+Caching Requests by Base DN
+If you do not want all search requests cached, specify an array of base
+DNs for search requests to cache in the LDAPCache constructor.
+
+For example, the following section of code constructs a cache that only
+tracks search requests that specify the base DNs ou=People,dc=example,dc=com
+ and ou=Groups,dc=example,dc=com.
+/* 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);
+
+Sharing a Cache Among Connections
+
+cache
+sharing between connections
+
+You can also share the same in-memory cache among different connections.
+
+Invoke the getCache method of an LDAPConnection
+ object to get the LDAPCache object that
+is used.
+Invoke the setCache method of a different
+LDAPConnection object to associate the retrieved LDAPCache
+ object with the connection.
+
+When you clone an LDAPConnection object, the
+new object automatically shares the same LDAPCache object
+with the original object.
+Flushing the Cache
+
+cache
+flushing
+
+To flush items from the cache, invoke the flushEntries method
+of the LDAPCache object. You can flush either selected
+items or all items from the cache.
+
+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 flushEntries method. If the base DN
+of a cached search request falls within the scope you specified, the search
+request is flushed from the cache.
+
+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 ou=People,dc=example,dc=com
+ subtree, the item is removed from the cache.
+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);
+
+To flush all items from the cache, pass null as
+the first argument of the flushEntries method:
+
+
+myCache.flushEntries(null, 0);
+
+Getting Cache Statistics
+
+cache
+getting statistics
+
+
+You can invoke the following methods of the LDAPCache object
+to get statistics on the cache.
+To get the total amount of available space in bytes that are
+left in the cache, invoke the getAvailableSize method.
+
+To get the array of base DNs of the search requests to be
+cached, invoke the getBaseDNs method.
+To get the total number of items that have been flushed from
+the cache, not including items flushed when invoking the flushEntries method,
+invoke the getNumFlushes method.
+To get the maximum size of the cache in bytes, invoke the
+getSize method.
+To get the maximum amount of time that an item can be cached
+in seconds, get the getTimeToLive method.
+
+
+You can also get a running count of the number of requests that access
+the cache.
+To get the total number of requests for retrieving items from
+the cache, invoke the getTotalOperation method.
+
+To get the total number of requests that retrieved an item
+from the cache, invoke the getNumHits method.
+
+To get the total number of requests that failed to find and
+retrieve an item from the cache, invoke the getNumMisses method.
+
+
+For example, the following section of code gets and prints cache statistics.
+
+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.");
+ }
+}
+
+
+Cloning a Connection With &DirectorySDKForJava;
+
+connection
+cloning
+
+You can create several LDAPConnection objects
+that share a single physical network connection to the LDAP server by invoking
+the LDAPConnection.clone method.
+
+Clones have the following properties:
+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.
+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.
+
+If the clone disconnects or reconnects, the clone is completely
+dissociated from the source object and other clones.
+A cloned LDAPConnection object has
+a separate set of session preferences and constraints. In other words, the
+clone is associated with its own LDAPSearchConstraints object.
+Changes to an option or to a search constraint only affect requests issued
+using that object.For example, suppose an LDAPConnection object
+allows a maximum of 100 results to be returned from a search. If you clone
+an LDAPConnection 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.
+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 LDAPConnection
+ object is no longer a clone of another LDAPConnection object.
+
+
+
+Manipulating Distinguished Names With &DirectorySDKForJava;
+
+distinguished names
+manipulating
+
+A distinguished name (DN) uniquely identifies an entry in the directory
+tree. You can get the DN for an entry as explained in Getting Distinguished
+Names. Alternatively, you can specify a DN to read an entry from the
+directory as explained in
+Reading an Entry With Directory SDK for Java. &DirectorySDKForJava; includes
+a utility class, LDAPDN, that provides
+methods for manipulating DNs.
+If you want to access individual components of a distinguished name
+or a relative distinguished name, invoke the LDAPDN.explodeDN method
+or the LDAPDN.explodeRDN method.
+Both methods return an array of String objects
+that represent the individual components of the distinguished name.
+You can specify whether or not you want the names of the components
+included in the array by using the notypes parameter.
+
+Set notypes to false if
+you want to include component attribute types in the array.
+LDAPDN.explodeDN("uid=bjensen,ou=People,dc=example,dc=com", false);
+
+The method returns the array {"uid=bjensen", "ou=People", "dc=example",
+"dc=com"}.
+Set notypes to true if
+you do not want component attribute types returned in the array.
+LDAPDN.explodeDN("uid=bjensen,ou=People,dc=example,dc=com", true);
+
+The method returns the array {"bjensen", "People", "example",
+"com"}.
+
+
+
diff --git a/mozilla/directory/docs/ldapjdk/jdk-comparing.sgm b/mozilla/directory/docs/ldapjdk/jdk-comparing.sgm
new file mode 100644
index 00000000000..44ba4c4a212
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/jdk-comparing.sgm
@@ -0,0 +1,123 @@
+
+Comparing Attribute Values With &DirectorySDKForJava;
+
+attributes
+comparing values
+
+comparing attribute values
+
+This chapter explains how to compare the value of an attribute in an
+entry against a specified value.
+
+This chapter covers the following topics:
+Specifying the
+Attribute and Value With Directory SDK for Java
+Performing the Comparison
+With Directory SDK for Java
+Example Attribute Value
+Comparison With Directory SDK for Java
+
+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 mail attribute of an entry contains the value
+bjensen@example.com.
+
+To compare a specified value against an attribute of an entry in the
+directory, you need to follow this general procedure.
+Specify the name of the attribute that you want to check and
+the value that you want to use for comparison.
+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.
+
+
+Specifying the Attribute and
+Value With &DirectorySDKForJava;
+Use an LDAPAttribute object to specify the name
+of the attribute to check. Also use the object to specify the value to use
+in the comparison.
+LDAPAttribute attr = new LDAPAttribute("mail", "bjensen@example.com");
+
+
+Performing the Comparison With &DirectorySDKForJava;
+To perform the comparison, use the compare method
+of the LDAPConnection object. Specify the distinguished
+name of the entry that you want to compare. The method returns true if
+the attribute contains the specified value.
+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());
+}
+
+Example Attribute Value Comparison With &DirectorySDKForJava;
+The following example compares values for the objectclass attribute
+with values on Barbara Jensen's entry.
+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.");
+ }
+ }
+}
+
+
diff --git a/mozilla/directory/docs/ldapjdk/jdk-controls.sgm b/mozilla/directory/docs/ldapjdk/jdk-controls.sgm
new file mode 100644
index 00000000000..78d63170d1d
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/jdk-controls.sgm
@@ -0,0 +1,940 @@
+
+LDAP Controls With &DirectorySDKForJava;
+
+This chapter explains how LDAP controls work and how to use the LDAP
+controls.
+
+This chapter covers the following topics:
+How LDAP Controls Work
+With Directory SDK for Java
+Using Controls in the LDAP
+Java Classes
+Determining the Controls Supported the Server With Directory SDK for Java
+Using the Server-Side Sorting
+Control With Directory SDK for Java
+Using the Persistent Search
+Control With Directory SDK for Java
+Using the Entry Change
+Notification Control With Directory SDK for Java
+Using the Virtual List Control With Directory SDK for Java
+Using the Manage DSA
+IT Control With Directory SDK for Java
+Using Password Policy Controls
+With Directory SDK for Java
+Using the Proxied Authorization
+Control With Directory SDK for Java
+
+
+How LDAP Controls Work With &DirectorySDKForJava;
+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.
+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.
+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.
+
+A control specifies the following information:
+A unique object identifier (OID)
+An indication of whether the control is critical to the operation
+
+Optional data related to the control, such as the server-side
+sorting control, where attributes used for sorting search results are needed
+
+
+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 Determining the Controls Supported the Server With Directory SDK for Java for instructions.
+
+When your client includes a control in a request for an LDAP operation,
+the server can respond in one of the following ways:
+If the server supports this control and if the control is
+appropriate, the server should use the control when performing the operation.
+
+
+
+If the server does not support the control type or if the control is
+not appropriate, the server should do one of the following:
+If the control is marked as critical to the operation, the
+server should not perform the operation. Instead, the server should send an
+unavailable critical extension result code. When receiving this
+result code, your client returns an LDAPException with
+the result code LDAPException.UNAVAILABLE_CRITICAL_EXTENSION.
+
+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.
+
+
+
+Servers can also send controls back to clients.
+
+Two types of controls exist:
+Server controls can be included in requests sent by clients
+and in responses sent by servers.
+Client controls affect the behavior of the LDAP Java classes
+only and are never sent to the server.&DirectorySDKForJava; does
+not support client controls.
+
+
+Using Controls in the LDAP Java Classes
+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.
+In the LDAP Java classes, a control is represented by an object of the
+LDAPControl class.
+
+To include a control in a request, do the following:
+Invoke the getSearchConstraints method
+of the LDAPConnection object to get a clone of
+LDAPSearchConstraints for this connection.
+Invoke the setServerControls method of
+the cloned constraints object, passing in the LDAPControl object
+that represents the control to include.
+Invoke the appropriate method to perform the LDAP operation,
+passing in the constraints object.For example, if you are performing
+a search, invoke the search method. Pass the search constraints
+as an argument.
+You can also include controls by invoking the setServerControls method
+for the default set of search constraints. Alternatively, invoke the setOption
+ method to set the LDAPv3.SERVERCONTROLS 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.
+You can then retrieve data from the returned controls through accessor
+methods in the LDAPControl object.
+Determining the Controls Supported the
+Server With &DirectorySDKForJava;
+LDAP v3 states that servers should list any controls that servers support
+in the supportedControl attribute in the root DSE. The
+following OIDs have corresponding constants that are defined in the LDAP Java
+classes.
+
+1.2.840.113556.1.4.473
+netscape.ldap.controls.LDAPSortControl.SORTREQUEST
+For instructions on using this control, refer to Using the Server-Side Sorting Control With Directory SDK for Java.
+
+
+2.16.840.1.113730.3.4.2
+netscape.ldap.LDAPControl.MANAGEDSAIT
+For instructions on using this control, refer to Using the Manage DSA
+IT Control With Directory SDK for Java.
+
+
+2.16.840.1.113730.3.4.3
+netscape.ldap.controls.LDAPPersistSearchControl.PERSISTENTSEARCH
+For instructions on using this control, refer to Using the Persistent Search
+Control With Directory SDK for Java.
+
+
+2.16.840.1.113730.3.4.4
+netscape.ldap.LDAPControl.PWEXPIRED
+For instructions on using this control, refer to Using Password Policy Controls
+With Directory SDK for Java.
+
+
+2.16.840.1.113730.3.4.5
+netscape.ldap.LDAPControl.PWEXPIRING
+For instructions on using this control, refer to Using Password Policy Controls
+With Directory SDK for Java.
+
+
+2.16.840.1.113730.3.4.9
+netscape.ldap.controls.LDAPVirtualListControl.VIRTUALLIST
+For instructions on using this control, refer to Using the Virtual List Control With Directory SDK for Java.
+
+
+2.16.840.1.113730.3.4.12
+netscape.ldap.controls.LDAPProxiedAuthControl.PROXIEDAUTHREQUEST
+For instructions on using this control, refer to Using the Proxied Authorization Control With Directory SDK for Java.
+
+
+
+The following example searches for the root DSE. Then the example prints
+the values of the supportedControl attribute.
+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());
+ }
+ }
+}
+
+Using the Server-Side Sorting Control With &DirectorySDKForJava;
+
+search results
+sorting
+
+sorting search results
+
+The control represented with the OID that corresponds to the constant
+netscape.ldap.LDAPControl.SORTREQUEST is a server-side sorting
+control. The server-side sorting control is defined in RFC 2891.
+When you send a search request with this control to the server, the server
+should sort the results before sending them back to you.
+Specifying the Server-Side Sort Order
+With Directory SDK for Java
+To specify the sort order of the results, construct one or more
+LDAPSortKey objects. Each object represents a sort key that is
+generated from a string in the following format:
+[-]attrName[:matchingRuleOID
+]
+Here, attrName represents the name of the
+attribute to use for sorting. matchingRuleOID represents
+the optional OID of the matching rule to use for sorting. The optional minus
+sign (-) indicates that the results should be sorted in
+reverse order for that attribute.
+For example, the following string specifies that results should be sorted
+by first name (givenname) in descending order:
+-givenname
+Pass this string to the LDAPSortKey constructor
+to create a sort key:
+LDAPSortKey reverseSortByFirstName = new LDAPSortKey("-givenname");
+
+To sort by more than one attribute, construct more than one LDAPSortKey
+ object and create an array of the objects.
+For example, suppose you want to sort the result by last name (sn)
+in ascending order. If two or more entries have the same last name, you want
+to sort the result by first name (givenname) in ascending
+order. To specify this sort order, you construct two LDAPSortKey objects.
+Then create an array:
+LDAPSortKey sortByLastName = new LDAPSortKey("sn");
+LDAPSortKey sortByFirstName = new LDAPSortKey("givenname");
+LDAPSortKey[] sortOrder = { sortByLastName, sortByFirstName };
+
+Creating the Server-Side Sorting Control
+With &DirectorySDKForJava;
+Next, to create the server-side sorting control, construct a new
+LDAPSortControl object. Pass the LDAPSortKey object,
+or the array of LDAPSortKey objects, to the LDAPSortControl
+ constructor.
+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.
+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:
+LDAPSortKey sortOrder = new LDAPSortKey("-givenname");
+LDAPSortControl sortCtrl = new LDAPSortControl(sortOrder, true);
+
+Performing the Server—Side Sort
+With &DirectorySDKForJava;
+
+To specify that you want the server to sort the results, do the following:
+Get a clone of LDAPSearchConstraints for
+the current connection by invoking the getSearchConstraints method
+of the LDAPConnection object.
+Invoke the setServerControls method for
+the copied LDAPSearchConstraints object, and pass in
+the LDAPSortControl object that you have constructed.
+
+Invoke the search method of the LDAPConnection
+ object, passing in the LDAPSearchConstraints object.
+The server returns a result for the search operation and a response
+control. The response control indicates the success or failure of the sorting.
+
+Invoke the getResponseControls method of
+the LDAPSearchResults object to retrieve any controls
+sent back by the server in response to the search.Response controls
+are passed back as an array of LDAPControl objects.
+
+Examine the type of each returned control.
+
+If a control is an instance of LDAPSortControl,
+you can read the result code for the sorting operation with the getResultCode
+ method.
+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 getFailedAttribute method.
+The server can return the following result codes that apply to the sorting
+operation.
+
+LDAPException.ADMIN_LIMIT_EXCEEDED
+Too many entries exist for the server to sort.
+
+
+LDAPException.BUSY
+The server is too busy to sort the results.
+
+
+LDAPException.INAPPROPRIATE_MATCHING
+The sort key list specifies a matching rule that is not recognized
+or appropriate.
+
+
+LDAPException.INSUFFICIENT_ACCESS_RIGHTS
+The server did not send the sorted results because the client
+has insufficient access rights.
+
+
+LDAPException.NO_SUCH_ATTRIBUTE
+The sort key list specifies an attribute that does not exist.
+
+
+LDAPException.OPERATION_ERROR
+An internal server error occurred.
+
+
+LDAPException.OTHER
+This general result code indicates that the server failed
+to sort the results for a reason other than the results listed here.
+
+
+LDAPException.STRONG_AUTH_REQUIRED
+The server refused to send back the sorted search results
+because the server requires that you use a stronger authentication method.
+
+
+LDAPException.SUCCESS
+The results were sorted successfully.
+
+
+LDAPException.TIME_LIMIT_EXCEEDED
+The maximum time allowed for a search was exceeded before
+the server finished sorting the results.
+
+
+LDAPException.UNWILLING_TO_PERFORM
+The server is unable to sort the results.
+
+
+
+
+Interpreting the Server-Side Sort
+Results With &DirectorySDKForJava;
+The following table shows the kinds of results to expect from the LDAP
+server under different conditions.
+
Server
+Responses to Sort Controls
+
+
+
+
+Supports sort control?
+
+Sort control marked critical?
+
+Any other conditions?
+
+Results From LDAP Server
+
+
+
+
+
+Server does not support sort control.
+
+Control is not marked as critical.
+
+Not applicable
+
+The server ignores the sorting control. The server returns the entries
+unsorted.
+
+
+
+Server does not support sort control.
+
+Control is marked as critical.
+
+Not applicable
+
+The server does not send back any entries.
+
+
+
+Server does support sort control.
+
+Control is not marked as critical.
+
+The server cannot sort the results with the specified sort key list.
+
+
+
+The server returns the entries unsorted.
+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.
+
+
+
+
+
+Server does support sort control.
+
+Control is marked as critical.
+
+The server cannot sort the results with the specified sort key list.
+
+
+
+The server does not return any entries.
+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.
+
+
+
+
+
+Server does support sort control.
+
+has no effect on results
+
+The search failed.
+
+
+The server returns a result code for the search operation.
+
+The server does not send back the sorting response control.
+
+
+
+
+
+
+Server does support sort control.
+
+has no effect on results
+
+The server successfully sorted the entries.
+
+
+The server returns the entries in sorted order.
+
+The server sends back the sorting response control, which
+specifies the result code of the sort attempt as LDAPException.SUCCESS
+.
+
+
+
+
+
+
+
+Example of Using Server-Side Sorting
+With &DirectorySDKForJava;
+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.
+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());
+ }
+ }
+}
+
+
+Using the Persistent Search Control With &DirectorySDKForJava;
+
+persistent searches
+
+The control represented with the OID that corresponds to the constant
+netscape.ldap.LDAPControl.PERSISTENTSEARCH is a persistent search
+control. A persistent search, an ongoing search operation,
+allows your LDAP client to get notification of changes to the directory.
+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.
+You can use this control in conjunction with an entry change notification
+control, as described in Using the Entry Change Notification Control
+With Directory SDK for Java.
+Creating the Persistent Search
+Control With Directory SDK for Java
+
+To create a persistent search control, you construct a new LDAPPersistSearchControl
+ object. When invoking the LDAPPersistSearchControl constructor,
+you can specify the following information:
+
+
+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 (|)
+operator:
+ADD indicates that you want to track added
+entries.
+DELETE indicates that you want to track
+deleted entries.
+MODDN indicates that you want to track
+renamed entries.
+MODIFY indicates that you want to track
+modified entries.
+
+
+A preference indicating whether you want the server to return
+all entries that initially matched the search criteria
+A preference indicating whether or not you want entry change
+notification controls included with every modified entry returned by the server
+
+
+This code excerpt shows an example of creating a persistent search control.
+
+/* 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);
+
+Performing the Persistent Search
+With Directory SDK for Java
+
+To specify that you want to start a persistent search, do the following:
+Get a clone of LDAPSearchConstraints for
+the current connection by invoking the getSearchConstraints method
+of the LDAPConnection object.
+Invoke the setServerControls method for
+the cloned LDAPSearchConstraints object, and pass in
+the LDAPPersistSearchControl object that you have constructed.
+
+Invoke the search method of the LDAPConnection object,
+passing in the LDAPSearchConstraints object.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 Using the
+Entry Change Notification Control With Directory SDK for Java.
+
+To end the persistent search, invoke the abandon method
+of the LDAPConnection object. Alternatively, invoke
+the disconnect method to disconnect from the server.
+
+Example of Using the Persistent
+Search Control With Directory SDK for Java
+The following example performs a persistent search. The example receives
+entry change notification controls from the server.
+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());
+ }
+ }
+}
+
+
+Using the Entry Change Notification
+Control With &DirectorySDKForJava;
+The control represented with the OID that corresponds to the constant
+netscape.ldap.LDAPEntryChangeControl.ENTRYCHANGED is an entry
+change notification control. These types of controls can be included
+with entries sent back from the server during a persistent search.
+Getting the Entry Change Notification
+Control With Directory SDK for Java
+
+To get an entry change notification control that is included with an
+entry, do the following:
+As you retrieve each entry, invoke the getResponseControls
+ method of the LDAPConnection object to retrieve
+any response controls sent back from the server.Response controls
+are passed back as an array of LDAPControl objects.
+
+Pass this array of LDAPControl objects
+as an argument to the LDAPPersistSearchControl.parseResponse static
+method to retrieve the entry change notification control.
+
+An entry change notification control is represented by an object of
+the LDAPEntryChangeControl class. To get data from
+this control, you can invoke the accessor methods, such as getChangeNumber
+, getChangeType, and getPreviousDN.
+
+Working With Change Log Numbers
+With Directory SDK for Java
+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.
+You can get the change number for a modified entry from the LDAPEntryChangeControl
+ object.
+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.
+To determine the DN for the change log entry, search the root DSE to
+retrieve the changelog attribute. For example, the value
+of this attribute might be cn=changelog, which is the DN
+for the change log entry.
+Each change log record is an entry under the change log entry. The change
+log number is the value of the changenumber attribute of
+the record. To get a specific change log record, search with base DN cn=changelog
+ and filter changenumber=value.
+Here, value is the change number of the record.
+
+
+Using the Virtual List Control With &DirectorySDKForJava;
+The control represented with the OID that corresponds to the constant
+netscape.ldap.controls.LDAPVirtualListControl.VIRTUALLIST is a
+virtual list 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.
+After you set the list size with the setListSize method
+of the LDAPVirtualListControl object, invoke the
+setRange method. The method recreates the control with the new data.
+setRange generates the BER-encoded request to be sent to the server.
+setListSize does not generate the request.
+Using the Manage DSA IT Control With &DirectorySDKForJava;
+The control represented with the OID that corresponds to the constant
+netscape.ldap.controls.LDAPControl.MANAGEDSAIT is a manage
+DSA IT control. The control is for managing search references
+in the directory and is defined in RFC
+3296.
+To create this control, construct a new LDAPControl object.
+In the LDAPControl constructor, set the OID of the control
+to netscape.ldap.controls.LDAPControl.MANAGEDSAIT.
+Add this control to the array of LDAPControl objects.
+When you pass the array to a method that performs an LDAP operation, the server
+treats search references as ordinary entries.
+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.
+Using Password Policy Controls With &DirectorySDKForJava;
+
+&cnDirectoryServer; uses two server response controls to send information
+back to a client after an LDAP bind operation.
+The control represented with the OID that corresponds to the
+constant netscape.ldap.controls.LDAPControl.PWEXPIRED is
+the expired password control.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.
+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 LDAP_UNWILLING_TO_PERFORM result code with
+an expired password control.
+The control represented with the OID that corresponds to the
+constant netscape.ldap.controls.LDAPControl.PWEXPIRING is
+the password expiring warning control.This
+control is used if the server is configured to expire user passwords after
+a certain amount of time.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 getValue method for this LDAPControl
+ object, the method returns the number of seconds before the password
+expires.
+
+To get these server response controls when binding, invoke the getResponseControls
+ method of the LDAPConnection object after
+you attempt to authenticate to the server.
+Using the Proxied Authorization Control
+With &DirectorySDKForJava;
+The control represented with the OID that corresponds to the constant
+netscape.ldap.controls.LDAPProxiedAuthControl.PROXIEDAUTHREQUEST is
+a proxied authorization control. It allows LDAP clients
+to use different credentials, without rebinding, when executing LDAP operations.
+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.
+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.
+
+
diff --git a/mozilla/directory/docs/ldapjdk/jdk-extended-ops.sgm b/mozilla/directory/docs/ldapjdk/jdk-extended-ops.sgm
new file mode 100644
index 00000000000..926f7c9fc41
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/jdk-extended-ops.sgm
@@ -0,0 +1,156 @@
+
+Extended Operations With &DirectorySDKForJava;
+
+This chapter explains LDAP v3 extended operations. This chapter also
+explains how to use the extended operations that are supported by your LDAP
+server.
+
+This chapter covers the following topics:
+How Extended Operations
+Work With Directory SDK for Java
+Implementing Support
+for Extended Operations on the Server With Directory SDK for Java
+
+Determining the
+Extended Operations Supported With Directory SDK for Java
+
+Performing an Extended
+Operation With Directory SDK for Java
+Example Extended Operation
+With Directory SDK for Java
+
+
+How Extended Operations Work With &DirectorySDKForJava;
+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. Within the request, the client specifies the following:
+The OID of the extended operation to perform
+Data specific to the extended operation
+
+
+The server receives the request. The server then performs the extended
+operation. The server can send back to the client a response containing:
+An OID
+Any additional data
+
+
+To use extended operations, both the server and the client must know
+the specific extended operation to be performed.
+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.
+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.
+
+
+Implementing Support for Extended Operations
+on the Server With Directory SDK for Java
+
+LDAP servers
+extended operations and
+
+&cnDirectoryServer; supports a plug-in API that allows you to write
+your own server plug-in to handle extended operations.
+
+You can write an extended operation that does the following:
+Registers the OID of an extended operation as supported, so
+the OID appears as a value of the supportedExtension attribute
+on the root DSE
+Gets information from an extended operation request
+
+Creates and sends an extended operation response back to the
+client
+
+
+Determining the Extended Operations
+Supported With &DirectorySDKForJava;
+To determine the extended operations supported by the server, get the
+root DSE of the server, and check the supportedExtension 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 supportedExtension attribute,
+the server does not support any extended operations. For instructions on reading
+the root DSE, refer to Getting the Root DSE With Directory SDK for
+Java.
+Performing an Extended Operation With &DirectorySDKForJava;
+
+LDAP clients
+extended operations and
+
+
+To request an extended operation, do the following:
+Construct a new LDAPExtendedOperation object,
+specifying the OID of the extended operation and the data that you want applied
+to the operation.
+Invoke the extendedOperation method of
+the LDAPConnection object, passing the method of the
+newly constructed LDAPExtendedOperation object.
+
+
+The LDAPExtendedOperation object that is returned
+represents the server response. You can invoke the getID and
+getValue methods of this object to get the OID and the data from
+the server's response.
+Example Extended Operation With &DirectorySDKForJava;
+The following example shows an LDAP client that requests an extended
+operation with the OID 1.2.3.4 from the server.
+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");
+ }
+ }
+}
+
+
diff --git a/mozilla/directory/docs/ldapjdk/jdk-filter-conf.sgm b/mozilla/directory/docs/ldapjdk/jdk-filter-conf.sgm
new file mode 100644
index 00000000000..71c116aa395
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/jdk-filter-conf.sgm
@@ -0,0 +1,545 @@
+
+Using Filter Configuration Files
+
+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:
+
+Understanding Filter
+Configuration Files
+Understanding
+the Configuration File Syntax
+Understanding Filter
+Parameters
+Loading Filter Configuration
+Files
+Retrieving Filters
+
+Adding Filter Prefixes and
+Suffixes
+
+
+Understanding Filter Configuration Files
+
+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:
+bjensen@example.com
+You might want to use this search filter:
+(mail=bjensen@example.com)
+Similarly, suppose the search term entered by the user contains numbers, like
+this:
+555-1212
+In this case, you might want to use this search filter:
+(telephoneNumber=555-1212)
+Rather than write code to construct the search filter explicitly, you can generate
+filters using a filter configuration file. A filter configuration
+file specifies a list of filters that you can load and use in your searches.
+
+Understanding the Configuration
+File Syntax
+filter configuration filessyntax
+
+A filter configuration file has the following format:
+tag
+ pattern1delimiters
+filter1-1desc1-1 [scope1
+]
+ filter1-2
+desc1-2 [scope2]
+
+ pattern2delimiters
+filter2-1desc2-1 [scope3
+]
+ …
+Each element in the file is a string, surrounded by quotes (").
+Comments consist of lines starting with #.
+The format supports these elements:
+
+tag
+Identifies a group of filters.
+You can use different tags to distinguish filters for different types of objects.
+For example, you can use a "person" tag to identify filters for
+person entries, a "organization" tag to represent filters for organization
+entries, and so forth.
+You can specify multiple tags for the same group of filters in the configuration
+file using the keyword and, such as "people and organization"
+.
+You can specify a tag, or part of a tag, as a parameter. The tag narrows the
+list of filters that the function retrieves.
+
+
+pattern
+Specifies a regular expression used to determine which filter is selected
+based on the search criteria.
+For example, if you specify ^[0-9] as the pattern for a filter,
+the filter is selected for all search criteria beginning with a number.
+
+
+delimiters
+Specify what characters separate one field from another within search
+criteria.
+For example, if the search criteria consists of a city name and state abbreviation
+separated by a comma, specify "," as the delimiter.
+
+
+filter
+Specifies an LDAP filter including %v to represent
+the search criteria.
+For example, to search email addresses, use the filter (mail=%v).
+During runtime, if the search criteria bjensen@example.com is entered,
+the filter becomes (mail=bjensen@example.com).
+If the search criteria consists of a number of delimited fields such as a
+surname,first name format
+like Jensen, Barbara, use %v1, %v2
+, …, %vn to represent the fields within the search
+criteria. For example:
+"people"
+ "^[A-Z]*," "," "(&(sn=%v1)(givenName=%v2))"
+In the example, the delimiter is a comma. The word before the delimiter replaces
+%v1 in the filter, and the word after the delimiter replaces%v1
+. A search for:
+Jensen, Barbararesults in
+a filter:
+(&(sn=Jensen)(givenName=Barbara))
+You can also specify ranges of fields. For example, to specify the values in
+the first three fields, use %v1-3. To specify values from the third
+field to the last field, use %v3-. To specify the value in the
+last field, use %v$.
+
+
+desc
+Specify short text descriptions of the filters.
+
+
+scope
+Specify the scope of each search.
+This field is optional. It can take the values "base",
+"onelevel", or "subtree".
+
+
+
+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 (@).
+
+"people"
+ "^[0-9][0-9-]*$" " " "(telephoneNumber=*%v)" "phone number ends with"
+ "@" " " "(mail=%v)" "email address is"
+ "(mail=%v*)" "email address starts with"
+
+Specify the filters in the order that you want them to be used. For example,
+if you want to apply the (mail=%v) filter before the
+(mail=%v*) filter, make sure that the filters appear in that order.
+
+Understanding Filter Parameters
+
+Configuration file filter specifications support the following parameters:
+
+%v
+Insert the search criterion verbatim in place of %v.
+
+For example, if the filter specification is (mail=%v), entering
+bjensen results in the filter (mail=bjensen).
+
+
+%v$
+Insert the last word of search criterion verbatim in place of
+%v.
+For example, if the filter specification is (sn=%v$), entering
+Barbara Jensen results in the filter (sn=Jensen).
+
+
+%vN
+Insert the Nth word of the criteria in
+place of %v, where N is a single digit
+between 1 and 9.
+For example, if the filter specification is (sn=%v2), entering
+Barbara Jensen results in the filter (sn=Jensen).
+
+
+%vM-
+N
+Insert the sequence of the Mth through
+Nth words of the criteria in place of %v, where
+M and N are single digits between 1 and 9.
+
+For example, if the filter specification is (cn=%v1-2), entering
+Barbara Jensen results in the filter (cn=Barbara Jensen).
+
+
+
+%vN-
+Insert the sequence of th eNth through
+last words of the criteria in place of %v, where
+N is a single digit between 1 and 9.
+For example, if the filter specification is (cn=%v2-), entering
+Ms. Barbara Jensen results in the filter (cn=Barbara Jensen).
+
+
+
+
+
+Loading Filter Configuration Files
+filter configuration filesloading
+
+loading filter configuration files
+To use a filter configuration file, you need to create an LDAPFilterDescriptor
+ object. The LDAPFilterDescriptor constructor allows
+you to read in the filter configuration file from one of the following:
+
+A file in the local file system to which you specify the path
+
+A file served by a web server to which you specify the URL
+
+A location in memory where you specify a StringBuffer object
+containing the configuration information
+
+The following section of code reads in a filter configuration file named
+ldapfilter.conf in the current directory.
+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() );
+}
+
+Retrieving Filters
+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 bjensen@example.com, you can have your client automatically
+search for this value in the mail attribute.
+Retrieving Filters Using A Filter Configuration
+File
+
+Invoke the LDAPFilterDescriptor constructor to read
+in the filter configuration file.
+Invoke the getFilters method of the LDAPFilterDescriptor
+ object.Specify the tag of the section that you want to use
+in the filter configuration file.You do not need to invoke the
+setupFilter of the LDAPFilter object to generate
+the filter. The getFilters method of the LDAPFilterDescriptor
+ object does this already. You just need to invoke the getFilter
+ method of the LDAPFilter object to get the generated
+filter.This method returns an LDAPFilterList object,
+which is an enumeration of LDAPFilter objects containing the
+filters for the specified search term.
+Invoke the next method of the LDAPFilterList
+ object to iterate through the LDAPFilter objects.
+
+For each LDAPFilter object, get the filter by invoking
+the getFilter method, passing no arguments.To get
+the total number of filter configuration lines that match the specified search term,
+invoke the numFilters method of the LDAPFilterList object.
+This number decrements each time you invoke the next or nextElement method.
+
+
+
+Retrieving Telephone Number and Mail Filters
+This example uses a filter configuration file, ldapfilter.conf,
+with the following specifications:
+"people"
+ "^[0-9][0-9-]*$" " " "(telephoneNumber=*%v)" "phone number ends with"
+ "@" " " "(mail=%v)" "email address is"
+ "(mail=%v*)" "email address starts with"
+The following code retrieves, generates, and prints filters matching the criteria:
+
+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());
+}
+When built into a program, compiled, and run, this code produces the following
+output:
+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*)
+
+
+
+Adding Filter Prefixes and Suffixes
+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:
+(&(l=Sunnyvale)
+The filter prefix now requires the following suffix to balance the number of
+parentheses:
+)
+For example, given the following filter:
+(sn=Jensen)
+You can use the filter prefix (&(l=Sunnyvale and the
+filter suffix ) to narrow down the search to only the entries matching
+l=Sunnyvale:
+(&(l=Sunnyvale)(sn=Jensen))
+You can set up the filter prefix and suffix in several ways:
+
+To set these for all filters generated from the filter configuration
+file, invoke the setFilterAffixes method of the LDAPFilterDescriptor
+ object.
+To set the prefix or suffix for a specific filter, do one of the following:
+
+
+Invoke the setFilterAffixes method of the
+LDAPFilter object, then invoke the getFilter method,
+passing in the search term again. This builds the filter again, using the specified
+search term with the prefix and suffix.
+Invoke the getFilter method, passing in the search
+term, the prefix, and the suffix.
+Invoke the setupFilter method, passing the search
+term, the prefix, and the suffix.
+
+Setting the prefix and suffix for an individual filter overrides any prefix
+or suffix set for the entire filter configuration file.
+
+Adding Affixes for All Filters
+The following code loads a filter configuration file ldapfilter.conf
+ into memory, and adds the prefix (&(l=Sunnyvale and
+suffix ) to each filter retrieved from the file:
+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 = ")";
+ filtdesc.setFilterAffixes(prefix, suffix);
+
+ /* 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());
+}
+For example, if the following search term is passed to the LDAPFilterDescriptor.getFilters
+ method:
+bjensen@example.com
+and the corresponding filter, not including the prefix or suffix, is:
+(mail=bjensen@example.com)
+the entire filter string retrieved by the LDAPFilter.getFilter method
+is:
+(&(l=Sunnyvale)(mail=bjensen@example.com))
+
+Adding Affixes Using setFilterAffixes
+
+The following code loads a filter configuration file ldapfilter.conf
+ into memory, and uses the LDAPFilter.setFilterAffixes method
+to add the prefix (&(l=Sunnyvale and suffix ) to
+a generated filter:
+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 = ")";
+ filtline.setFilterAffixes(prefix, suffix);
+ String filterString = filtline.getFilter(searchTerm);
+ System.out.println(" Generated filter string: " +
+ filterString + "\n");
+ }
+} catch ( Exception e ) {
+ System.out.println( "Error: " + e.toString() );
+}
+For example, if the following search term is passed to the LDAPFilterDescriptor.getFilters
+ method:
+bjensen@example.com
+and the corresponding filter, not including the prefix or suffix, is:
+(mail=bjensen@example.com)
+the entire filter string retrieved by the LDAPFilter.getFilter method
+is:
+(&(l=Sunnyvale)(mail=bjensen@example.com))
+
+Adding Affixes Using getFilter
+The following code loads a filter configuration file ldapfilter.conf
+ into memory, and uses the LDAPFilter.getFilter method
+to add the prefix (&(l=Sunnyvale and suffix ) to
+a generated filter:
+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 = ")";
+ String filterString =
+ filtline.getFilter(searchTerm, prefix, suffix);
+ System.out.println(" Generated filter string: " +
+ filterString + "\n");
+ }
+} catch ( Exception e ) {
+ System.out.println( "Error: " + e.toString() );
+}
+For example, if the following search term is passed to the LDAPFilterDescriptor.getFilters
+ method:
+bjensen@example.com
+and the corresponding filter, not including the prefix or suffix, is:
+(mail=bjensen@example.com)
+the entire filter string retrieved by the LDAPFilter.getFilter method
+is:
+(&(l=Sunnyvale)(mail=bjensen@example.com))
+
+Adding Affixes Using setupFilter
+The following code loads a filter configuration file ldapfilter.conf
+ into memory, and uses the LDAPFilter.setupFilter method
+to add the prefix (&(l=Sunnyvale and suffix ) to
+a generated filter:
+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 = ")";
+ filtline.setupFilter(searchTerm, prefix, suffix);
+ String filterString = filtline.getFilter();
+ System.out.println(" Generated filter string: "
+ + filterString + "\n");
+ }
+} catch ( Exception e ) {
+ System.out.println( "Error: " + e.toString() );
+}
+For example, if the following search term is passed to the LDAPFilterDescriptor.getFilters
+ method:
+bjensen@example.com
+and the corresponding filter, not including the prefix or suffix, is:
+(mail=bjensen@example.com)
+the entire filter string retrieved by the LDAPFilter.getFilter method
+is:
+(&(l=Sunnyvale)(mail=bjensen@example.com))
+
+
+
diff --git a/mozilla/directory/docs/ldapjdk/jdk-ldap-urls.sgm b/mozilla/directory/docs/ldapjdk/jdk-ldap-urls.sgm
new file mode 100644
index 00000000000..c2d2678ab4b
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/jdk-ldap-urls.sgm
@@ -0,0 +1,202 @@
+
+LDAP URLs With &DirectorySDKForJava;
+
+This chapter describes how to use LDAP URLs to search and retrieve data
+from the directory.
+
+This chapter covers the following topics:
+Getting the Components of
+an LDAP URL With Directory SDK for Java
+Processing an LDAP URL With
+Directory SDK for Java
+Searching Using an LDAP
+URL With Directory SDK for Java
+
+
+Getting the Components of an LDAP URL With &DirectorySDKForJava;
+
+To get the individual components of an LDAP URL, pass the URL to the
+LDAPUrl constructor to create a new LDAPUrl object.
+Then, use the following methods:
+To get an array of the attributes that should be returned
+in the search results, use the getAttributeArray method.
+To get these attributes as an enumeration, use the getAttributes method.
+
+To get the host name of the LDAP server, use the getHost
+ method.
+To get the port number of the LDAP server, use the getPort
+ method.
+To get the base DN, use the getDN method.
+
+To get the scope of the search, use the getScope method.
+
+To get the search filter, use the getFilter method.
+
+
+
+Processing an LDAP URL With &DirectorySDKForJava;
+
+To process the search request specified by an LDAP URL, you can invoke
+one of the following methods, passing in the LDAPUrl object:
+
+If the URL specifies a base search for a single entry, invoke
+the read method of the LDAPConnection object.
+This method reads the entry from the directory.
+Otherwise, invoke the search method of
+the LDAPConnection object to perform the search.
+
+
+Both methods create a new LDAPConnection object
+and connect to the LDAP server specified in the URL. Next, the methods perform
+the search. Then the methods disconnect.
+Searching Using an LDAP URL With &DirectorySDKForJava;
+The following example demonstrates a search that uses an LDAP URL, invoking
+the search method of the LDAPConnection object
+to perform the search. Before the search is performed, the LDAP URL is exploded
+using the methods suggested previously in this chapter.
+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);
+ }
+}
+When this program is compiled and run against a directory that holds
+Barbara Jensen's entry, the program generates the following output.
+$ java SrchUrl -h myhost -p 1389
+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
+
+
diff --git a/mozilla/directory/docs/ldapjdk/jdk-quickstart.sgm b/mozilla/directory/docs/ldapjdk/jdk-quickstart.sgm
new file mode 100644
index 00000000000..58754638f9c
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/jdk-quickstart.sgm
@@ -0,0 +1,212 @@
+
+Getting Started With &DirectorySDKForJava;
+
+This chapter shows how to develop a first LDAP client with the &DirectorySDKForJava;.
+
+
+This chapter covers the following topics:
+Understanding
+the LDAP Java Classes
+Understanding the
+Sample Java Client
+Sample Java Code
+
+
+
+Understanding the LDAP Java
+Classes
+
+packages
+summary of
+
+&DirectorySDKForJava;
+packages
+
+&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.
+The classes are organized in the following packages.
+
+com.netscape.sasl
+Contains the interfaces and classes that you can use to enable
+your client to authenticate by using a SASL mechanism.
+
+
+com.netscape.sasl.mechanisms
+Contains an implementation of the EXTERNAL SASL
+mechanism driver.
+
+
+netscape.ldap
+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.
+
+
+
+netscape.ldap.ber.stream
+Contains the LDAP Java classes that implement the Basic
+Encoding Rules (BER) for transfer syntax. For more information
+about BER, see ISO-IEC 8825 at http://www.iso.ch/
+.
+
+
+netscape.ldap.controls
+Contains the LDAP Java classes that implement specific LDAP
+v3 controls. The implementations include controls to request server-side sorting
+and persistent searches.
+
+
+netscape.ldap.factory
+Contains classes that allow you to create an SSL socket connection
+to a server.
+
+
+netscape.ldap.util
+Contains utility classes, such as classes to parse LDIF data
+and filters that allow regular expression matching.
+
+
+
+Clients typically execute methods in &DirectorySDKForJava; synchronously.
+All LDAP operations block until the operations are completed, except for the
+search method, which can return information before all the results
+have been received.
+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 Chapter 13, Writing Asynchronous Clients With Directory SDK for Java.
+Understanding the Sample Java Client
+The sample client in this chapter retrieves the full name (cn),
+last name (sn), email address (mail),
+and telephone number (telephoneNumber) of Barbara Jensen.
+You can find the program in the GetAttrs.java file in
+the examples/java directory.
+
+The client does the following:
+Creates a new LDAPConnection object,
+which represents the connection to the LDAP server
+Connects to the server
+Searches for a single entry, identified by the DN using the
+following search criteria:
+
+The base DN, the starting point for the search, is uid=bjensen,ou=People,dc=example,dc=com
+.
+The search scope is LDAPConnection.SCOPE_BASE,
+meaning only the base DN.
+The search filter is "objectclass=*", meaning
+the filter matches any entry.As the scope narrows the search
+to a single entry, the search filter does not need to be more specific.
+
+
+To invoke a search on a single entry with these parameters is equivalent
+to using the LDAPConnection.read method.
+
+Iterates through the enumerated search results to retrieve
+and print the values of the cn, sn,
+mail, and telephoneNumber attributesThis
+iteration also allows the client to obtain multiple values for a single attribute.
+
+Disconnects from the server
+Before you compile the sample client, make sure that the packages/ldapjdk.jar
+ file is in your CLASSPATH.
+Sample Java Code
+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());
+ }
+ }
+}
+
+
diff --git a/mozilla/directory/docs/ldapjdk/jdk-sasl.sgm b/mozilla/directory/docs/ldapjdk/jdk-sasl.sgm
new file mode 100644
index 00000000000..09d86bf31e5
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/jdk-sasl.sgm
@@ -0,0 +1,338 @@
+
+SASL Authentication With &DirectorySDKForJava;
+
+This chapter describes the process of using a SASL mechanism to authenticate
+an LDAP client to an LDAP server.
+
+This chapter covers the following topics:
+Understanding SASL and Directory
+SDK for Java
+Preparing to Use SASL Authentication
+With Directory SDK for Java
+Using SASL in the Client With
+Directory SDK for Java
+Further Reading About SASL
+
+
+
+Understanding SASL and &DirectorySDKForJava;
+
+SASL
+defined
+
+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.
+All SASL mechanisms are registered with the Internet Assigned Numbers
+Authority (IANA). Included among these mechanisms are KERBEROS_V4,
+GSSAPI, 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.
+When a client attempts to authenticate to an LDAP server with the
+LDAPConnection.authenticate 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.
+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.
+If the server does not support any of the requested mechanisms, the
+SDK returns an AuthenticationNotSupportedException.
+If the mechanism driver requires additional authentication data from
+the client, the driver sends a Callback object to the
+client. To prepare for the callback, the client implements a CallbackHandler
+ 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 CallbackHandler object
+with Callback objects for each item to be processed.
+The CallbackHandler then determines how to proceed.
+&DirectorySDKForJava; includes a package, com.netscape.sasl,
+that contains the code necessary to perform all of the steps involved in SASL
+authentication.
+Preparing to Use SASL Authentication With &DirectorySDKForJava;
+
+Before performing SASL authentication, you must do the following:
+Ensure that your LDAP server supports at least one SASL mechanism
+
+Ensure that your client environment supports at least one
+SASL mechanism supported by the server
+
+SASL Support on the Server
+
+SASL
+server-side requirements
+
+&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.
+
+If you write your own plug-in, your plug-in uses a registered SASL mechanism
+to do the following:
+Get information from a SASL bind request.
+Create and send a SASL bind response back to the client.
+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.
+
+
+SASL Support on the Client
+
+SASL
+client-side requirements
+
+To authenticate over SASL, you must have a mechanism in your SASL client
+package. If you have obtained a ClientFactory class
+that can produce a SASL mechanism that your server supports, you can name
+its package in your code.
+
+This option can be performed in one of two ways:
+Request a SASL client. Specify the package in the javax.security.sasl.client.pkgs
+ property of its Hashtable.
+Set the package as the default factory for the session with
+the Sasl.setSaslClientFactory method.
+
+For example, you might have a class, mysecurity.sasl.ClientFactory
+, capable of producing a SaslClient object
+for one or more mechanisms. You could then write either of the two following
+bits of code:
+Hashtable props = new Hashtable();
+props.put("javax.security.sasl.client.pkgs", "mysecurity.sasl");
+ld.authenticate(dn, props, cbh);
+Sasl.setSaslClientFactory (new mysecurity.sasl.ClientFactory());
+ld.authenticate(dn, props, cbh);
+The parameters used have the following descriptions:
+
+dn
+Authentication DN
+
+
+props
+Optional properties that the mechanism accepts
+Refer to Using
+the External Mechanism for details.
+
+
+cbh
+Instance of CallbackHandler that is
+implemented in your application
+
+
+
+
+Implementing javax.security.auth.callback
+
+
+authentication
+implementing SASL callbacks
+
+callbacks
+implementing for SASL
+
+SASL
+implementing callbacks
+
+Some SASL mechanisms require additional credentials during the authentication
+process. To provide this additional information, your SASL client might need
+to implement Callback objects and a CallbackHandler
+ to list credentials. Callback and
+CallbackHandler are part of the javax.security.auth.callback
+ package.
+The following example shows Callback and
+CallbackHandler implementations.
+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;
+}
+
+
+Using SASL in the Client With &DirectorySDKForJava;
+
+You are ready to authenticate when you have done the following:
+Determined that at least one SASL mechanism exists in common
+between the server and your client environment
+Implemented javax.security.auth.callback.CallbackHandler
+ if you might need to supply additional credentials during authentication
+
+
+The following example shows how to use SASL in an application:
+Hashtable props = new Hashtable();
+props.put("javax.security.sasl.client.pkgs", "mysecurity.sasl");
+ld.authenticate(dn, props, new SampleCallbackHandler());
+Using the External Mechanism
+
+
+SASL
+using the EXTERNAL mechanism with
+
+SSL
+using SASL with
+
+&DirectorySDKForJava; includes a mechanism called EXTERNAL.
+This mechanism verifies that SSL authentication has already completed before
+the mechanism allows a client to connect over LDAP.
+
+To use the EXTERNAL mechanism, do the following:
+Bind to the server, and authenticate using SSL.Refer
+to Connecting to a
+Server Over SSL With Directory SDK for Java for details.
+
+Call the LDAPConnection.authenticate method
+as follows:
+ld = new LDAPConnection();
+ld.authenticate(
+ null, new String[]{"EXTERNAL"}, null, (CallbackHandler)null);
+LDAPConnection.authenticate takes the following parameters.
+
+
+dn
+Authentication DN
+
+
+mechanisms
+List of SASL mechanisms to use for authentication
+If null is specified, &DirectorySDKForJava; queries
+the server for all available mechanisms.
+
+
+props
+Optional properties that the mechanism accepts, which include
+the following:
+
+javax.security.sasl.encryption.minimum
+The minimum key length to be used during the session.
+The default value is 0, no session protection. A
+value of 1 enables integrity protection only.
+
+
+javax.security.sasl.encryption.maximum
+The maximum key length to be used during the session.
+The default value is 256.
+
+
+javax.security.sasl.server.authentication
+A boolean value.
+true if a server must authenticate to the client.
+The default value is false.
+
+
+javax.security.sasl.ip.local
+The client's IP address in dotted decimal format.
+This value is required for KERBEROS_V4 authentication.
+No default value exists.
+
+
+javax.security.sasl.ip.remote
+The server's IP address in dotted decimal format.
+This value is required for KERBEROS_V4 authentication.
+No default value exists.
+
+
+javax.security.sasl.maxbuffer
+The maximum size of the security layer frames.
+The default is 0, meaning that the client does not
+use the security layer.
+
+
+javax.security.sasl.client.pkgs
+A bar-separated list of package names to use when locating
+a SaslClientFactory.
+
+
+
+
+
+cbh
+Instance of CallbackHandler that is
+implemented in your application.
+
+
+
+
+
+
+Other SASL Mechanisms
+Authentication with a SASL mechanism other than EXTERNAL requires
+you to implement classes for the mechanism in the client and on the server.
+
+
+Further Reading About SASL
+SASL is described in RFC 4422.
+For a current list of registered SASL mechanisms, see http://www.iana.org/assignments/sasl-mechanisms
+.
+
diff --git a/mozilla/directory/docs/ldapjdk/jdk-searching.sgm b/mozilla/directory/docs/ldapjdk/jdk-searching.sgm
new file mode 100644
index 00000000000..221ebc3e6c4
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/jdk-searching.sgm
@@ -0,0 +1,970 @@
+
+Searching the Directory With &DirectorySDKForJava;
+
+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.
+
+This chapter covers the following topics:
+Searching With the LDAP
+Java Classes
+Sending a Search Request
+With Directory SDK for Java
+Getting the Search Results
+With Directory SDK for Java
+Sorting the Search Results
+With Directory SDK for Java
+Abandoning a Search
+With Directory SDK for Java
+Searching the Directory
+With Directory SDK for Java
+Reading an Entry With Directory
+SDK for Java
+Listing Child Entries
+With Directory SDK for Java
+
+
+Searching With the LDAP Java Classes
+
+In &DirectorySDKForJava;, searches are represented by objects of
+the following classes:
+You can send a search request by invoking the search method
+of the LDAPConnection object.
+You can specify a set of search constraints by using an
+LDAPSearchConstraints 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.
+You can specify different parts of the search criteria in
+separate arguments. Alternatively, you can construct an LDAPUrl object
+to specify the search criteria.
+You can search for a single entry by invoking the read method
+of the LDAPConnection object.
+The server returns the search results to the LDAP Java classes,
+which represents the results as an LDAPSearchResults object.
+
+
+
+Sending a Search Request With &DirectorySDKForJava;
+To search the directory, use the search method of
+the LDAPConnection object. The search results are returned
+in the form of an LDAPSearchResults object.
+public LDAPSearchResults search(String base, int scope,
+ String filter, String attrs[], boolean attrsOnly,
+ LDAPSearchConstraints cons) throws LDAPException
+You need to specify the following parameters as arguments to the search
+ method.
+
+base
+Specifies the base DN, which is the entry on and under which
+the search is carried out.
+For example, when searching entries with DNs such as uid=bjensen,ou=People,dc=example,dc=com
+, the base could be ou=People,dc=example,dc=com
+ or dc=example,dc=com.
+
+
+scope
+Specifies the scope of the search.
+You can adjust the scope of the search to examine only the entry identified
+by the base, only those entries one level down the
+tree from the base, or the entire subtree underneath
+the base.
+
+
+filter
+Specifies what to search for.
+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.”
+
+
+attrsattrsOnly
+
+Specify the entry attributes to retrieve.
+For example, you can use attrs 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 attrsOnly to
+true.
+
+
+cons
+Specifies constraints to apply to the search when you do not
+want to use the default constraints.
+
+
+
+The following figure illustrates how search criteria work.
+Criteria for an LDAP Search
+
+
+How search criteria work
+
+
+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 LDAPUrl object. See Chapter 7, LDAP URLs With Directory SDK for Java for
+details.
+Specifying the Base DN and Scope
+
+base DN
+explained
+
+scope
+explained
+
+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.
+The base DN is the DN of the entry that serves as the starting point
+of the search.
+
+To specify the scope of the search, you pass one of the following values
+as the scope parameter:
+LDAPv3.SCOPE_SUB — Search the base
+entry and all entries at all levels under the base entry.
+
+
+Subtree scope applies to everything below the base DN.
+
+
+
+LDAPv3.SCOPE_ONE — Search all entries
+at one level under the base entry.
+
+
+One level scope applies to all entries just below the
+base DN.
+
+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.
+LDAPv3.SCOPE_BASE — Search only
+the base entry.
+
+
+Base scope applies only to the base DN entry.
+
+
+Use this setting if you want to read the attributes of only the base
+entry.
+
+
+Specifying a Search Filter
+
+filters
+
+search filters
+specifying
+
+When you search the directory, you use a search filter to define the
+search. Here is the basic syntax for a search filter:
+(attributeoperator
+value)
+Here is a simple example of a search filter:
+(cn=Barbara Jensen)
+In this example, cn is the attribute. = is
+the operator. Barbara Jensen is the value. The filter finds
+entries with the common name Barbara Jensen.
+Valid attributes that you can use in your search filter are provided
+in the documentation for the LDAP server.
+Following are descriptions of valid operators for search filters, and
+example filters that use the operators.
+
+=
+Return entries whose attributes are equal to the value provided.
+For example, the following filter matches Barbara Jensen's entry:
+(cn=Barbara Jensen)
+
+
+>=
+Return entries whose attributes are greater than or equal
+to the value provided.
+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 sn=Seuss and sn=Zhivago:
+(sn>=jensen)
+
+
+<=
+Return entries whose attributes are less than or equal to
+the value provided.
+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 sn=Anderson and sn=Cubbins:
+
+(sn<=jensen)
+
+
+=*
+Return entries that have a value set for the attribute (presence).
+
+For example, the following filter matches all entries that have a value
+for the surname:
+(sn=*)
+
+
+~=
+Return entries whose attribute value approximately matches
+the specified value, such as the value sounds like the specified value.
+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:
+(sn~=jensen)
+
+
+
+With Boolean operators and with parentheses, you can combine different
+sets of conditions. Here is the syntax for combining search filters:
+(boolean(filter1)(
+filter2)(…))
+Following are descriptions of the valid boolean operators.
+
+&
+Return entries that match all specified filters.
+
+
+|
+Return entries that match one or more of the specified filters.
+
+
+!
+Return entries that do not match the specified filter.
+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 filter1 nor filter2,”
+use the syntax:
+(!(|(filter1)(filter2)))
+
+
+
+
+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 F:
+(givenName=F*)
+
+Specifying the Attributes to Retrieve
+
+attributes
+operational
+
+attributes
+retrieving in a search
+
+operational attributes
+
+
+With the attrs 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:
+To return selected attributes, pass an array of the attribute
+names as the attrs parameter. For example, to return
+only email addresses and phone numbers, pass the array {"mail", "telephoneNumber"}
+ as the attrs parameter.
+To return all attributes in an entry, pass null as
+the attrs parameter.
+To return no attributes from an entry, pass LDAPv3.NO_ATTRS
+ as the attrs parameter.
+
+You might plan to sort the results on your client as described in Sorting the Search Results With Directory SDK
+for Java. 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.
+Some attributes are used by servers for administering the directory.
+For example, the creatorsName attribute specifies the DN
+of the user who added the entry. These attributes are called operational
+attributes.
+Servers do not normally return operational attributes in search results
+unless you specify the attributes by name. For example, if you pass null
+ as the attrs parameter to retrieve all
+of the attributes in entries found by the search, the operational attribute
+creatorsName is not returned to your client. You need to explicitly
+specify the creatorsName attribute in the attrs parameter.
+
+To return all attributes in an entry with selected operational attributes,
+pass a string array containing LDAPv3.ALL_USER_ATTRS,
+and also the names of the operational attributes as the attrs parameter.
+Following are a few operational attributes and a description of what each
+attribute contains.
+
+createTimestamp
+The time when the entry was added to the directory.
+
+
+modifyTimestamp
+The time when the entry was last modified.
+
+
+creatorsName
+Distinguished name (DN) of the user who added the entry to
+the directory.
+
+
+modifiersName
+DN of the user who last modified the entry.
+
+
+subschemaSubentry
+DN of the subschema entry, that controls the schema for this
+entry.
+
+
+
+
+Setting Search Preferences
+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.
+The LDAPSearchConstraints class represents a
+set of search constraints. The methods of this class allow you to get and
+set the constraints.
+Setting Preferences for All Searches
+
+search results
+setting preferences
+
+The LDAPConnection 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.
+
+To get the default set of search constraints for the connection,
+you can use the getSearchConstraints method.
+
+To get or set any of the search constraints individually,
+you can use the getOption method and the setOption method.
+
+
+For example, if you want to specify the maximum number of results returned,
+you can set this constraint for the connection:
+LDAPConnection ld = new LDAPConnection();
+ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
+ld.setOption(LDAPv3.SIZELIMIT, new Integer(100));
+
+Overriding Preferences for
+Individual Searches
+To override the default set of search constraints for a given search
+request, construct your own LDAPSearchConstraints object.
+Pass the object to the search method of the LDAPConnection
+ object.
+You can also modify a copy of the existing search constraints. Pass
+the modified set of constraints to the search method. Invoke
+the getSearchConstraints method of the LDAPConnection
+ object to get the default set of constraints for that connection.
+Then invoke the clone method of the LDAPSearchConstraints object
+to make a copy of the set that you can then modify.
+Configuring the Search to Wait
+for All Results
+
+search results
+waiting for all
+
+By default, the search method of the LDAPConnection
+ object does not block until all results are received. Instead,
+the search method returns as soon as one of the results
+has been received.
+
+If you want the search method to block until all
+results are received, you can do one of the following:
+Use the setOption method of the LDAPConnection
+ object to set the LDAPv3.BATCHSIZE preference
+to 0.
+Pass a 0 to the setBatchSize method
+of the LDAPSearchConstraints object to change the behavior
+for a particular set of search constraints.
+
+Whether waiting for one or all results of the search method,
+you still need to invoke the next method of the returned
+LDAPSearchResults object to retrieve each individual result.
+
+Setting Size and Time Limits
+
+search results
+setting size limits
+
+search results
+setting time limits
+
+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 1000. No maximum time limit is set for waiting on
+an operation to complete.
+
+To change these default values, you can do one of the following:
+Use the setOption method of the LDAPConnection
+ object to set the LDAPv3.SIZELIMIT and
+LDAPv3.TIMELIMIT preferences.
+Use the setMaxResults method and the
+setTimeLimit method of the LDAPSearchConstraints object
+to change the behavior for a particular set of search constraints.
+
+
+
+When you set the size limit or time limit, you might cause an LDAPException
+ to be returned. The exception is returned when the limit is exceeded.
+
+If the size limit is exceeded, the server returns an LDAPException.SIZE_LIMIT_EXCEEDED
+ result code.
+If the time limit is exceeded, the server returns an LDAPException.TIME_LIMIT_EXCEEDED
+ result code.
+
+
+
+Search Request Example
+The following section of code searches for all entries with surname
+Jensen. The search retrieves the names and values of the cn,
+mail, and telephoneNumber attributes.
+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);
+}
+
+
+Getting the Search Results With &DirectorySDKForJava;
+
+search results
+getting
+
+When you invoke the search method of an LDAPConnection
+ object to search the directory, the method returns the search
+results in the form of an LDAPSearchResults object.
+The search results consist of an enumeration of entries, which are represented
+by LDAPEntry objects. The search results can also include
+smart referrals, also known as search references, and
+exceptions.
+Each entry contains a set of attributes, which are represented by
+LDAPAttributeSet objects. Individual attributes are represented
+by LDAPAttribute objects. Each attribute has a set
+of values that you can get.
+The following figure illustrates the relationship between entries, attributes,
+values, and search results.
+Entries, Attributes, and Values in
+Search Results
+
+
+Relationship between entries, attributes, values, and
+search results
+
+
+Getting Entries
+
+entries
+getting from search results
+
+search results
+getting entries
+
+The LDAPSearchResults 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 ADMIN_LIMIT_EXCEEDED
+, TIME_LIMIT_EXCEEDED, or SIZE_LIMIT_EXCEEDED
+ result code from the server. When the result code is received, &DirectorySDKForJava; adds
+an exception for this result code to the search results.
+To get entries from the LDAPSearchResults object,
+you can either invoke the next method or the nextElement
+ method.
+
+When you invoke the next method, if the
+next item in the search results is an entry, the method returns an LDAPEntry
+ object.
+
+
+referrals
+LDAPReferralException and
+
+referrals
+getting from search results
+If the next item is a search reference, one of the following can
+occur:
+If referrals are not followed automatically, an LDAPReferralException
+ is returned. The exception is also returned if the referral hop
+limit is exceeded.
+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.
+
+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.See Handling Referrals With Directory SDK for Java for
+more information about referrals and search references.If the
+next item is an LDAP result code such as ADMIN_LIMIT_EXCEEDED,
+TIME_LIMIT_EXCEEDED, or SIZE_LIMIT_EXCEEDED,
+the LDAP Java classes return an LDAPException.
+
+When you invoke the nextElement method,
+the method returns an object that you must cast. The object is an LDAPEntry
+ object, an LDAPReferralException, or an
+LDAPException.
+
+As you iterate through the search results, you can invoke the hasMoreElements
+ method to determine if you have reached the end of the search results.
+
+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... */
+}
+
+Getting Distinguished Names
+
+distinguished names
+getting from search results
+
+search results
+getting distinguished names
+
+To get the distinguished name of an LDAPEntry object,
+invoke the getDN method. This method returns a String
+.
+LDAPEntry nextEntry = res.next();
+String nextDN = nextEntry.getDN();
+Although the netscape.ldap package includes an
+LDAPDN class, you typically do not construct objects of this class
+to represent DNs. The LDAPDN class is mainly a utility
+class that provides methods for manipulating string DNs.
+Getting Attributes
+
+attributes
+getting from search results
+
+search results
+getting attributes
+
+To get the set of attributes in an LDAPEntry object,
+invoke the getAttributeSet method. This method returns
+an LDAPAttributeSet object.
+LDAPEntry nextEntry = res.next();
+LDAPAttributeSet entryAttrs = nextEntry.getAttributeSet();
+To get individual attributes from an LDAPAttributeSet object,
+invoke the getAttributes method. This method returns an
+enumeration of attributes. You can then iterate through the elements in this
+enumeration to retrieve individual LDAPAttribute objects.
+/* 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());
+}
+To determine the number of attributes in the LDAPAttributeSet object,
+invoke the size method.
+
+You can also retrieve a specific attribute from the entry or from the
+attribute set.
+To get a specific attribute from an LDAPEntry object,
+invoke the getAttribute method.
+To get a specific attribute from an LDAPAttributeSet object,
+invoke the getAttribute method.
+
+Both methods return an LDAPAttribute object.
+LDAPEntry nextEntry = res.next();
+LDAPAttribute anAttr = nextEntry.getAttribute("cn");
+
+Getting Attribute Types
+and Values
+
+attributes
+getting from search results
+
+search results
+getting attribute types
+
+search results
+getting attribute values
+
+To get the name of an LDAPAttribute object, invoke
+the getName method.
+LDAPAttribute nextAttr = (LDAPAttribute)enumAttrs.nextElement();
+String attrName = nextAttr.getName();
+
+To get the values in an LDAPAttribute object,
+you can use the following methods:
+To get the String values, invoke the
+getStringValues method.
+To get the binary values as byte arrays, invoke the getByteValues
+ method.
+
+Both methods return an enumeration that you can iterate through to retrieve
+individual results. For example, if an error occurs when you invoke getStringValues
+, although the values are binary data, the methods return null
+.
+You can also count the number of values in an attribute by invoking
+the size method of the LDAPAttribute object.
+
+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);
+ }
+}
+
+
+Sorting the Search Results With &DirectorySDKForJava;
+
+search results
+sorting
+
+sorting search results
+
+
+With &DirectorySDKForJava;, you can sort the search results in two
+ways.
+You can specify that the LDAP server should sort the results
+before returning the results to your client.Send a server-side
+sort control to the server as described in Chapter 10,
+LDAP Controls With Directory SDK for Java. Server-side sorting might
+work best if you specify a filter that uses an indexed attribute.
+
+After you receive the results from the server, you can sort
+the results on your client.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.
+
+You can sort the results on the client by invoking the sort method of
+the LDAPSearchResults object.
+
+LDAPEntryComparator interface
+example of
+
+LDAPEntryCompareAttrNames class
+example of
+When invoking this method, you need to pass a comparator object,
+which is an object of a class that implements the LDAPEntryComparator interface. &DirectorySDKForJava; includes
+an LDAPCompareAttrNames class that implements this
+interface. This class specifies how entries are compared with each other and
+sorted.
+To construct an LDAPCompareAttrNames 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 LDAPCompareAttrNames constructor. For example,
+the following section of code sorts first by surname, sn,
+and then by common name, cn, in ascending order:
+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));
+If all search results have not yet been returned, the sort method
+blocks until all results have been received.
+Abandoning a Search With &DirectorySDKForJava;
+
+abandoning a search
+
+searching the directory
+abandoning a search
+
+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 abandon
+ method of the LDAPConnection object. Pass
+in the LDAPSearchResults object that was returned to
+you when you first invoked the search method.
+Searching the Directory With &DirectorySDKForJava;
+
+searching the directory
+example of
+
+The following example prints the values of all attributes in the entries
+returned by a search.
+Searching for a Specific Entry
+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());
+ }
+ }
+}
+
+
+Reading an Entry With &DirectorySDKForJava;
+
+entries
+reading from directory
+
+reading an entry from the directory
+
+To get a single entry from the directory, use the read method
+of the LDAPConnection 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.
+To retrieve data from the entry, you can use the same classes with their
+methods, as described in Getting
+Attributes and in
+Getting Attribute Types and Values.
+The following example retrieves an entry and prints the values of its
+attributes.
+Retrieving a Specific Entry
+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());
+ }
+ }
+}
+
+
+Listing Child Entries With &DirectorySDKForJava;
+
+entries
+retrieving child entries of
+
+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 LDAPv3.SCOPE_ONE.
+Using Scope of One to Retrieve Child Entries
+
+
+Search for child entries
+
+
+The following code performs a one-level search:
+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());
+}
+
+
diff --git a/mozilla/directory/docs/ldapjdk/jdk-server-info.sgm b/mozilla/directory/docs/ldapjdk/jdk-server-info.sgm
new file mode 100644
index 00000000000..9af59075a5d
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/jdk-server-info.sgm
@@ -0,0 +1,575 @@
+
+Getting Server Information With &DirectorySDKForJava;
+
+
+This chapter explains how to access and modify information about your
+LDAP server over the LDAP protocol.
+
+This chapter covers the following topics:
+About DSEs
+
+Getting the Root DSE
+With Directory SDK for Java
+Checking Support for
+LDAP v3 With Directory SDK for Java
+Getting Schema Information
+With Directory SDK for Java
+
+
+About DSEs
+The acronym DSE refers to a DSA-specific
+entry in the directory. A DSA is a directory system agent,
+an X.500 term for a directory server. A DSE contains information specific
+to the server.
+LDAP v3 uses the concept of the root DSE. 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 dc=example,dc=com
+, cn=config, and similar suffixes in the directory
+tree. Servers that do not support LDAP v3 therefore do not necessarily have
+a root DSE.
+
+The root DSE can contain the following information:
+The naming contexts the server supports, such as dc=example,dc=com
+ or cn=config
+URLs to alternate servers that can be contacted if the server
+is unavailable
+The LDAP v3 extended operations the server supports
+
+The LDAP v3 controls the server supports
+The SASL mechanisms the server supports
+The versions of LDAP the server supports
+Additional, server-specific information
+
+
+Getting the Root DSE With &DirectorySDKForJava;
+
+
+DSE
+root
+
+root DSE
+
+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.
+
+altServer
+LDAP URLs that identify other servers to contact when the
+server is not available.
+
+
+namingContexts
+Naming contexts, such as dc=example,dc=com,
+supported by the server.
+
+
+supportedControl
+Object identifiers (OIDs) of LDAP v3
+controls supported by the server.
+If this attribute is not present, the server does not support LDAP v3
+controls.
+
+
+supportedExtension
+Object identifiers (OIDs) of LDAP v3 extended operations supported
+by the server.
+If this attribute is not present, the server does not support LDAP v3
+extended operations.
+
+
+supportedLDAPVersion
+Versions of LDAP, 2 or 3,
+supported by the server.
+
+
+supportedSASLMechanisms
+Names of SASL mechanisms supported by the server.
+If this attribute is not present, the server does not support any SASL
+mechanisms.
+
+
+
+
+To access the root DSE of an LDAP server, do the following:
+Turn off automatic referral handling, and connect to the LDAP
+server.See Creating
+a Connection and Setting Preferences With Directory SDK for Java and Connecting to an LDAP Server
+With Directory SDK for Java. See also Handling Referrals With Directory SDK for Java for
+instructions.
+
+
+Search the directory with the following criteria:
+Set the search scope to a base search.
+
+Specify an empty string for the base DN.
+Use the search filter (objectclass=*).
+
+
+Refer to Chapter 4, Searching the Directory With Directory SDK for Java for instructions.
+If an LDAPException is returned with a result
+code such as OPERATION_ERROR, PROTOCOL_ERROR
+, REFERRAL, or NO_SUCH_OBJECT
+, the LDAP server probably does not support LDAP v3.
+
+
+The following code excerpt retrieves the root DSE, and then displays
+the attributes.
+/* 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());
+}
+
+Checking Support for LDAP v3 With &DirectorySDKForJava;
+
+
+LDAP servers
+protocol version supported
+
+You can determine what version an LDAP server supports by getting the
+supportedLDAPVersion attribute from the root DSE. This attribute
+should contain the value 3. The attribute can also contain
+other values, such as 2, so iterate through the values
+of this attribute.
+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.
+/* 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.");
+}
+
+Getting Schema Information With &DirectorySDKForJava;
+
+
+LDAP servers
+schema
+
+schema
+
+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.
+Understanding Schema Over LDAP
+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
+subschema entry.
+To find the DN of the subschema entry, get the subschemaSubentry operational
+attribute from the root DSE or from any entry. This code excerpt demonstrates
+how to retrieve the subschema entry DN.
+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());
+}
+The subschema entry can have the following attributes.
+
+objectClasses
+Specifies the object class definitions in the schema.
+Each value of this attribute is an object class that is known to the
+server.
+
+
+attributeTypes
+Specifies the attribute type definitions in the schema.
+Each value of this attribute is an attribute type that is known to the
+server.
+
+
+matchingRules
+Specifies the matching rule definitions in the schema.
+Each value of this attribute is a matching rule that is known to the
+server.
+
+
+matchingRuleUse
+Specifies the use of a matching rule in the schema.
+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.
+
+
+syntaxes
+Specifies the syntax definitions in the schema.
+Each value of this attribute is syntax that is known to the server.
+
+
+
+In &DirectorySDKForJava;, the schema and elements in the schema are
+represented by classes in the netscape.ldap package. These
+classes include the following.
+
+LDAPSchema
+Schema used by an LDAP server
+
+
+LDAPSchemaElement
+Base class that represents a generic element in the schema
+
+
+LDAPObjectClassSchema
+Object class description in the schema
+
+
+LDAPAttributeSchema
+Attribute type description in the schema
+
+
+LDAPMatchingRuleSchema
+Matching rule description in the schema
+
+
+LDAPMatchingRuleUseSchema
+Use of a matching rule in the schema
+
+
+LDAPSyntaxSchema
+Syntax description in the schema
+
+
+
+These classes with their methods handle the subschema entry by using
+standard LDAP operations, such as search and modify.
+
+Getting Information About LDAP Schema
+To get the schema for an LDAP v3 server, construct a new LDAPSchema
+ object. Then, invoke the fetchSchema method,
+passing in an LDAPConnection object.
+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());
+}
+
+Working With Object Class
+Descriptions
+In the LDAP Java classes, the object class descriptions in a schema
+are represented by objects of the LDAPObjectClassSchema class.
+
+
+To get the object class descriptions from the schema, invoke one of
+the following methods:
+To get an enumeration of LDAPObjectClassSchema objects
+that represent the object classes in the schema, invoke the getObjectClasses
+ method.
+To get a specific object class description, invoke the getObjectClass
+ method and pass in the name of the object class.
+To get an enumeration of the names of object classes in the
+schema, invoke the getObjectClassNames method.
+
+
+
+An object class description consists of the following information, which
+you can retrieve by invoking methods of the LDAPObjectClassSchema object:
+
+An OID that identifies the object class, retrieved by invoking
+the getOID method
+A name that identifies the object class, retrieved by invoking
+the getName method
+A description that identifies the object class, retrieved
+by invoking the getDescription method
+A name that identifies the parent object class, retrieved
+by invoking the getSuperior method
+The list of required attributes, retrieved by invoking the
+getRequiredAttributes method
+The list of optional attributes that are allowed, retrieved
+by invoking the getOptionalAttributes method
+
+
+To add an object class description to the schema, construct a new
+LDAPObjectClassSchema object. You can specify the pieces of information
+in the object as individual arguments or in a description formatted according
+to RFC 4517,
+Lightweight Directory Access Protocol (LDAP): Syntaxes and Matching Rules.
+
+Then, you can either invoke the add method of this
+object or the addObjectClass method of the LDAPSchema
+ object.
+To remove an object class description, invoke the remove method
+of this object.
+Working With Attribute
+Type Descriptions
+In the LDAP Java classes, the attribute type descriptions in a schema
+are represented by objects of the LDAPAttributeSchema class.
+
+
+To get the attribute type descriptions from the schema, invoke one of
+the following methods:
+To get an enumeration of LDAPAttributeSchema objects
+that represent the attribute types in the schema, invoke the getAttributes
+ method.
+To get a specific attribute type description, invoke the
+getAttribute method and pass in the name of the attribute type.
+
+To get an enumeration of the names of attribute types in the
+schema, invoke the getAttributeNames method.
+
+
+
+An attribute type description consists of the following information,
+which you can retrieve by invoking methods of the LDAPAttributeSchema object:
+
+An OID that identifies the attribute type, retrieved by invoking
+the getOID method
+A name that identifies the attribute type, retrieved by invoking
+the getName method
+A description that identifies the attribute type, retrieved
+by invoking the getDescription method
+The syntax used by the attribute type, retrieved by invoking
+the getSyntax method
+An indication whether the attribute type is single-valued
+or multivalued, retrieved by invoking the isSingleValued method
+
+
+To add an attribute type description to the schema, construct a new
+LDAPAttributeSchema object. You can specify the pieces of information
+in the object as individual arguments or in a description formatted according
+to RFC 4517,
+Lightweight Directory Access Protocol (LDAP): Syntaxes and Matching Rules.
+
+Then, you can either invoke the add method of this
+object or the addAttributeType method of the LDAPSchema
+ object.
+To remove an attributeType description, invoke the
+remove method of this object.
+Working With Matching
+Rule Descriptions
+In the LDAP Java classes, the matching rule and matching rule use descriptions
+in a schema are represented by objects of the LDAPMatchingRuleSchema class.
+
+
+To get the matching rule descriptions from the schema, invoke one of
+the following methods:
+To get an enumeration of LDAPMatchingRuleSchema objects
+that represent the matching rules in the schema, invoke the getMatchingRules
+ method.
+To get a specific matching rule description, invoke the
+getMatchingRule method and pass in the name of the matching rule.
+
+To get an enumeration of the names of matching rules in the
+schema, invoke the getMatchingRuleNames method.
+
+
+
+A matching rule description consists of the following information, which
+you can retrieve by invoking methods of the LDAPMatchingRuleSchema object:
+
+An OID that identifies the matching rule, retrieved by invoking
+the getOID method
+A name that identifies the matching rule, retrieved by invoking
+the getName method
+A description that identifies the matching rule, retrieved
+by invoking the getDescription method
+The syntax of the matching rule, retrieved by invoking the
+getSyntax method
+
+To add a matching rule description to the schema, construct a new
+LDAPMatchingSchema object. You can specify the pieces of information
+in the object as individual arguments or in a description formatted according
+to RFC 4517, Lightweight Directory Access Protocol (LDAP):
+Syntaxes and Matching Rules.
+Then, you can either invoke the add method of this
+object or the addMatchingRule method of the LDAPSchema
+ object.
+To remove a matching rule description, invoke the remove method
+of this object.
+Example of Working With Schema
+The following example illustrates how to get the schema and how to add
+object classes and attribute types.
+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);
+ }
+ }
+}
+
+
+
diff --git a/mozilla/directory/docs/ldapjdk/jdk-ssl.sgm b/mozilla/directory/docs/ldapjdk/jdk-ssl.sgm
new file mode 100644
index 00000000000..68ec0e8f283
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/jdk-ssl.sgm
@@ -0,0 +1,209 @@
+
+SSL Connections With &DirectorySDKForJava;
+
+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.
+
+
+This chapter covers the following topics:
+How SSL Works With Directory
+SDK for Java
+Prerequisites for Connecting
+Over SSL With Directory SDK for Java
+Connecting to a Server Over
+SSL With Directory SDK for Java
+Using Certificate-Based
+Client Authentication With Directory SDK for Java
+
+
+How SSL Works With &DirectorySDKForJava;
+&DirectorySDKForJava; includes classes and methods to enable your
+application to connect to an LDAP server over a Secure Sockets
+Layer (SSL).
+Understanding SSL
+The primary goal of the SSL Protocol is to provide privacy and reliability
+between two communicating applications. For more information about SSL and
+Transport Layer Security, refer to RFC 2246,
+The TLS Protocol.
+The &DirectorySDKForJava; supports SSL 3.0.
+SSL and LDAP
+When an LDAP client connects to an LDAP server over SSL, the LDAP server
+identifies itself by sending its certificate to the
+LDAP client. The LDAP client needs to determine whether or not the certificate
+authority (CA) who issued the certificate is trusted.
+The LDAP server can also request that the client send a certificate
+to authenticate. This process is called certificate-based client
+authentication.
+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.
+To use SSL, you need a certificate database to
+hold the CA certificate. If certificate-based client authentication is used,
+you need the client certificate.
+Interfaces and Classes for SSL
+&DirectorySDKForJava; includes the LDAPSocketFactory interface.
+This interface describes a single method, makeSocket, 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.
+Classes that implement this interface rely on a separate class that
+implements SSL sockets. In the constructors for objects that implement
+LDAPSocketFactory, you typically need to specify the name of a
+class that implements SSL sockets. The following classes implement this interface.
+
+
+LDAPSSLSocketFactory
+Use this class if you are using the netscape.net.SSLSocket
+ class to implement SSL sockets. You can also use this class if
+the class that implements SSL sockets extends the Socket object.
+
+
+
+LDAPSSLSocketWrapFactory
+Use this class if the class that implements SSL sockets does
+not extend the Socket object. The LDAPSSLSocketWrapFactory
+ class wraps your SSL socket implementation class in a class that
+does extend the Socket object.
+
+
+JSSESocketFactory
+Use this class to rely on the standard SSL socket factory
+code.
+
+
+
+You can construct an object for one of these factory classes. You can
+pass the factory object to the constructor for the LDAPConnection object,
+to identify the socket factory that is used for the connection.
+
+Prerequisites for Connecting Over SSL
+With &DirectorySDKForJava;
+
+The LDAP Java classes that enable you to connect over SSL assume the
+following:
+Your client has access to a Netscape Security Services (NSS)
+certificate database.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.
+The database used contains one of the following certificates:
+
+The certificate of the CA who issued the server certificate
+
+If the CAs are organized hierarchically, the certificate of
+any CA in the hierarchy
+The certificate of the server
+
+
+The CA certificate is marked as trusted in
+the database.
+If you use certificate-based client authentication, you must
+have the following data:
+
+A client certificate issued by a CA trusted by the LDAP server
+This certificate must be in the client certificate database.
+
+A public key, private key pair in an NSS key database on the
+client side
+
+
+
+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.
+Your client might not find the CA certificate. Your client might also
+find that the CA certificate is marked as not trusted.
+If either condition occurs, your client refuses to connect to the server.
+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.
+The server might not find the CA certificate. The CA certificate might
+be marked as not trusted. If either condition occurs, the
+server refuses to authenticate your client.
+Connecting to a Server Over SSL With &DirectorySDKForJava;
+
+To connect to an LDAP server with SSL, do the following:
+Construct a new LDAPSSLSocketFactory object
+or a new LDAPSSLSocketWrapFactory object.This
+object represents the SSL socket factory used to create the sockets for establishing
+connections with the LDAP server.The constructors for these classes
+allow you to specify the name of the class used to create the actual sockets.
+
+For the LDAPSSLSocketFactory constructor,
+you should specify a class that implements the javax.net.ssl.SSLSocket
+ interface. By default, if you do not specify a class, the
+netscape.net.SSLSocket class is used.
+If the SSL socket class does not extend the Socket class,
+use the LDAPSSLSocketWrapFactory constructor.
+
+
+
+Pass the object that you constructed to the LDAPConnection
+ constructor.When first you establish a connection
+to the LDAP server, use the makeSocket method of the specified
+object that you used to construct the socket.
+
+Using Certificate-Based Client Authentication
+With &DirectorySDKForJava;
+
+authentication
+certificate-based
+
+certificate-based client authentication
+
+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.
+
+With &DirectorySDKForJava;, you can set up your client to perform
+certificate-based authentication in either of the following situations:
+Your client runs as an applet in a Netscape or Mozilla browser
+
+Your client uses a class implementing the LDAPSocketFactory
+ interface and supporting client-based authentication
+
+
+
+When using certificate-based client authentication, consider the following:
+
+The LDAPSSLSocketWrapFactory class
+does not support certificate-based client authentication.
+The LDAPSSLSocketFactory 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.
+
+
+To enable an applet to use certificate-based client authentication,
+do the following:
+Construct a new LDAPSSLSocketFactory object.
+
+Invoke the enableClientAuth method of the
+object to enable certificate-based client authentication.
+Pass the object that you constructed to the LDAPConnection
+ constructor.
+
+
diff --git a/mozilla/directory/docs/ldapjdk/jdk-understanding.sgm b/mozilla/directory/docs/ldapjdk/jdk-understanding.sgm
new file mode 100644
index 00000000000..ff5649d44b8
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/jdk-understanding.sgm
@@ -0,0 +1,412 @@
+
+Understanding the &DirectorySDKForJava;
+
+This chapter describes the LDAP Java classes and the &DirectorySDKForJava;,
+including the following sections:
+
+Understanding the LDAP
+Java Classes
+About &DirectorySDKForJava;
+
+
+
+Understanding the LDAP Java Classes
+
+
+packages
+summary of
+
+&DirectorySDKForJava;
+packages
+
+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.
+The classes are organized in the following packages:
+
+com.netscape.sasl
+Contains the interfaces and classes that you can use to enable your
+client to authenticate by using a SASL mechanism.
+
+
+com.netscape.sasl.mechanisms
+Contains an implementation of the EXTERNAL SASL mechanism driver.
+
+
+
+netscape.ldap
+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
+
+
+
+netscape.ldap.ber.stream
+Contains the LDAP Java classes that implement the Basic
+Encoding Rules (BER) for transfer syntax. For more information on BER,
+see ISO/IEC 8825 at http://www.iso.ch/
+.
+
+
+netscape.ldap.controls
+Contains the LDAP Java classes that implement specific LDAP v3 controls.
+These include controls to request server-side sorting and persistent searches.
+
+
+netscape.ldap.factory
+Contains classes that allow you to create an SSL socket connection
+to a server.
+
+
+netscape.ldap.util
+Contains utility classes, such as classes to parse LDIF data and filters
+that allow regular expression matching.
+
+
+
+Clients typically execute methods in the &DirectorySDKForJava; synchronously.
+All LDAP operations block until they are completed, except for the search
+ method, which can return information before all the results have been received.
+
+An asynchronous interface is also provided for circumstances requiring low-level
+interaction with an LDAP server. The asynchronous interface is discussed more fully
+in Chapter 33, Writing Asynchronous Clients With Directory SDK for Java.
+About &DirectorySDKForJava;
+This section covers the following topics:
+
+
+Exploring the Directory SDK for Java
+
+Preparing to Use Directory SDK for
+Java
+
+
+
+Exploring the &DirectorySDKForJava;
+
+&DirectorySDKForJava;
+contents
+
+TODO: verify this is all still true
+The &DirectorySDKForJava; contains the following directories:
+
+
+packages
+This directory contains the following JAR file:
+
+
+ldapjdk.jar
+ldapjdk.jar
+Contains classes for all packages listed in
+Understanding the LDAP Java Classes
+
+
+
+
+
+
+
+tools
+This directory contains Java classes for the LDAPDelete,
+LDAPModify, and LDAPSearch commands.
+
+
+
+
+Preparing to Use &DirectorySDKForJava;
+
+CLASSPATH
+setting
+
+TODO: is this right?
+Before compiling applications, add the following to your CLASSPATH environment
+variable:
+
+
+packages/ldapjdk.jar
+Containing the main LDAP Java classes
+
+
+
+
+
+
+
+
diff --git a/mozilla/directory/docs/ldapjdk/jdk-writing-client.sgm b/mozilla/directory/docs/ldapjdk/jdk-writing-client.sgm
new file mode 100644
index 00000000000..29bf290d7f0
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/jdk-writing-client.sgm
@@ -0,0 +1,361 @@
+
+Writing an LDAP Client With &DirectorySDKForJava;
+
+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.
+
+The chapter covers the following topics:
+Designing an LDAP Java
+Client
+Creating a Connection and
+Setting Preferences With Directory SDK for Java
+Connecting to an LDAP Server
+With Directory SDK for Java
+Binding and Authenticating
+to an LDAP Server With Directory SDK for Java
+Performing LDAP Operations
+With Directory SDK for Java
+Closing the Connection to
+an LDAP Server With Directory SDK for Java
+
+
+Designing an LDAP Java Client
+The following steps outline the typical process of communicating with
+an LDAP server. Follow these steps when writing your LDAP client.
+
+Create a new LDAPConnection object,
+and set any preferences that you want applied to all LDAP operations.
+
+Connect to an LDAP server.
+If necessary, bind to the LDAP server, specifying the version
+of LDAP supported by your client.
+Perform the LDAP operations, such as searching the directory
+or modifying entries in the directory.
+When finished performing operations, disconnect from the LDAP
+server.
+
+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
+389. The client then searches the directory for entries with the
+surname Jensen. Finally, the client displays the DNs of
+matching entries.
+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());
+ }
+ }
+}
+
+Creating a Connection and Setting Preferences
+With &DirectorySDKForJava;
+
+connection
+creating
+
+connection
+setting preferences
+
+LDAP session
+setting preferences
+
+The first step in writing an LDAP client is creating an LDAPConnection
+ object. This object represents the connection to an LDAP server.
+LDAPConnection ld = new LDAPConnection();
+If you plan to connect to the LDAP server over the Secure
+Sockets Layer (SSL) protocol, you need to specify a class that
+implements SSL sockets. Refer to Chapter 9,
+SSL Connections With Directory SDK for Java for details.
+The LDAPConnection 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 getOption method
+or the setOption method as described in the API specification.
+
+Connecting to an LDAP Server With &DirectorySDKForJava;
+
+LDAP servers
+connecting to
+
+LDAP clients
+connection to a server
+
+connection
+establishing
+
+session
+starting
+
+To connect to an LDAP server, use the connect method
+of the LDAPConnection object.
+LDAPConnection ld = new LDAPConnection();
+ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
+DEFAULT_PORT 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.
+
+connection
+specifying multiple LDAP servers
+
+failover support
+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 hostname:
+portnumber format.
+LDAPConnection ld = new LDAPConnection();
+ld.connect("ldap1.example.com ldap2.example.com:3890
+ ldap3.example.com:3900", LDAPv3.DEFAULT_PORT);
+
+Binding and Authenticating to an LDAP Server
+With &DirectorySDKForJava;
+
+LDAP clients
+authenticating with LDAP servers
+
+LDAP servers
+authenticating to
+
+bind operation
+
+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.
+
+An LDAP bind request contains the following information:
+LDAP version of the client
+DN that is used to authenticate
+Authentication method that is requested
+Credentials that are used to authenticate
+
+
+The client should send a bind request to the server in the following
+situations:
+You want to authenticate to the server.For example,
+if you want to add or modify entries in the directory, you need to authenticate
+as a user with access privileges.
+You are connecting to an LDAP v2 server.LDAP
+v2 servers typically require clients to bind before any operations can be
+performed.
+
+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.
+This section explains how to set up your client to bind to an LDAP server.
+Using Simple Authentication
+Simple authentication can be used when security is not a concern. If
+you plan to use simple authentication, use the authenticate method
+of the LDAPConnection object.
+LDAPConnection ld = new LDAPConnection();
+ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
+ld.authenticate("uid=bjensen,ou=People,cd=example,dc=com", "hifalutin");
+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 Chapter 10, LDAP Controls
+With Directory SDK for Java for details.
+Binding Anonymously
+
+anonymous bind
+
+binding
+anonymously
+
+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.
+In this kind of situation, use the authenticate method.
+Specify null for the DN and password.
+LDAPConnection ld = new LDAPConnection();
+ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
+ld.authenticate(null, null);
+
+Specifying the LDAP Version
+
+LDAP clients
+specifying protocol version
+
+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.
+
+To identify your client as an LDAP v3 client, do one of the following:
+Specify version 3 when invoking the authenticate method.
+
+LDAPConnection ld = new LDAPConnection();
+ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
+ld.authenticate(3, null, null);
+
+Invoke the setOption method of the
+LDAPConnection object to set the LDAPv3.PROTOCOL_VERSION preference
+to 3, then invoke the authenticate method.
+LDAPConnection ld = new LDAPConnection();
+ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
+ld.setOption(LDAPv3.PROTOCOL_VERSION, 3);
+ld.authenticate(null, null);
+
+
+
+Authenticating With the connect
+ Method
+The connect method of the LDAPConnection object
+has a signature that allows you to authenticate and specify the LDAP version
+supported by your client.
+You can specify all of this information using one method, rather than
+invoking several methods.
+LDAPConnection ld = new LDAPConnection();
+ld.connect(3, "ldap.example.com", LDAPv3.DEFAULT_PORT,
+ "uid=bjensen,ou=People,cd=example,dc=com", "hifalutin");
+
+
+Performing LDAP Operations With &DirectorySDKForJava;
+
+LDAP operations
+
+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.
+
+To perform LDAP operations, invoke these methods of the LDAPConnection
+ object:
+To search for entries in the directory, use the search method
+as explained in Chapter 4, Searching the
+Directory With Directory SDK for Java.
+To retrieve a single entry in the directory, use the read
+ method as explained in Chapter 4,
+Searching the Directory With Directory SDK for Java.
+To determine whether an attribute contains a certain value,
+use the compare method as explained in Chapter 6, Comparing Attribute Values With Directory
+SDK for Java.
+To add entries to the directory, use the add method
+as explained in Chapter 5, Adding, Updating,
+and Deleting Entries With Directory SDK for Java.
+To modify entries in the directory, use the modify method
+as explained in Chapter 5, Adding, Updating,
+and Deleting Entries With Directory SDK for Java.
+To delete entries from the directory, use the delete method
+as explained in Chapter 5, Adding, Updating,
+and Deleting Entries With Directory SDK for Java.
+To rename entries in the directory, use the rename method
+as explained in Chapter 5, Adding, Updating,
+and Deleting Entries With Directory SDK for Java.
+
+
+Closing the Connection to an LDAP Server With &DirectorySDKForJava;
+
+ending an LDAP session
+
+LDAP session
+ending
+
+closing an LDAP connection
+
+LDAP servers
+closing connection from client
+
+LDAP clients
+closing connection to server
+
+connection
+closing
+
+When you have finished performing all necessary LDAP operations, close
+the connection to the LDAP server. Use the disconnect method
+of the LDAPConnection object to disconnect from the
+LDAP server.
+LDAPConnection ld = new LDAPConnection();
+ld.connect("ldap.example.com", LDAPv3.DEFAULT_PORT);
+/*
+ * Authenticate and perform LDAP operations.
+ */
+ld.disconnect();
+
+
diff --git a/mozilla/directory/docs/ldapjdk/legal.sgm b/mozilla/directory/docs/ldapjdk/legal.sgm
new file mode 100644
index 00000000000..127dc0071c8
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/legal.sgm
@@ -0,0 +1,113 @@
+
+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.
+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.
+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.
+This distribution may include materials developed by third
+parties.
+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.
+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.
+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.
+Mozilla, Netscape, and Netscape Navigator are trademarks or
+registered trademarks of Netscape Communications Corporation in the
+United States and other countries.
+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.
+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.
+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.
+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.
+Cette distribution peut comprendre des composants
+développés par des tierces parties.
+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.
+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.
+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.
+Mozilla, Netscape, et Netscape Navigator sont des marques de
+Netscape Communications Corporation aux Etats-Unis et dans d'autres
+pays.
+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.
+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.
diff --git a/mozilla/directory/docs/ldapjdk/license.txt b/mozilla/directory/docs/ldapjdk/license.txt
new file mode 100644
index 00000000000..92f23fd1acf
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/license.txt
@@ -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/.
diff --git a/mozilla/directory/docs/ldapjdk/preface.sgm b/mozilla/directory/docs/ldapjdk/preface.sgm
new file mode 100644
index 00000000000..c0112065ab8
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/preface.sgm
@@ -0,0 +1,349 @@
+
+Preface
+&abstract;
+
+Who Should Use This Book
+This guide is intended for developers creating directory client applications.
+
+
+Before using this guide, you must be familiar with the following:
+&cnDirectoryServer; functionality
+Developing programs in the Java programming
+language
+Specifications for LDAP and related protocols, such as DSML
+v2
+Internet and World Wide Web technologies
+
+
+Before You Read This Book
+Before developing directory client applications, install &DirectorySDKForJava;.
+
+
+
+Additional Recommended Reading
+
+Directory client application developers might benefit from reading the
+following books:
+LDAP Programming with Java by Weltman
+and Dabhura (ISBN 0-201-65758-96)
+LDAP Programming, Management and Integration by
+Donley (ISBN 1930110405)
+LDAP: Programming Directory-Enabled Applications
+with Lightweight Directory Access Protocol by Howes and Smith
+(ISBN 1-57870-000-00)
+Understanding and Deploying LDAP Directory Services by
+Howes, et al. (ISBN 1-57870-070-10)
+
+
+In addition, keep bookmarks to the following IETF documents:
+
+RFC 2251, Lightweight Directory Access Protocol (v3)
+
+
+RFC 2252, Lightweight Directory Access Protocol (v3): Attribute
+Syntax Definitions
+
+RFC 2253, Lightweight Directory Access Protocol (v3): UTF-8
+String Representation of Distinguished Names
+
+RFC 2254, The String Representation of LDAP Search Filters
+
+
+RFC 2255, The LDAP URL Format
+
+RFC 2256, A Summary of the X.500(96) User Schema for use
+with LDAPv3
+
+RFC 2829, Authentication Methods for LDAP
+
+
+RFC 2830, Lightweight Directory Access Protocol (v3): Extension
+for Transport Layer Security
+
+RFC 2849, The LDAP Data Interchange Format (LDIF) - Technical
+Specification
+
+RFC 3377, Lightweight Directory Access Protocol (v3): Technical
+Specification
+
+
+How This Book Is Organized
+
+This guide includes the following chapters.
+Chapter 1, Understanding LDAP describes LDAP and directory concepts.
+Chapter 2, Choosing a Client SDK covers what to consider when choosing a software development kit for building directory client applications.
+Chapter 3,
+Best Practices for Writing Client Applications reviews what and what
+not to do when building directory client applications.
+Chapter 1, Getting
+Started With Directory SDK for Java gets you started using &DirectorySDKForJava;
+
+Chapter 2, Writing an LDAP Client With Directory SDK for Java covers the basics of writing
+a directory client application
+Chapter 3, Using the LDAP Java Classes provides a look how &DirectorySDKForJava; is
+structured
+Chapter 4, Searching the Directory With Directory SDK for Java shows you how to write client
+application code for searching a directory
+
+Chapter 5, Adding, Updating, and Deleting Entries With Directory SDK for Java shows you how to
+write client application code for changing directory entries
+Chapter 6, Comparing Attribute Values With Directory SDK for Java shows you how to comparing attribute
+values in a directory with known values
+Chapter 7, LDAP URLs With Directory SDK for Java shows you how to handle LDAP URLs
+
+Chapter 8, Getting Server Information With Directory SDK for Java shows you how to retrieve
+information about the directory and directory service
+Chapter 9, SSL Connections With Directory SDK for Java shows you how to write client application code
+that connects to the directory over SSL
+Chapter 10, LDAP Controls With Directory SDK for Java shows you how to handle supported LDAP
+controls
+Chapter 11, SASL Authentication With Directory SDK for Java shows you how to connect to the directory
+by using SASL
+Chapter 12, Extended Operations With Directory SDK for Java shows you how to write client
+application code for handling LDAP v3 extended operations
+Chapter 13, Writing Asynchronous Clients With Directory SDK for Java shows you how to write applications
+that do not block waiting for results
+Appendix A, Creative Commons Attribution-ShareAlike 2.5 provides the full text of the license governing this guide
+
+
+
+Related Reading
+
+SLAMD Distributed Load Generation Engine
+The SLAMD Distributed Load Generation Engine (SLAMD) is a
+Java 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 . SLAMD
+is also available as a java.net project. See .
+
+Java Naming and Directory Interface
+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 . The JNDI Tutorial contains detailed
+descriptions and examples of how to use JNDI. This tutorial is at .
+
+Typographic Conventions
+The following table describes the typographic changes that are used
+in this book.
+
Typographic Conventions
+
+
+
+
+Typeface
+
+Meaning
+
+Example
+
+
+
+
+
+AaBbCc123
+
+The names of commands, files, and directories, and onscreen computer
+output
+
+Edit your .login file.
+Use ls to list all files.
+machine_name% you have mail.
+
+
+
+
+AaBbCc123
+
+What you type, contrasted with onscreen computer output
+
+machine_name%su
+Password:
+
+
+
+AaBbCc123
+
+A placeholder to be replaced with a real name or value
+
+The command to remove a file is rmfilename
+.
+
+
+
+AaBbCc123
+
+Book titles, new terms, and terms to be emphasized (note that some emphasized
+items appear bold online)
+
+Read Chapter 6 in the User's Guide.
+A cache is a copy that is stored locally.
+Do not save the file.
+
+
+
+
+
+Shell Prompts in Command Examples
+The following table shows default system prompts and superuser prompts.
+
Shell Prompts
+
+
+
+
+Shell
+
+Prompt
+
+
+
+
+
+C shell on UNIX and Linux systems
+
+machine_name%
+
+
+
+C shell superuser on UNIX and Linux systems
+
+machine_name#
+
+
+
+Bourne shell and Korn shell on UNIX and Linux systems
+
+$
+
+
+
+Bourne shell and Korn shell superuser on UNIX and Linux systems
+
+
+#
+
+
+
+Microsoft Windows command line
+
+C:\
+
+
+
+
+
+Symbol Conventions
+The following table explains symbols that might be used in this book.
+
Symbol Conventions
+
+
+
+
+Symbol
+
+Description
+
+Example
+
+Meaning
+
+
+
+
+
+[ ]
+
+Contains optional arguments and command options.
+
+ls [-l]
+
+The -l option is not required.
+
+
+
+{ | }
+
+Contains a set of choices for a required command option.
+
+-d {y|n}
+
+The -d option requires that you use either the
+y argument or the n argument.
+
+
+
+${ }
+
+Indicates a variable reference.
+
+${com.sun.javaRoot}
+
+References the value of the com.sun.javaRoot variable.
+
+
+
+
+-
+
+Joins simultaneous multiple keystrokes.
+
+Control-A
+
+Press the Control key while you press the A key.
+
+
+
++
+
+Joins consecutive multiple keystrokes.
+
+Ctrl+A+N
+
+Press the Control key, release it, and then press the subsequent keys.
+
+
+
+
+→
+
+Indicates menu item selection in a graphical user interface.
+
+
+File → New → Templates
+
+From the File menu, choose New. From the New submenu, choose Templates.
+
+
+
+
+
+
+
diff --git a/mozilla/directory/docs/ldapjdk/understanding-ldap.sgm b/mozilla/directory/docs/ldapjdk/understanding-ldap.sgm
new file mode 100644
index 00000000000..c438e95e1bc
--- /dev/null
+++ b/mozilla/directory/docs/ldapjdk/understanding-ldap.sgm
@@ -0,0 +1,274 @@
+
+Understanding LDAP
+
+LDAP
+
+Lightweight Directory Access Protocol
+LDAP
+Lightweight Directory Access Protocol (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.
+
+This chapter explains the LDAP protocol, and the concepts behind LDAP.
+This chapter covers the following topics:
+How Directory Services Work
+
+How LDAP Servers
+Organize Directories
+How LDAP
+Clients and Servers Work
+Understanding LDAP
+v3
+
+
+How Directory Services Work
+
+directory
+definition of
+
+entries
+definition of
+
+attributes
+definition of
+
+A directory consists of entries that
+contain descriptive information. For example, a directory might contain entries
+that describe people or network resources, such as printers or fax machines.
+The descriptive information is stored in the attributes 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.
+
+entries
+example of
+
+attributes
+example of
+The entry for Barbara Jensen might have the
+following attributes:
+cn: Barbara Jensen
+mail: babs@example.com
+telephoneNumber: 555-1212
+roomNumber: 3995
+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:
+cn: Barbara Jensen
+cn: Babs Jensen
+mail: babs@example.com
+telephoneNumber: 555-1212
+roomNumber: 3995
+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.
+
+directory service
+definition of
+A directory service 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.
+&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.
+
+LDAP servers
+
+LDAP clients
+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.
+
+LDAP servers
+example of
+
+LDAP clients
+example of
+&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, Solaris naming
+services, Messaging Server, Portal Server, NameFinder, and the Mozilla mail
+client. Such clients use &cnDirectoryServer; to find, update, and add information
+about users.
+How LDAP Servers Organize Directories
+
+LDAP
+organization of data
+
+entries
+organization in LDAP
+
+LDAP servers
+how data is organized
+
+Because LDAP is intended to be a global directory service, data is organized
+hierarchically, starting at a root and branching down into individual entries.
+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.
+Hierarchy of Entries in a Directory
+
+
+Simple directory information tree with two organizational
+unit entries and two user entries
+
+
+
+relative distinguished names (RDNs)
+definition of
+
+RDNs
+relative distinguished names (RDNs)
+distinguished names (DNs)
+definition of
+
+CNs
+common names (CNs)
+DNs
+distinguished names (DNs)
+common names (CNs)
+Each entry is uniquely identified by a distinguished
+name (DN). A DN includes a relative distinguished name (RDN),
+that uniquely identifies the entry at that hierarchical level. For example,
+bjensen and kjensen 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 ou=People,dc=example,dc=com
+. DC is short for domain component. The full
+DN for this example would be uid=bjensen,ou=People,dc=example,dc=com.
+Here, uid is the user ID of the entry. ou is
+short for organizational unit.
+
+LDAP servers
+how data is distributed
+The data stored in a directory can be distributed among several
+LDAP servers. For example, one LDAP server at Example.com might
+contain entries representing North American organizational units and employees,
+while another LDAP server might contain entries representing European organizational
+units and employees.
+
+LDAP servers
+how referrals work
+
+referrals
+Some LDAP servers are set up to refer requests to other LDAP servers.
+For example, if the LDAP server at Example.com 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.
+
+How LDAP Clients and Servers
+Work
+
+LDAP servers
+LDAP clients and
+
+LDAP clients
+LDAP servers and
+
+LDAP clients
+operations performed by
+
+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.
+
+An LDAP client can perform these operations, among others:
+Search for and retrieve entries from the directory
+
+Add new entries to the directory
+Update entries in the directory
+Delete entries from the directory
+Rename entries in the directory
+
+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.
+
+LDAP servers
+connecting with LDAP clients
+
+LDAP clients
+connecting with LDAP servers
+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.
+
+LDAP servers
+authentication
+
+LDAP clients
+authentication
+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.
+Understanding LDAP v3
+
+LDAP
+version 3
+
+RFC
+4511 specifies LDAP version 3. Use this version of the protocol when
+writing new client applications.
+Many LDAP servers continue to support LDAP version 2 for use with legacy
+clients. This version of the protocol is specified in RFC 1777.
+
+LDAP v3 includes new features not present in version 2:
+Clients and servers can specify controls that
+extend the functionality of an LDAP operation.
+Clients can request that the server perform extended
+operations, operations not included in the list of standard LDAP
+operations.
+Clients can use Simple Authentication and Security
+Layer (SASL) mechanisms to authenticate to the directory. SASL
+is specified in
+RFC 4422.
+Servers, known as Directory System Agents (DSAs),
+have DSA-specific entries (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.
+
+Servers make their schemas, which define
+the object classes, attributes, syntaxes, and matching rules enforced by the
+directory, available to clients through the root DSE.
+
+UTF-8
+support of
+Both client and server applications can support data in UTF-8.
+UTF-8 is a transformation format of the Universal Character Set
+standard. UTF-8 is specified in RFC 3269. With UTF-8, clients can request and receive
+data that is tagged with language information.
+
+
+