2 * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 #pragma ident "%Z%%M% %I% %E% SMI"
9 * The contents of this file are subject to the Netscape Public
10 * License Version 1.1 (the "License"); you may not use this file
11 * except in compliance with the License. You may obtain a copy of
12 * the License at http://www.mozilla.org/NPL/
14 * Software distributed under the License is distributed on an "AS
15 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
16 * implied. See the License for the specific language governing
17 * rights and limitations under the License.
19 * The Original Code is Mozilla Communicator client code, released
22 * The Initial Developer of the Original Code is Netscape
23 * Communications Corporation. Portions created by Netscape are
24 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
31 #define LDAP_GET_BITOPT( ld, bit ) \
32 ((ld)->ld_options & bit ) != 0 ? 1 : 0
34 static int nsldapi_get_api_info( LDAPAPIInfo
*aip
);
35 static int nsldapi_get_feature_info( LDAPAPIFeatureInfo
*fip
);
40 ldap_get_option( LDAP
*ld
, int option
, void *optdata
)
44 if ( !nsldapi_initialized
) {
45 nsldapi_initialize_defaults();
49 * optdata MUST be a valid pointer...
53 return(LDAP_PARAM_ERROR
);
56 * process global options (not associated with an LDAP session handle)
58 if ( option
== LDAP_OPT_MEMALLOC_FN_PTRS
) {
60 *((struct ldap_memalloc_fns
*)optdata
) = nsldapi_memalloc_fns
;
64 if ( option
== LDAP_OPT_API_INFO
) {
65 rc
= nsldapi_get_api_info( (LDAPAPIInfo
*)optdata
);
66 if ( rc
!= LDAP_SUCCESS
) {
68 LDAP_SET_LDERRNO( ld
, rc
, NULL
, NULL
);
75 * LDAP_OPT_DEBUG_LEVEL is global
77 if (LDAP_OPT_DEBUG_LEVEL
== option
)
80 *((int *) optdata
) = ldap_debug
;
81 #endif /* LDAP_DEBUG */
86 * if ld is NULL, arrange to return options from our default settings
89 ld
= &nsldapi_ld_defaults
;
92 if ( !NSLDAPI_VALID_LDAP_POINTER( ld
)) {
93 return( -1 ); /* punt */
97 if (ld
!= &nsldapi_ld_defaults
)
98 LDAP_MUTEX_LOCK( ld
, LDAP_OPTION_LOCK
);
102 *((int *) optdata
) = LDAP_GET_BITOPT( ld
, LDAP_BITOPT_DNS
);
106 case LDAP_OPT_REFERRALS
:
108 LDAP_GET_BITOPT( ld
, LDAP_BITOPT_REFERRALS
);
111 #ifdef LDAP_SSLIO_HOOKS
113 *((int *) optdata
) = LDAP_GET_BITOPT( ld
, LDAP_BITOPT_SSL
);
116 case LDAP_OPT_RESTART
:
117 *((int *) optdata
) = LDAP_GET_BITOPT( ld
, LDAP_BITOPT_RESTART
);
120 case LDAP_OPT_RECONNECT
:
122 LDAP_GET_BITOPT( ld
, LDAP_BITOPT_RECONNECT
);
126 case LDAP_OPT_ASYNC_CONNECT
:
128 LDAP_GET_BITOPT( ld
, LDAP_BITOPT_ASYNC
);
130 #endif /* LDAP_ASYNC_IO */
132 /* stuff in the sockbuf */
133 case LDAP_X_OPT_SOCKBUF
:
134 *((Sockbuf
**) optdata
) = ld
->ld_sbp
;
137 if ( ber_sockbuf_get_option( ld
->ld_sbp
,
138 LBER_SOCKBUF_OPT_DESC
, optdata
) != 0 ) {
139 LDAP_SET_LDERRNO( ld
, LDAP_LOCAL_ERROR
, NULL
, NULL
);
144 /* fields in the LDAP structure */
146 *((int *) optdata
) = ld
->ld_deref
;
148 case LDAP_OPT_SIZELIMIT
:
149 *((int *) optdata
) = ld
->ld_sizelimit
;
151 case LDAP_OPT_TIMELIMIT
:
152 *((int *) optdata
) = ld
->ld_timelimit
;
154 case LDAP_OPT_REFERRAL_HOP_LIMIT
:
155 *((int *) optdata
) = ld
->ld_refhoplimit
;
157 case LDAP_OPT_PROTOCOL_VERSION
:
158 *((int *) optdata
) = ld
->ld_version
;
160 case LDAP_OPT_SERVER_CONTROLS
:
162 case LDAP_OPT_CLIENT_CONTROLS
:
163 *((LDAPControl
***)optdata
) = NULL
;
164 /* nsldapi_dup_controls returns -1 and sets lderrno on error */
165 rc
= nsldapi_dup_controls( ld
, (LDAPControl
***)optdata
,
166 ( option
== LDAP_OPT_SERVER_CONTROLS
) ?
167 ld
->ld_servercontrols
: ld
->ld_clientcontrols
);
171 case LDAP_OPT_REBIND_FN
:
172 *((LDAP_REBINDPROC_CALLBACK
**) optdata
) = ld
->ld_rebind_fn
;
174 case LDAP_OPT_REBIND_ARG
:
175 *((void **) optdata
) = ld
->ld_rebind_arg
;
178 #ifdef LDAP_SSLIO_HOOKS
179 /* i/o function pointers */
180 case LDAP_OPT_IO_FN_PTRS
:
181 if ( ld
->ld_io_fns_ptr
== NULL
) {
182 memset( optdata
, 0, sizeof( struct ldap_io_fns
));
185 *((struct ldap_io_fns
*)optdata
) = *(ld
->ld_io_fns_ptr
);
189 /* extended i/o function pointers */
190 case LDAP_X_OPT_EXTIO_FN_PTRS
:
191 if ( ((struct ldap_x_ext_io_fns
*) optdata
)->lextiof_size
== LDAP_X_EXTIO_FNS_SIZE_REV0
) {
192 ((struct ldap_x_ext_io_fns_rev0
*) optdata
)->lextiof_close
= ld
->ld_extclose_fn
;
193 ((struct ldap_x_ext_io_fns_rev0
*) optdata
)->lextiof_connect
= ld
->ld_extconnect_fn
;
194 ((struct ldap_x_ext_io_fns_rev0
*) optdata
)->lextiof_read
= ld
->ld_extread_fn
;
195 ((struct ldap_x_ext_io_fns_rev0
*) optdata
)->lextiof_write
= ld
->ld_extwrite_fn
;
196 ((struct ldap_x_ext_io_fns_rev0
*) optdata
)->lextiof_poll
= ld
->ld_extpoll_fn
;
197 ((struct ldap_x_ext_io_fns_rev0
*) optdata
)->lextiof_newhandle
= ld
->ld_extnewhandle_fn
;
198 ((struct ldap_x_ext_io_fns_rev0
*) optdata
)->lextiof_disposehandle
= ld
->ld_extdisposehandle_fn
;
199 ((struct ldap_x_ext_io_fns_rev0
*) optdata
)->lextiof_session_arg
= ld
->ld_ext_session_arg
;
200 } else if ( ((struct ldap_x_ext_io_fns
*) optdata
)->lextiof_size
==
201 LDAP_X_EXTIO_FNS_SIZE
) {
203 *((struct ldap_x_ext_io_fns
*) optdata
) = ld
->ld_ext_io_fns
;
205 LDAP_SET_LDERRNO( ld
, LDAP_PARAM_ERROR
, NULL
, NULL
);
209 #endif /* LDAP_SSLIO_HOOKS */
211 /* thread function pointers */
212 case LDAP_OPT_THREAD_FN_PTRS
:
214 *((struct ldap_thread_fns
*) optdata
) = ld
->ld_thread
;
217 /* DNS function pointers */
218 case LDAP_OPT_DNS_FN_PTRS
:
220 *((struct ldap_dns_fns
*) optdata
) = ld
->ld_dnsfn
;
223 /* cache function pointers */
224 case LDAP_OPT_CACHE_FN_PTRS
:
226 *((struct ldap_cache_fns
*) optdata
) = ld
->ld_cache
;
228 case LDAP_OPT_CACHE_STRATEGY
:
229 *((int *) optdata
) = ld
->ld_cache_strategy
;
231 case LDAP_OPT_CACHE_ENABLE
:
232 *((int *) optdata
) = ld
->ld_cache_on
;
235 case LDAP_OPT_ERROR_NUMBER
:
236 *((int *) optdata
) = LDAP_GET_LDERRNO( ld
, NULL
, NULL
);
239 case LDAP_OPT_ERROR_STRING
:
240 (void)LDAP_GET_LDERRNO( ld
, NULL
, (char **)optdata
);
241 *((char **) optdata
) = nsldapi_strdup( *((char **) optdata
));
244 case LDAP_OPT_MATCHED_DN
:
245 (void)LDAP_GET_LDERRNO( ld
, (char **)optdata
, NULL
);
246 *((char **) optdata
) = nsldapi_strdup( *((char **) optdata
));
249 case LDAP_OPT_PREFERRED_LANGUAGE
:
250 if ( NULL
!= ld
->ld_preferred_language
) {
251 *((char **) optdata
) =
252 nsldapi_strdup(ld
->ld_preferred_language
);
254 *((char **) optdata
) = NULL
;
258 case LDAP_OPT_API_FEATURE_INFO
:
259 rc
= nsldapi_get_feature_info( (LDAPAPIFeatureInfo
*)optdata
);
260 if ( rc
!= LDAP_SUCCESS
) {
261 LDAP_SET_LDERRNO( ld
, rc
, NULL
, NULL
);
266 case LDAP_OPT_HOST_NAME
:
267 *((char **) optdata
) = nsldapi_strdup( ld
->ld_defhost
);
270 case LDAP_X_OPT_CONNECT_TIMEOUT
:
271 *((int *) optdata
) = ld
->ld_connect_timeout
;
274 #ifdef LDAP_SASLIO_HOOKS
276 case LDAP_OPT_X_SASL_MECH
:
277 *((char **) optdata
) = nsldapi_strdup(ld
->ld_def_sasl_mech
);
279 case LDAP_OPT_X_SASL_REALM
:
280 *((char **) optdata
) = nsldapi_strdup(ld
->ld_def_sasl_realm
);
282 case LDAP_OPT_X_SASL_AUTHCID
:
283 *((char **) optdata
) = nsldapi_strdup(ld
->ld_def_sasl_authcid
);
285 case LDAP_OPT_X_SASL_AUTHZID
:
286 *((char **) optdata
) = nsldapi_strdup(ld
->ld_def_sasl_authzid
);
288 case LDAP_OPT_X_SASL_SSF
:
293 if( ld
->ld_defconn
== NULL
||
294 ld
->ld_defconn
->lconn_sb
== NULL
) {
297 ctx
= (sasl_conn_t
*)(ld
->ld_defconn
->lconn_sb
->sb_sasl_ctx
);
301 sc
= sasl_getprop( ctx
, SASL_SSF
, (const void **) &ssf
);
302 if ( sc
!= SASL_OK
) {
305 *((sasl_ssf_t
*) optdata
) = *ssf
;
308 case LDAP_OPT_X_SASL_SSF_MIN
:
309 *((sasl_ssf_t
*) optdata
) = ld
->ld_sasl_secprops
.min_ssf
;
311 case LDAP_OPT_X_SASL_SSF_MAX
:
312 *((sasl_ssf_t
*) optdata
) = ld
->ld_sasl_secprops
.max_ssf
;
314 case LDAP_OPT_X_SASL_MAXBUFSIZE
:
315 *((sasl_ssf_t
*) optdata
) = ld
->ld_sasl_secprops
.maxbufsize
;
317 case LDAP_OPT_X_SASL_SSF_EXTERNAL
:
318 case LDAP_OPT_X_SASL_SECPROPS
:
320 * These options are write only. Making these options
321 * read/write would expose semi-private interfaces of libsasl
322 * for which there are no cross platform/standardized
325 LDAP_SET_LDERRNO( ld
, LDAP_PARAM_ERROR
, NULL
, NULL
);
331 LDAP_SET_LDERRNO( ld
, LDAP_PARAM_ERROR
, NULL
, NULL
);
334 if (ld
!= &nsldapi_ld_defaults
)
335 LDAP_MUTEX_UNLOCK( ld
, LDAP_OPTION_LOCK
);
341 * Table of extended API features we support.
342 * The first field is the version of the info. strcuture itself; we do not
343 * use the ones from this table so it is okay to leave as zero.
345 static LDAPAPIFeatureInfo nsldapi_extensions
[] = {
346 { 0, "SERVER_SIDE_SORT", LDAP_API_FEATURE_SERVER_SIDE_SORT
},
347 { 0, "VIRTUAL_LIST_VIEW", LDAP_API_FEATURE_VIRTUAL_LIST_VIEW
},
348 { 0, "PERSISTENT_SEARCH", LDAP_API_FEATURE_PERSISTENT_SEARCH
},
349 { 0, "PROXY_AUTHORIZATION", LDAP_API_FEATURE_PROXY_AUTHORIZATION
},
350 { 0, "X_LDERRNO", LDAP_API_FEATURE_X_LDERRNO
},
351 { 0, "X_MEMCACHE", LDAP_API_FEATURE_X_MEMCACHE
},
352 { 0, "X_IO_FUNCTIONS", LDAP_API_FEATURE_X_IO_FUNCTIONS
},
353 { 0, "X_EXTIO_FUNCTIONS", LDAP_API_FEATURE_X_EXTIO_FUNCTIONS
},
354 { 0, "X_DNS_FUNCTIONS", LDAP_API_FEATURE_X_DNS_FUNCTIONS
},
355 { 0, "X_MEMALLOC_FUNCTIONS", LDAP_API_FEATURE_X_MEMALLOC_FUNCTIONS
},
356 { 0, "X_THREAD_FUNCTIONS", LDAP_API_FEATURE_X_THREAD_FUNCTIONS
},
357 { 0, "X_EXTHREAD_FUNCTIONS", LDAP_API_FEATURE_X_EXTHREAD_FUNCTIONS
},
358 { 0, "X_GETLANGVALUES", LDAP_API_FEATURE_X_GETLANGVALUES
},
359 { 0, "X_CLIENT_SIDE_SORT", LDAP_API_FEATURE_X_CLIENT_SIDE_SORT
},
360 { 0, "X_URL_FUNCTIONS", LDAP_API_FEATURE_X_URL_FUNCTIONS
},
361 { 0, "X_FILTER_FUNCTIONS", LDAP_API_FEATURE_X_FILTER_FUNCTIONS
},
364 #define NSLDAPI_EXTENSIONS_COUNT \
365 (sizeof(nsldapi_extensions)/sizeof(LDAPAPIFeatureInfo))
368 * Retrieve information about this implementation of the LDAP API.
369 * Returns an LDAP error code.
372 nsldapi_get_api_info( LDAPAPIInfo
*aip
)
377 return( LDAP_PARAM_ERROR
);
380 aip
->ldapai_api_version
= LDAP_API_VERSION
;
382 if ( aip
->ldapai_info_version
!= LDAP_API_INFO_VERSION
) {
383 aip
->ldapai_info_version
= LDAP_API_INFO_VERSION
;
384 return( LDAP_PARAM_ERROR
);
387 aip
->ldapai_protocol_version
= LDAP_VERSION_MAX
;
388 aip
->ldapai_vendor_version
= LDAP_VENDOR_VERSION
;
390 if (( aip
->ldapai_vendor_name
= nsldapi_strdup( LDAP_VENDOR_NAME
))
392 return( LDAP_NO_MEMORY
);
395 if ( NSLDAPI_EXTENSIONS_COUNT
< 1 ) {
396 aip
->ldapai_extensions
= NULL
;
398 if (( aip
->ldapai_extensions
= NSLDAPI_CALLOC(
399 NSLDAPI_EXTENSIONS_COUNT
+ 1, sizeof(char *))) == NULL
) {
400 NSLDAPI_FREE( aip
->ldapai_vendor_name
);
401 aip
->ldapai_vendor_name
= NULL
;
402 return( LDAP_NO_MEMORY
);
405 for ( i
= 0; i
< NSLDAPI_EXTENSIONS_COUNT
; ++i
) {
406 if (( aip
->ldapai_extensions
[i
] = nsldapi_strdup(
407 nsldapi_extensions
[i
].ldapaif_name
)) == NULL
) {
408 ldap_value_free( aip
->ldapai_extensions
);
409 NSLDAPI_FREE( aip
->ldapai_vendor_name
);
410 aip
->ldapai_extensions
= NULL
;
411 aip
->ldapai_vendor_name
= NULL
;
412 return( LDAP_NO_MEMORY
);
417 return( LDAP_SUCCESS
);
422 * Retrieves information about a specific extended feature of the LDAP API/
423 * Returns an LDAP error code.
426 nsldapi_get_feature_info( LDAPAPIFeatureInfo
*fip
)
430 if ( fip
== NULL
|| fip
->ldapaif_name
== NULL
) {
431 return( LDAP_PARAM_ERROR
);
434 if ( fip
->ldapaif_info_version
!= LDAP_FEATURE_INFO_VERSION
) {
435 fip
->ldapaif_info_version
= LDAP_FEATURE_INFO_VERSION
;
436 return( LDAP_PARAM_ERROR
);
439 for ( i
= 0; i
< NSLDAPI_EXTENSIONS_COUNT
; ++i
) {
440 if ( strcmp( fip
->ldapaif_name
,
441 nsldapi_extensions
[i
].ldapaif_name
) == 0 ) {
442 fip
->ldapaif_version
=
443 nsldapi_extensions
[i
].ldapaif_version
;
448 return(( i
< NSLDAPI_EXTENSIONS_COUNT
) ? LDAP_SUCCESS
449 : LDAP_PARAM_ERROR
);