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_url_list2hosts(lo->ldo_defludp);
222 return LDAP_OPT_SUCCESS;
225 * (char **) outvalue = ldap_url_list2urls(lo->ldo_defludp);
226 return LDAP_OPT_SUCCESS;
228 case LDAP_OPT_ERROR_NUMBER:
233 * (int *) outvalue = ld->ld_errno;
234 return LDAP_OPT_SUCCESS;
236 case LDAP_OPT_ERROR_STRING:
242 if( ld->ld_error == NULL ) {
243 * (char **) outvalue = NULL;
245 * (char **) outvalue = LDAP_STRDUP(ld->ld_error);
248 return LDAP_OPT_SUCCESS;
250 case LDAP_OPT_MATCHED_DN:
256 if( ld->ld_matched == NULL ) {
257 * (char **) outvalue = NULL;
259 * (char **) outvalue = LDAP_STRDUP(ld->ld_matched);
262 return LDAP_OPT_SUCCESS;
264 case LDAP_OPT_API_FEATURE_INFO: {
265 LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue;
268 if(info == NULL) return LDAP_OPT_ERROR;
270 if(info->ldapaif_info_version != LDAP_FEATURE_INFO_VERSION) {
271 /* api info version mismatch */
272 info->ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
273 return LDAP_OPT_ERROR;
276 if(info->ldapaif_name == NULL) return LDAP_OPT_ERROR;
278 for(i=0; features[i].ldapaif_name != NULL; i++) {
279 if(!strcmp(info->ldapaif_name, features[i].ldapaif_name)) {
280 info->ldapaif_version =
281 features[i].ldapaif_version;
282 return LDAP_OPT_SUCCESS;
288 case LDAP_OPT_DEBUG_LEVEL:
289 * (int *) outvalue = lo->ldo_debug;
290 return LDAP_OPT_SUCCESS;
294 if ( ldap_pvt_tls_get_option((struct ldapoptions *)lo, option, outvalue ) == 0 )
295 return LDAP_OPT_SUCCESS;
301 return LDAP_OPT_ERROR;
308 LDAP_CONST void *invalue)
310 struct ldapoptions *lo;
312 if( ldap_int_global_options.ldo_valid != LDAP_INITIALIZED ) {
313 ldap_int_initialize();
317 lo = &ldap_int_global_options;
320 assert( LDAP_VALID( ld ) );
322 if( !LDAP_VALID( ld ) ) {
323 return LDAP_OPT_ERROR;
326 lo = &ld->ld_options;
330 case LDAP_OPT_REFERRALS:
331 if(invalue == LDAP_OPT_OFF) {
332 LDAP_BOOL_CLR(lo, LDAP_BOOL_REFERRALS);
334 LDAP_BOOL_SET(lo, LDAP_BOOL_REFERRALS);
336 return LDAP_OPT_SUCCESS;
338 case LDAP_OPT_RESTART:
339 if(invalue == LDAP_OPT_OFF) {
340 LDAP_BOOL_CLR(lo, LDAP_BOOL_RESTART);
342 LDAP_BOOL_SET(lo, LDAP_BOOL_RESTART);
344 return LDAP_OPT_SUCCESS;
347 /* options which can withstand invalue == NULL */
349 case LDAP_OPT_SERVER_CONTROLS: {
350 LDAPControl *const *controls =
351 (LDAPControl *const *) invalue;
353 ldap_controls_free( lo->ldo_sctrls );
355 if( controls == NULL || *controls == NULL ) {
356 lo->ldo_sctrls = NULL;
357 return LDAP_OPT_SUCCESS;
360 lo->ldo_sctrls = ldap_controls_dup( controls );
362 if(lo->ldo_sctrls == NULL) {
363 /* memory allocation error ? */
366 } return LDAP_OPT_SUCCESS;
368 case LDAP_OPT_CLIENT_CONTROLS: {
369 LDAPControl *const *controls =
370 (LDAPControl *const *) invalue;
372 ldap_controls_free( lo->ldo_cctrls );
374 if( controls == NULL || *controls == NULL ) {
375 lo->ldo_cctrls = NULL;
376 return LDAP_OPT_SUCCESS;
379 lo->ldo_cctrls = ldap_controls_dup( controls );
381 if(lo->ldo_cctrls == NULL) {
382 /* memory allocation error ? */
385 } return LDAP_OPT_SUCCESS;
387 case LDAP_OPT_TIMEOUT: {
388 const struct timeval *tv =
389 (const struct timeval *) invalue;
391 if ( lo->ldo_tm_api != NULL ) {
392 LDAP_FREE( lo->ldo_tm_api );
393 lo->ldo_tm_api = NULL;
396 if ( ldap_int_timeval_dup( &lo->ldo_tm_api, tv ) != 0 ) {
397 return LDAP_OPT_ERROR;
399 } return LDAP_OPT_SUCCESS;
401 case LDAP_OPT_NETWORK_TIMEOUT: {
402 const struct timeval *tv =
403 (const struct timeval *) invalue;
405 if ( lo->ldo_tm_net != NULL ) {
406 LDAP_FREE( lo->ldo_tm_net );
407 lo->ldo_tm_net = NULL;
410 if ( ldap_int_timeval_dup( &lo->ldo_tm_net, tv ) != 0 ) {
411 return LDAP_OPT_ERROR;
413 } return LDAP_OPT_SUCCESS;
416 if(invalue == NULL) {
417 /* no place to set from */
418 return LDAP_OPT_ERROR;
421 /* options which cannot withstand invalue == NULL */
424 case LDAP_OPT_API_INFO:
430 lo->ldo_deref = * (const int *) invalue;
431 return LDAP_OPT_SUCCESS;
433 case LDAP_OPT_SIZELIMIT:
434 lo->ldo_sizelimit = * (const int *) invalue;
435 return LDAP_OPT_SUCCESS;
437 case LDAP_OPT_TIMELIMIT:
438 lo->ldo_timelimit = * (const int *) invalue;
439 return LDAP_OPT_SUCCESS;
441 case LDAP_OPT_PROTOCOL_VERSION: {
442 int vers = * (const int *) invalue;
443 if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) {
447 ld->ld_version = vers;
448 } return LDAP_OPT_SUCCESS;
451 case LDAP_OPT_HOST_NAME: {
452 const char *host = (const char *) invalue;
453 LDAPURLDesc *ludlist = NULL;
454 int rc = LDAP_OPT_SUCCESS;
457 rc = ldap_url_parsehosts(&ludlist, host);
459 } else if(ld == NULL) {
461 * must want global default returned
462 * to initial condition.
464 rc = ldap_url_parselist(&ludlist, "ldap://localhost/");
468 * must want the session default
469 * updated to the current global default
471 ludlist = ldap_url_duplist(
472 ldap_int_global_options.ldo_defludp);
477 if (rc == LDAP_OPT_SUCCESS) {
478 if (lo->ldo_defludp != NULL)
479 ldap_free_urllist(lo->ldo_defludp);
480 lo->ldo_defludp = ludlist;
486 const char *urls = (const char *) invalue;
487 LDAPURLDesc *ludlist = NULL;
488 int rc = LDAP_OPT_SUCCESS;
491 rc = ldap_url_parselist(&ludlist, urls);
493 } else if(ld == NULL) {
495 * must want global default returned
496 * to initial condition.
498 rc = ldap_url_parselist(&ludlist, "ldap://localhost/");
502 * must want the session default
503 * updated to the current global default
505 ludlist = ldap_url_duplist(
506 ldap_int_global_options.ldo_defludp);
511 if (rc == LDAP_OPT_SUCCESS) {
512 if (lo->ldo_defludp != NULL)
513 ldap_free_urllist(lo->ldo_defludp);
514 lo->ldo_defludp = ludlist;
519 case LDAP_OPT_ERROR_NUMBER: {
520 int err = * (const int *) invalue;
523 /* need a struct ldap */
528 } return LDAP_OPT_SUCCESS;
530 case LDAP_OPT_ERROR_STRING: {
531 const char *err = (const char *) invalue;
534 /* need a struct ldap */
539 LDAP_FREE(ld->ld_error);
542 ld->ld_error = LDAP_STRDUP(err);
543 } return LDAP_OPT_SUCCESS;
545 case LDAP_OPT_MATCHED_DN: {
546 const char *err = (const char *) invalue;
549 /* need a struct ldap */
553 if( ld->ld_matched ) {
554 LDAP_FREE(ld->ld_matched);
557 ld->ld_matched = LDAP_STRDUP(err);
558 } return LDAP_OPT_SUCCESS;
560 case LDAP_OPT_API_FEATURE_INFO:
564 case LDAP_OPT_DEBUG_LEVEL:
565 lo->ldo_debug = * (const int *) invalue;
566 return LDAP_OPT_SUCCESS;
570 if ( ldap_pvt_tls_set_option( lo, option, (void *)invalue ) == 0 )
571 return LDAP_OPT_SUCCESS;
576 return LDAP_OPT_ERROR;