3 * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
11 #include <ac/stdlib.h>
13 #include <ac/socket.h>
14 #include <ac/string.h>
19 static const LDAPAPIFeatureInfo features[] = {
20 #ifdef LDAP_API_FEATURE_X_OPENLDAP
21 { /* OpenLDAP Extensions API Feature */
22 LDAP_FEATURE_INFO_VERSION,
24 LDAP_API_FEATURE_X_OPENLDAP
28 #ifdef LDAP_API_FEATURE_THREAD_SAFE
29 { /* Basic Thread Safe */
30 LDAP_FEATURE_INFO_VERSION,
32 LDAP_API_FEATURE_THREAD_SAFE
35 #ifdef LDAP_API_FEATURE_SESSION_THREAD_SAFE
36 { /* Session Thread Safe */
37 LDAP_FEATURE_INFO_VERSION,
38 "SESSION_THREAD_SAFE",
39 LDAP_API_FEATURE_SESSION_THREAD_SAFE
42 #ifdef LDAP_API_FEATURE_OPERATION_THREAD_SAFE
43 { /* Operation Thread Safe */
44 LDAP_FEATURE_INFO_VERSION,
45 "OPERATION_THREAD_SAFE",
46 LDAP_API_FEATURE_OPERATION_THREAD_SAFE
49 #ifdef LDAP_API_FEATURE_X_OPENLDAP_REENTRANT
50 { /* OpenLDAP Reentrant */
51 LDAP_FEATURE_INFO_VERSION,
52 "X_OPENLDAP_REENTRANT",
53 LDAP_API_FEATURE_X_OPENLDAP_REENTRANT
56 #if defined( LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE ) && \
57 defined( LDAP_THREAD_SAFE )
58 { /* OpenLDAP Thread Safe */
59 LDAP_FEATURE_INFO_VERSION,
60 "X_OPENLDAP_THREAD_SAFE",
61 LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE
64 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
66 LDAP_FEATURE_INFO_VERSION,
68 LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
71 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
73 LDAP_FEATURE_INFO_VERSION,
74 "X_OPENLDAP_V2_REFERRALS",
75 LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
87 const struct ldapoptions *lo;
89 if( ldap_int_global_options.ldo_valid != LDAP_INITIALIZED ) {
90 ldap_int_initialize();
94 lo = &ldap_int_global_options;
97 assert( LDAP_VALID( ld ) );
99 if( !LDAP_VALID( ld ) ) {
100 return LDAP_OPT_ERROR;
103 lo = &ld->ld_options;
106 if(outvalue == NULL) {
107 /* no place to get to */
108 return LDAP_OPT_ERROR;
112 case LDAP_OPT_API_INFO: {
113 struct ldapapiinfo *info = (struct ldapapiinfo *) outvalue;
116 /* outvalue must point to an apiinfo structure */
117 return LDAP_OPT_ERROR;
120 if(info->ldapai_info_version != LDAP_API_INFO_VERSION) {
121 /* api info version mismatch */
122 info->ldapai_info_version = LDAP_API_INFO_VERSION;
123 return LDAP_OPT_ERROR;
126 info->ldapai_api_version = LDAP_API_VERSION;
127 info->ldapai_api_version = LDAP_API_VERSION;
128 info->ldapai_protocol_version = LDAP_VERSION_MAX;
130 if(features[0].ldapaif_name == NULL) {
131 info->ldapai_extensions = NULL;
134 info->ldapai_extensions = LDAP_MALLOC(sizeof(char *) *
135 sizeof(features)/sizeof(LDAPAPIFeatureInfo));
137 for(i=0; features[i].ldapaif_name != NULL; i++) {
138 info->ldapai_extensions[i] =
139 LDAP_STRDUP(features[i].ldapaif_name);
142 info->ldapai_extensions[i] = NULL;
145 info->ldapai_vendor_name = LDAP_STRDUP(LDAP_VENDOR_NAME);
146 info->ldapai_vendor_version = LDAP_VENDOR_VERSION;
148 return LDAP_OPT_SUCCESS;
157 * (ber_socket_t *) outvalue = ber_pvt_sb_get_desc( &(ld->ld_sb) );
158 return LDAP_OPT_SUCCESS;
160 case LDAP_OPT_TIMEOUT:
161 /* the caller has to free outvalue ! */
162 if ( ldap_int_timeval_dup( outvalue, lo->ldo_tm_api) != 0 )
164 return LDAP_OPT_ERROR;
166 return LDAP_OPT_SUCCESS;
168 case LDAP_OPT_NETWORK_TIMEOUT:
169 /* the caller has to free outvalue ! */
170 if ( ldap_int_timeval_dup( outvalue, lo->ldo_tm_net ) != 0 )
172 return LDAP_OPT_ERROR;
174 return LDAP_OPT_SUCCESS;
177 * (int *) outvalue = lo->ldo_deref;
178 return LDAP_OPT_SUCCESS;
180 case LDAP_OPT_SIZELIMIT:
181 * (int *) outvalue = lo->ldo_sizelimit;
182 return LDAP_OPT_SUCCESS;
184 case LDAP_OPT_TIMELIMIT:
185 * (int *) outvalue = lo->ldo_timelimit;
186 return LDAP_OPT_SUCCESS;
188 case LDAP_OPT_REFERRALS:
189 * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_REFERRALS);
190 return LDAP_OPT_SUCCESS;
192 case LDAP_OPT_RESTART:
193 * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_RESTART);
194 return LDAP_OPT_SUCCESS;
196 case LDAP_OPT_DNS: /* LDAPv2 */
197 * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_DNS);
198 return LDAP_OPT_SUCCESS;
200 case LDAP_OPT_PROTOCOL_VERSION:
201 if ((ld != NULL) && ld->ld_version) {
202 * (int *) outvalue = ld->ld_version;
204 * (int *) outvalue = lo->ldo_version;
206 return LDAP_OPT_SUCCESS;
208 case LDAP_OPT_SERVER_CONTROLS:
209 * (LDAPControl ***) outvalue =
210 ldap_controls_dup( lo->ldo_sctrls );
212 return LDAP_OPT_SUCCESS;
214 case LDAP_OPT_CLIENT_CONTROLS:
215 * (LDAPControl ***) outvalue =
216 ldap_controls_dup( lo->ldo_cctrls );
218 return LDAP_OPT_SUCCESS;
220 case LDAP_OPT_HOST_NAME:
221 * (char **) outvalue = LDAP_STRDUP(lo->ldo_defhost);
222 return LDAP_OPT_SUCCESS;
224 case LDAP_OPT_ERROR_NUMBER:
229 * (int *) outvalue = ld->ld_errno;
230 return LDAP_OPT_SUCCESS;
232 case LDAP_OPT_ERROR_STRING:
238 if( ld->ld_error == NULL ) {
239 * (char **) outvalue = NULL;
241 * (char **) outvalue = LDAP_STRDUP(ld->ld_error);
244 return LDAP_OPT_SUCCESS;
246 case LDAP_OPT_MATCHED_DN:
252 if( ld->ld_matched == NULL ) {
253 * (char **) outvalue = NULL;
255 * (char **) outvalue = LDAP_STRDUP(ld->ld_matched);
258 return LDAP_OPT_SUCCESS;
260 case LDAP_OPT_API_FEATURE_INFO: {
261 LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue;
264 if(info == NULL) return LDAP_OPT_ERROR;
266 if(info->ldapaif_info_version != LDAP_FEATURE_INFO_VERSION) {
267 /* api info version mismatch */
268 info->ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
269 return LDAP_OPT_ERROR;
272 if(info->ldapaif_name == NULL) return LDAP_OPT_ERROR;
274 for(i=0; features[i].ldapaif_name != NULL; i++) {
275 if(!strcmp(info->ldapaif_name, features[i].ldapaif_name)) {
276 info->ldapaif_version =
277 features[i].ldapaif_version;
278 return LDAP_OPT_SUCCESS;
284 case LDAP_OPT_DEBUG_LEVEL:
285 * (int *) outvalue = lo->ldo_debug;
286 return LDAP_OPT_SUCCESS;
290 if ( ldap_pvt_tls_get_option(lo, option, outvalue ) == 0 )
291 return LDAP_OPT_SUCCESS;
297 return LDAP_OPT_ERROR;
304 LDAP_CONST void *invalue)
306 struct ldapoptions *lo;
308 if( ldap_int_global_options.ldo_valid != LDAP_INITIALIZED ) {
309 ldap_int_initialize();
313 lo = &ldap_int_global_options;
316 assert( LDAP_VALID( ld ) );
318 if( !LDAP_VALID( ld ) ) {
319 return LDAP_OPT_ERROR;
322 lo = &ld->ld_options;
326 case LDAP_OPT_REFERRALS:
327 if(invalue == LDAP_OPT_OFF) {
328 LDAP_BOOL_CLR(lo, LDAP_BOOL_REFERRALS);
330 LDAP_BOOL_SET(lo, LDAP_BOOL_REFERRALS);
332 return LDAP_OPT_SUCCESS;
334 case LDAP_OPT_RESTART:
335 if(invalue == LDAP_OPT_OFF) {
336 LDAP_BOOL_CLR(lo, LDAP_BOOL_RESTART);
338 LDAP_BOOL_SET(lo, LDAP_BOOL_RESTART);
340 return LDAP_OPT_SUCCESS;
343 /* options which can withstand invalue == NULL */
345 case LDAP_OPT_SERVER_CONTROLS: {
346 LDAPControl *const *controls =
347 (LDAPControl *const *) invalue;
349 ldap_controls_free( lo->ldo_sctrls );
351 if( controls == NULL || *controls == NULL ) {
352 lo->ldo_sctrls = NULL;
353 return LDAP_OPT_SUCCESS;
356 lo->ldo_sctrls = ldap_controls_dup( controls );
358 if(lo->ldo_sctrls == NULL) {
359 /* memory allocation error ? */
362 } return LDAP_OPT_SUCCESS;
364 case LDAP_OPT_CLIENT_CONTROLS: {
365 LDAPControl *const *controls =
366 (LDAPControl *const *) invalue;
368 ldap_controls_free( lo->ldo_cctrls );
370 if( controls == NULL || *controls == NULL ) {
371 lo->ldo_cctrls = NULL;
372 return LDAP_OPT_SUCCESS;
375 lo->ldo_cctrls = ldap_controls_dup( controls );
377 if(lo->ldo_cctrls == NULL) {
378 /* memory allocation error ? */
381 } return LDAP_OPT_SUCCESS;
383 case LDAP_OPT_TIMEOUT: {
384 const struct timeval *tv =
385 (const struct timeval *) invalue;
387 if ( lo->ldo_tm_api != NULL ) {
388 LDAP_FREE( lo->ldo_tm_api );
389 lo->ldo_tm_api = NULL;
392 if ( ldap_int_timeval_dup( &lo->ldo_tm_api, tv ) != 0 ) {
393 return LDAP_OPT_ERROR;
395 } return LDAP_OPT_SUCCESS;
397 case LDAP_OPT_NETWORK_TIMEOUT: {
398 const struct timeval *tv =
399 (const struct timeval *) invalue;
401 if ( lo->ldo_tm_net != NULL ) {
402 LDAP_FREE( lo->ldo_tm_net );
403 lo->ldo_tm_net = NULL;
406 if ( ldap_int_timeval_dup( &lo->ldo_tm_net, tv ) != 0 ) {
407 return LDAP_OPT_ERROR;
409 } return LDAP_OPT_SUCCESS;
412 if(invalue == NULL) {
413 /* no place to set from */
414 return LDAP_OPT_ERROR;
417 /* options which cannot withstand invalue == NULL */
420 case LDAP_OPT_API_INFO:
426 lo->ldo_deref = * (const int *) invalue;
427 return LDAP_OPT_SUCCESS;
429 case LDAP_OPT_SIZELIMIT:
430 lo->ldo_sizelimit = * (const int *) invalue;
431 return LDAP_OPT_SUCCESS;
433 case LDAP_OPT_TIMELIMIT:
434 lo->ldo_timelimit = * (const int *) invalue;
435 return LDAP_OPT_SUCCESS;
437 case LDAP_OPT_PROTOCOL_VERSION: {
438 int vers = * (const int *) invalue;
439 if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) {
443 ld->ld_version = vers;
444 } return LDAP_OPT_SUCCESS;
447 case LDAP_OPT_HOST_NAME: {
448 const char *host = (const char *) invalue;
450 if(lo->ldo_defhost != NULL) {
451 LDAP_FREE(lo->ldo_defhost);
452 lo->ldo_defhost = NULL;
456 lo->ldo_defhost = LDAP_STRDUP(host);
457 return LDAP_OPT_SUCCESS;
462 * must want global default returned
463 * to initial condition.
465 lo->ldo_defhost = LDAP_STRDUP("localhost");
469 * must want the session default
470 * updated to the current global default
472 lo->ldo_defhost = LDAP_STRDUP(
473 ldap_int_global_options.ldo_defhost);
475 } return LDAP_OPT_SUCCESS;
477 case LDAP_OPT_ERROR_NUMBER: {
478 int err = * (const int *) invalue;
481 /* need a struct ldap */
486 } return LDAP_OPT_SUCCESS;
488 case LDAP_OPT_ERROR_STRING: {
489 const char *err = (const char *) invalue;
492 /* need a struct ldap */
497 LDAP_FREE(ld->ld_error);
500 ld->ld_error = LDAP_STRDUP(err);
501 } return LDAP_OPT_SUCCESS;
503 case LDAP_OPT_MATCHED_DN: {
504 const char *err = (const char *) invalue;
507 /* need a struct ldap */
511 if( ld->ld_matched ) {
512 LDAP_FREE(ld->ld_matched);
515 ld->ld_matched = LDAP_STRDUP(err);
516 } return LDAP_OPT_SUCCESS;
518 case LDAP_OPT_API_FEATURE_INFO:
522 case LDAP_OPT_DEBUG_LEVEL:
523 lo->ldo_debug = * (const int *) invalue;
524 return LDAP_OPT_SUCCESS;
528 if ( ldap_pvt_tls_set_option( lo, option, invalue ) == 0 )
529 return LDAP_OPT_SUCCESS;
534 return LDAP_OPT_ERROR;