X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Foptions.c;h=69db0c6651d02021f194a83cff2671749de7bdd5;hb=eb4761c71703bfef45b7b6a1d0d7c4ac7cdacc3c;hp=fae53f0f21b25e59b33a9579815bdb79ae54a13b;hpb=d9b09ecc1f68b5c3ac1bce16cc8a34fa99a4463b;p=openldap diff --git a/libraries/libldap/options.c b/libraries/libldap/options.c index fae53f0f21..69db0c6651 100644 --- a/libraries/libldap/options.c +++ b/libraries/libldap/options.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2005 The OpenLDAP Foundation. + * Copyright 1998-2010 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,6 +28,12 @@ #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 */ @@ -171,14 +177,18 @@ ldap_get_option( case LDAP_OPT_TIMEOUT: /* the caller has to free outvalue ! */ - if ( ldap_int_timeval_dup( outvalue, lo->ldo_tm_api) != 0 ) { + 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 ( ldap_int_timeval_dup( outvalue, lo->ldo_tm_net ) != 0 ) { + 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; @@ -227,7 +237,35 @@ ldap_get_option( * (char **) outvalue = ldap_url_list2urls(lo->ldo_defludp); return LDAP_OPT_SUCCESS; - case LDAP_OPT_ERROR_NUMBER: + case LDAP_OPT_DEFBASE: + if( lo->ldo_defbase == NULL ) { + * (char **) outvalue = NULL; + } else { + * (char **) outvalue = LDAP_STRDUP(lo->ldo_defbase); + } + + return LDAP_OPT_SUCCESS; + + case LDAP_OPT_CONNECT_ASYNC: + * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_CONNECT_ASYNC); + return LDAP_OPT_SUCCESS; + + case LDAP_OPT_CONNECT_CB: + { + /* Getting deletes the specified callback */ + ldaplist **ll = &lo->ldo_conn_cbs; + for (;*ll;ll = &(*ll)->ll_next) { + if ((*ll)->ll_data == outvalue) { + ldaplist *lc = *ll; + *ll = lc->ll_next; + LDAP_FREE(lc); + break; + } + } + } + return LDAP_OPT_SUCCESS; + + case LDAP_OPT_RESULT_CODE: if(ld == NULL) { /* bad param */ break; @@ -235,7 +273,7 @@ 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; @@ -258,7 +296,7 @@ ldap_get_option( if( ld->ld_matched == NULL ) { * (char **) outvalue = NULL; } else { - * (char **) outvalue = LDAP_STRDUP(ld->ld_matched); + * (char **) outvalue = LDAP_STRDUP( ld->ld_matched ); } return LDAP_OPT_SUCCESS; @@ -304,6 +342,18 @@ ldap_get_option( case LDAP_OPT_DEBUG_LEVEL: * (int *) outvalue = lo->ldo_debug; return LDAP_OPT_SUCCESS; + + case LDAP_OPT_X_KEEPALIVE_IDLE: + * (int *) outvalue = lo->ldo_keepalive_idle; + return LDAP_OPT_SUCCESS; + + case LDAP_OPT_X_KEEPALIVE_PROBES: + * (int *) outvalue = lo->ldo_keepalive_probes; + return LDAP_OPT_SUCCESS; + + case LDAP_OPT_X_KEEPALIVE_INTERVAL: + * (int *) outvalue = lo->ldo_keepalive_interval; + return LDAP_OPT_SUCCESS; default: #ifdef HAVE_TLS @@ -315,6 +365,11 @@ ldap_get_option( if ( ldap_int_sasl_get_option( ld, option, outvalue ) == 0 ) { return LDAP_OPT_SUCCESS; } +#endif +#ifdef HAVE_GSSAPI + if ( ldap_int_gssapi_get_option( ld, option, outvalue ) == 0 ) { + return LDAP_OPT_SUCCESS; + } #endif /* bad param */ break; @@ -377,6 +432,14 @@ ldap_set_option( LDAP_BOOL_SET(lo, LDAP_BOOL_RESTART); } return LDAP_OPT_SUCCESS; + + 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; } /* options which can withstand invalue == NULL */ @@ -385,7 +448,8 @@ ldap_set_option( 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; @@ -404,7 +468,8 @@ ldap_set_option( 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; @@ -419,77 +484,6 @@ ldap_set_option( } } return LDAP_OPT_SUCCESS; - case LDAP_OPT_TIMEOUT: { - const struct timeval *tv = - (const struct timeval *) invalue; - - if ( lo->ldo_tm_api != NULL ) { - LDAP_FREE( lo->ldo_tm_api ); - lo->ldo_tm_api = NULL; - } - - if ( ldap_int_timeval_dup( &lo->ldo_tm_api, tv ) != 0 ) { - return LDAP_OPT_ERROR; - } - } return LDAP_OPT_SUCCESS; - - case LDAP_OPT_NETWORK_TIMEOUT: { - const struct timeval *tv = - (const struct timeval *) invalue; - - if ( lo->ldo_tm_net != NULL ) { - LDAP_FREE( lo->ldo_tm_net ); - lo->ldo_tm_net = NULL; - } - - if ( ldap_int_timeval_dup( &lo->ldo_tm_net, tv ) != 0 ) { - return LDAP_OPT_ERROR; - } - } 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; - } - - if(invalue == NULL) { - /* no place to set from */ - return LDAP_OPT_ERROR; - } - - /* options which cannot withstand invalue == NULL */ - - switch(option) { - case LDAP_OPT_API_INFO: - case LDAP_OPT_DESC: - /* READ ONLY */ - break; - - case LDAP_OPT_DEREF: - lo->ldo_deref = * (const int *) invalue; - return LDAP_OPT_SUCCESS; - - case LDAP_OPT_SIZELIMIT: - lo->ldo_sizelimit = * (const int *) invalue; - return LDAP_OPT_SUCCESS; - - case LDAP_OPT_TIMELIMIT: - lo->ldo_timelimit = * (const int *) invalue; - 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_HOST_NAME: { const char *host = (const char *) invalue; @@ -505,7 +499,9 @@ ldap_set_option( * must want global default returned * to initial condition. */ - rc = ldap_url_parselist(&ludlist, "ldap://localhost/"); + rc = ldap_url_parselist_ext(&ludlist, "ldap://localhost/", NULL, + LDAP_PVT_URL_PARSE_NOEMPTY_HOST + | LDAP_PVT_URL_PARSE_DEF_PORT ); } else { /* @@ -532,13 +528,17 @@ ldap_set_option( int rc = LDAP_OPT_SUCCESS; if(urls != NULL) { - rc = ldap_url_parselist(&ludlist, urls); + 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. */ - rc = ldap_url_parselist(&ludlist, "ldap://localhost/"); + rc = ldap_url_parselist_ext(&ludlist, "ldap://localhost/", NULL, + LDAP_PVT_URL_PARSE_NOEMPTY_HOST + | LDAP_PVT_URL_PARSE_DEF_PORT ); } else { /* @@ -548,7 +548,7 @@ ldap_set_option( ludlist = ldap_url_duplist( ldap_int_global_options.ldo_defludp); if (ludlist == NULL) - rc = LDAP_NO_MEMORY; + rc = LDAP_URL_ERR_MEM; } switch (rc) { @@ -573,7 +573,7 @@ ldap_set_option( break; } - if (rc == LDAP_OPT_SUCCESS) { + if (rc == LDAP_SUCCESS) { if (lo->ldo_defludp != NULL) ldap_free_urllist(lo->ldo_defludp); lo->ldo_defludp = ludlist; @@ -581,45 +581,58 @@ ldap_set_option( return rc; } - case LDAP_OPT_ERROR_NUMBER: { - int err = * (const int *) invalue; + case LDAP_OPT_DEFBASE: { + const char *newbase = (const char *) invalue; + char *defbase = NULL; - if(ld == NULL) { - /* need a struct ldap */ - break; - } + if ( newbase != NULL ) { + defbase = LDAP_STRDUP( newbase ); + if ( defbase == NULL ) return LDAP_NO_MEMORY; - ld->ld_errno = err; + } 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: { + 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; } - ld->ld_error = LDAP_STRDUP(err); + if ( err ) { + ld->ld_error = LDAP_STRDUP(err); + } } return LDAP_OPT_SUCCESS; case LDAP_OPT_MATCHED_DN: { - const char *err = (const char *) invalue; + const char *matched = (const char *) invalue; - if(ld == NULL) { + if (ld == NULL) { /* need a struct ldap */ - break; + return LDAP_OPT_ERROR; } if( ld->ld_matched ) { LDAP_FREE(ld->ld_matched); + ld->ld_matched = NULL; } - ld->ld_matched = LDAP_STRDUP(err); + if ( matched ) { + ld->ld_matched = LDAP_STRDUP( matched ); + } } return LDAP_OPT_SUCCESS; case LDAP_OPT_REFERRAL_URLS: { @@ -627,23 +640,67 @@ ldap_set_option( if(ld == NULL) { /* need a struct ldap */ - break; + return LDAP_OPT_ERROR; } if( ld->ld_referrals ) { LDAP_VFREE(ld->ld_referrals); } - ld->ld_referrals = ldap_value_dup(referrals); + 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 = * (const int *) invalue; - return LDAP_OPT_SUCCESS; + case LDAP_OPT_TIMEOUT: + case LDAP_OPT_NETWORK_TIMEOUT: + case LDAP_OPT_CONNECT_CB: + case LDAP_OPT_X_KEEPALIVE_IDLE: + case LDAP_OPT_X_KEEPALIVE_PROBES : + case LDAP_OPT_X_KEEPALIVE_INTERVAL : + if(invalue == NULL) { + /* no place to set from */ + return LDAP_OPT_ERROR; + } + break; default: #ifdef HAVE_TLS @@ -653,9 +710,91 @@ ldap_set_option( #ifdef HAVE_CYRUS_SASL if ( ldap_int_sasl_set_option( ld, option, (void *)invalue ) == 0 ) return LDAP_OPT_SUCCESS; +#endif +#ifdef HAVE_GSSAPI + if ( ldap_int_gssapi_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; + + case LDAP_OPT_CONNECT_CB: + { + /* setting pushes the callback */ + ldaplist *ll; + ll = LDAP_MALLOC( sizeof( *ll )); + ll->ll_data = (void *)invalue; + ll->ll_next = lo->ldo_conn_cbs; + lo->ldo_conn_cbs = ll; + } + return LDAP_OPT_SUCCESS; + case LDAP_OPT_X_KEEPALIVE_IDLE: + lo->ldo_keepalive_idle = * (const int *) invalue; + return LDAP_OPT_SUCCESS; + case LDAP_OPT_X_KEEPALIVE_PROBES : + lo->ldo_keepalive_probes = * (const int *) invalue; + return LDAP_OPT_SUCCESS; + case LDAP_OPT_X_KEEPALIVE_INTERVAL : + lo->ldo_keepalive_interval = * (const int *) invalue; + return LDAP_OPT_SUCCESS; + } return LDAP_OPT_ERROR; } @@ -670,3 +809,25 @@ ldap_set_rebind_proc( LDAP *ld, LDAP_REBIND_PROC *proc, void *params ) 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; +}