X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Foptions.c;h=b4224bc1f16b5af5e5d0f986c423dee74733d73f;hb=ae471f78c32d7531c729aa88116b8b413cc200bf;hp=f03382519efc99302895c66eaaba9cd327c501f2;hpb=37636eabd33eb03ce3a90a7cc82901800aaf51ac;p=openldap diff --git a/libraries/libldap/options.c b/libraries/libldap/options.c index f03382519e..b4224bc1f1 100644 --- a/libraries/libldap/options.c +++ b/libraries/libldap/options.c @@ -1,18 +1,39 @@ -/* - * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2008 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . */ #include "portable.h" #include -#include + +#include #include #include +#include #include "ldap-int.h" +#define LDAP_OPT_REBIND_PROC 0x4e814d +#define LDAP_OPT_REBIND_PARAMS 0x4e814e + +#define LDAP_OPT_NEXTREF_PROC 0x4e815d +#define LDAP_OPT_NEXTREF_PARAMS 0x4e815e + +#define LDAP_OPT_URLLIST_PROC 0x4e816d +#define LDAP_OPT_URLLIST_PARAMS 0x4e816e + static const LDAPAPIFeatureInfo features[] = { #ifdef LDAP_API_FEATURE_X_OPENLDAP { /* OpenLDAP Extensions API Feature */ @@ -58,13 +79,6 @@ static const LDAPAPIFeatureInfo features[] = { LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE }, #endif -#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS - { /* DNS */ - LDAP_FEATURE_INFO_VERSION, - "X_OPENLDAP_V2_DNS", - LDAP_API_FEATURE_X_OPENLDAP_V2_DNS - }, -#endif #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS { /* V2 Referrals */ LDAP_FEATURE_INFO_VERSION, @@ -83,19 +97,17 @@ ldap_get_option( { struct ldapoptions *lo; - if( ldap_int_global_options.ldo_valid != LDAP_INITIALIZED ) { - ldap_int_initialize(); + /* Get pointer to global option structure */ + lo = LDAP_INT_GLOBAL_OPT(); + if (NULL == lo) { + return LDAP_NO_MEMORY; } - if(outvalue == NULL) { - /* no place to get to */ - return LDAP_OPT_ERROR; + if( lo->ldo_valid != LDAP_INITIALIZED ) { + ldap_int_initialize(lo, NULL); } - if(ld == NULL) { - lo = &ldap_int_global_options; - - } else { + if(ld != NULL) { assert( LDAP_VALID( ld ) ); if( !LDAP_VALID( ld ) ) { @@ -105,6 +117,11 @@ ldap_get_option( lo = &ld->ld_options; } + if(outvalue == NULL) { + /* no place to get to */ + return LDAP_OPT_ERROR; + } + switch(option) { case LDAP_OPT_API_INFO: { struct ldapapiinfo *info = (struct ldapapiinfo *) outvalue; @@ -120,7 +137,6 @@ ldap_get_option( return LDAP_OPT_ERROR; } - info->ldapai_api_version = LDAP_API_VERSION; info->ldapai_api_version = LDAP_API_VERSION; info->ldapai_protocol_version = LDAP_VERSION_MAX; @@ -133,25 +149,48 @@ ldap_get_option( for(i=0; features[i].ldapaif_name != NULL; i++) { info->ldapai_extensions[i] = - strdup(features[i].ldapaif_name); + LDAP_STRDUP(features[i].ldapaif_name); } info->ldapai_extensions[i] = NULL; } - info->ldapai_vendor_name = strdup(LDAP_VENDOR_NAME); + info->ldapai_vendor_name = LDAP_STRDUP(LDAP_VENDOR_NAME); info->ldapai_vendor_version = LDAP_VENDOR_VERSION; return LDAP_OPT_SUCCESS; } break; case LDAP_OPT_DESC: - if(ld == NULL) { + if( ld == NULL || ld->ld_sb == NULL ) { /* bad param */ break; } - * (int *) outvalue = ber_pvt_sb_get_desc( &(ld->ld_sb) ); + ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, outvalue ); + return LDAP_OPT_SUCCESS; + + case LDAP_OPT_SOCKBUF: + if( ld == NULL ) break; + *(Sockbuf **)outvalue = ld->ld_sb; + return LDAP_OPT_SUCCESS; + + case LDAP_OPT_TIMEOUT: + /* the caller has to free outvalue ! */ + if ( lo->ldo_tm_api.tv_sec < 0 ) { + *(void **)outvalue = NULL; + } else if ( ldap_int_timeval_dup( outvalue, &lo->ldo_tm_api ) != 0 ) { + return LDAP_OPT_ERROR; + } + return LDAP_OPT_SUCCESS; + + case LDAP_OPT_NETWORK_TIMEOUT: + /* the caller has to free outvalue ! */ + if ( lo->ldo_tm_net.tv_sec < 0 ) { + *(void **)outvalue = NULL; + } else if ( ldap_int_timeval_dup( outvalue, &lo->ldo_tm_net ) != 0 ) { + return LDAP_OPT_ERROR; + } return LDAP_OPT_SUCCESS; case LDAP_OPT_DEREF: @@ -174,16 +213,8 @@ ldap_get_option( * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_RESTART); return LDAP_OPT_SUCCESS; - case LDAP_OPT_DNS: /* LDAPv2 */ - * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_DNS); - return LDAP_OPT_SUCCESS; - case LDAP_OPT_PROTOCOL_VERSION: - if ((ld != NULL) && ld->ld_version) { - * (int *) outvalue = ld->ld_version; - } else { - * (int *) outvalue = lo->ldo_version; - } + * (int *) outvalue = lo->ldo_version; return LDAP_OPT_SUCCESS; case LDAP_OPT_SERVER_CONTROLS: @@ -199,16 +230,27 @@ ldap_get_option( return LDAP_OPT_SUCCESS; case LDAP_OPT_HOST_NAME: - /* - * draft-ietf-ldapext-ldap-c-api-01 doesn't state - * whether caller has to free host names or not, - * we do. - */ + * (char **) outvalue = ldap_url_list2hosts(lo->ldo_defludp); + return LDAP_OPT_SUCCESS; + + case LDAP_OPT_URI: + * (char **) outvalue = ldap_url_list2urls(lo->ldo_defludp); + return LDAP_OPT_SUCCESS; + + case LDAP_OPT_DEFBASE: + if( lo->ldo_defbase == NULL ) { + * (char **) outvalue = NULL; + } else { + * (char **) outvalue = LDAP_STRDUP(lo->ldo_defbase); + } - * (char **) outvalue = strdup(lo->ldo_defhost); return LDAP_OPT_SUCCESS; - case LDAP_OPT_ERROR_NUMBER: + case LDAP_OPT_CONNECT_ASYNC: + * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_CONNECT_ASYNC); + return LDAP_OPT_SUCCESS; + + case LDAP_OPT_RESULT_CODE: if(ld == NULL) { /* bad param */ break; @@ -216,43 +258,47 @@ ldap_get_option( * (int *) outvalue = ld->ld_errno; return LDAP_OPT_SUCCESS; - case LDAP_OPT_ERROR_STRING: + case LDAP_OPT_DIAGNOSTIC_MESSAGE: if(ld == NULL) { /* bad param */ break; } - /* - * draft-ietf-ldapext-ldap-c-api-01 doesn't require - * the client to have to free error strings, we do - */ - if( ld->ld_error == NULL ) { * (char **) outvalue = NULL; } else { - * (char **) outvalue = strdup(ld->ld_error); + * (char **) outvalue = LDAP_STRDUP(ld->ld_error); } return LDAP_OPT_SUCCESS; - case LDAP_OPT_MATCH_STRING: + case LDAP_OPT_MATCHED_DN: if(ld == NULL) { /* bad param */ break; } - /* - * draft-ietf-ldapext-ldap-c-api-01 doesn't require - * the client to have to free error strings, we do - */ - if( ld->ld_matched == NULL ) { * (char **) outvalue = NULL; } else { - * (char **) outvalue = strdup(ld->ld_matched); + * (char **) outvalue = LDAP_STRDUP( ld->ld_matched ); } - return 0; + return LDAP_OPT_SUCCESS; + + case LDAP_OPT_REFERRAL_URLS: + if(ld == NULL) { + /* bad param */ + break; + } + + if( ld->ld_referrals == NULL ) { + * (char ***) outvalue = NULL; + } else { + * (char ***) outvalue = ldap_value_dup(ld->ld_referrals); + } + + return LDAP_OPT_SUCCESS; case LDAP_OPT_API_FEATURE_INFO: { LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue; @@ -283,6 +329,16 @@ ldap_get_option( return LDAP_OPT_SUCCESS; default: +#ifdef HAVE_TLS + if ( ldap_pvt_tls_get_option( ld, option, outvalue ) == 0 ) { + return LDAP_OPT_SUCCESS; + } +#endif +#ifdef HAVE_CYRUS_SASL + if ( ldap_int_sasl_get_option( ld, option, outvalue ) == 0 ) { + return LDAP_OPT_SUCCESS; + } +#endif /* bad param */ break; } @@ -297,15 +353,28 @@ ldap_set_option( LDAP_CONST void *invalue) { struct ldapoptions *lo; + int *dbglvl = NULL; - if( ldap_int_global_options.ldo_valid != LDAP_INITIALIZED ) { - ldap_int_initialize(); + /* Get pointer to global option structure */ + lo = LDAP_INT_GLOBAL_OPT(); + if (lo == NULL) { + return LDAP_NO_MEMORY; } - if(ld == NULL) { - lo = &ldap_int_global_options; + /* + * The architecture to turn on debugging has a chicken and egg + * problem. Thus, we introduce a fix here. + */ + + if (option == LDAP_OPT_DEBUG_LEVEL) { + dbglvl = (int *) invalue; + } + + if( lo->ldo_valid != LDAP_INITIALIZED ) { + ldap_int_initialize(lo, dbglvl); + } - } else { + if(ld != NULL) { assert( LDAP_VALID( ld ) ); if( !LDAP_VALID( ld ) ) { @@ -331,52 +400,31 @@ ldap_set_option( LDAP_BOOL_SET(lo, LDAP_BOOL_RESTART); } return LDAP_OPT_SUCCESS; - } - - if(invalue == NULL) { - /* no place to set from */ - return LDAP_OPT_ERROR; - } - - switch(option) { - case LDAP_OPT_API_INFO: - case LDAP_OPT_DESC: - /* READ ONLY */ - break; - - case LDAP_OPT_DEREF: - lo->ldo_deref = * (int *) invalue; - return LDAP_OPT_SUCCESS; - - case LDAP_OPT_SIZELIMIT: - lo->ldo_sizelimit = * (int *) invalue; - return LDAP_OPT_SUCCESS; - case LDAP_OPT_TIMELIMIT: - lo->ldo_timelimit = * (int *) invalue; + case LDAP_OPT_CONNECT_ASYNC: + if(invalue == LDAP_OPT_OFF) { + LDAP_BOOL_CLR(lo, LDAP_BOOL_CONNECT_ASYNC); + } else { + LDAP_BOOL_SET(lo, LDAP_BOOL_CONNECT_ASYNC); + } return LDAP_OPT_SUCCESS; + } - case LDAP_OPT_PROTOCOL_VERSION: { - int vers = * (int *) invalue; - if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) { - /* not supported */ - break; - } - ld->ld_version = vers; - } return LDAP_OPT_SUCCESS; - + /* options which can withstand invalue == NULL */ + switch ( option ) { case LDAP_OPT_SERVER_CONTROLS: { - LDAPControl **controls = (LDAPControl **) invalue; + LDAPControl *const *controls = + (LDAPControl *const *) invalue; - ldap_controls_free( lo->ldo_sctrls ); + if( lo->ldo_sctrls ) + ldap_controls_free( lo->ldo_sctrls ); if( controls == NULL || *controls == NULL ) { lo->ldo_sctrls = NULL; return LDAP_OPT_SUCCESS; } - lo->ldo_sctrls = - ldap_controls_dup( (LDAPControl **) invalue ); + lo->ldo_sctrls = ldap_controls_dup( controls ); if(lo->ldo_sctrls == NULL) { /* memory allocation error ? */ @@ -385,17 +433,18 @@ ldap_set_option( } return LDAP_OPT_SUCCESS; case LDAP_OPT_CLIENT_CONTROLS: { - LDAPControl **controls = (LDAPControl **) invalue; + LDAPControl *const *controls = + (LDAPControl *const *) invalue; - ldap_controls_free( lo->ldo_cctrls ); + if( lo->ldo_cctrls ) + ldap_controls_free( lo->ldo_cctrls ); if( controls == NULL || *controls == NULL ) { lo->ldo_cctrls = NULL; return LDAP_OPT_SUCCESS; } - lo->ldo_cctrls = - ldap_controls_dup( (LDAPControl **) invalue ); + lo->ldo_cctrls = ldap_controls_dup( controls ); if(lo->ldo_cctrls == NULL) { /* memory allocation error ? */ @@ -403,73 +452,321 @@ ldap_set_option( } } return LDAP_OPT_SUCCESS; + case LDAP_OPT_HOST_NAME: { - char* host = (char *) invalue; + const char *host = (const char *) invalue; + LDAPURLDesc *ludlist = NULL; + int rc = LDAP_OPT_SUCCESS; + + if(host != NULL) { + rc = ldap_url_parsehosts( &ludlist, host, + lo->ldo_defport ? lo->ldo_defport : LDAP_PORT ); + + } else if(ld == NULL) { + /* + * must want global default returned + * to initial condition. + */ + rc = ldap_url_parselist_ext(&ludlist, "ldap://localhost/", NULL, + LDAP_PVT_URL_PARSE_NOEMPTY_HOST + | LDAP_PVT_URL_PARSE_DEF_PORT ); - if(lo->ldo_defhost != NULL) { - LDAP_FREE(lo->ldo_defhost); - lo->ldo_defhost = NULL; + } else { + /* + * must want the session default + * updated to the current global default + */ + ludlist = ldap_url_duplist( + ldap_int_global_options.ldo_defludp); + if (ludlist == NULL) + rc = LDAP_NO_MEMORY; } - if(host != NULL) { - lo->ldo_defhost = strdup(host); - return LDAP_OPT_SUCCESS; + if (rc == LDAP_OPT_SUCCESS) { + if (lo->ldo_defludp != NULL) + ldap_free_urllist(lo->ldo_defludp); + lo->ldo_defludp = ludlist; } + return rc; + } - if(ld == NULL) { + case LDAP_OPT_URI: { + const char *urls = (const char *) invalue; + LDAPURLDesc *ludlist = NULL; + int rc = LDAP_OPT_SUCCESS; + + if(urls != NULL) { + rc = ldap_url_parselist_ext(&ludlist, urls, NULL, + LDAP_PVT_URL_PARSE_NOEMPTY_HOST + | LDAP_PVT_URL_PARSE_DEF_PORT ); + } else if(ld == NULL) { /* * must want global default returned * to initial condition. */ - lo->ldo_defhost = strdup("localhost"); + rc = ldap_url_parselist_ext(&ludlist, "ldap://localhost/", NULL, + LDAP_PVT_URL_PARSE_NOEMPTY_HOST + | LDAP_PVT_URL_PARSE_DEF_PORT ); } else { /* * must want the session default * updated to the current global default */ - lo->ldo_defhost = strdup( - ldap_int_global_options.ldo_defhost); + ludlist = ldap_url_duplist( + ldap_int_global_options.ldo_defludp); + if (ludlist == NULL) + rc = LDAP_URL_ERR_MEM; } - } return LDAP_OPT_SUCCESS; - case LDAP_OPT_ERROR_NUMBER: { - int err = * (int *) invalue; + switch (rc) { + case LDAP_URL_SUCCESS: /* Success */ + rc = LDAP_SUCCESS; + break; - if(ld == NULL) { - /* need a struct ldap */ + case LDAP_URL_ERR_MEM: /* can't allocate memory space */ + rc = LDAP_NO_MEMORY; + break; + + case LDAP_URL_ERR_PARAM: /* parameter is bad */ + case LDAP_URL_ERR_BADSCHEME: /* URL doesn't begin with "ldap[si]://" */ + case LDAP_URL_ERR_BADENCLOSURE: /* URL is missing trailing ">" */ + case LDAP_URL_ERR_BADURL: /* URL is bad */ + case LDAP_URL_ERR_BADHOST: /* host port is bad */ + case LDAP_URL_ERR_BADATTRS: /* bad (or missing) attributes */ + case LDAP_URL_ERR_BADSCOPE: /* scope string is invalid (or missing) */ + case LDAP_URL_ERR_BADFILTER: /* bad or missing filter */ + case LDAP_URL_ERR_BADEXTS: /* bad or missing extensions */ + rc = LDAP_PARAM_ERROR; break; } - ld->ld_errno = err; + if (rc == LDAP_SUCCESS) { + if (lo->ldo_defludp != NULL) + ldap_free_urllist(lo->ldo_defludp); + lo->ldo_defludp = ludlist; + } + return rc; + } + + case LDAP_OPT_DEFBASE: { + const char *newbase = (const char *) invalue; + char *defbase = NULL; + + if ( newbase != NULL ) { + defbase = LDAP_STRDUP( newbase ); + if ( defbase == NULL ) return LDAP_NO_MEMORY; + + } else if ( ld != NULL ) { + defbase = LDAP_STRDUP( ldap_int_global_options.ldo_defbase ); + if ( defbase == NULL ) return LDAP_NO_MEMORY; + } + + if ( lo->ldo_defbase != NULL ) + LDAP_FREE( lo->ldo_defbase ); + lo->ldo_defbase = defbase; } return LDAP_OPT_SUCCESS; - case LDAP_OPT_ERROR_STRING: { - char* err = (char *) invalue; + case LDAP_OPT_DIAGNOSTIC_MESSAGE: { + const char *err = (const char *) invalue; if(ld == NULL) { /* need a struct ldap */ - break; + return LDAP_OPT_ERROR; } if( ld->ld_error ) { LDAP_FREE(ld->ld_error); + ld->ld_error = NULL; + } + + if ( err ) { + ld->ld_error = LDAP_STRDUP(err); + } + } return LDAP_OPT_SUCCESS; + + case LDAP_OPT_MATCHED_DN: { + const char *matched = (const char *) invalue; + + if (ld == NULL) { + /* need a struct ldap */ + return LDAP_OPT_ERROR; + } + + if( ld->ld_matched ) { + LDAP_FREE(ld->ld_matched); + ld->ld_matched = NULL; + } + + if ( matched ) { + ld->ld_matched = LDAP_STRDUP( matched ); + } + } return LDAP_OPT_SUCCESS; + + case LDAP_OPT_REFERRAL_URLS: { + char *const *referrals = (char *const *) invalue; + + if(ld == NULL) { + /* need a struct ldap */ + return LDAP_OPT_ERROR; + } + + if( ld->ld_referrals ) { + LDAP_VFREE(ld->ld_referrals); } - ld->ld_error = strdup(err); + if ( referrals ) { + ld->ld_referrals = ldap_value_dup(referrals); + } + } return LDAP_OPT_SUCCESS; + + /* Only accessed from inside this function by ldap_set_rebind_proc() */ + case LDAP_OPT_REBIND_PROC: { + lo->ldo_rebind_proc = (LDAP_REBIND_PROC *)invalue; + } return LDAP_OPT_SUCCESS; + case LDAP_OPT_REBIND_PARAMS: { + lo->ldo_rebind_params = (void *)invalue; + } return LDAP_OPT_SUCCESS; + + /* Only accessed from inside this function by ldap_set_nextref_proc() */ + case LDAP_OPT_NEXTREF_PROC: { + lo->ldo_nextref_proc = (LDAP_NEXTREF_PROC *)invalue; + } return LDAP_OPT_SUCCESS; + case LDAP_OPT_NEXTREF_PARAMS: { + lo->ldo_nextref_params = (void *)invalue; } return LDAP_OPT_SUCCESS; + /* Only accessed from inside this function by ldap_set_urllist_proc() */ + case LDAP_OPT_URLLIST_PROC: { + lo->ldo_urllist_proc = (LDAP_URLLIST_PROC *)invalue; + } return LDAP_OPT_SUCCESS; + case LDAP_OPT_URLLIST_PARAMS: { + lo->ldo_urllist_params = (void *)invalue; + } return LDAP_OPT_SUCCESS; + + /* read-only options */ + case LDAP_OPT_API_INFO: + case LDAP_OPT_DESC: + case LDAP_OPT_SOCKBUF: case LDAP_OPT_API_FEATURE_INFO: - /* read-only */ - break; + return LDAP_OPT_ERROR; + /* options which cannot withstand invalue == NULL */ + case LDAP_OPT_DEREF: + case LDAP_OPT_SIZELIMIT: + case LDAP_OPT_TIMELIMIT: + case LDAP_OPT_PROTOCOL_VERSION: + case LDAP_OPT_RESULT_CODE: case LDAP_OPT_DEBUG_LEVEL: - lo->ldo_debug = * (int *) invalue; - return LDAP_OPT_SUCCESS; + case LDAP_OPT_TIMEOUT: + case LDAP_OPT_NETWORK_TIMEOUT: + if(invalue == NULL) { + /* no place to set from */ + return LDAP_OPT_ERROR; + } + break; default: +#ifdef HAVE_TLS + if ( ldap_pvt_tls_set_option( ld, option, (void *)invalue ) == 0 ) + return LDAP_OPT_SUCCESS; +#endif +#ifdef HAVE_CYRUS_SASL + if ( ldap_int_sasl_set_option( ld, option, (void *)invalue ) == 0 ) + return LDAP_OPT_SUCCESS; +#endif /* bad param */ - break; + return LDAP_OPT_ERROR; + } + + /* options which cannot withstand invalue == NULL */ + + switch(option) { + case LDAP_OPT_DEREF: + /* FIXME: check value for protocol compliance? */ + lo->ldo_deref = * (const int *) invalue; + return LDAP_OPT_SUCCESS; + + case LDAP_OPT_SIZELIMIT: + /* FIXME: check value for protocol compliance? */ + lo->ldo_sizelimit = * (const int *) invalue; + return LDAP_OPT_SUCCESS; + + case LDAP_OPT_TIMELIMIT: + /* FIXME: check value for protocol compliance? */ + lo->ldo_timelimit = * (const int *) invalue; + return LDAP_OPT_SUCCESS; + + case LDAP_OPT_TIMEOUT: { + const struct timeval *tv = + (const struct timeval *) invalue; + + lo->ldo_tm_api = *tv; + } return LDAP_OPT_SUCCESS; + + case LDAP_OPT_NETWORK_TIMEOUT: { + const struct timeval *tv = + (const struct timeval *) invalue; + + lo->ldo_tm_net = *tv; + } return LDAP_OPT_SUCCESS; + + case LDAP_OPT_PROTOCOL_VERSION: { + int vers = * (const int *) invalue; + if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) { + /* not supported */ + break; + } + lo->ldo_version = vers; + } return LDAP_OPT_SUCCESS; + + case LDAP_OPT_RESULT_CODE: { + int err = * (const int *) invalue; + + if(ld == NULL) { + /* need a struct ldap */ + break; + } + + ld->ld_errno = err; + } return LDAP_OPT_SUCCESS; + + case LDAP_OPT_DEBUG_LEVEL: + lo->ldo_debug = * (const int *) invalue; + return LDAP_OPT_SUCCESS; } return LDAP_OPT_ERROR; } + +int +ldap_set_rebind_proc( LDAP *ld, LDAP_REBIND_PROC *proc, void *params ) +{ + int rc; + rc = ldap_set_option( ld, LDAP_OPT_REBIND_PROC, (void *)proc ); + if( rc != LDAP_OPT_SUCCESS ) return rc; + + rc = ldap_set_option( ld, LDAP_OPT_REBIND_PARAMS, (void *)params ); + return rc; +} + +int +ldap_set_nextref_proc( LDAP *ld, LDAP_NEXTREF_PROC *proc, void *params ) +{ + int rc; + rc = ldap_set_option( ld, LDAP_OPT_NEXTREF_PROC, (void *)proc ); + if( rc != LDAP_OPT_SUCCESS ) return rc; + + rc = ldap_set_option( ld, LDAP_OPT_NEXTREF_PARAMS, (void *)params ); + return rc; +} + +int +ldap_set_urllist_proc( LDAP *ld, LDAP_URLLIST_PROC *proc, void *params ) +{ + int rc; + rc = ldap_set_option( ld, LDAP_OPT_URLLIST_PROC, (void *)proc ); + if( rc != LDAP_OPT_SUCCESS ) return rc; + + rc = ldap_set_option( ld, LDAP_OPT_URLLIST_PARAMS, (void *)params ); + return rc; +}