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 <filename>libldap</filename> 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 <function>ldap_delete_ext_s +</function> 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 <function>ldap_delete_ext +</function> 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++; +} + + +<literal>while</literal> Loop +This example sets up a while loop to call your function +when you are not checking for the server’s response. +Using a <literal>while</literal> 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 <function>ldap_parse_result</function> 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 <structname>LDAPMessage</structname> 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 <structname>LDAPMessage</structname> 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 <function> +ldap_get_option</function> + +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 <structname>LDAPMessage</structname> 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 <function>ldap_parse_result +</function> 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 <structname>LDAPMessage</structname> 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 <structname>LDAP</structname> 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 <function>ldap_get_lderrno</function> 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 <structname>LDAP</structname> 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 ); + +<structname> +LDAP_CALL</structname> and <structname>LDAP_CALLBACK</structname> 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. +<structname>LDAPControl</structname> 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. +<function>ldap_create_persistentsearch_control +</function> 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_CALLBACK LDAP_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_CALLBACK LDAP_CF_SEARCH_CALLBACKLDAP_CF_COMPARE_CALLBACK +LDAP_CF_ADD_CALLBACKLDAP_CF_DELETE_CALLBACK LDAP_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 + + + + + +LDAPHostEnt LDAP_DNSFN_GETHOSTBYNAME LDAP_DNSFN_GETHOSTBYADDR ldap_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_CALLBACK LDAP_IOF_CONNECT_CALLBACK LDAP_IOF_IOCTL_CALLBACK + LDAP_IOF_READ_CALLBACK LDAP_IOF_SELECT_CALLBACK LDAP_IOF_SOCKET_CALLBACK + LDAP_IOF_SSL_ENABLE_CALLBACK LDAP_IOF_WRITE_CALLBACK ldap_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. +<structname>berval</structname> + +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. +<structname>berval</structname> Definition +typedef struct berval { + unsigned long bv_len; + char *bv_val; +}; + +<structname>berval</structname> Field +Descriptions + + + + +Field + +What It Contains + + + + + +bv_len + +The length of the data in bytes. + + + +bv_val + +A pointer to the binary data itself. + + + +
+
+
+<structname>BerElement</structname> + +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. + + +<structname>FriendlyMap</structname> +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. + + + + +<structname>LDAP</structname> + +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. + +<structname>LDAPAPIFeatureInfo</structname> + +C SDK data types +LDAPAPIFeatureInfo + +LDAPAPIFeatureInfo + +LDAPAPIFeatureInfo is a structure that represents +information about the extended features of &DirectorySDKForC;. +<structname>LDAPAPIFeatureInfo</structname> 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 <structname>LDAPAPIFeatureInfo +</structname> +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 +<structname>LDAPAPIFeatureInfo</structname> 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. + + + +
+
+
+<structname>LDAPAPIInfo</structname> + +C SDK data types +LDAPAPIInfo + +LDAPAPIInfo + +LDAPAPIInfo is a structure that represents information +about the API and supported extensions. +<structname>LDAPAPIInfo</structname> 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 <structname>LDAPAPIInfo +</structname> +LDAPAPIInfo ldai; + ldai.ldapai_info_version = LDAP_API_INFO_VERSION; + if ( ldap_get_option( NULL, LDAP_OPT_API_INFO, &ldia ) == 0 ) ... + +Parameters +<structname>LDAPAPIInfo</structname> 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. + + + +
+
+
+<structname>ldap_cache_fns</structname> + +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. + +<structname>LDAP_CALLOC_CALLBACK</structname> + +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 + +<structname>LDAP_CANCELPROC_CALLBACK</structname> + +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 + +<structname>LDAP_CF_ADD_CALLBACK</structname> + +C SDK data types +LDAP_CF_ADD_CALLBACK + +LDAP_CF_ADD_CALLBACK + +This callback function prototype of ldap_cache_fns + is deprecated. +<structname>LDAP_CF_BIND_CALLBACK</structname> + +C SDK data types +LDAP_CF_BIND_CALLBACK + +LDAP_CF_BIND_CALLBACK + +This callback function prototype of ldap_cache_fns + is deprecated. +<structname>LDAP_CF_COMPARE_CALLBACK</structname> + +C SDK data types +LDAP_CF_COMPARE_CALLBACK + +LDAP_CF_COMPARE_CALLBACK + +This callback function prototype of ldap_cache_fns + is deprecated. +<structname>LDAP_CF_DELETE_CALLBACK</structname> + +C SDK data types +LDAP_CF_DELETE_CALLBACK + +LDAP_CF_DELETE_CALLBACK + +This callback function prototype of ldap_cache_fns + is deprecated. +<structname>LDAP_CF_FLUSH_CALLBACK</structname> + +C SDK data types +LDAP_CF_FLUSH_CALLBACK + +LDAP_CF_FLUSH_CALLBACK + +This callback function prototype of ldap_cache_fns + is deprecated. +<structname>LDAP_CF_MODIFY_CALLBACK</structname> + +C SDK data types +LDAP_CF_MODIFY_CALLBACK + +LDAP_CF_MODIFY_CALLBACK + +This callback function prototype of ldap_cache_fns + is deprecated. +<structname>LDAP_CF_MODRDN_CALLBACK</structname> + +C SDK data types +LDAP_CF_MODRDN_CALLBACK + +LDAP_CF_MODRDN_CALLBACK + +This callback function prototype of ldap_cache_fns + is deprecated. +<structname>LDAP_CF_RESULT_CALLBACK</structname> + +C SDK data types +LDAP_CF_RESULT_CALLBACK + +LDAP_CF_RESULT_CALLBACK + +This callback function prototype of ldap_cache_fns + is deprecated. +<structname>LDAP_CF_SEARCH_CALLBACK</structname> + +C SDK data types +LDAP_CF_SEARCH_CALLBACK + +LDAP_CF_SEARCH_CALLBACK + +This callback function prototype of ldap_cache_fns + is deprecated. +<structname>LDAP_CF_UNBIND_CALLBACK</structname> + +C SDK data types +LDAP_CF_UNBIND_CALLBACK + +LDAP_CF_UNBIND_CALLBACK + +This callback function prototype of ldap_cache_fns + is deprecated. +<structname>LDAP_CMP_CALLBACK</structname> + +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. +<structname>LDAP_CMP_CALLBACK</structname> Prototype +typedef int (LDAP_C LDAP_CALLBACK + LDAP_CMP_CALLBACK)(const char*, const char*); + +See Also +ldap_sort_entries, ldap_multisort_entries. + +<structname>LDAPControl</structname> + +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 <structname>LDAPControl</structname> +typedef struct ldapcontrol { + char *ldctl_oid; + struct berval ldctl_value; + char ldctl_iscritical; +} LDAPControl; + +<structname>LDAPControl</structname> 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. + + + + + +
+
+<structname>LDAP_DNSFN_GETHOSTBYADDR</structname> + +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. +<structname>LDAP_DNSFN_GETHOSTBYADDR</structname> 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 ); + + + +<structname>LDAP_DNSFN_GETHOSTBYNAME</structname> + +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. +<structname>LDAP_DNSFN_GETHOSTBYNAME</structname> 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 ); + + + +<structname>ldap_dns_fns</structname> + +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. + +<structname>ldap_dns_fns</structname> Definition +struct ldap_dns_fns { + void *lddnsfn_extradata; + int lddnsfn_bufsize; + LDAP_DNSFN_GETHOSTBYNAME *lddnsfn_gethostbyname; + LDAP_DNSFN_GETHOSTBYADDR *lddnsfn_gethostbyaddr; +}; + +<structname>ldap_dns_fns</structname> 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. + + + +
+
+
+<structname>ldap_extra_thread_fns</structname> + +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. +<structname>ldap_extra_thread_fns</structname> 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; +}; + +<structname>ldap_extra_thread_fns</structname> 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 . + + + +
+
+<structname>LDAPFiltDesc</structname> + +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. + +<structname>LDAPFiltInfo</structname> + +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. +<structname>LDAPFiltInfo</structname> 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; + +<structname>LDAPFilterInfo</structname> 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 <structname>LDAPFiltInfo</structname> 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 +
+
+<structname>LDAP_FREE_CALLBACK</structname> + +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 + +<structname>LDAPHostEnt</structname> + +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. +<structname>LDAPHostEnt</structname> Definition +typedef struct LDAPHostEnt { + char *ldaphe_name; + char **ldaphe_aliases; + int ldaphe_addrtype; + int ldaphe_length; + char **ldaphe_addr_list; +} LDAPHostEnt; + +<structname>LDAPHostEnt</structname> 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 +
+<structname>LDAP_IOF_CLOSE_CALLBACK</structname> + +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. +<structname>LDAP_IOF_CLOSE_CONNECT_CALLBACK</structname> Prototype + +typedef int (LDAP_C LDAP_CALLBACK + LDAP_IOF_CLOSE_CALLBACK )( LBER_SOCKET ); + + + +<structname>LDAP_IOF_CONNECT_CALLBACK</structname> + +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. +<structname>LDAP_IOF_CONNECT_CALLBACK</structname> Prototype + +typedef int (LDAP_C LDAP_CALLBACK + LDAP_IOF_CONNECT_CALLBACK )( LBER_SOCKET, + struct sockaddr *, int ); + + + +<structname>LDAP_IOF_IOCTL_CALLBACK</structname> + +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. +<structname>LDAP_IOF_IOCTL_CALLBACK</structname> Prototype + +typedef int (LDAP_C LDAP_CALLBACK + LDAP_IOF_IOCTL_CALLBACK)( LBER_SOCKET, int, ... ); + + + +<structname>LDAP_IOF_READ_CALLBACK</structname> + +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. +<structname>LDAP_IOF_READ_CALLBACK</structname> Prototype + +typedef int (LDAP_C LDAP_CALLBACK + LDAP_IOF_READ_CALLBACK)( LBER_SOCKET, void *, int ); + + + +<structname>LDAP_IOF_SELECT_CALLBACK</structname> + +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. +<structname>LDAP_IOF_SELECT_CALLBACK</structname> Prototype + +typedef int (LDAP_C LDAP_CALLBACK +LDAP_IOF_SELECT_CALLBACK)( int, fd_set *, fd_set *, + fd_set *, struct timeval * ); + + + +<structname>LDAP_IOF_SOCKET_CALLBACK</structname> + +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. +<structname>LDAP_IOF_SOCKET_CALLBACK</structname> Prototype + +typedef LBER_SOCKET (LDAP_C LDAP_CALLBACK + LDAP_IOF_SOCKET_CALLBACK)( int, int, int ); + + + +<structname>LDAP_IOF_SSL_ENABLE_CALLBACK</structname> + +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. +<structname>LDAP_IOF_SSL_ENABLE_CALLBACK</structname> Prototype + +typedef int (LDAP_C LDAP_CALLBACK + LDAP_IOF_SSL_ENABLE_CALLBACK )( LBER_SOCKET ); + + + +<structname>LDAP_IOF_WRITE_CALLBACK</structname> + +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. +<structname>LDAP_IOF_WRITE_CALLBACK</structname> Prototype + +typedef int (LDAP_C LDAP_CALLBACK LDAP_IOF_WRITE_CALLBACK) + ( LBER_SOCKET, const void *, int ); + + + +<structname>ldap_io_fns</structname> + +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). +<structname>ldap_io_fns</structname> 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; +}; + +<structname>ldap_io_fns</structname> 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 + . + + + +
+<structname>LDAP_KEYCMP_CALLBACK</structname> + +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 +
+<structname>LDAP_KEYFREE_CALLBACK</structname> + +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. + +<structname>LDAP_KEYGEN_CALLBACK</structname> + +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. + +<structname>LDAP_MALLOC_CALLBACK</structname> + +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 + +<structname>ldap_memalloc_fns</structname> + +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 <structname>ldap_memalloc_fns +</structname> +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 + + + + +<structname>LDAPMemCache</structname> + +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 <structname> +LDAPMemCache</structname> 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. + + + + +
+
+<structname>LDAPMessage</structname> + +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. +
+<structname>LDAPMod</structname> + +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. +<structname>LDAPMod</structname> 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; + +<structname>LDAPMod</structname> 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 <structname>LDAPMod</structname> 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 ); +} +... + + +
+<structname>LDAPpwdpolicy</structname> + +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. + +<structname>LDAPpwdpolicy</structname> 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; +<structname>LDAPpwdpolicy</structname> 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. + +
+<structname>LDAP_REALLOC_CALLBACK</structname> + +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 + +<structname>LDAP_REBINDPROC_CALLBACK</structname> + +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. +<structname>LDAP_REBINDPROC_CALLBACK</structname> 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 + +<structname>LDAPsortkey</structname> + +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 +<structname>LDAPsortkey</structname> Definition +typedef struct LDAPsortkey { + char *sk_attrtype; + char *sk_matchruleoid; + int sk_reverseorder; +} LDAPsortkey; + +<structname>LDAPsortkey</structname> 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. +
+
+<structname>LDAP_TF_GET_ERRNO_CALLBACK</structname> + +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 +<structname>LDAP_TF_GET_ERRNO_CALLBACK</structname> Prototype + +typedef int (LDAP_C LDAP_CALLBACK + LDAP_TF_GET_ERRNO_CALLBACK) ( void ); + + + +<structname>LDAP_TF_GET_LDERRNO_CALLBACK</structname> + +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. + +<structname>LDAP_TF_GET_LDERRNO_CALLBACK</structname> Prototype + +typedef int (LDAP_C LDAP_CALLBACK + LDAP_TF_GET_LDERRNO_CALLBACK)( char **, char **, void * ); + + + +<structname>LDAP_TF_SET_ERRNO_CALLBACK</structname> + +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 +<structname>LDAP_TF_SET_ERRNO_CALLBACK</structname> Prototype + +typedef void (LDAP_C LDAP_CALLBACK + LDAP_TF_SET_ERRNO_CALLBACK)( int ); + + + +<structname>LDAP_TF_SET_LDERRNO_CALLBACK</structname> + +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. +<structname>LDAP_TF_SET_LDERRNO_CALLBACK</structname> Prototype + +typedef void (LDAP_C LDAP_CALLBACK + LDAP_TF_SET_LDERRNO_CALLBACK)( int, char *, char *, void * ); + + + +<structname>LDAP_TF_MUTEX_ALLOC_CALLBACK</structname> + +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 +<structname>LDAP_TF_MUTEX_ALLOC_CALLBACK</structname> Prototype + +typedef void *(LDAP_C LDAP_CALLBACK + LDAP_TF_MUTEX_ALLOC_CALLBACK)( void ); + + +See Also +ldap_thread_fns + +<structname>LDAP_TF_MUTEX_FREE_CALLBACK</structname> + +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 +<structname>LDAP_TF_MUTEX_FREE_CALLBACK</structname> Prototype + +typedef void (LDAP_C LDAP_CALLBACK + LDAP_TF_MUTEX_FREE_CALLBACK)( void * ); + + +See Also +ldap_thread_fns + +<structname>LDAP_TF_MUTEX_LOCK_CALLBACK</structname> + +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 +<structname>LDAP_TF_MUTEX_LOCK_CALLBACK</structname> Prototype + +typedef int (LDAP_C LDAP_CALLBACK + LDAP_TF_MUTEX_LOCK_CALLBACK)( void * ); + + +See Also +ldap_thread_fns + +<structname>LDAP_TF_MUTEX_TRYLOCK_CALLBACK</structname> + +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;. + +<structname>LDAP_TF_MUTEX_UNLOCK_CALLBACK</structname> + +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 +<structname>LDAP_TF_MUTEX_UNLOCK_CALLBACK</structname> Prototype + +typedef int (LDAP_C LDAP_CALLBACK + LDAP_TF_MUTEX_UNLOCK_CALLBACK)( void * ); + + +See Also +ldap_thread_fns + +<structname>LDAP_TF_SEMA_ALLOC_CALLBACK</structname> + +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;. + +<structname>LDAP_TF_SEMA_FREE_CALLBACK</structname> + +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;. + + +<structname>LDAP_TF_SEMA_POST_CALLBACK</structname> + +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;. + +<structname>LDAP_TF_SEMA_WAIT_CALLBACK</structname> + +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;. + + +<structname>LDAP_TF_THREADID_CALLBACK</structname> + +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 +<structname>LDAP_TF_THREADID_CALLBACK</structname> Prototype + +typedef void *(LDAP_C LDAP_CALLBACK + LDAP_TF_THREADID_CALLBACK)( void ); + + +See Also +ldap_thread_fns + +<structname>ldap_thread_fns</structname> + +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 +<structname>ldap_thread_fns</structname> 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; +}; + +<structname>ldap_thread_fns</structname> 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. + + + +
+
+
+<structname>LDAPURLDesc</structname> + +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. +<structname>LDAPURLDesc</structname> 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 + +<structname>LDAPURLDesc</structname> 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. +<structname>LDAPURLDesc +</structname> Parsed URL Values + + + + +Component + +Value + + + + + +ludpp->lud_host + +ldap.example.com + + + +ludpp->lud_port + +5000 + + + +ludpp->lud_dn + +dc=example,dc=com + + + +ludpp->lud_attrs[0] + +cn + + + +ludpp->lud_attrs[1] + +mail + + + +ludpp->lud_attrs[2] + +telephoneNumber + + + +ludpp->lud_attrs[3] + +NULL + + + +ludpp->lud_scope + +LDAP_SCOPE_SUBTREE + + + +ludpp->lud_filter + +(sn=Jensen) + + + +
+To free the LDAPURLDesc structure, call the ldap_free_urldesc routine.
+
+<structname>LDAPuserstatus</structname> + +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. + +<structname>LDAPuserstatus</structname> 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; +<structname>LDAPuserstatus</structname> 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. + +
+<structname>LDAP_VALCMP_CALLBACK</structname> + +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. +<structname>LDAP_VALCMP_CALLBACK</structname> 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 + +<structname>LDAPVersion</structname> + +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. +<structname>LDAPVersion</structname> Definition +typedef struct _LDAPVersion { + int sdk_version; + int protocol_version; + int SSL_version; + int security_level; +} LDAPVersion; + +<structname>LDAPVersion</structname> 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 + . + + + +
+
+
+<structname>LDAPVirtualList</structname> + +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. + + +<structname>LDAPVirtualList</structname> 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; + +<structname>LDAPVirtualList</structname> 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. + + + +
+
+
+<structname>LDAP_X_EXTIOF_CLOSE_CALLBACK</structname> +This specifies the prototype for an extended I/O callback function to +close a socket connection. +Description +<structname>LDAP_X_EXTIOF_CLOSE_CALLBACK</structname> Prototype + +typedef int (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_CLOSE_CALLBACK )( + int s, void *arg ); + + +See Also +ldap_x_ext_io_fns + +<structname>LDAP_X_EXTIOF_CONNECT_CALLBACK</structname> +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 + . +<structname>LDAP_X_EXTIOF_CONNECT_CALLBACK</structname> 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 + +<structname>LDAP_X_EXTIOF_DISPOSEHANDLE_CALLBACK</structname> +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. +<structname>LDAP_X_EXTIOF_DISPOSEHANDLE_CALLBACK</structname> Prototype + +typedef void (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_DISPOSEHANDLE_CALLBACK)( + LDAP *ld, void *arg ); + + +See Also +ldap_x_ext_io_fns + +<structname>LDAP_X_EXTIOF_NEWHANDLE_CALLBACK</structname> +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. +<structname>LDAP_X_EXTIOF_NEWHANDLE_CALLBACK</structname> Prototype + +typedef int (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_NEWHANDLE_CALLBACK)( + LDAP *ld, void *arg ); + + +See Also +ldap_x_ext_io_fns + +<structname>ldap_x_ext_io_fns</structname> +This is a structure to hold extended I/O function pointers. +<structname>ldap_x_ext_io_fns</structname> 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) + + +<structname>LDAP_X_EXTIOF_POLL_CALLBACK</structname> +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. +<structname>LDAP_X_EXTIOF_POLL_CALLBACK</structname> 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 + +<structname>ldap_x_hostlist_status</structname> +This structure contains utility functions for parsing space-separated +host lists. +Description +<structname>ldap_x_hostlist_status</structname> 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 ); + + + +<structname>LDAP_X_PollFD</structname> +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 +<structname>LDAP_X_PollFD</structname> 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 + pattern1 delimiters +filter1-1 desc1-1 [scope] + filter1-2 desc1-2 [ +scope] + pattern2 delimiters +filter2-1 desc2-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. +Functions to Encode +and Decode BER + + + + +Function + +Description + + + + + +ber_alloc, ber_alloc_t +, ber_sockbuf_alloc, ber_special_alloc + +Allocate new BER elements. + + + +ber_bvecfree, ber_bvfree +, ber_free, ber_sockbuf_free +, ber_sockbuf_free_data + +Free allocated memory. + + + +ber_bvdup, ber_dup + + +Duplicate BER structures. + + + +ber_init, ber_init_w_nullchar + + +Construct new structures. + + + +ber_get_boolean, +ber_get_int, ber_get_next, ber_get_next_buffer, ber_get_next_buffer_ext +, ber_get_null, +ber_get_option, ber_get_stringa, ber_get_stringal, ber_get_stringb + + +Retrieve miscellaneous information. + + + +ber_put_bitstring, ber_put_boolean, ber_put_enum, ber_put_int, ber_put_null, ber_put_ostring, ber_put_seq, ber_put_set, ber_put_string + + +Write miscellaneous information. + + + +ber_first_element, ber_next_element, ber_peek_tag +, ber_skip_tag + +Target specific elements and tags. + + + +ber_set_option, ber_set_string_translators + + +Set session parameters. + + + +ber_flatten, ber_printf +, ber_read, ber_reset +, ber_scanf, ber_sockbuf_get_option +, ber_sockbuf_set_option, ber_start_seq, ber_start_seq, ber_start_set, ber_svecfree, ber_write + +Miscellaneous functions. + + + +
+
+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_dn ldap_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. + +Extensions Provided + + + + +Function + +Description + + + + + +ldap_x_hostlist_first, ldap_x_hostlist_next, ldap_x_hostlist_status + + +Utility functions for parsing space-separated host lists. + + + +
+
+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 <acronym>NSPR</acronym> + +C SDK +functions +for NSPR + +The functions listed in Table 21–17 + tie libldap into Netscape Portable Runtime, +NSPR. +Functions to Work with <acronym> +NSPR</acronym> + + + + +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. +Outdated LDAP v2 Functions +and New Equivalents + + + + +LDAP v2 Functions + +LDAP v3 Equivalent + + + + + +ldap_abandon + +ldap_abandon_ext + + + +ldap_add, ldap_add_s + + +ldap_add_ext, ldap_add_ext_s + + + + +ldap_compare, ldap_compare_s + + +ldap_compare_ext, +ldap_compare_ext_s + + + +ldap_delete, ldap_delete_s + + +ldap_delete_ext, +ldap_delete_ext_s + + + +ldap_modify, ldap_modify_s + + +ldap_modify_ext, +ldap_modify_ext_s + + + +ldap_modrdn2, ldap_modrdn2_s + + +ldap_rename, ldap_rename_s + + + + +ldap_search, ldap_search_s +, ldap_search_st + +ldap_search_ext, +ldap_search_ext_s, ldap_search_ext_s - +use timeout argument + + + +ldap_unbind, ldap_unbind_s + + +ldap_unbind_ext replaces both forms +which are identical besides the suffix. + + + +
+
+
+Functions Alphabetically + +C SDK +functions +alphabetically + +functions +C SDK +C SDK, functions +<function>ber_alloc</function> +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 + + +<function>ber_alloc_t</function> +The ber_alloc_t function constructs and returns +a BerElement structure. +Syntax +#include <lber.h> +BerElement* ber_alloc_t( int options ); + +Parameters +<function>ber_alloc_t</function> 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 + +
+<function>ber_bvecfree</function> +The ber_bvecfree function frees an array of berval structures. +Syntax +#include <lber.h> +void ber_bvecfree( struct berval **bv ); + +Parameters +<function>ber_bvecfree</function> 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 +
+<function>ber_bvdup</function> +The ber_bvdup function returns a copy of a berval structure. +Syntax +#include <lber.h> +berval* ber_bvdup( const struct berval *bv ); + +Parameters +<function>ber_bvdup</function> 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 +. +
+<function>ber_bvfree</function> +The ber_bvfree function frees a berval structure. +Syntax +#include <lber.h> + void ber_bvfree( struct berval *bv ); + +Parameters +<function>ber_bvfree</function> 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 + +
+<function>ber_dup</function> +The ber_dup function returns a copy of a BerElement structure. +Syntax +#include <lber.h> +BerElement* ber_dup( BerElement *ber ); + +Parameters +<function>ber_dup</function> 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. +
+<function>ber_first_element</function> +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 +<function>ber_first_element</function> 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 +
+<function>ber_flatten</function> +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 +<function>ber_flatten</function> 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 +
+<function>ber_free</function> +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 +<function>ber_free</function> 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 <function>ber_free</function> +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 +
+<function>ber_get_boolean</function> +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 +<function>ber_get_boolean</function> 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. +
+<function>ber_get_int</function> +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 +<function>ber_get_int</function> 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. +
+<function>ber_get_next</function> +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 +<function>ber_get_next</function> 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. + +
+<function>ber_get_next_buffer</function> +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. +<function>ber_get_next_buffer_ext</function> +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 +<function>ber_get_next_buffer_ext</function> 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. + + + +
+
+
+<function>ber_get_null</function> +The ber_get_null function is used to read a NULL + element. +Syntax +#include <lber.h> +unsigned long ber_get_null( BerElement *ber ); + +Parameters +<function>ber_get_null</function> Function +Parameter + + + + +Parameter + +Description + + + + + +ber + +Pointer to a BerElement. + + + +
+
+Returns +Returns the tag of the element it skips over. +
+<function>ber_get_option</function> +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 ); + + +<function>ber_get_stringa</function> +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 ); + + +<function>ber_get_stringal</function> +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. + +<function>ber_get_stringb</function> +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. + +<function>ber_init</function> +The ber_init function constructs a new BerElement. +Syntax +#include <lber.h> +BerElement * ber_init( const struct berval *bv ); + +Parameters +<function>ber_init</function> 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. + + + +
+<function>ber_init_w_nullchar</function> +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 ); + + +<function>ber_next_element</function> +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 +<function>ber_next_element</function> 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 +
+<function>ber_peek_tag</function> +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 +<function>ber_peek_tag</function> 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. +
+<function>ber_printf</function> +The ber_printf function encodes a BER element. +Syntax +#include <lber.h> +ber_printf( BerElement *ber, const char *fmt, ... ); + +Parameters +<function>ber_printf</function> 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. +
+<function>ber_put_bitstring</function> +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. + +<function>ber_put_boolean</function> +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. + +<function>ber_put_enum</function> +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 ); + + +<function>ber_put_int</function> +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 ); + + +<function>ber_put_null</function> +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 ); + + +<function>ber_put_ostring</function> +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 ); + + +<function>ber_put_seq</function> +The ber_put_seq function puts a sequence to a BerElement. +Syntax +#include <lber.h> +int ber_put_seq( BerElement *ber ); + +Parameters +<function>ber_put_seq</function> 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 +. +
+<function>ber_put_set</function> +The ber_put_set function puts a set to a BerElement. +Syntax +#include <lber.h> +int ber_put_set( BerElement *ber ); + +Parameters +<function>ber_put_set</function> 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. + +
+<function>ber_put_string</function> +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 ); + + +<function>ber_read</function> +Syntax +#include <lber.h> +long ber_read( BerElement *ber, char *buf, unsigned long len ); + + +<function>ber_reset</function> +Syntax +#include <lber.h> +void ber_reset( BerElement *ber, int was_writing ); + + +<function>ber_scanf</function> +The ber_scanf function decodes a BerElement. +Syntax +#include <lber.h> +unsigned long ber_scanf( BerElement *ber, const char *fmt, ... ); + +Parameters +<function>ber_scanf</function> 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 +
+<function>ber_set_option</function> +Syntax +#include <lber.h> +int ber_set_option( BerElement *ber, int option, void *value ); + + +<function>ber_set_string_translators</function> +Syntax +#include <lber.h> +unsigned long ber_skip_tag( BerElement *ber, unsigned long *len ); + + +<function>ber_skip_tag</function> +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 +<function>ber_skip_tag</function> 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 +
+<function>ber_sockbuf_alloc</function> +Syntax +#include <lber.h> +Sockbuf* ber_sockbuf_alloc( void ); + + +<function>ber_sockbuf_free</function> +Syntax +#include <lber.h> +void ber_sockbuf_free( Sockbuf* p ); + + +<function>ber_sockbuf_free_data</function> +Syntax +#include <lber.h> +void ber_sockbuf_free_data(Sockbuf *p); + + +<function>ber_sockbuf_get_option</function> +Syntax +#include <lber.h> +int ber_sockbuf_get_option( Sockbuf *sb, int option, void *value ); + + +<function>ber_sockbuf_set_option</function> +Syntax +#include <lber.h> +int ber_sockbuf_set_option( Sockbuf *sb, int option, void *value ); + + +<function>ber_special_alloc</function> +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. + + +<function>ber_special_free</function> +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 + +<function>ber_stack_init</function> +Syntax +#include <lber.h> +int) LDAP_CALL ber_stack_init(BerElement *ber, int options, + char * buf, size_t size); + + +<function>ber_start_seq</function> +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 + +<function>ber_start_set</function> +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 + +<function>ber_svecfree</function> +Syntax +#include <lber.h> +void ber_svecfree( char **vals ); + + +<function>ber_write</function> +Syntax +#include <lber.h> +long ber_write( BerElement *ber, char *buf, + unsigned long len, int nosos ); + + +<function>ldap_abandon</function> +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 +<function>ldap_abandon</function> 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 <function>ldap_url_search</function> 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 +
+<function>ldap_abandon_ext</function> +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 +<function>ldap_abandon_ext</function> 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 <function>ldap_abandon_ext</function> +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 + +
+<function>ldap_add</function> +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 +<function>ldap_add</function> 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 <function>ldap_add</function> +#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 +
+<function>ldap_add_ext</function> +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 +<function>ldap_add_ext</function> 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 +
+<function>ldap_add_ext_s</function> +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 +<function>ldap_add_ext_s</function> 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 + +
+<function>ldap_add_s</function> +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 +<function>ldap_add_s</function> 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 <function>ldap_add_s</function> +#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 +
+<function>ldap_ber_free</function> +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 +<function>ldap_ber_free</function> 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 +
+<function>ldap_bind</function> +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 +<function>ldap_bind</function> 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 +
+<function>ldap_bind_s</function> +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 +<function>ldap_bind_s</function> 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 +
+<function>ldap_build_filter</function> +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 + +<function>ldap_cache_flush</function> +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 + + +<function>ldap_charray_add</function> +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 + . +<function>ldap_charray_dup</function> +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 + . + +<function>ldap_charray_free</function> +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 + . +<function>ldap_charray_inlist</function> +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 + . + +<function>ldap_charray_merge</function> +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 + . +<function>ldap_charray_position</function> +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 + . + +<function>ldap_compare</function> +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 +<function>ldap_compare</function> 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 <function>ldap_compare</function> +#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 +
+<function>ldap_compare_ext</function> +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 +<function>ldap_compare_ext</function> 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 + +
+<function>ldap_compare_ext_s</function> +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 +<function>ldap_compare_ext_s</function> 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 +
+<function>ldap_compare_s</function> +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 +<function>ldap_compare_s</function> 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 <function>ldap_compare_s</function> +#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 +
+<function>ldap_control_free</function> +The ldap_control_free function frees an LDAPControl structure from memory. +Syntax +#include <ldap.h> +void ldap_control_free( LDAPControl *ctrl ); + +Parameters +<function>ldap_control_free</function> 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 +
+<function>ldap_controls_free</function> +The ldap_controls_free function frees an array +of LDAPControl structures from memory. +Syntax +#include <ldap.h> +void ldap_controls_free( LDAPControl **ctrls ); + +Parameters +<function>ldap_controls_free</function> 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 +
+<function>ldap_count_entries</function> +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 +<function>ldap_count_entries</function> 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 +
+<function>ldap_count_messages</function> +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 +<function>ldap_count_messages</function> 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 +
+<function>ldap_count_references</function> +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 +<function>ldap_count_references</function> 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 + +
+<function>ldap_count_values</function> +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 +<function>ldap_count_values</function> Function +Parameter + + + + +Parameter + +Description + + + + + +values + +Array of values. + + + +
+
+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 <function>ldap_count_values</function> +#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 +
+<function>ldap_count_values_len</function> +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 +<function>ldap_count_values_len</function> Function +Parameter + + + + +Parameter + +Description + + + + + +values + +Array of berval structures. + + + + +
+
+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 <function>ldap_count_values_len +</function> +#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 +
+<function>ldap_create_authzid_control +</function> +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 +<function>ldap_create_authzid_control</function> 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 + +
+<function>ldap_create_filter</function> +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 +<function>ldap_create_filter</function> 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 <function> +ldap_create_filter</function> +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 +
+<function>ldap_create_geteffectiveRights_control</function> +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 +<function>ldap_create_geteffectiveRights_control +</function> 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. + + + + +
+
+
+<function>ldap_create_persistentsearch_control</function> +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 +<function>ldap_create_persistentsearch_control +</function> 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 +
+<function>ldap_create_pwdpolicy_control +</function> +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 +<function>ldap_create_pwdpolicy_control</function> 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 +
+<function>ldap_create_proxiedauth_control</function> +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 +<function>ldap_create_proxiedauth_control +</function> 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). + + +
+<function>ldap_create_proxyauth_control</function> +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 +<function>ldap_create_proxyauth_control</function> 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 +
+<function>ldap_create_sort_control</function> +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 +<function>ldap_create_sort_control</function> 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 +
+<function>ldap_create_sort_keylist</function> +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 +<function>ldap_create_sort_keylist</function> 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 +
+<function>ldap_create_userstatus_control +</function> +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 +<function>ldap_create_userstatus_control</function> 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 + +
+<function>ldap_create_virtuallist_control</function> +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 +<function>ldap_create_virtuallist_control +</function> 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 + +
+<function>ldap_delete</function> +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 +<function>ldap_delete</function> 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 <function>ldap_delete</function> +#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 +
+<function>ldap_delete_ext</function> +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 +<function>ldap_delete_ext</function> 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 + +
+<function>ldap_delete_ext_s</function> +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 +<function>ldap_delete_ext_s</function> 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 +
+<function>ldap_delete_s</function> +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 +<function>ldap_delete_s</function> 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 <function>ldap_delete_s</function> +#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 +
+<function>ldap_dn2ufn</function> +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 +<function>ldap_dn2ufn</function> 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 (). + +
+<function>ldap_entry2html</function> +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 +<function>ldap_entry2html</function> 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 +
+<function>ldap_entry2html_search</function> +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 +<function>ldap_entry2html_search</function> 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 + +
+<function>ldap_entry2text</function> +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 +<function>ldap_entry2text</function> 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 +
+<function>ldap_entry2text_search</function> +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 +<function>ldap_entry2text_search</function> 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 +
+<function>ldap_err2string</function> +The ldap_err2string function returns the corresponding +error message for an error code. +Syntax +#include <ldap.h> + char * ldap_err2string( int err ); + +Parameters +<function>ldap_err2string</function> 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 <function>ldap_err2string</function> +#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 +
+<function>ldap_explode_dn</function> +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 +<function>ldap_explode_dn</function> 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 +
+<function>ldap_explode_dns</function> +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 +<function>ldap_explode_dns</function> 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. + + + +
+<function>ldap_explode_rdn</function> +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 +<function>ldap_explode_rdn</function> 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 +
+<function>ldap_extended_operation</function> +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 +<function>ldap_extended_operation</function> 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 +
+<function>ldap_extended_operation_s</function> +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 +<function>ldap_extended_operation_s</function> 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 +
+<function>ldap_first_attribute</function> +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 +<function>ldap_first_attribute</function> 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 <function>ldap_first_attribute +</function> +#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 +
+<function>ldap_first_disptmpl</function> +The ldap_first_disptmpl function returns the first +template in a list. +Syntax +#include <disptmpl.h> + ldap_first_disptmpl( struct ldap_disptmpl *tmpllist ); + +Parameters +<function>ldap_first_disptmpl</function> 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 + +
+<function>ldap_first_entry</function> +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 +<function>ldap_first_entry</function> 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 +
+<function>ldap_first_message</function> +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 +<function>ldap_first_message</function> 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 +
+<function>ldap_first_reference</function> +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 +<function>ldap_first_reference</function> 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 + +
+<function>ldap_first_searchobj</function> +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 +<function>ldap_first_searchobj</function> 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 +
+<function>ldap_first_tmplcol</function> +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 +<function>ldap_first_tmplcol</function> 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 +
+<function>ldap_first_tmplrow</function> +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 +<function>ldap_first_tmplrow</function> 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 +
+<function>ldap_free_friendlymap</function> +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 +<function>ldap_free_friendlymap</function> 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 <function>ldap_free_friendlymap +</function> +#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 +
+<function>ldap_free_searchprefs</function> +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 +<function>ldap_free_searchprefs</function> 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 +
+<function>ldap_free_sort_keylist</function> +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 +<function>ldap_free_sort_keylist</function> 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 +
+<function>ldap_free_templates</function> +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 +<function>ldap_free_templates</function> 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. +
+<function>ldap_free_urldesc</function> +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 +<function>ldap_free_urldesc</function> 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 <function>ldap_free_urldesc</function> +#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 +
+<function>ldap_friendly_name</function> +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 +<function>ldap_friendly_name</function> 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 <function>ldap_friendly_name +</function> +#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 +
+<function>ldap_get_dn</function> +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 +<function>ldap_get_dn</function> 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 <function>ldap_get_dn</function> +#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 + +
+<function>ldap_get_entry_controls</function> +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 +<function>ldap_get_entry_controls</function> 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. + +
+<function>ldap_getfilter_free</function> +The ldap_getfilter_free function frees the memory +used by a filter set. +Syntax +#include <ldap.h> + void ldap_getfilter_free( LDAPFiltDesc *lfdp ); + +Parameters +<function>ldap_getfilter_free</function> 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 <function>ldap_getfilter_free +</function> +#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 +
+<function>ldap_getfirstfilter</function> +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 +<function>ldap_getfirstfilter</function> 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 <function>ldap_getfirstfilter +</function> +#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 + +
+<function>ldap_get_lang_values</function> +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 +<function>ldap_get_lang_values</function> 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 + +
+<function>ldap_get_lang_values_len</function> +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 +<function>ldap_get_lang_values_len</function> 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 +
+<function>ldap_get_lderrno</function> +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 +<function>ldap_get_lderrno</function> 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 <function>ldap_get_lderrno</function> +#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 +
+<function>ldap_getnextfilter</function> +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 +<function>ldap_getnextfilter</function> 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 +
+<function>ldap_get_option</function> +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 +<function>ldap_get_option</function> 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 <function> +ldap_get_options</function> 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 <function>ldap_get_option</function> +#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 <structname>LDAP_OPT_API_FEATURE_INFO</structname> and <structname> +LDAP_OPT_API_INFO</structname> +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 +
+<function>ldap_get_values</function> +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 +<function>ldap_get_values</function> 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 <function>ldap_get_values</function> +#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 +
+<function>ldap_get_values_len</function> +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 +<function>ldap_get_values_len</function> 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. +<function>ldap_get_values_len</function> +#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 +
+<function>ldap_init</function> +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 +<function>ldap_init</function> 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–27 ld1.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 <function>ldap_init +</function> +... +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–27 ld1.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. +<function>ldap_init</function> 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 <function>ldap_init</function> +#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 + +
+<function>ldap_init_getfilter</function> +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 +<function>ldap_init_getfilter</function> 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 +
+<function>ldap_init_getfilter_buf</function> +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 +<function>ldap_init_getfilter_buf</function> Function +Parameters + + + + +Parameter + +Description + + + + + +buf + +Buffer containing LDAP filter configuration information. + + + +buflen + +Size of the buffer + + + +
+
+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 <function>ldap_init_getfilter +</function> +#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 +
+<function>ldap_init_searchprefs</function> +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 +<function>ldap_init_searchprefs</function> 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 +
+<function>ldap_init_searchprefs_buf</function> +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 +<function>ldap_init_searchprefs_buf</function> 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 +
+<function>ldap_init_templates</function> +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 +<function>ldap_init_templates</function> 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 +
+<function>ldap_init_templates_buf</function> +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 +<function>ldap_init_templates_buf</function> 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 +
+<function>ldap_is_dns_dn</function> +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 (). + + + +<function>ldap_is_ldap_url</function> +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 +<function>ldap_is_ldap_url</function> 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 <function>ldap_is_ldap_url</function> +#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 +
+<function>ldap_keysort_entries</function> +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 +<function>ldap_keysort_entries</function> 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 + +
+<function>ldap_memcache_destroy</function> +The ldap_memcache_destroy function frees an LDAPMemCache structure from memory. +Syntax +#include <ldap.h> + void ldap_memcache_destroy( LDAPMemCache *cache ); + +Parameters +<function>ldap_memcache_destroy</function> 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 +
+<function>ldap_memcache_flush</function> +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 +<function>ldap_memcache_flush</function> 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. +
+<function>ldap_memcache_get</function> +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 +<function>ldap_memcache_get</function> 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 +
+<function>ldap_memcache_init</function> +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 +<function>ldap_memcache_init</function> 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 + +
+<function>ldap_memcache_set</function> +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 +<function>ldap_memcache_set</function> 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 +
+<function>ldap_memcache_update</function> +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 +<function>ldap_memcache_update</function> 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 +
+<function>ldap_memfree</function> +The ldap_memfree function frees memory allocated +by an LDAP API function call. +Syntax +#include <ldap.h> + void ldap_memfree( void *p ); + +Parameters +<function>ldap_memfree</function> 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 <function>ldap_memfree</function> +#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 +
+<function>ldap_modify</function> +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 +<function>ldap_modify</function> 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 <function>ldap_modify</function> +#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 +
+<function>ldap_modify_ext</function> +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 +<function>ldap_modify_ext</function> 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 +
+<function>ldap_modify_ext_s</function> +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 +<function>ldap_modify_ext_s</function> 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 +
+<function>ldap_modify_s</function> +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 +<function>ldap_modify_s</function> 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 <function>ldap_modify_s</function> +#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 +
+<function>ldap_modrdn</function> +This function is deprecated and should not be used. It is included +in ldap-deprecated.h for backward-compatibility. Use ldap_rename instead. +<function>ldap_modrdn_s</function> +This function is deprecated and should not be used. It is included +in ldap-deprecated.h for backward-compatibility. Use ldap_rename_s instead. + + +<function>ldap_modrdn2</function> +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 +<function>ldap_modrdn2</function> 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 <function>ldap_modrdn2</function> +#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 +
+<function>ldap_modrdn2_s</function> +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 +<function>ldap_modrdn2_s</function> 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 <function>ldap_modrdn2_s</function> +#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 +
+<function>ldap_mods_free</function> +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 +<function>ldap_mods_free</function> 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 <function>ldap_mods_free</function> +#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 ); +} +... + + +
+<function>ldap_msgfree</function> +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 +<function>ldap_msgfree</function> 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 <function>ldap_msgfree</function> +#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 + +
+<function>ldap_msgid</function> +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 +<function>ldap_msgid</function> 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 <function>ldap_msgid</function> +#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 +
+<function>ldap_msgtype</function> + +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 +<function>ldap_msgtype</function> 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 <function>ldap_msgtype</function> +#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 +
+<function>ldap_multisort_entries</function> +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 +<function>ldap_multisort_entries</function> 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 <function>ldap_multisort_entries +</function> +#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 +
+<function>ldap_name2template</function> +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 +<function>ldap_name2template</function> 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. +
+<function>ldap_next_attribute</function> +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 +<function>ldap_next_attribute</function> 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 + +
+<function>ldap_next_disptmpl</function> +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 +<function>ldap_next_disptmpl</function> 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 +
+<function>ldap_next_entry</function> +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 +<function>ldap_next_entry</function> 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 +
+<function>ldap_next_message</function> +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 +<function>ldap_next_message</function> 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 +
+<function>ldap_next_reference</function> +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 +<function>ldap_next_reference</function> 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 +
+<function>ldap_next_searchobj</function> +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 +<function>ldap_next_searchobj</function> 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 +
+<function>ldap_next_tmplcol</function> +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 +<function>ldap_next_tmplcol</function> 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 +
+<function>ldap_next_tmplrow</function> +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 +<function>ldap_next_tmplrow</function> 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 . +
+<function>ldap_oc2template</function> +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 +<function>ldap_oc2template</function> 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. +
+<function>ldap_open</function> +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 +<function>ldap_open</function> 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). +
+<function>ldap_parse_authzid_control +</function> +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 +<function>ldap_parse_authzid_control</function> 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 + +
+<function>ldap_parse_entrychange_control</function> +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 +<function>ldap_parse_entrychange_control</function> 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 +
+<function>ldap_parse_extended_result</function> +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 +<function>ldap_parse_extended_result</function> 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 +
+<function>ldap_parse_passwd</function> +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 +<function>ldap_parse_passwd</function> 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. + + + +
+<function>ldap_parse_passwd_result</function> +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 +<function>ldap_parse_passwd_result</function> 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. + + + +
+<function>ldap_parse_pwdpolicy_control +</function> +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 +<function>ldap_parse_pwdpolicy_control</function> 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 +
+<function>ldap_parse_reference</function> +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 +<function>ldap_parse_reference</function> 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. +
+<function>ldap_parse_result</function> +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 +<function>ldap_parse_result</function> 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 +
+<function>ldap_parse_sasl_bind_result</function> +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 +<function>ldap_parse_sals_bind_result</function> 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 +
+<function>ldap_parse_sort_control</function> + +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 +<function>ldap_parse_sort_control</function> 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 +
+<function>ldap_parse_userstatus_control +</function> + +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 +<function>ldap_parse_userstatus_control</function> 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 + +
+<function>ldap_parse_whoami</function> + +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 +<function>ldap_parse_whoami</function> 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. + + +
+<function>ldap_parse_whoami_result</function> + +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 +<function>ldap_parse_whoami_result</function> 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. + + +
+<function>ldap_parse_virtuallist_control</function> + +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 +<function>ldap_parse_virtuallist_control</function> 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 + +
+<function>ldap_passwd</function> + +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 +<function>ldap_passwd</function> 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. + + + +
+<function>ldap_passwd_s</function> + +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 +<function>ldap_passwd</function> 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. + + + +
+<function>ldap_perror</function> + +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 +<function>ldap_perror</function> 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 <function>ldap_perror</function> +... +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 +
+<function>ldap_rename</function> + +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 +<function>ldap_rename</function> 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 +
+<function>ldap_rename_s</function> + +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 +<function>ldap_rename</function> 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 +
+<function>ldap_result</function> + +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 +<function>ldap_result</function> 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 + +
+<function>ldap_result2error</function> + +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 +<function>ldap_result2error</function> 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 +
+<function>ldap_sasl_bind</function> + +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 +<function>ldap_sasl_bind</function> 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 +
+<function>ldap_sasl_bind_s</function> + +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 +<function>ldap_sasl_bind_s</function> 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 +
+<function>ldap_search</function> + +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 +<function>ldap_search</function> 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 <function>ldap_search</function> +#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 +
+<function>ldap_search_ext</function> + +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 +<function>ldap_search_ext</function> 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 + +
+<function>ldap_search_ext_s</function> + +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 +<function>ldap_search_ext_s</function> 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 +
+<function>ldap_search_s</function> + +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 + . +<function>ldap_search_s</function> 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 <function>ldap_search_s</function> +#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 +
+<function>ldap_search_st</function> + +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 +<function>ldap_search_st</function> 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 +
+<function>ldap_set_filter_additions</function> + +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 +<function>ldap_set_filter_additions</function> 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 <function>ldap_set_filter_additions +</function> +#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 +
+<function>ldap_setfilteraffixes</function> + +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 + +<function>ldap_set_lderrno</function> + +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 +<function>ldap_set_lderrno</function> 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 <function>ldap_set_lderrno</function> +#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 + +
+<function>ldap_set_option</function> + +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 +<function>ldap_set_option</function> 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 <function>ldap_set_option +</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. 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 <function>ldap_set_option</function> +#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 +
+<function>ldap_set_rebind_proc</function> + +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 +<function>ldap_set_rebind_proc</function> 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 <function>ldap_set_rebind_proc +</function> +#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 +
+<function>ldap_simple_bind</function> + +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 +<function>ldap_simple_bind</function> 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 <function>ldap_simple_bind</function> +#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 +
+<function>ldap_simple_bind_s</function> + +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 +<function>ldap_simple_bind_s</function> 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 <function>ldap_simple_bind_s +</function> +#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 +
+<function>ldap_sort_entries</function> + +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 +<function>ldap_sort_entries</function> 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 <function>ldap_sort_entries</function> +#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 +
+<function>ldap_start_tls_s</function> + +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 +<function>ldap_start_tls_s</function> 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. + + +
+<function>ldap_sort_strcasecmp</function> + +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 +<function>ldap_sort_strcasecmp</function> 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 +
+<function>ldap_sort_values</function> + +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 +<function>ldap_sort_values</function> 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 <function>ldap_sort_values</function> +#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. + +
+<function>ldapssl_advclientauth_init</function> + +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. +<function>ldapssl_advclientauth_init</function> 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 <function>ldapssl_advclientauth_init +</function> +#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 + +
+<function>ldapssl_client_init</function> +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 +<function>ldapssl_client_init</function> 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 <function>ldapssl_client_init +</function> +#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 + +
+<function>ldapssl_clientauth_init</function> +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 +<function>ldapssl_clientauth_init</function> 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 <function>ldapssl_clientauth_init +</function> +#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 +
+<function>ldapssl_enable_clientauth</function> +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 +<function>ldapssl_enable_clientauth</function> 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 +
+<function>ldapssl_err2string</function> +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 +<function>ldapssl_err2string</function> 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 +
+<function>ldapssl_init</function> +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 +<function>ldapssl_init</function> 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 <function>ldapssl_init</function> +#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 +
+<function>ldapssl_install_routines</function> +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 +<function>ldapssl_install_routines</function> 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 <function>ldapssl_install_routines +</function> +#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 +
+<function>ldapssl_pkcs_init</function> +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. +<structname>ldapssl_pkcs_fns</structname> 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 +<function>ldapssl_pkcs_init</function> 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 + +
+<function>ldapssl_serverauth_init</function> +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. +<function>ldapssl_serverauth_init</function> 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 + +
+<function>ldapssl_set_strength</function> +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. +<function>ldapssl_set_strength</function> 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. + + + + + + +
+
+
+<function>ldapssl_tls_start_s</function> +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 +<function>ldapssl_tls_start_s</function> 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. +
+<function>ldap_str2charray</function> + +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. +<function>ldap_tmplattrs</function> + +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 +<function>ldap_tmplattrs</function> 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 +
+<function>ldap_tmplerr2string</function> + +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 +<function>ldap_tmplerr2string</function> Function +Parameter + + + + +Parameter + +Description + + + + + +err + +Error returned. + + + +
+
+
+<function>ldap_ufn_search_c</function> + +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. + +<function>ldap_ufn_search_ct</function> +This function will be deprecated and should not be used. It is +included in ldap-to-be-deprecated.h for backward-compatibility. + + + +<function>ldap_ufn_search_s</function> +This function will be deprecated and should not be used. It is +included in ldap-to-be-deprecated.h for backward-compatibility. + +<function>ldap_ufn_setfilter</function> +This function will be deprecated and should not be used. It is +included in ldap-to-be-deprecated.h for backward-compatibility. + + + +<function>ldap_ufn_setprefix</function> +This function will be deprecated and should not be used. It is +included in ldap-to-be-deprecated.h for backward-compatibility. + +<function>ldap_ufn_timeout</function> +This function will be deprecated and should not be used. It is +included in ldap-to-be-deprecated.h for backward-compatibility. + + + +<function>ldap_unbind</function> + +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 +<function>ldap_unbind</function> 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 <function>ldap_unbind</function> +#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 + +
+<function>ldap_unbind_s</function> + +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 +<function>ldap_unbind_s</function> 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 <function>ldap_unbind_s</function> +#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 + +
+<function>ldap_unbind_ext</function> + +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 +<function>ldap_unbind_ext</function> 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 + +
+<function>ldap_url_parse</function> + +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 +<function>ldap_url_parse</function> 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 <function>ldap_url_parse</function> +#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 +
+<function>ldap_url_parse_no_defaults</function> + +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 +<function>ldap_url_parse_no_defaults</function> 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). +
+<function>ldap_url_search</function> + +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 +<function>ldap_url_search</function> 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 <function>ldap_url_search +</function> +#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 + +
+<function>ldap_url_search_s</function> + +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 +<function>ldap_url_search_s</function> 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 <function>ldap_url_search_s</function> +#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 + +
+<function>ldap_url_search_st</function> + +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 +<function>ldap_url_search_st</function> 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 + +
+<function>ldap_utf8characters</function> + +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 +<function>ldap_utf8characters</function> Function +Parameter + + + + +Parameter + +Description + + + + + +char + +Pointer to a UTF-8 string. + + + +
+
+Returns +Returns the number of UTF-8 characters in the 0 terminated +array. +
+<function>ldap_utf8copy</function> + +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 +<function>ldap_utf8copy</function> 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. +
+<function>ldap_utf8getcc</function> + +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 +<function>ldap_utf8getcc</function> Function +Parameter + + + + +Parameter + +Description + + + + + +src + +Pointer to a UCS-4 character. + + + +
+
+
+<function>ldap_utf8isalnum</function> + +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 +<function>ldap_utf8isalnum</function> Function +Parameter + + + + +Parameter + +Description + + + + + +s + +Pointer to a UTF-8 character. + + + +
+
+
+<function>ldap_utf8isalpha</function> + +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 +<function>ldap_utf8isalpha</function> Function +Parameter + + + + +Parameter + +Description + + + + + +s + +Pointer to a UTF-8 character. + + + +
+
+
+<function>ldap_utf8isdigit</function> + +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 +<function>ldap_utf8isdigit</function> Function +Parameter + + + + +Parameter + +Description + + + + + +s + +Pointer to a UTF-8 character. + + + +
+
+
+<function>ldap_utf8isspace</function> + +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 +<function>ldap_utf8isspace</function> Function +Parameter + + + + +Parameter + +Description + + + + + +s + +Pointer to a UTF-8 character. + + + +
+
+
+<function>ldap_utf8len</function> + +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 +<function>ldap_utf8len</function> Function +Parameter + + + + +Parameter + +Description + + + + + +char + +Pointer to a UTF-8 string. + + + +
+
+
+<function>ldap_utf8next</function> + +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 +<function>ldap_utf8next</function> Function +Parameter + + + + +Parameter + +Description + + + + + +char + +Pointer to a UTF-8 character. + + + +
+
+
+<function>ldap_utf8prev</function> + +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 +<function>ldap_utf8prev</function> Function +Parameter + + + + +Parameter + +Description + + + + + +char + +Pointer to a UTF-8 character. + + + +
+
+
+<function>ldap_utf8strtok_r</function> + +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 +<function>ldap_utf8strtok_r</function> 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. +
+<function>ldap_whoami</function> + +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 +<function>ldap_whoami</function> 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. + + +
+<function>ldap_whoami_s</function> + +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 +<function>ldap_whoami_s</function> 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. + + +
+<function>ldap_vals2html</function> + +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 +<function>ldap_vals2html</function> 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 +
+<function>ldap_vals2text</function> + +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 +<function>ldap_vals2text</function> 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 +
+<function>ldap_value_free</function> + +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 +<function>ldap_value_free</function> Function +Parameter + + + + +Parameter + +Description + + + + + +values + +Array of values. + + + +
+
+Description +Use the ldap_value_free_len function +if the values are berval structures. + +Example +See the example under ldap_get_values. + +See Also +ldap_get_values, +ldap_value_free_len +
+<function>ldap_value_free_len</function> + +C SDK functions +ldap_value_free_len + +ldap_value_free_len + +The ldap_value_free_len function frees an array +of berval structures from memory. +Syntax +#include <ldap.h> + void ldap_value_free_len( struct berval **values ); + +Parameters +<function>ldap_value_free_len</function> Function +Parameter + + + + +Parameter + +Description + + + + + +values + +Array of berval structures. + + + +
+
+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 +
+<function>ldap_version</function> + +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 +<function>ldap_version</function> 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 +
+<function>ldap_x_calloc</function> + +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 +<function>ldap_x_calloc</function> 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 +
+<function>ldap_x_free</function> +The ldap_x_free function frees allocated memory. +Syntax +#include <ldap-extension.h> +void ldap_x_free( void *ptr ); + +Parameters +<function>ldap_x_free</function> 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 +
+<function>ldap_x_hostlist_first</function> +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, + +<function>ldap_x_hostlist_next</function> +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, + +<function>ldap_x_hostlist_status</function> +See Also +ldap_x_hostlist_first, ldap_x_hostlist_next, LDAP_X_EXTIOF_CONNECT_CALLBACK + + +<function>ldap_x_hostlist_statusfree</function> +See Also +ldap_x_hostlist_first, ldap_x_hostlist_next, LDAP_X_EXTIOF_CONNECT_CALLBACK + + +<function>ldap_x_malloc</function> +The ldap_x_malloc function allocates space for +an object. +Syntax +#include <ldap-extension.h> +void *ldap_x_malloc( size_t size ); + +Parameters +<function>ldap_x_malloc</function> 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 +
+<function>ldap_x_realloc</function> +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 +<function>ldap_x_realloc</function> Function +Parameter + + + + +Parameter + +Description + + + + + +ptr + +Pointer to a block of memory. + + + +size + +Specifies the new size of the block. + + + +
+
+See Also +ldap_x_free, ldap_x_calloc + , ldap_x_malloc +
+<function>prldap_get_default_socket_info</function> + +C SDK functions +prldap_* + +prldap_* + +The prldap_get_default_socket_info function retrieves +default socket information. +Syntax +#include <ldappr.h> +int prldap_get_default_socket_info( LDAP *ld, PRLDAPSocketInfo *soip ); + +Parameters +<function>prldap_get_default_socket_info</function> 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 + +
+<function>prldap_get_session_info</function> +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 +<function>prldap_get_session_info</function> 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 +
+<function>prldap_get_session_option</function> +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 + +<function>prldap_get_socket_info</function> +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 +<function>prldap_get_socket_info</function> 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 +
+<function>prldap_init</function> +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 +<function>prldap_init</function> 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 +
+<function>prldap_install_routines</function> +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 +<function>prldap_install_routines</function> 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 +
+<function>prldap_set_default_socket_info</function> +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 +<function>prldap_set_default_socket_info</function> 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 +
+<function>prldap_set_session_info</function> +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 +<function>prldap_set_session_info</function> 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 +
+<function>prldap_set_session_option</function> +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 +<function>prldap_set_session_option</function> Function +Parameters + + + + +Parameter + +Description + + + + + +ld + +The session handle returned from prldap_init. + + + + +option + + + + +
+
+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 +
+<function>prldap_set_socket_info</function> +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 +<function>prldap_set_socket_info</function> 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. +<structname>LDAPURLDesc</structname> 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. +<structname> +LDAPURLDesc</structname> 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 <structname>LDAPURLDesc</structname> 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 <structname>ldap_thread_fns</structname> 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. +<structname>ldap_thread_fns</structname> 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. +<structname>ldap_thread_fns +</structname> 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 <structname>ldap_extra_thread_fns</structname> 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 <structname>ldap_extra_thread_fns +</structname> 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 <structname>ldap_thread_fns +</structname> 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. +Numerical Listing of Result +Codes by Value + + + + +Decimal + +Hexadecimal + +Defined Name + + + + + +0 + +0x00 + +LDAP_SUCCESS + + + +1 + +0x01 + +LDAP_OPERATIONS_ERROR + + + +2 + +0x02 + +LDAP_PROTOCOL_ERROR + + + +3 + +0x03 + +LDAP_TIMELIMIT_EXCEEDED + + + +4 + +0x04 + +LDAP_SIZELIMIT_EXCEEDED + + + +5 + +0x05 + +LDAP_COMPARE_FALSE + + + +6 + +0x06 + +LDAP_COMPARE_TRUE + + + +7 + +0x07 + +LDAP_STRONG_AUTH_NOT_SUPPORTED + + + +8 + +0x08 + +LDAP_STRONG_AUTH_REQUIRED + + + +9 + +0x09 + +LDAP_PARTIAL_RESULTS + + + +10 + +0x0a + +LDAP_REFERRAL + + + +11 + +0x0b + +LDAP_ADMINLIMIT_EXCEEDED + + + +12 + +0x0c + +LDAP_UNAVAILABLE_CRITICAL_EXTENSION + + + +13 + +0x0d + +LDAP_CONFIDENTIALITY_REQUIRED + + + +14 + +0x0e + +LDAP_SASL_BIND_IN_PROGRESS + + + + + + + + + +16 + +0x10 + +LDAP_NO_SUCH_ATTRIBUTE + + + +17 + +0x11 + +LDAP_UNDEFINED_TYPE + + + +18 + +0x12 + +LDAP_INAPPROPRIATE_MATCHING + + + +19 + +0x13 + +LDAP_CONSTRAINT_VIOLATION + + + +20 + +0x14 + +LDAP_TYPE_OR_VALUE_EXISTS + + + +21 + +0x15 + +LDAP_INVALID_SYNTAX + + + + + + + + + +32 + +0x20 + +LDAP_NO_SUCH_OBJECT + + + +33 + +0x21 + +LDAP_ALIAS_PROBLEM + + + +34 + +0x22 + +LDAP_INVALID_DN_SYNTAX + + + +35 + +0x23 + +LDAP_IS_LEAF + + + +36 + +0x24 + +LDAP_ALIAS_DEREF_PROBLEM + + + + + + + + + +48 + +0x30 + +LDAP_INAPPROPRIATE_AUTH + + + +49 + +0x31 + +LDAP_INVALID_CREDENTIALS + + + +50 + +0x32 + +LDAP_INSUFFICIENT_ACCESS + + + +51 + +0x33 + +LDAP_BUSY + + + +52 + +0x34 + +LDAP_UNAVAILABLE + + + +53 + +0x35 + +LDAP_UNWILLING_TO_PERFORM + + + +54 + +0x36 + +LDAP_LOOP_DETECT + + + + + + + + + +60 + +0x3C + +LDAP_SORT_CONTROL_MISSING + + + +61 + +0x3D + +LDAP_INDEX_RANGE_ERROR + + + + + + + + + +64 + +0x40 + +LDAP_NAMING_VIOLATION + + + +65 + +0x41 + +LDAP_OBJECT_CLASS_VIOLATION + + + +66 + +0x42 + +LDAP_NOT_ALLOWED_ON_NONLEAF + + + +67 + +0x43 + +LDAP_NOT_ALLOWED_ON_RDN + + + +68 + +0x44 + +LDAP_ALREADY_EXISTS + + + +69 + +0x45 + +LDAP_NO_OBJECT_CLASS_MODS + + + +70 + +0x46 + +LDAP_RESULTS_TOO_LARGE + + + +71 + +0x47 + +LDAP_AFFECTS_MULTIPLE_DSAS + + + + + + + + + +80 + +0x50 + +LDAP_OTHER + + + +81 + +0x51 + +LDAP_SERVER_DOWN + + + +82 + +0x52 + +LDAP_LOCAL_ERROR + + + +83 + +0x53 + +LDAP_ENCODING_ERROR + + + +84 + +0x54 + +LDAP_DECODING_ERROR + + + +85 + +0x55 + +LDAP_TIMEOUT + + + +86 + +0x56 + +LDAP_AUTH_UNKNOWN + + + +87 + +0x57 + +LDAP_FILTER_ERROR + + + +88 + +0x58 + +LDAP_USER_CANCELLED + + + +89 + +0x59 + +LDAP_PARAM_ERROR + + + +90 + +0x5a + +LDAP_NO_MEMORY + + + +91 + +0x5b + +LDAP_CONNECT_ERROR + + + +92 + +0x5c + +LDAP_NOT_SUPPORTED + + + +93 + +0x5d + +LDAP_CONTROL_NOT_FOUND + + + +94 + +0x5e + +LDAP_NO_RESULTS_RETURNED + + + +95 + +0x5f + +LDAP_MORE_RESULTS_TO_RETURN + + + +96 + +0x60 + +LDAP_CLIENT_LOOP + + + +97 + +0x61 + +LDAP_REFERRAL_LIMIT_EXCEEDED + + + +
+
+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. +<function>ldap_search_ext_s</function> 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. +<function>ldap_search_ext</function> 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: + +(attribute operator +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. +<function>ldap_result</function> 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 <function>ldapssl_init +</function> + +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 <function>ldapssl_init</function> +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 <function>ldapssl_init</function> +As an alternative to calling the ldapssl_init function, +you can use the following procedure. +To Initialize a Client SSL Connection (Alternative Method Using <function> +ldap_init</function> + +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 <function> +ldap_init</function>) +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 + ). + + + +
+<filename>ldap.h</filename> 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 + + +<filename>lber.h</filename> 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. + +<filename>ldap_ssl.h</filename> 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" + +<filename>ldappr.h</filename> 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 + +<filename class="libraryfile">liblber</filename> 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. +<structname>LDAPMod</structname> 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. +<structname>LDAPMod +</structname> 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. +<structname>berval</structname> 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 <structname>berval</structname> 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 <structname> +LDAPMod</structname> 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 rm filename +. + + + +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 <filename>libldap</filename> 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 + pattern1 delimiters +filter1-1 desc1-1 [scope1 +] + filter1-2 +desc1-2 [scope2] + + pattern2 delimiters +filter2-1 desc2-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 <literal>setFilterAffixes +</literal> +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 <literal>getFilter</literal> +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 <literal>setupFilter</literal> +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 <literal>javax.security.auth.callback +</literal> + +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 <literal>External</literal> 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: +(attribute operator +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 <literal>connect +</literal> 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 rm filename +. + + + +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. + + +