ldap_version() function. This function fills an LDAPVersion structure that contains the version information.
The following example illustrates the kinds of version information you can retrieve from this structure.
...
#include <stdio.h>
#include "ldap.h"
...
LDAPVersion ver;
double SDKVersion;
...
/* Print version information. */
SDKVersion = ldap_version( &ver );
printf( "SDK Version: %1.2f\n", SDKVersion/100.0 );
printf( "Highest LDAP Protocol Supported: %1.2f\n",
ver.protocol_version/100.0 );
printf( "SSL Level Supported: %1.2f\n", ver.SSL_version/100.0 );
if ( ver.security_level != LDAP_SECURITY_NONE ) {printf( "Level of encryption: %d bits\n", ver.security_level );
} else {printf( "SSL not enabled.\n" );
}
...
Table 5.1 API functions that allocate and free memory
LDAPMessage structure representing the result returned from the server. LDAPMessage structure (for example, if you are calling functions that do not interact with the server), you can get error information from the connection handle. 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 DN that matches the entry that is closest to the requested entry.
For example, suppose the LDAP server processes a request to modify the entry with the DN "uid=bjensen,ou=Contractors,o=Airius.com" but that entry does not exist in the directory.
LDAP_NO_SUCH_OBJECT. LDAP_NO_SUCH_OBJECT. 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 :
LDAP_API(int) LDAP_CALL ldap_parse_result( LDAP *ld, LDAPMessage *res,The different types of information are returned in the following parameters of this function:
int *errcodep, char **matcheddnp, char **errmsgp, char ***referralsp,
LDAPControl ***serverctrlsp, int freeit );
errcodep argument. errmsgp argument. matcheddnp argument. (See "Receiving the Portion of the DN Matching an Entry" for details.) ldap_err2string() function. (See the section "Getting the Error Message" for details.)
For a listing and descriptions of the different LDAP result codes, see Chapter 19, "Result Codes".
The following section of code gets and prints information about an error returned from the server.
...
#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, For details, see
"Receiving the Portion of the DN Matching an 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 );
}
...
LDAPMessage structure (for example, if you are calling functions that do not interact with the server), you can get error information from the connection handle (the LDAP structure).
To get information about the last error that has occurred, call the ldap_get_lderrno() function :
LDAP_API(int) LDAP_CALL ldap_get_lderrno(LDAP *ld, char **m, char **s);The different types of information are returned in the following ways:
s argument. m argument. (See "Receiving the Portion of the DN Matching an Entry" for details.) ldap_get_lderrno() function, set the parameters to a NULL value. For example:
ldap_get_lderrno( ld, NULL, NULL );Note that you can also get the error message describing the LDAP result code by using the
ldap_err2string() function. (See the section "Getting the Error Message" for details.)
For a listing and descriptions of the different LDAP result codes, see Chapter 19, "Result Codes".
The following section of code gets and prints information about an error.
...
#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, For details, see
"Receiving the Portion of the DN Matching an Entry". */
if ( matched_msg != NULL && *matched_msg != '\0' ) {fprintf( stderr,
"Part of the DN that matches an existing entry: %s\n",
matched_msg );
}
...
ldap_err2string() function . The function returns a pointer to the error message. For example:
...
#include <stdio.h>
#include "ldap.h"
...
int rc;
...
if ( rc != LDAP_SUCCESS ) {fprintf( stderr, "Error: %s\n", ldap_err2string( rc ) );
}
...Note that the pointer returned by this function is a pointer to static data. Do not free this string.
LDAP structure. If you want to set error codes and error information in the LDAP structure, call the ldap_set_lderrno() function .
The following section of code sets the LDAP_PARAM_ERROR error code in the LDAP structure.
...
#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 );
}
...
ldap_perror() function . (Note that this function is still supported in the Netscape Directory SDK for C, but its use is deprecated. For more information, see "Backward Compatibility with Earlier Releases.")
The ldap_perror() function uses the connection handle to retrieve and print the error message for the last operation performed.
This example prints a message if a function fails to delete an entry in the server.
...
#include "ldap.h"
...
LDAP *ld;
char *dn = "uid=bjensen, ou=People, o=Airius.com";
...
if ( ldap_delete_s( ld, dn ) != LDAP_SUCCESS ) {ldap_perror( ld, "ldap_delete_s" );
return( 1 );
}
...In the preceding example, the client prints out this error message if it does not have access permissions to delete the entry:
ldap_delete_s: Insufficient access
ldap_search_ext_s(), or the asynchronous function ldap_search_ext(). In general, the synchronous functions have names ending with the characters _s (for example, ldap_search_ext_s()).
ldap_search()) ldap_search_ext()) ldap_search_ext_s()) ldap_search_s()) LDAP_SUCCESS if successful and an LDAP error code if not successful.
This example calls a synchronous function to delete an entry in the directory.
...
#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, For details, see
"Receiving the Portion of the DN Matching an 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 additional sample programs that call synchronous functions, see the source files in the
examples directory of the Netscape Directory SDK for C.
ldap_result() function to check the status of the LDAP operation.
This section explains how to call an asynchronous function and check the results of the LDAP operation. The following topics are covered:
examples directory of the Netscape Directory SDK for C.
_ext) 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 successfully sent the request to the server.
For example, the following section of code send an LDAP delete request to the server. The example checks if the result was successfully sent.
...
#include <stdio.h>
#include "ldap.h"
...
/* Change these as needed. */
#define DELETE_DN "uid=wjensen,ou=People,o=Airius.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 );
}
...
ldap_result() function, and pass the message ID as a parameter. You can also specify a timeout period to wait for results from the server.
The function returns one of the following values:
int global_counter = 0;
void
do_other_work()
{global_counter++;
}You can set up a
while loop to call your function when you are not checking for the server's response:
...
#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 passed. Continue looping. */
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 the top of the loop and call ldap_result() again). */
if ( !finished ) {do_other_work();
}
...
}
...
ldap_result() function gets the response sent from the server, the result parameter passes back a pointer to an LDAPMessage structure. This structure contains the server's response, which can include the following information:
ldap_parse_result() function:
LDAP_API(int) LDAP_CALLYou can get the following information from arguments of this function:
ldap_parse_result( LDAP *ld, LDAPMessage *res, int *errcodep,
char **matcheddnp, char **errmsgp, char ***referralsp,
LDAPControl ***serverctrlsp, int freeit );
errcodep is the LDAP result code of the operation that the server finished processing matcheddnp is the portion of the DN that matches an existing entry, if the server is not able to find an entry for a DN that you've specified (for details, see "Receiving the Portion of the DN Matching an Entry") errmsgp is an additional error message that the server can send to your client. referralsp is a set of referrals sent back to your client by the server, if you've requested an entry that is not part of the directory tree managed by the server and if the server is configured to refer clients to other LDAP servers. serverctrlsp is a set of server response controls applicable to the LDAP operation. ldap_msgfree()to free the LDAPMessage structure unless the structure is part of a chain of results. If you pass a non-zero value for the freeit parameter, the structure is automatically freed after the information is retrieved.
Note that the result code returned by this function is not the same as the result code of the operation (errcodep). The result code returned by this operation indicates the success or failure of parsing the LDAPMessage structure.
For example, the following section of code retrieves error information from an LDAPMessage structure returned by the ldap_result().
...
#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. (For details, see
"Receiving the Portion of the DN Matching an 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( "Operation completed successfully" );
}
}
...
ldap_abandon_ext() function. The function returns LDAP_SUCCESS if successful or an LDAP result code if an error occurs.
Once you cancel an LDAP operation, you cannot retrieve the results of that operation. (In other words, calling ldap_result() does not return any results.)
ldap_result() within a loop to poll the results of the LDAP delete operation.
...
#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,o=Airius.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 period
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.
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:
/* 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 don't 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. (For details, see
"Receiving the Portion of the DN Matching an 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"
"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++;
}
...
LDAP_NO_SUCH_OBJECT result code. LDAP_PARTIAL_RESULTS for LDAP v2 clients, LDAP_REFERRAL for LDAP v3 clients) and one or more LDAP URLs. LDAP_PARTIAL_RESULTS or LDAP_REFERRAL). You can get the LDAP URLs from the result by calling the ldap_parse_result() function. LDAP_RES_SEARCH_REFERENCE. 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, then call the ldap_msgtype() function to determine if the message is of the type LDAP_RES_SEARCH_REFERENCE. ldap_set_option() function and pass LDAP_OPT_REFERRALS as the value of the option parameter.
optdata parameter to LDAP_OPT_OFF. optdata parameter to LDAP_OPT_ON. LDAP_OPT_OFF and LDAP_OPT_ON are cast to (void *). You can pass these parameters directly to the function (see the example below).
The following example prevents the client from automatically following referrals to other LDAP servers.
#include <stdio.h>
#include "ldap.h"
...
LDAP *ld;
int rc;
char *host = "localhost";
...
/* Initialize a session with the LDAP server ldap.netscape.com:389. */
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 );
}
...
LDAP_REFERRAL_LIMIT_EXCEEDED is returned.
To set this limit, pass LDAP_OPT_REFERRAL_HOP_LIMIT as the value of the option parameter and pass the maximum number of hops as value of the optdata parameter.
By default, the maximum number of hops is 5.
LDAP_REBINDPROC_CALLBACK. Then, you specify that your function should be used if binding to other servers when following referrals.
The following steps explain how this works:
LDAP_OPT_REBIND_FN option), passing 0 as the freeit argument. dnp, passwdp, and authmethodp arguments to point to the following information: dnp argument is set to point to the DN to be used to authenticate to the new LDAP server. passwdp argument is set to point to the credentials for this DN. authmethodp argument is set to point to the method of authentication used (for example, LDAP_AUTH_SIMPLE). LDAP_SUCCESS, and referral processing continues. freeit argument. freeit is 0, set the following pointers: dnp to point to the DN to be used for authentication. passwdp to point to the credentials to be used for authentication. authmethodp to point to the method of authentication used (for example, LDAP_AUTH_SIMPLE). arg argument, which is a pointer to the argument specified in the ldap_set_rebind_proc() function.
If successful, return LDAP_SUCCESS. Otherwise, return the appropriate LDAP error code. freeit is 1, free any memory that you allocated to create the DN and credentials. int LDAP_CALL LDAP_CALLBACK rebindproc( LDAP *ld, char **dnp,The parameters for this prototype are described below:
char **passwdp, int *authmethodp, int freeit, void *arg );
| Parameter Name | Description |
|---|---|
ld | |
dnp | |
| passwdp | A pointer to the user's (or entity's) password. Your function needs to set this value. |
| authmethodp | |
| freeit | |
| arg |
LDAP_CALL and LDAP_CALLBACK are used to set up calling conventions (for example, Pascal calling conventions on Windows). These are defined in the lber.h header file.
ldap_set_rebind_proc() , specifying your function and any data that you want passed as an argument. ldap_set_option() to set the LDAP_OPT_REBIND_FN option to your function and the LDAP_OPT_REBIND_ARG option to specify any arguments you want passed to your rebind function.ldap_memcache_init() function to create a new LDAPMemCache structure, which is the cache. Pass the pointer to this structure to subsequent operations. ldap_memcache_set() function to associate the cache with an LDAP connection handle (an LDAP structure). #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. */
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 );
}
...
NOTE: On Windows NT, if theWhen a search request is cached, the search criteria is 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 (for example, specifying that you want all attributes returned instead of just the uid attribute), your client gets the results from the server rather than from the cache. The cache periodically checks for expired items and removes them from the cache. If you are writing a multithreaded application and want to set up a separate thread to keep the cache up-to-date, you can call theldap_memcache_init()function returns anLDAP_PARAM_ERRORresult code, verify that your client is using the version of thensldap32v30.dllfile provided with the Netscape Directory SDK 3.0 for C. (Some of the Netscape servers, such as the Netscape Directory Server 3.0, install an older verison of thensldap32v30.dllfile in the Windows system32 directory.) For example, you may want to copy thensldap32v30.dllfile provided with the Netscape Directory SDK 3.0 for C to your client's directory.
ldap_memcache_update() function.
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.
LDAP_SERVER_DOWN or LDAP_CONNECT_ERROR result code.
To reconnect to the server, you can do one of the following:
LDAP_OPT_RECONNECT) to connect to the server again with the same connection handle.ldap_unbind() or ldap_unbind_s() function to free the existing connection handle (the LDAP structure), and then call the ldap_init() function to open and initialize a new connection. For example:
#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. */
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 );
...The disadvantage of this approach is that you need free the
LDAP connection handle, which can make it difficult to share connection handles between threads. If you do not want to free the connection handle, you can use the reconnect option instead, as described in "Using the Reconnect Option."
ldap_set_option() function to set the LDAP_OPT_RECONNECT option to LDAP_OPT_ON. Do this right after calling ldap_init():
#include "ldap.h"
...
#define HOSTNAME "localhost"
#define PORTNUMBER LDAP_PORT
...
LDAP *ld;...
/* Get a handle to an LDAP connection. */
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 */
}
...After setting this option, if the connection to the LDAP server has been lost (if the LDAP API library returns an
LDAP_SERVER_DOWN or LDAP_CONNECT_ERROR result code to your client), call the ldap_simple_bind_s() function to reestablish a connection to one of the hosts specified in the ldap_init() function call.
If your client is able to reconnect with the server, the ldap_simple_bind_s() function call issues an LDAP bind request to the server and returns the result.
Note that if the client has been successfully authenticated to the server using the current LDAP structure and if the connection to the LDAP server has not been lost, ldap_simple_bind_s() returns LDAP_SUCCESS without contacting the LDAP server.
The function is designed to do this in cases where more than one thread shares the same LDAP connection handle and receives an LDAP_SERVER_DOWN or LDAP_CONNECT_ERROR error. If multiple threads call the ldap_simple_bind_s() function, the function is designed so that only one of the threads actually issues the bind operation. For the other threads, the function returns LDAP_SUCCESS without contacting the LDAP server.
The important side effect to note is that if the LDAP_OPT_RECONNECT option is set, ldap_simple_bind_s() may return LDAP_SUCCESS without contacting the LDAP server. (The function only returns this if a bind with the DN was successfully performed in the past.)
The following section of code attempts to reconnect to the server if the client is disconnected from the server:
#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 );
Last Updated: 10/01/98 17:03:32