1 /* $OpenLDAP: pkg/ldap/libraries/libldap/options.c,v 1.75.2.6 2008/02/11 23:26:41 kurt Exp $ */ 2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 3 * 4 * Copyright 1998-2008 The OpenLDAP Foundation. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted only as authorized by the OpenLDAP 9 * Public License. 10 * 11 * A copy of this license is available in the file LICENSE in the 12 * top-level directory of the distribution or, alternatively, at 13 * <http://www.OpenLDAP.org/license.html>. 14 */ 15 16 #include "portable.h" 17 18 #include <stdio.h> 19 20 #include <ac/stdlib.h> 21 22 #include <ac/socket.h> 23 #include <ac/string.h> 24 #include <ac/time.h> 25 26 #include "ldap-int.h" 27 28 #define LDAP_OPT_REBIND_PROC 0x4e814d 29 #define LDAP_OPT_REBIND_PARAMS 0x4e814e 30 31 #define LDAP_OPT_NEXTREF_PROC 0x4e815d 32 #define LDAP_OPT_NEXTREF_PARAMS 0x4e815e 33 34 #define LDAP_OPT_URLLIST_PROC 0x4e816d 35 #define LDAP_OPT_URLLIST_PARAMS 0x4e816e 36 37 static const LDAPAPIFeatureInfo features[] = { 38 #ifdef LDAP_API_FEATURE_X_OPENLDAP 39 { /* OpenLDAP Extensions API Feature */ 40 LDAP_FEATURE_INFO_VERSION, 41 "X_OPENLDAP", 42 LDAP_API_FEATURE_X_OPENLDAP 43 }, 44 #endif 45 46 #ifdef LDAP_API_FEATURE_THREAD_SAFE 47 { /* Basic Thread Safe */ 48 LDAP_FEATURE_INFO_VERSION, 49 "THREAD_SAFE", 50 LDAP_API_FEATURE_THREAD_SAFE 51 }, 52 #endif 53 #ifdef LDAP_API_FEATURE_SESSION_THREAD_SAFE 54 { /* Session Thread Safe */ 55 LDAP_FEATURE_INFO_VERSION, 56 "SESSION_THREAD_SAFE", 57 LDAP_API_FEATURE_SESSION_THREAD_SAFE 58 }, 59 #endif 60 #ifdef LDAP_API_FEATURE_OPERATION_THREAD_SAFE 61 { /* Operation Thread Safe */ 62 LDAP_FEATURE_INFO_VERSION, 63 "OPERATION_THREAD_SAFE", 64 LDAP_API_FEATURE_OPERATION_THREAD_SAFE 65 }, 66 #endif 67 #ifdef LDAP_API_FEATURE_X_OPENLDAP_REENTRANT 68 { /* OpenLDAP Reentrant */ 69 LDAP_FEATURE_INFO_VERSION, 70 "X_OPENLDAP_REENTRANT", 71 LDAP_API_FEATURE_X_OPENLDAP_REENTRANT 72 }, 73 #endif 74 #if defined( LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE ) && \ 75 defined( LDAP_THREAD_SAFE ) 76 { /* OpenLDAP Thread Safe */ 77 LDAP_FEATURE_INFO_VERSION, 78 "X_OPENLDAP_THREAD_SAFE", 79 LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE 80 }, 81 #endif 82 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS 83 { /* V2 Referrals */ 84 LDAP_FEATURE_INFO_VERSION, 85 "X_OPENLDAP_V2_REFERRALS", 86 LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS 87 }, 88 #endif 89 {0, NULL, 0} 90 }; 91 92 int 93 ldap_get_option( 94 LDAP *ld, 95 int option, 96 void *outvalue) 97 { 98 struct ldapoptions *lo; 99 100 /* Get pointer to global option structure */ 101 lo = LDAP_INT_GLOBAL_OPT(); 102 if (NULL == lo) { 103 return LDAP_NO_MEMORY; 104 } 105 106 if( lo->ldo_valid != LDAP_INITIALIZED ) { 107 ldap_int_initialize(lo, NULL); 108 } 109 110 if(ld != NULL) { 111 assert( LDAP_VALID( ld ) ); 112 113 if( !LDAP_VALID( ld ) ) { 114 return LDAP_OPT_ERROR; 115 } 116 117 lo = &ld->ld_options; 118 } 119 120 if(outvalue == NULL) { 121 /* no place to get to */ 122 return LDAP_OPT_ERROR; 123 } 124 125 switch(option) { 126 case LDAP_OPT_API_INFO: { 127 struct ldapapiinfo *info = (struct ldapapiinfo *) outvalue; 128 129 if(info == NULL) { 130 /* outvalue must point to an apiinfo structure */ 131 return LDAP_OPT_ERROR; 132 } 133 134 if(info->ldapai_info_version != LDAP_API_INFO_VERSION) { 135 /* api info version mismatch */ 136 info->ldapai_info_version = LDAP_API_INFO_VERSION; 137 return LDAP_OPT_ERROR; 138 } 139 140 info->ldapai_api_version = LDAP_API_VERSION; 141 info->ldapai_protocol_version = LDAP_VERSION_MAX; 142 143 if(features[0].ldapaif_name == NULL) { 144 info->ldapai_extensions = NULL; 145 } else { 146 int i; 147 info->ldapai_extensions = LDAP_MALLOC(sizeof(char *) * 148 sizeof(features)/sizeof(LDAPAPIFeatureInfo)); 149 150 for(i=0; features[i].ldapaif_name != NULL; i++) { 151 info->ldapai_extensions[i] = 152 LDAP_STRDUP(features[i].ldapaif_name); 153 } 154 155 info->ldapai_extensions[i] = NULL; 156 } 157 158 info->ldapai_vendor_name = LDAP_STRDUP(LDAP_VENDOR_NAME); 159 info->ldapai_vendor_version = LDAP_VENDOR_VERSION; 160 161 return LDAP_OPT_SUCCESS; 162 } break; 163 164 case LDAP_OPT_DESC: 165 if( ld == NULL || ld->ld_sb == NULL ) { 166 /* bad param */ 167 break; 168 } 169 170 ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, outvalue ); 171 return LDAP_OPT_SUCCESS; 172 173 case LDAP_OPT_SOCKBUF: 174 if( ld == NULL ) break; 175 *(Sockbuf **)outvalue = ld->ld_sb; 176 return LDAP_OPT_SUCCESS; 177 178 case LDAP_OPT_TIMEOUT: 179 /* the caller has to free outvalue ! */ 180 if ( lo->ldo_tm_api.tv_sec < 0 ) { 181 *(void **)outvalue = NULL; 182 } else if ( ldap_int_timeval_dup( outvalue, &lo->ldo_tm_api ) != 0 ) { 183 return LDAP_OPT_ERROR; 184 } 185 return LDAP_OPT_SUCCESS; 186 187 case LDAP_OPT_NETWORK_TIMEOUT: 188 /* the caller has to free outvalue ! */ 189 if ( lo->ldo_tm_net.tv_sec < 0 ) { 190 *(void **)outvalue = NULL; 191 } else if ( ldap_int_timeval_dup( outvalue, &lo->ldo_tm_net ) != 0 ) { 192 return LDAP_OPT_ERROR; 193 } 194 return LDAP_OPT_SUCCESS; 195 196 case LDAP_OPT_DEREF: 197 * (int *) outvalue = lo->ldo_deref; 198 return LDAP_OPT_SUCCESS; 199 200 case LDAP_OPT_SIZELIMIT: 201 * (int *) outvalue = lo->ldo_sizelimit; 202 return LDAP_OPT_SUCCESS; 203 204 case LDAP_OPT_TIMELIMIT: 205 * (int *) outvalue = lo->ldo_timelimit; 206 return LDAP_OPT_SUCCESS; 207 208 case LDAP_OPT_REFERRALS: 209 * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_REFERRALS); 210 return LDAP_OPT_SUCCESS; 211 212 case LDAP_OPT_RESTART: 213 * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_RESTART); 214 return LDAP_OPT_SUCCESS; 215 216 case LDAP_OPT_PROTOCOL_VERSION: 217 * (int *) outvalue = lo->ldo_version; 218 return LDAP_OPT_SUCCESS; 219 220 case LDAP_OPT_SERVER_CONTROLS: 221 * (LDAPControl ***) outvalue = 222 ldap_controls_dup( lo->ldo_sctrls ); 223 224 return LDAP_OPT_SUCCESS; 225 226 case LDAP_OPT_CLIENT_CONTROLS: 227 * (LDAPControl ***) outvalue = 228 ldap_controls_dup( lo->ldo_cctrls ); 229 230 return LDAP_OPT_SUCCESS; 231 232 case LDAP_OPT_HOST_NAME: 233 * (char **) outvalue = ldap_url_list2hosts(lo->ldo_defludp); 234 return LDAP_OPT_SUCCESS; 235 236 case LDAP_OPT_URI: 237 * (char **) outvalue = ldap_url_list2urls(lo->ldo_defludp); 238 return LDAP_OPT_SUCCESS; 239 240 case LDAP_OPT_DEFBASE: 241 if( lo->ldo_defbase == NULL ) { 242 * (char **) outvalue = NULL; 243 } else { 244 * (char **) outvalue = LDAP_STRDUP(lo->ldo_defbase); 245 } 246 247 return LDAP_OPT_SUCCESS; 248 249 case LDAP_OPT_CONNECT_ASYNC: 250 * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_CONNECT_ASYNC); 251 return LDAP_OPT_SUCCESS; 252 253 case LDAP_OPT_RESULT_CODE: 254 if(ld == NULL) { 255 /* bad param */ 256 break; 257 } 258 * (int *) outvalue = ld->ld_errno; 259 return LDAP_OPT_SUCCESS; 260 261 case LDAP_OPT_DIAGNOSTIC_MESSAGE: 262 if(ld == NULL) { 263 /* bad param */ 264 break; 265 } 266 267 if( ld->ld_error == NULL ) { 268 * (char **) outvalue = NULL; 269 } else { 270 * (char **) outvalue = LDAP_STRDUP(ld->ld_error); 271 } 272 273 return LDAP_OPT_SUCCESS; 274 275 case LDAP_OPT_MATCHED_DN: 276 if(ld == NULL) { 277 /* bad param */ 278 break; 279 } 280 281 if( ld->ld_matched == NULL ) { 282 * (char **) outvalue = NULL; 283 } else { 284 * (char **) outvalue = LDAP_STRDUP( ld->ld_matched ); 285 } 286 287 return LDAP_OPT_SUCCESS; 288 289 case LDAP_OPT_REFERRAL_URLS: 290 if(ld == NULL) { 291 /* bad param */ 292 break; 293 } 294 295 if( ld->ld_referrals == NULL ) { 296 * (char ***) outvalue = NULL; 297 } else { 298 * (char ***) outvalue = ldap_value_dup(ld->ld_referrals); 299 } 300 301 return LDAP_OPT_SUCCESS; 302 303 case LDAP_OPT_API_FEATURE_INFO: { 304 LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue; 305 int i; 306 307 if(info == NULL) return LDAP_OPT_ERROR; 308 309 if(info->ldapaif_info_version != LDAP_FEATURE_INFO_VERSION) { 310 /* api info version mismatch */ 311 info->ldapaif_info_version = LDAP_FEATURE_INFO_VERSION; 312 return LDAP_OPT_ERROR; 313 } 314 315 if(info->ldapaif_name == NULL) return LDAP_OPT_ERROR; 316 317 for(i=0; features[i].ldapaif_name != NULL; i++) { 318 if(!strcmp(info->ldapaif_name, features[i].ldapaif_name)) { 319 info->ldapaif_version = 320 features[i].ldapaif_version; 321 return LDAP_OPT_SUCCESS; 322 } 323 } 324 } 325 break; 326 327 case LDAP_OPT_DEBUG_LEVEL: 328 * (int *) outvalue = lo->ldo_debug; 329 return LDAP_OPT_SUCCESS; 330 331 default: 332 #ifdef HAVE_TLS 333 if ( ldap_pvt_tls_get_option( ld, option, outvalue ) == 0 ) { 334 return LDAP_OPT_SUCCESS; 335 } 336 #endif 337 #ifdef HAVE_CYRUS_SASL 338 if ( ldap_int_sasl_get_option( ld, option, outvalue ) == 0 ) { 339 return LDAP_OPT_SUCCESS; 340 } 341 #endif 342 /* bad param */ 343 break; 344 } 345 346 return LDAP_OPT_ERROR; 347 } 348 349 int 350 ldap_set_option( 351 LDAP *ld, 352 int option, 353 LDAP_CONST void *invalue) 354 { 355 struct ldapoptions *lo; 356 int *dbglvl = NULL; 357 358 /* Get pointer to global option structure */ 359 lo = LDAP_INT_GLOBAL_OPT(); 360 if (lo == NULL) { 361 return LDAP_NO_MEMORY; 362 } 363 364 /* 365 * The architecture to turn on debugging has a chicken and egg 366 * problem. Thus, we introduce a fix here. 367 */ 368 369 if (option == LDAP_OPT_DEBUG_LEVEL) { 370 dbglvl = (int *) invalue; 371 } 372 373 if( lo->ldo_valid != LDAP_INITIALIZED ) { 374 ldap_int_initialize(lo, dbglvl); 375 } 376 377 if(ld != NULL) { 378 assert( LDAP_VALID( ld ) ); 379 380 if( !LDAP_VALID( ld ) ) { 381 return LDAP_OPT_ERROR; 382 } 383 384 lo = &ld->ld_options; 385 } 386 387 switch(option) { 388 case LDAP_OPT_REFERRALS: 389 if(invalue == LDAP_OPT_OFF) { 390 LDAP_BOOL_CLR(lo, LDAP_BOOL_REFERRALS); 391 } else { 392 LDAP_BOOL_SET(lo, LDAP_BOOL_REFERRALS); 393 } 394 return LDAP_OPT_SUCCESS; 395 396 case LDAP_OPT_RESTART: 397 if(invalue == LDAP_OPT_OFF) { 398 LDAP_BOOL_CLR(lo, LDAP_BOOL_RESTART); 399 } else { 400 LDAP_BOOL_SET(lo, LDAP_BOOL_RESTART); 401 } 402 return LDAP_OPT_SUCCESS; 403 404 case LDAP_OPT_CONNECT_ASYNC: 405 if(invalue == LDAP_OPT_OFF) { 406 LDAP_BOOL_CLR(lo, LDAP_BOOL_CONNECT_ASYNC); 407 } else { 408 LDAP_BOOL_SET(lo, LDAP_BOOL_CONNECT_ASYNC); 409 } 410 return LDAP_OPT_SUCCESS; 411 } 412 413 /* options which can withstand invalue == NULL */ 414 switch ( option ) { 415 case LDAP_OPT_SERVER_CONTROLS: { 416 LDAPControl *const *controls = 417 (LDAPControl *const *) invalue; 418 419 if( lo->ldo_sctrls ) 420 ldap_controls_free( lo->ldo_sctrls ); 421 422 if( controls == NULL || *controls == NULL ) { 423 lo->ldo_sctrls = NULL; 424 return LDAP_OPT_SUCCESS; 425 } 426 427 lo->ldo_sctrls = ldap_controls_dup( controls ); 428 429 if(lo->ldo_sctrls == NULL) { 430 /* memory allocation error ? */ 431 break; 432 } 433 } return LDAP_OPT_SUCCESS; 434 435 case LDAP_OPT_CLIENT_CONTROLS: { 436 LDAPControl *const *controls = 437 (LDAPControl *const *) invalue; 438 439 if( lo->ldo_cctrls ) 440 ldap_controls_free( lo->ldo_cctrls ); 441 442 if( controls == NULL || *controls == NULL ) { 443 lo->ldo_cctrls = NULL; 444 return LDAP_OPT_SUCCESS; 445 } 446 447 lo->ldo_cctrls = ldap_controls_dup( controls ); 448 449 if(lo->ldo_cctrls == NULL) { 450 /* memory allocation error ? */ 451 break; 452 } 453 } return LDAP_OPT_SUCCESS; 454 455 456 case LDAP_OPT_HOST_NAME: { 457 const char *host = (const char *) invalue; 458 LDAPURLDesc *ludlist = NULL; 459 int rc = LDAP_OPT_SUCCESS; 460 461 if(host != NULL) { 462 rc = ldap_url_parsehosts( &ludlist, host, 463 lo->ldo_defport ? lo->ldo_defport : LDAP_PORT ); 464 465 } else if(ld == NULL) { 466 /* 467 * must want global default returned 468 * to initial condition. 469 */ 470 rc = ldap_url_parselist_ext(&ludlist, "ldap://localhost/", NULL, 471 LDAP_PVT_URL_PARSE_NOEMPTY_HOST 472 | LDAP_PVT_URL_PARSE_DEF_PORT ); 473 474 } else { 475 /* 476 * must want the session default 477 * updated to the current global default 478 */ 479 ludlist = ldap_url_duplist( 480 ldap_int_global_options.ldo_defludp); 481 if (ludlist == NULL) 482 rc = LDAP_NO_MEMORY; 483 } 484 485 if (rc == LDAP_OPT_SUCCESS) { 486 if (lo->ldo_defludp != NULL) 487 ldap_free_urllist(lo->ldo_defludp); 488 lo->ldo_defludp = ludlist; 489 } 490 return rc; 491 } 492 493 case LDAP_OPT_URI: { 494 const char *urls = (const char *) invalue; 495 LDAPURLDesc *ludlist = NULL; 496 int rc = LDAP_OPT_SUCCESS; 497 498 if(urls != NULL) { 499 rc = ldap_url_parselist_ext(&ludlist, urls, NULL, 500 LDAP_PVT_URL_PARSE_NOEMPTY_HOST 501 | LDAP_PVT_URL_PARSE_DEF_PORT ); 502 } else if(ld == NULL) { 503 /* 504 * must want global default returned 505 * to initial condition. 506 */ 507 rc = ldap_url_parselist_ext(&ludlist, "ldap://localhost/", NULL, 508 LDAP_PVT_URL_PARSE_NOEMPTY_HOST 509 | LDAP_PVT_URL_PARSE_DEF_PORT ); 510 511 } else { 512 /* 513 * must want the session default 514 * updated to the current global default 515 */ 516 ludlist = ldap_url_duplist( 517 ldap_int_global_options.ldo_defludp); 518 if (ludlist == NULL) 519 rc = LDAP_URL_ERR_MEM; 520 } 521 522 switch (rc) { 523 case LDAP_URL_SUCCESS: /* Success */ 524 rc = LDAP_SUCCESS; 525 break; 526 527 case LDAP_URL_ERR_MEM: /* can't allocate memory space */ 528 rc = LDAP_NO_MEMORY; 529 break; 530 531 case LDAP_URL_ERR_PARAM: /* parameter is bad */ 532 case LDAP_URL_ERR_BADSCHEME: /* URL doesn't begin with "ldap[si]://" */ 533 case LDAP_URL_ERR_BADENCLOSURE: /* URL is missing trailing ">" */ 534 case LDAP_URL_ERR_BADURL: /* URL is bad */ 535 case LDAP_URL_ERR_BADHOST: /* host port is bad */ 536 case LDAP_URL_ERR_BADATTRS: /* bad (or missing) attributes */ 537 case LDAP_URL_ERR_BADSCOPE: /* scope string is invalid (or missing) */ 538 case LDAP_URL_ERR_BADFILTER: /* bad or missing filter */ 539 case LDAP_URL_ERR_BADEXTS: /* bad or missing extensions */ 540 rc = LDAP_PARAM_ERROR; 541 break; 542 } 543 544 if (rc == LDAP_SUCCESS) { 545 if (lo->ldo_defludp != NULL) 546 ldap_free_urllist(lo->ldo_defludp); 547 lo->ldo_defludp = ludlist; 548 } 549 return rc; 550 } 551 552 case LDAP_OPT_DEFBASE: { 553 const char *newbase = (const char *) invalue; 554 char *defbase = NULL; 555 556 if ( newbase != NULL ) { 557 defbase = LDAP_STRDUP( newbase ); 558 if ( defbase == NULL ) return LDAP_NO_MEMORY; 559 560 } else if ( ld != NULL ) { 561 defbase = LDAP_STRDUP( ldap_int_global_options.ldo_defbase ); 562 if ( defbase == NULL ) return LDAP_NO_MEMORY; 563 } 564 565 if ( lo->ldo_defbase != NULL ) 566 LDAP_FREE( lo->ldo_defbase ); 567 lo->ldo_defbase = defbase; 568 } return LDAP_OPT_SUCCESS; 569 570 case LDAP_OPT_DIAGNOSTIC_MESSAGE: { 571 const char *err = (const char *) invalue; 572 573 if(ld == NULL) { 574 /* need a struct ldap */ 575 return LDAP_OPT_ERROR; 576 } 577 578 if( ld->ld_error ) { 579 LDAP_FREE(ld->ld_error); 580 ld->ld_error = NULL; 581 } 582 583 if ( err ) { 584 ld->ld_error = LDAP_STRDUP(err); 585 } 586 } return LDAP_OPT_SUCCESS; 587 588 case LDAP_OPT_MATCHED_DN: { 589 const char *matched = (const char *) invalue; 590 591 if (ld == NULL) { 592 /* need a struct ldap */ 593 return LDAP_OPT_ERROR; 594 } 595 596 if( ld->ld_matched ) { 597 LDAP_FREE(ld->ld_matched); 598 ld->ld_matched = NULL; 599 } 600 601 if ( matched ) { 602 ld->ld_matched = LDAP_STRDUP( matched ); 603 } 604 } return LDAP_OPT_SUCCESS; 605 606 case LDAP_OPT_REFERRAL_URLS: { 607 char *const *referrals = (char *const *) invalue; 608 609 if(ld == NULL) { 610 /* need a struct ldap */ 611 return LDAP_OPT_ERROR; 612 } 613 614 if( ld->ld_referrals ) { 615 LDAP_VFREE(ld->ld_referrals); 616 } 617 618 if ( referrals ) { 619 ld->ld_referrals = ldap_value_dup(referrals); 620 } 621 } return LDAP_OPT_SUCCESS; 622 623 /* Only accessed from inside this function by ldap_set_rebind_proc() */ 624 case LDAP_OPT_REBIND_PROC: { 625 lo->ldo_rebind_proc = (LDAP_REBIND_PROC *)invalue; 626 } return LDAP_OPT_SUCCESS; 627 case LDAP_OPT_REBIND_PARAMS: { 628 lo->ldo_rebind_params = (void *)invalue; 629 } return LDAP_OPT_SUCCESS; 630 631 /* Only accessed from inside this function by ldap_set_nextref_proc() */ 632 case LDAP_OPT_NEXTREF_PROC: { 633 lo->ldo_nextref_proc = (LDAP_NEXTREF_PROC *)invalue; 634 } return LDAP_OPT_SUCCESS; 635 case LDAP_OPT_NEXTREF_PARAMS: { 636 lo->ldo_nextref_params = (void *)invalue; 637 } return LDAP_OPT_SUCCESS; 638 639 /* Only accessed from inside this function by ldap_set_urllist_proc() */ 640 case LDAP_OPT_URLLIST_PROC: { 641 lo->ldo_urllist_proc = (LDAP_URLLIST_PROC *)invalue; 642 } return LDAP_OPT_SUCCESS; 643 case LDAP_OPT_URLLIST_PARAMS: { 644 lo->ldo_urllist_params = (void *)invalue; 645 } return LDAP_OPT_SUCCESS; 646 647 /* read-only options */ 648 case LDAP_OPT_API_INFO: 649 case LDAP_OPT_DESC: 650 case LDAP_OPT_SOCKBUF: 651 case LDAP_OPT_API_FEATURE_INFO: 652 return LDAP_OPT_ERROR; 653 654 /* options which cannot withstand invalue == NULL */ 655 case LDAP_OPT_DEREF: 656 case LDAP_OPT_SIZELIMIT: 657 case LDAP_OPT_TIMELIMIT: 658 case LDAP_OPT_PROTOCOL_VERSION: 659 case LDAP_OPT_RESULT_CODE: 660 case LDAP_OPT_DEBUG_LEVEL: 661 case LDAP_OPT_TIMEOUT: 662 case LDAP_OPT_NETWORK_TIMEOUT: 663 if(invalue == NULL) { 664 /* no place to set from */ 665 return LDAP_OPT_ERROR; 666 } 667 break; 668 669 default: 670 #ifdef HAVE_TLS 671 if ( ldap_pvt_tls_set_option( ld, option, (void *)invalue ) == 0 ) 672 return LDAP_OPT_SUCCESS; 673 #endif 674 #ifdef HAVE_CYRUS_SASL 675 if ( ldap_int_sasl_set_option( ld, option, (void *)invalue ) == 0 ) 676 return LDAP_OPT_SUCCESS; 677 #endif 678 /* bad param */ 679 return LDAP_OPT_ERROR; 680 } 681 682 /* options which cannot withstand invalue == NULL */ 683 684 switch(option) { 685 case LDAP_OPT_DEREF: 686 /* FIXME: check value for protocol compliance? */ 687 lo->ldo_deref = * (const int *) invalue; 688 return LDAP_OPT_SUCCESS; 689 690 case LDAP_OPT_SIZELIMIT: 691 /* FIXME: check value for protocol compliance? */ 692 lo->ldo_sizelimit = * (const int *) invalue; 693 return LDAP_OPT_SUCCESS; 694 695 case LDAP_OPT_TIMELIMIT: 696 /* FIXME: check value for protocol compliance? */ 697 lo->ldo_timelimit = * (const int *) invalue; 698 return LDAP_OPT_SUCCESS; 699 700 case LDAP_OPT_TIMEOUT: { 701 const struct timeval *tv = 702 (const struct timeval *) invalue; 703 704 lo->ldo_tm_api = *tv; 705 } return LDAP_OPT_SUCCESS; 706 707 case LDAP_OPT_NETWORK_TIMEOUT: { 708 const struct timeval *tv = 709 (const struct timeval *) invalue; 710 711 lo->ldo_tm_net = *tv; 712 } return LDAP_OPT_SUCCESS; 713 714 case LDAP_OPT_PROTOCOL_VERSION: { 715 int vers = * (const int *) invalue; 716 if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) { 717 /* not supported */ 718 break; 719 } 720 lo->ldo_version = vers; 721 } return LDAP_OPT_SUCCESS; 722 723 case LDAP_OPT_RESULT_CODE: { 724 int err = * (const int *) invalue; 725 726 if(ld == NULL) { 727 /* need a struct ldap */ 728 break; 729 } 730 731 ld->ld_errno = err; 732 } return LDAP_OPT_SUCCESS; 733 734 case LDAP_OPT_DEBUG_LEVEL: 735 lo->ldo_debug = * (const int *) invalue; 736 return LDAP_OPT_SUCCESS; 737 } 738 return LDAP_OPT_ERROR; 739 } 740 741 int 742 ldap_set_rebind_proc( LDAP *ld, LDAP_REBIND_PROC *proc, void *params ) 743 { 744 int rc; 745 rc = ldap_set_option( ld, LDAP_OPT_REBIND_PROC, (void *)proc ); 746 if( rc != LDAP_OPT_SUCCESS ) return rc; 747 748 rc = ldap_set_option( ld, LDAP_OPT_REBIND_PARAMS, (void *)params ); 749 return rc; 750 } 751 752 int 753 ldap_set_nextref_proc( LDAP *ld, LDAP_NEXTREF_PROC *proc, void *params ) 754 { 755 int rc; 756 rc = ldap_set_option( ld, LDAP_OPT_NEXTREF_PROC, (void *)proc ); 757 if( rc != LDAP_OPT_SUCCESS ) return rc; 758 759 rc = ldap_set_option( ld, LDAP_OPT_NEXTREF_PARAMS, (void *)params ); 760 return rc; 761 } 762 763 int 764 ldap_set_urllist_proc( LDAP *ld, LDAP_URLLIST_PROC *proc, void *params ) 765 { 766 int rc; 767 rc = ldap_set_option( ld, LDAP_OPT_URLLIST_PROC, (void *)proc ); 768 if( rc != LDAP_OPT_SUCCESS ) return rc; 769 770 rc = ldap_set_option( ld, LDAP_OPT_URLLIST_PARAMS, (void *)params ); 771 return rc; 772 } 773