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