Back to index

lightning-sunbird  0.9+nobinonly
getoption.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla Communicator client code, released
00015  * March 31, 1998.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 #include "ldap-int.h"
00038 
00039 #define LDAP_GET_BITOPT( ld, bit ) \
00040        ((ld)->ld_options & bit ) != 0 ? 1 : 0
00041 
00042 static int nsldapi_get_api_info( LDAPAPIInfo *aip );
00043 static int nsldapi_get_feature_info( LDAPAPIFeatureInfo *fip );
00044 
00045 
00046 int
00047 LDAP_CALL
00048 ldap_get_option( LDAP *ld, int option, void *optdata )
00049 {
00050        int           rc = 0;
00051 
00052        if ( !nsldapi_initialized ) {
00053               nsldapi_initialize_defaults();
00054        }
00055 
00056     /*
00057      * optdata MUST be a valid pointer...
00058      */
00059     if (NULL == optdata)
00060     {
00061         return(LDAP_PARAM_ERROR);
00062     }
00063        /*
00064         * process global options (not associated with an LDAP session handle)
00065         */
00066        if ( option == LDAP_OPT_MEMALLOC_FN_PTRS ) {
00067               /* struct copy */
00068               *((struct ldap_memalloc_fns *)optdata) = nsldapi_memalloc_fns;
00069               return( 0 );
00070        }
00071 
00072        if ( option == LDAP_OPT_API_INFO ) {
00073               rc = nsldapi_get_api_info( (LDAPAPIInfo *)optdata );
00074               if ( rc != LDAP_SUCCESS ) {
00075                      if ( ld != NULL ) {
00076                             LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
00077                      }
00078                      return( -1 );
00079               }
00080               return( 0 );
00081        }
00082     /* 
00083      * LDAP_OPT_DEBUG_LEVEL is global 
00084      */
00085     if (LDAP_OPT_DEBUG_LEVEL == option) 
00086     {
00087 #ifdef LDAP_DEBUG      
00088         *((int *) optdata) = ldap_debug;
00089 #endif /* LDAP_DEBUG */
00090         return ( 0 );
00091     }
00092 
00093        /*
00094         * if ld is NULL, arrange to return options from our default settings
00095         */
00096        if ( ld == NULL ) {
00097               ld = &nsldapi_ld_defaults;
00098        }
00099 
00100        if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
00101               return( -1 ); /* punt */
00102        }
00103 
00104 
00105        if (ld != &nsldapi_ld_defaults)
00106               LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK );
00107        switch( option ) {
00108 #ifdef LDAP_DNS
00109        case LDAP_OPT_DNS:
00110               *((int *) optdata) = LDAP_GET_BITOPT( ld, LDAP_BITOPT_DNS );
00111               break;
00112 #endif
00113 
00114        case LDAP_OPT_REFERRALS:
00115               *((int *) optdata) =
00116                   LDAP_GET_BITOPT( ld, LDAP_BITOPT_REFERRALS );
00117               break;
00118 
00119        case LDAP_OPT_SSL:
00120               *((int *) optdata) = LDAP_GET_BITOPT( ld, LDAP_BITOPT_SSL );
00121               break;
00122 
00123        case LDAP_OPT_RESTART:
00124               *((int *) optdata) = LDAP_GET_BITOPT( ld, LDAP_BITOPT_RESTART );
00125               break;
00126 
00127        case LDAP_OPT_RECONNECT:
00128               *((int *) optdata) =
00129                   LDAP_GET_BITOPT( ld, LDAP_BITOPT_RECONNECT );
00130               break;
00131 
00132 #ifdef LDAP_ASYNC_IO
00133        case LDAP_OPT_ASYNC_CONNECT:
00134               *((int *) optdata) =
00135                   LDAP_GET_BITOPT( ld, LDAP_BITOPT_ASYNC );
00136               break;
00137 #endif /* LDAP_ASYNC_IO */
00138 
00139        /* stuff in the sockbuf */
00140        case LDAP_OPT_DESC:
00141               if ( ber_sockbuf_get_option( ld->ld_sbp,
00142                   LBER_SOCKBUF_OPT_DESC, optdata ) != 0 ) {
00143                      LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR, NULL, NULL );
00144                      rc = -1;
00145               }
00146               break;
00147 
00148        /* fields in the LDAP structure */
00149        case LDAP_OPT_DEREF:
00150               *((int *) optdata) = ld->ld_deref;
00151               break;
00152        case LDAP_OPT_SIZELIMIT:
00153               *((int *) optdata) = ld->ld_sizelimit;
00154                 break;  
00155        case LDAP_OPT_TIMELIMIT:
00156               *((int *) optdata) = ld->ld_timelimit;
00157                 break;
00158        case LDAP_OPT_REFERRAL_HOP_LIMIT:
00159                *((int *) optdata) = ld->ld_refhoplimit;
00160               break;
00161        case LDAP_OPT_PROTOCOL_VERSION:
00162                *((int *) optdata) = ld->ld_version;
00163               break;
00164        case LDAP_OPT_SERVER_CONTROLS:
00165               /* fall through */
00166        case LDAP_OPT_CLIENT_CONTROLS:
00167               *((LDAPControl ***)optdata) = NULL;
00168               /* nsldapi_dup_controls returns -1 and sets lderrno on error */
00169               rc = nsldapi_dup_controls( ld, (LDAPControl ***)optdata,
00170                   ( option == LDAP_OPT_SERVER_CONTROLS ) ?
00171                   ld->ld_servercontrols : ld->ld_clientcontrols );
00172               break;
00173 
00174        /* rebind proc */
00175        case LDAP_OPT_REBIND_FN:
00176               *((LDAP_REBINDPROC_CALLBACK **) optdata) = ld->ld_rebind_fn;
00177               break;
00178        case LDAP_OPT_REBIND_ARG:
00179               *((void **) optdata) = ld->ld_rebind_arg;
00180               break;
00181 
00182        /* i/o function pointers */
00183        case LDAP_OPT_IO_FN_PTRS:
00184               if ( ld->ld_io_fns_ptr == NULL ) {
00185                      memset( optdata, 0, sizeof( struct ldap_io_fns ));
00186               } else {
00187                      /* struct copy */
00188                      *((struct ldap_io_fns *)optdata) = *(ld->ld_io_fns_ptr);
00189               }
00190               break;
00191 
00192        /* extended i/o function pointers */
00193        case LDAP_X_OPT_EXTIO_FN_PTRS:
00194          if ( ((struct ldap_x_ext_io_fns *) optdata)->lextiof_size == LDAP_X_EXTIO_FNS_SIZE_REV0) {
00195            ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_close = ld->ld_extclose_fn;
00196            ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_connect = ld->ld_extconnect_fn;
00197            ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_read = ld->ld_extread_fn;
00198            ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_write = ld->ld_extwrite_fn;
00199            ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_poll = ld->ld_extpoll_fn;
00200            ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_newhandle = ld->ld_extnewhandle_fn;
00201            ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_disposehandle = ld->ld_extdisposehandle_fn;
00202            ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_session_arg = ld->ld_ext_session_arg;
00203          } else if ( ((struct ldap_x_ext_io_fns *) optdata)->lextiof_size ==
00204                     LDAP_X_EXTIO_FNS_SIZE ) {
00205            /* struct copy */
00206            *((struct ldap_x_ext_io_fns *) optdata) = ld->ld_ext_io_fns;
00207          } else {       
00208            LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
00209            rc = -1;
00210          }
00211          break;
00212 
00213        /* thread function pointers */
00214        case LDAP_OPT_THREAD_FN_PTRS:
00215               /* struct copy */
00216               *((struct ldap_thread_fns *) optdata) = ld->ld_thread;
00217               break;
00218 
00219        /* DNS function pointers */
00220        case LDAP_OPT_DNS_FN_PTRS:
00221               /* struct copy */
00222               *((struct ldap_dns_fns *) optdata) = ld->ld_dnsfn;
00223               break;
00224 
00225        /* cache function pointers */
00226        case LDAP_OPT_CACHE_FN_PTRS:
00227               /* struct copy */
00228               *((struct ldap_cache_fns *) optdata) = ld->ld_cache;
00229               break;
00230        case LDAP_OPT_CACHE_STRATEGY:
00231               *((int *) optdata) = ld->ld_cache_strategy;
00232               break;
00233        case LDAP_OPT_CACHE_ENABLE:
00234               *((int *) optdata) = ld->ld_cache_on;
00235               break;
00236 
00237        case LDAP_OPT_ERROR_NUMBER:
00238               *((int *) optdata) = LDAP_GET_LDERRNO( ld, NULL, NULL );
00239               break;
00240 
00241        case LDAP_OPT_ERROR_STRING:
00242               (void)LDAP_GET_LDERRNO( ld, NULL, (char **)optdata );
00243               *((char **) optdata) = nsldapi_strdup( *((char **) optdata ));
00244               break;
00245 
00246        case LDAP_OPT_MATCHED_DN:
00247               (void)LDAP_GET_LDERRNO( ld, (char **)optdata, NULL );
00248               *((char **) optdata) = nsldapi_strdup( *((char **) optdata ));
00249               break;
00250 
00251        case LDAP_OPT_PREFERRED_LANGUAGE:
00252               if ( NULL != ld->ld_preferred_language ) {
00253                      *((char **) optdata) =
00254                          nsldapi_strdup(ld->ld_preferred_language);
00255               } else {
00256                      *((char **) optdata) = NULL;
00257               }
00258               break;
00259 
00260        case LDAP_OPT_API_FEATURE_INFO:
00261               rc = nsldapi_get_feature_info( (LDAPAPIFeatureInfo *)optdata );
00262               if ( rc != LDAP_SUCCESS ) {
00263                      LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
00264                      rc = -1;
00265               }
00266               break;
00267 
00268        case LDAP_OPT_HOST_NAME:
00269               *((char **) optdata) = nsldapi_strdup( ld->ld_defhost );
00270               break;
00271 
00272         case LDAP_X_OPT_CONNECT_TIMEOUT:
00273                 *((int *) optdata) = ld->ld_connect_timeout;
00274                 break;
00275 
00276        default:
00277               LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
00278               rc = -1;
00279        }
00280        if (ld != &nsldapi_ld_defaults)
00281               LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK  );
00282        return( rc );
00283 }
00284 
00285 
00286 /*
00287  * Table of extended API features we support.
00288  * The first field is the version of the info. strcuture itself; we do not
00289  * use the ones from this table so it is okay to leave as zero.
00290  */
00291 static LDAPAPIFeatureInfo nsldapi_extensions[] = {
00292     { 0, "SERVER_SIDE_SORT",              LDAP_API_FEATURE_SERVER_SIDE_SORT },
00293     { 0, "VIRTUAL_LIST_VIEW",             LDAP_API_FEATURE_VIRTUAL_LIST_VIEW },
00294     { 0, "PERSISTENT_SEARCH",             LDAP_API_FEATURE_PERSISTENT_SEARCH },
00295     { 0, "PROXY_AUTHORIZATION",           LDAP_API_FEATURE_PROXY_AUTHORIZATION },
00296     { 0, "X_LDERRNO",                     LDAP_API_FEATURE_X_LDERRNO },
00297     { 0, "X_MEMCACHE",                    LDAP_API_FEATURE_X_MEMCACHE },
00298     { 0, "X_IO_FUNCTIONS",         LDAP_API_FEATURE_X_IO_FUNCTIONS },
00299     { 0, "X_EXTIO_FUNCTIONS",             LDAP_API_FEATURE_X_EXTIO_FUNCTIONS },
00300     { 0, "X_DNS_FUNCTIONS",        LDAP_API_FEATURE_X_DNS_FUNCTIONS },
00301     { 0, "X_MEMALLOC_FUNCTIONS",   LDAP_API_FEATURE_X_MEMALLOC_FUNCTIONS },
00302     { 0, "X_THREAD_FUNCTIONS",            LDAP_API_FEATURE_X_THREAD_FUNCTIONS },
00303     { 0, "X_EXTHREAD_FUNCTIONS",   LDAP_API_FEATURE_X_EXTHREAD_FUNCTIONS },
00304     { 0, "X_GETLANGVALUES",        LDAP_API_FEATURE_X_GETLANGVALUES },
00305     { 0, "X_CLIENT_SIDE_SORT",            LDAP_API_FEATURE_X_CLIENT_SIDE_SORT },
00306     { 0, "X_URL_FUNCTIONS",        LDAP_API_FEATURE_X_URL_FUNCTIONS },
00307     { 0, "X_FILTER_FUNCTIONS",            LDAP_API_FEATURE_X_FILTER_FUNCTIONS },
00308 };
00309 
00310 #define NSLDAPI_EXTENSIONS_COUNT   \
00311        (sizeof(nsldapi_extensions)/sizeof(LDAPAPIFeatureInfo))
00312 
00313 /*
00314  * Retrieve information about this implementation of the LDAP API.
00315  * Returns an LDAP error code.
00316  */
00317 static int
00318 nsldapi_get_api_info( LDAPAPIInfo *aip )
00319 {
00320        int    i;
00321 
00322        if ( aip == NULL ) {
00323               return( LDAP_PARAM_ERROR );
00324        }
00325 
00326        aip->ldapai_api_version = LDAP_API_VERSION;
00327 
00328        if ( aip->ldapai_info_version != LDAP_API_INFO_VERSION ) {
00329               aip->ldapai_info_version = LDAP_API_INFO_VERSION;
00330               return( LDAP_PARAM_ERROR );
00331        }
00332 
00333        aip->ldapai_protocol_version = LDAP_VERSION_MAX;
00334        aip->ldapai_vendor_version = LDAP_VENDOR_VERSION;
00335 
00336        if (( aip->ldapai_vendor_name = nsldapi_strdup( LDAP_VENDOR_NAME ))
00337            == NULL ) {
00338               return( LDAP_NO_MEMORY );
00339        }
00340 
00341        if ( NSLDAPI_EXTENSIONS_COUNT < 1 ) {
00342               aip->ldapai_extensions = NULL;
00343        } else {
00344               if (( aip->ldapai_extensions = NSLDAPI_CALLOC(
00345                   NSLDAPI_EXTENSIONS_COUNT + 1, sizeof(char *))) == NULL ) {
00346                      NSLDAPI_FREE( aip->ldapai_vendor_name );
00347                      aip->ldapai_vendor_name = NULL;
00348                      return( LDAP_NO_MEMORY );
00349               }
00350 
00351               for ( i = 0; i < NSLDAPI_EXTENSIONS_COUNT; ++i ) {
00352                      if (( aip->ldapai_extensions[i] = nsldapi_strdup(
00353                          nsldapi_extensions[i].ldapaif_name )) == NULL ) {
00354                             ldap_value_free( aip->ldapai_extensions );
00355                             NSLDAPI_FREE( aip->ldapai_vendor_name );
00356                             aip->ldapai_extensions = NULL;
00357                             aip->ldapai_vendor_name = NULL;
00358                             return( LDAP_NO_MEMORY );
00359                      }
00360               }
00361        }
00362 
00363        return( LDAP_SUCCESS );
00364 }
00365 
00366 
00367 /*
00368  * Retrieves information about a specific extended feature of the LDAP API/
00369  * Returns an LDAP error code.
00370  */
00371 static int
00372 nsldapi_get_feature_info( LDAPAPIFeatureInfo *fip )
00373 {
00374        int    i;
00375 
00376        if ( fip == NULL || fip->ldapaif_name == NULL ) {
00377               return( LDAP_PARAM_ERROR );
00378        }
00379 
00380        if ( fip->ldapaif_info_version != LDAP_FEATURE_INFO_VERSION ) {
00381               fip->ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
00382               return( LDAP_PARAM_ERROR );
00383        }
00384 
00385        for ( i = 0; i < NSLDAPI_EXTENSIONS_COUNT; ++i ) {
00386               if ( strcmp( fip->ldapaif_name,
00387                   nsldapi_extensions[i].ldapaif_name ) == 0 ) {
00388                      fip->ldapaif_version =
00389                          nsldapi_extensions[i].ldapaif_version;
00390                      break;
00391               }
00392        }
00393 
00394        return(( i < NSLDAPI_EXTENSIONS_COUNT ) ? LDAP_SUCCESS
00395            : LDAP_PARAM_ERROR );
00396 }