diff options
Diffstat (limited to 'ldap/c-sdk/libraries/libldap/getoption.c')
-rw-r--r-- | ldap/c-sdk/libraries/libldap/getoption.c | 475 |
1 files changed, 475 insertions, 0 deletions
diff --git a/ldap/c-sdk/libraries/libldap/getoption.c b/ldap/c-sdk/libraries/libldap/getoption.c new file mode 100644 index 000000000..73e21a2dc --- /dev/null +++ b/ldap/c-sdk/libraries/libldap/getoption.c @@ -0,0 +1,475 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998-1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#include "ldap-int.h" + +#define LDAP_GET_BITOPT( ld, bit ) \ + ((ld)->ld_options & bit ) != 0 ? 1 : 0 + +static int nsldapi_get_api_info( LDAPAPIInfo *aip ); +static int nsldapi_get_feature_info( LDAPAPIFeatureInfo *fip ); + + +int +LDAP_CALL +ldap_get_option( LDAP *ld, int option, void *optdata ) +{ + int rc = 0; + + if ( !nsldapi_initialized ) { + nsldapi_initialize_defaults(); + } + + /* + * optdata MUST be a valid pointer... + */ + if (NULL == optdata) + { + return(LDAP_PARAM_ERROR); + } + /* + * process global options (not associated with an LDAP session handle) + */ + if ( option == LDAP_OPT_MEMALLOC_FN_PTRS ) { + /* struct copy */ + *((struct ldap_memalloc_fns *)optdata) = nsldapi_memalloc_fns; + return( 0 ); + } + + if ( option == LDAP_OPT_API_INFO ) { + rc = nsldapi_get_api_info( (LDAPAPIInfo *)optdata ); + if ( rc != LDAP_SUCCESS ) { + if ( ld != NULL ) { + LDAP_SET_LDERRNO( ld, rc, NULL, NULL ); + } + return( -1 ); + } + return( 0 ); + } + /* + * LDAP_OPT_DEBUG_LEVEL is global + */ + if (LDAP_OPT_DEBUG_LEVEL == option) + { +#ifdef LDAP_DEBUG + *((int *) optdata) = ldap_debug; +#endif /* LDAP_DEBUG */ + return ( 0 ); + } + + /* + * if ld is NULL, arrange to return options from our default settings + */ + if ( ld == NULL ) { + ld = &nsldapi_ld_defaults; + } + + if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) { + return( -1 ); /* punt */ + } + + + if (ld != &nsldapi_ld_defaults) + LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK ); + switch( option ) { +#ifdef LDAP_DNS + case LDAP_OPT_DNS: + *((int *) optdata) = LDAP_GET_BITOPT( ld, LDAP_BITOPT_DNS ); + break; +#endif + + case LDAP_OPT_REFERRALS: + *((int *) optdata) = + LDAP_GET_BITOPT( ld, LDAP_BITOPT_REFERRALS ); + break; + + case LDAP_OPT_SSL: + *((int *) optdata) = LDAP_GET_BITOPT( ld, LDAP_BITOPT_SSL ); + break; + + case LDAP_OPT_RESTART: + *((int *) optdata) = LDAP_GET_BITOPT( ld, LDAP_BITOPT_RESTART ); + break; + + case LDAP_OPT_RECONNECT: + *((int *) optdata) = + LDAP_GET_BITOPT( ld, LDAP_BITOPT_RECONNECT ); + break; + + case LDAP_OPT_NOREBIND: + *((int *) optdata) = + LDAP_GET_BITOPT( ld, LDAP_BITOPT_NOREBIND ); + break; + +#ifdef LDAP_ASYNC_IO + case LDAP_OPT_ASYNC_CONNECT: + *((int *) optdata) = + LDAP_GET_BITOPT( ld, LDAP_BITOPT_ASYNC ); + break; +#endif /* LDAP_ASYNC_IO */ + + /* stuff in the sockbuf */ + case LDAP_X_OPT_SOCKBUF: + *((Sockbuf **) optdata) = ld->ld_sbp; + break; + + case LDAP_OPT_DESC: + if ( ber_sockbuf_get_option( ld->ld_sbp, + LBER_SOCKBUF_OPT_DESC, optdata ) != 0 ) { + LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR, NULL, NULL ); + rc = -1; + } + break; + + /* fields in the LDAP structure */ + case LDAP_OPT_DEREF: + *((int *) optdata) = ld->ld_deref; + break; + case LDAP_OPT_SIZELIMIT: + *((int *) optdata) = ld->ld_sizelimit; + break; + case LDAP_OPT_TIMELIMIT: + *((int *) optdata) = ld->ld_timelimit; + break; + case LDAP_OPT_REFERRAL_HOP_LIMIT: + *((int *) optdata) = ld->ld_refhoplimit; + break; + case LDAP_OPT_PROTOCOL_VERSION: + *((int *) optdata) = ld->ld_version; + break; + case LDAP_OPT_SERVER_CONTROLS: + /* fall through */ + case LDAP_OPT_CLIENT_CONTROLS: + *((LDAPControl ***)optdata) = NULL; + /* nsldapi_dup_controls returns -1 and sets lderrno on error */ + rc = nsldapi_dup_controls( ld, (LDAPControl ***)optdata, + ( option == LDAP_OPT_SERVER_CONTROLS ) ? + ld->ld_servercontrols : ld->ld_clientcontrols ); + break; + + /* rebind proc */ + case LDAP_OPT_REBIND_FN: + *((LDAP_REBINDPROC_CALLBACK **) optdata) = ld->ld_rebind_fn; + break; + case LDAP_OPT_REBIND_ARG: + *((void **) optdata) = ld->ld_rebind_arg; + break; + + /* i/o function pointers */ + case LDAP_OPT_IO_FN_PTRS: + if ( ld->ld_io_fns_ptr == NULL ) { + memset( optdata, 0, sizeof( struct ldap_io_fns )); + } else { + /* struct copy */ + *((struct ldap_io_fns *)optdata) = *(ld->ld_io_fns_ptr); + } + break; + + /* extended i/o function pointers */ + case LDAP_X_OPT_EXTIO_FN_PTRS: + if ( ((struct ldap_x_ext_io_fns *) optdata)->lextiof_size == LDAP_X_EXTIO_FNS_SIZE_REV0) { + ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_close = ld->ld_extclose_fn; + ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_connect = ld->ld_extconnect_fn; + ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_read = ld->ld_extread_fn; + ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_write = ld->ld_extwrite_fn; + ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_poll = ld->ld_extpoll_fn; + ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_newhandle = ld->ld_extnewhandle_fn; + ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_disposehandle = ld->ld_extdisposehandle_fn; + ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_session_arg = ld->ld_ext_session_arg; + } else if ( ((struct ldap_x_ext_io_fns *) optdata)->lextiof_size == + LDAP_X_EXTIO_FNS_SIZE ) { + /* struct copy */ + *((struct ldap_x_ext_io_fns *) optdata) = ld->ld_ext_io_fns; + } else { + LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); + rc = -1; + } + break; + + /* get socketargp in extended i/o function */ + case LDAP_X_OPT_SOCKETARG: + if ( ber_sockbuf_get_option( ld->ld_sbp,LBER_SOCKBUF_OPT_SOCK_ARG, optdata) + != 0 ) { + LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR, NULL, NULL ); + rc = -1; + } + break; + + /* thread function pointers */ + case LDAP_OPT_THREAD_FN_PTRS: + /* struct copy */ + *((struct ldap_thread_fns *) optdata) = ld->ld_thread; + break; + + /* extra thread function pointers */ + case LDAP_OPT_EXTRA_THREAD_FN_PTRS: + /* struct copy */ + *((struct ldap_extra_thread_fns *) optdata) = ld->ld_thread2; + break; + + /* DNS function pointers */ + case LDAP_OPT_DNS_FN_PTRS: + /* struct copy */ + *((struct ldap_dns_fns *) optdata) = ld->ld_dnsfn; + break; + + /* cache function pointers */ + case LDAP_OPT_CACHE_FN_PTRS: + /* struct copy */ + *((struct ldap_cache_fns *) optdata) = ld->ld_cache; + break; + case LDAP_OPT_CACHE_STRATEGY: + *((int *) optdata) = ld->ld_cache_strategy; + break; + case LDAP_OPT_CACHE_ENABLE: + *((int *) optdata) = ld->ld_cache_on; + break; + + case LDAP_OPT_ERROR_NUMBER: + *((int *) optdata) = LDAP_GET_LDERRNO( ld, NULL, NULL ); + break; + + case LDAP_OPT_ERROR_STRING: + (void)LDAP_GET_LDERRNO( ld, NULL, (char **)optdata ); + *((char **) optdata) = nsldapi_strdup( *((char **) optdata )); + break; + + case LDAP_OPT_MATCHED_DN: + (void)LDAP_GET_LDERRNO( ld, (char **)optdata, NULL ); + *((char **) optdata) = nsldapi_strdup( *((char **) optdata )); + break; + + case LDAP_OPT_PREFERRED_LANGUAGE: + if ( NULL != ld->ld_preferred_language ) { + *((char **) optdata) = + nsldapi_strdup(ld->ld_preferred_language); + } else { + *((char **) optdata) = NULL; + } + break; + + case LDAP_OPT_API_FEATURE_INFO: + rc = nsldapi_get_feature_info( (LDAPAPIFeatureInfo *)optdata ); + if ( rc != LDAP_SUCCESS ) { + LDAP_SET_LDERRNO( ld, rc, NULL, NULL ); + rc = -1; + } + break; + + case LDAP_OPT_HOST_NAME: + *((char **) optdata) = nsldapi_strdup( ld->ld_defhost ); + break; + + case LDAP_X_OPT_CONNECT_TIMEOUT: + *((int *) optdata) = ld->ld_connect_timeout; + break; + +#ifdef LDAP_SASLIO_HOOKS + /* SASL options */ + case LDAP_OPT_X_SASL_MECH: + *((char **) optdata) = nsldapi_strdup(ld->ld_def_sasl_mech); + break; + case LDAP_OPT_X_SASL_REALM: + *((char **) optdata) = nsldapi_strdup(ld->ld_def_sasl_realm); + break; + case LDAP_OPT_X_SASL_AUTHCID: + *((char **) optdata) = nsldapi_strdup(ld->ld_def_sasl_authcid); + break; + case LDAP_OPT_X_SASL_AUTHZID: + *((char **) optdata) = nsldapi_strdup(ld->ld_def_sasl_authzid); + break; + case LDAP_OPT_X_SASL_SSF: + { + int sc; + sasl_ssf_t *ssf; + sasl_conn_t *ctx; + if( ld->ld_defconn == NULL ) { + return -1; + } + ctx = (sasl_conn_t *)(ld->ld_defconn->lconn_sasl_ctx); + if ( ctx == NULL ) { + return -1; + } + sc = sasl_getprop( ctx, SASL_SSF, (const void **) &ssf ); + if ( sc != SASL_OK ) { + return -1; + } + *((sasl_ssf_t *) optdata) = *ssf; + } + break; + case LDAP_OPT_X_SASL_SSF_MIN: + *((sasl_ssf_t *) optdata) = ld->ld_sasl_secprops.min_ssf; + break; + case LDAP_OPT_X_SASL_SSF_MAX: + *((sasl_ssf_t *) optdata) = ld->ld_sasl_secprops.max_ssf; + break; + case LDAP_OPT_X_SASL_MAXBUFSIZE: + *((sasl_ssf_t *) optdata) = ld->ld_sasl_secprops.maxbufsize; + break; + case LDAP_OPT_X_SASL_SSF_EXTERNAL: + case LDAP_OPT_X_SASL_SECPROPS: + /* + * These options are write only. Making these options + * read/write would expose semi-private interfaces of libsasl + * for which there are no cross platform/standardized + * definitions. + */ + LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); + rc = -1; + break; +#endif + + default: + LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL ); + rc = -1; + } + if (ld != &nsldapi_ld_defaults) + LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK ); + return( rc ); +} + + +/* + * Table of extended API features we support. + * The first field is the version of the info. strcuture itself; we do not + * use the ones from this table so it is okay to leave as zero. + */ +static LDAPAPIFeatureInfo nsldapi_extensions[] = { + { 0, "SERVER_SIDE_SORT", LDAP_API_FEATURE_SERVER_SIDE_SORT }, + { 0, "VIRTUAL_LIST_VIEW", LDAP_API_FEATURE_VIRTUAL_LIST_VIEW }, + { 0, "PERSISTENT_SEARCH", LDAP_API_FEATURE_PERSISTENT_SEARCH }, + { 0, "PROXY_AUTHORIZATION", LDAP_API_FEATURE_PROXY_AUTHORIZATION }, + { 0, "X_LDERRNO", LDAP_API_FEATURE_X_LDERRNO }, + { 0, "X_MEMCACHE", LDAP_API_FEATURE_X_MEMCACHE }, + { 0, "X_IO_FUNCTIONS", LDAP_API_FEATURE_X_IO_FUNCTIONS }, + { 0, "X_EXTIO_FUNCTIONS", LDAP_API_FEATURE_X_EXTIO_FUNCTIONS }, + { 0, "X_DNS_FUNCTIONS", LDAP_API_FEATURE_X_DNS_FUNCTIONS }, + { 0, "X_MEMALLOC_FUNCTIONS", LDAP_API_FEATURE_X_MEMALLOC_FUNCTIONS }, + { 0, "X_THREAD_FUNCTIONS", LDAP_API_FEATURE_X_THREAD_FUNCTIONS }, + { 0, "X_EXTHREAD_FUNCTIONS", LDAP_API_FEATURE_X_EXTHREAD_FUNCTIONS }, + { 0, "X_GETLANGVALUES", LDAP_API_FEATURE_X_GETLANGVALUES }, + { 0, "X_CLIENT_SIDE_SORT", LDAP_API_FEATURE_X_CLIENT_SIDE_SORT }, + { 0, "X_URL_FUNCTIONS", LDAP_API_FEATURE_X_URL_FUNCTIONS }, + { 0, "X_FILTER_FUNCTIONS", LDAP_API_FEATURE_X_FILTER_FUNCTIONS }, +}; + +#define NSLDAPI_EXTENSIONS_COUNT \ + (sizeof(nsldapi_extensions)/sizeof(LDAPAPIFeatureInfo)) + +/* + * Retrieve information about this implementation of the LDAP API. + * Returns an LDAP error code. + */ +static int +nsldapi_get_api_info( LDAPAPIInfo *aip ) +{ + int i; + + if ( aip == NULL ) { + return( LDAP_PARAM_ERROR ); + } + + aip->ldapai_api_version = LDAP_API_VERSION; + + if ( aip->ldapai_info_version != LDAP_API_INFO_VERSION ) { + aip->ldapai_info_version = LDAP_API_INFO_VERSION; + return( LDAP_PARAM_ERROR ); + } + + aip->ldapai_protocol_version = LDAP_VERSION_MAX; + aip->ldapai_vendor_version = LDAP_VENDOR_VERSION; + + if (( aip->ldapai_vendor_name = nsldapi_strdup( LDAP_VENDOR_NAME )) + == NULL ) { + return( LDAP_NO_MEMORY ); + } + + if ( NSLDAPI_EXTENSIONS_COUNT < 1 ) { + aip->ldapai_extensions = NULL; + } else { + if (( aip->ldapai_extensions = NSLDAPI_CALLOC( + NSLDAPI_EXTENSIONS_COUNT + 1, sizeof(char *))) == NULL ) { + NSLDAPI_FREE( aip->ldapai_vendor_name ); + aip->ldapai_vendor_name = NULL; + return( LDAP_NO_MEMORY ); + } + + for ( i = 0; i < NSLDAPI_EXTENSIONS_COUNT; ++i ) { + if (( aip->ldapai_extensions[i] = nsldapi_strdup( + nsldapi_extensions[i].ldapaif_name )) == NULL ) { + ldap_value_free( aip->ldapai_extensions ); + NSLDAPI_FREE( aip->ldapai_vendor_name ); + aip->ldapai_extensions = NULL; + aip->ldapai_vendor_name = NULL; + return( LDAP_NO_MEMORY ); + } + } + } + + return( LDAP_SUCCESS ); +} + + +/* + * Retrieves information about a specific extended feature of the LDAP API/ + * Returns an LDAP error code. + */ +static int +nsldapi_get_feature_info( LDAPAPIFeatureInfo *fip ) +{ + int i; + + if ( fip == NULL || fip->ldapaif_name == NULL ) { + return( LDAP_PARAM_ERROR ); + } + + if ( fip->ldapaif_info_version != LDAP_FEATURE_INFO_VERSION ) { + fip->ldapaif_info_version = LDAP_FEATURE_INFO_VERSION; + return( LDAP_PARAM_ERROR ); + } + + for ( i = 0; i < NSLDAPI_EXTENSIONS_COUNT; ++i ) { + if ( strcmp( fip->ldapaif_name, + nsldapi_extensions[i].ldapaif_name ) == 0 ) { + fip->ldapaif_version = + nsldapi_extensions[i].ldapaif_version; + break; + } + } + + return(( i < NSLDAPI_EXTENSIONS_COUNT ) ? LDAP_SUCCESS + : LDAP_PARAM_ERROR ); +} |