1 /* $NetBSD: options.c,v 1.1.1.2 2010/03/08 02:14:20 lukem Exp $ */ 2 3 /* OpenLDAP: pkg/ldap/libraries/libldap/options.c,v 1.75.2.11 2009/08/12 23:40:56 quanah Exp */ 4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 1998-2009 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 102 /* Get pointer to global option structure */ 103 lo = LDAP_INT_GLOBAL_OPT(); 104 if (NULL == lo) { 105 return LDAP_NO_MEMORY; 106 } 107 108 if( lo->ldo_valid != LDAP_INITIALIZED ) { 109 ldap_int_initialize(lo, NULL); 110 } 111 112 if(ld != NULL) { 113 assert( LDAP_VALID( ld ) ); 114 115 if( !LDAP_VALID( ld ) ) { 116 return LDAP_OPT_ERROR; 117 } 118 119 lo = &ld->ld_options; 120 } 121 122 if(outvalue == NULL) { 123 /* no place to get to */ 124 return LDAP_OPT_ERROR; 125 } 126 127 switch(option) { 128 case LDAP_OPT_API_INFO: { 129 struct ldapapiinfo *info = (struct ldapapiinfo *) outvalue; 130 131 if(info == NULL) { 132 /* outvalue must point to an apiinfo structure */ 133 return LDAP_OPT_ERROR; 134 } 135 136 if(info->ldapai_info_version != LDAP_API_INFO_VERSION) { 137 /* api info version mismatch */ 138 info->ldapai_info_version = LDAP_API_INFO_VERSION; 139 return LDAP_OPT_ERROR; 140 } 141 142 info->ldapai_api_version = LDAP_API_VERSION; 143 info->ldapai_protocol_version = LDAP_VERSION_MAX; 144 145 if(features[0].ldapaif_name == NULL) { 146 info->ldapai_extensions = NULL; 147 } else { 148 int i; 149 info->ldapai_extensions = LDAP_MALLOC(sizeof(char *) * 150 sizeof(features)/sizeof(LDAPAPIFeatureInfo)); 151 152 for(i=0; features[i].ldapaif_name != NULL; i++) { 153 info->ldapai_extensions[i] = 154 LDAP_STRDUP(features[i].ldapaif_name); 155 } 156 157 info->ldapai_extensions[i] = NULL; 158 } 159 160 info->ldapai_vendor_name = LDAP_STRDUP(LDAP_VENDOR_NAME); 161 info->ldapai_vendor_version = LDAP_VENDOR_VERSION; 162 163 return LDAP_OPT_SUCCESS; 164 } break; 165 166 case LDAP_OPT_DESC: 167 if( ld == NULL || ld->ld_sb == NULL ) { 168 /* bad param */ 169 break; 170 } 171 172 ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_GET_FD, outvalue ); 173 return LDAP_OPT_SUCCESS; 174 175 case LDAP_OPT_SOCKBUF: 176 if( ld == NULL ) break; 177 *(Sockbuf **)outvalue = ld->ld_sb; 178 return LDAP_OPT_SUCCESS; 179 180 case LDAP_OPT_TIMEOUT: 181 /* the caller has to free outvalue ! */ 182 if ( lo->ldo_tm_api.tv_sec < 0 ) { 183 *(void **)outvalue = NULL; 184 } else if ( ldap_int_timeval_dup( outvalue, &lo->ldo_tm_api ) != 0 ) { 185 return LDAP_OPT_ERROR; 186 } 187 return LDAP_OPT_SUCCESS; 188 189 case LDAP_OPT_NETWORK_TIMEOUT: 190 /* the caller has to free outvalue ! */ 191 if ( lo->ldo_tm_net.tv_sec < 0 ) { 192 *(void **)outvalue = NULL; 193 } else if ( ldap_int_timeval_dup( outvalue, &lo->ldo_tm_net ) != 0 ) { 194 return LDAP_OPT_ERROR; 195 } 196 return LDAP_OPT_SUCCESS; 197 198 case LDAP_OPT_DEREF: 199 * (int *) outvalue = lo->ldo_deref; 200 return LDAP_OPT_SUCCESS; 201 202 case LDAP_OPT_SIZELIMIT: 203 * (int *) outvalue = lo->ldo_sizelimit; 204 return LDAP_OPT_SUCCESS; 205 206 case LDAP_OPT_TIMELIMIT: 207 * (int *) outvalue = lo->ldo_timelimit; 208 return LDAP_OPT_SUCCESS; 209 210 case LDAP_OPT_REFERRALS: 211 * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_REFERRALS); 212 return LDAP_OPT_SUCCESS; 213 214 case LDAP_OPT_RESTART: 215 * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_RESTART); 216 return LDAP_OPT_SUCCESS; 217 218 case LDAP_OPT_PROTOCOL_VERSION: 219 * (int *) outvalue = lo->ldo_version; 220 return LDAP_OPT_SUCCESS; 221 222 case LDAP_OPT_SERVER_CONTROLS: 223 * (LDAPControl ***) outvalue = 224 ldap_controls_dup( lo->ldo_sctrls ); 225 226 return LDAP_OPT_SUCCESS; 227 228 case LDAP_OPT_CLIENT_CONTROLS: 229 * (LDAPControl ***) outvalue = 230 ldap_controls_dup( lo->ldo_cctrls ); 231 232 return LDAP_OPT_SUCCESS; 233 234 case LDAP_OPT_HOST_NAME: 235 * (char **) outvalue = ldap_url_list2hosts(lo->ldo_defludp); 236 return LDAP_OPT_SUCCESS; 237 238 case LDAP_OPT_URI: 239 * (char **) outvalue = ldap_url_list2urls(lo->ldo_defludp); 240 return LDAP_OPT_SUCCESS; 241 242 case LDAP_OPT_DEFBASE: 243 if( lo->ldo_defbase == NULL ) { 244 * (char **) outvalue = NULL; 245 } else { 246 * (char **) outvalue = LDAP_STRDUP(lo->ldo_defbase); 247 } 248 249 return LDAP_OPT_SUCCESS; 250 251 case LDAP_OPT_CONNECT_ASYNC: 252 * (int *) outvalue = (int) LDAP_BOOL_GET(lo, LDAP_BOOL_CONNECT_ASYNC); 253 return LDAP_OPT_SUCCESS; 254 255 case LDAP_OPT_CONNECT_CB: 256 { 257 /* Getting deletes the specified callback */ 258 ldaplist **ll = &lo->ldo_conn_cbs; 259 for (;*ll;ll = &(*ll)->ll_next) { 260 if ((*ll)->ll_data == outvalue) { 261 ldaplist *lc = *ll; 262 *ll = lc->ll_next; 263 LDAP_FREE(lc); 264 break; 265 } 266 } 267 } 268 return LDAP_OPT_SUCCESS; 269 270 case LDAP_OPT_RESULT_CODE: 271 if(ld == NULL) { 272 /* bad param */ 273 break; 274 } 275 * (int *) outvalue = ld->ld_errno; 276 return LDAP_OPT_SUCCESS; 277 278 case LDAP_OPT_DIAGNOSTIC_MESSAGE: 279 if(ld == NULL) { 280 /* bad param */ 281 break; 282 } 283 284 if( ld->ld_error == NULL ) { 285 * (char **) outvalue = NULL; 286 } else { 287 * (char **) outvalue = LDAP_STRDUP(ld->ld_error); 288 } 289 290 return LDAP_OPT_SUCCESS; 291 292 case LDAP_OPT_MATCHED_DN: 293 if(ld == NULL) { 294 /* bad param */ 295 break; 296 } 297 298 if( ld->ld_matched == NULL ) { 299 * (char **) outvalue = NULL; 300 } else { 301 * (char **) outvalue = LDAP_STRDUP( ld->ld_matched ); 302 } 303 304 return LDAP_OPT_SUCCESS; 305 306 case LDAP_OPT_REFERRAL_URLS: 307 if(ld == NULL) { 308 /* bad param */ 309 break; 310 } 311 312 if( ld->ld_referrals == NULL ) { 313 * (char ***) outvalue = NULL; 314 } else { 315 * (char ***) outvalue = ldap_value_dup(ld->ld_referrals); 316 } 317 318 return LDAP_OPT_SUCCESS; 319 320 case LDAP_OPT_API_FEATURE_INFO: { 321 LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue; 322 int i; 323 324 if(info == NULL) return LDAP_OPT_ERROR; 325 326 if(info->ldapaif_info_version != LDAP_FEATURE_INFO_VERSION) { 327 /* api info version mismatch */ 328 info->ldapaif_info_version = LDAP_FEATURE_INFO_VERSION; 329 return LDAP_OPT_ERROR; 330 } 331 332 if(info->ldapaif_name == NULL) return LDAP_OPT_ERROR; 333 334 for(i=0; features[i].ldapaif_name != NULL; i++) { 335 if(!strcmp(info->ldapaif_name, features[i].ldapaif_name)) { 336 info->ldapaif_version = 337 features[i].ldapaif_version; 338 return LDAP_OPT_SUCCESS; 339 } 340 } 341 } 342 break; 343 344 case LDAP_OPT_DEBUG_LEVEL: 345 * (int *) outvalue = lo->ldo_debug; 346 return LDAP_OPT_SUCCESS; 347 348 case LDAP_OPT_X_KEEPALIVE_IDLE: 349 * (int *) outvalue = lo->ldo_keepalive_idle; 350 return LDAP_OPT_SUCCESS; 351 352 case LDAP_OPT_X_KEEPALIVE_PROBES: 353 * (int *) outvalue = lo->ldo_keepalive_probes; 354 return LDAP_OPT_SUCCESS; 355 356 case LDAP_OPT_X_KEEPALIVE_INTERVAL: 357 * (int *) outvalue = lo->ldo_keepalive_interval; 358 return LDAP_OPT_SUCCESS; 359 360 default: 361 #ifdef HAVE_TLS 362 if ( ldap_pvt_tls_get_option( ld, option, outvalue ) == 0 ) { 363 return LDAP_OPT_SUCCESS; 364 } 365 #endif 366 #ifdef HAVE_CYRUS_SASL 367 if ( ldap_int_sasl_get_option( ld, option, outvalue ) == 0 ) { 368 return LDAP_OPT_SUCCESS; 369 } 370 #endif 371 #ifdef HAVE_GSSAPI 372 if ( ldap_int_gssapi_get_option( ld, option, outvalue ) == 0 ) { 373 return LDAP_OPT_SUCCESS; 374 } 375 #endif 376 /* bad param */ 377 break; 378 } 379 380 return LDAP_OPT_ERROR; 381 } 382 383 int 384 ldap_set_option( 385 LDAP *ld, 386 int option, 387 LDAP_CONST void *invalue) 388 { 389 struct ldapoptions *lo; 390 int *dbglvl = NULL; 391 392 /* Get pointer to global option structure */ 393 lo = LDAP_INT_GLOBAL_OPT(); 394 if (lo == NULL) { 395 return LDAP_NO_MEMORY; 396 } 397 398 /* 399 * The architecture to turn on debugging has a chicken and egg 400 * problem. Thus, we introduce a fix here. 401 */ 402 403 if (option == LDAP_OPT_DEBUG_LEVEL) { 404 dbglvl = (int *) invalue; 405 } 406 407 if( lo->ldo_valid != LDAP_INITIALIZED ) { 408 ldap_int_initialize(lo, dbglvl); 409 } 410 411 if(ld != NULL) { 412 assert( LDAP_VALID( ld ) ); 413 414 if( !LDAP_VALID( ld ) ) { 415 return LDAP_OPT_ERROR; 416 } 417 418 lo = &ld->ld_options; 419 } 420 421 switch(option) { 422 case LDAP_OPT_REFERRALS: 423 if(invalue == LDAP_OPT_OFF) { 424 LDAP_BOOL_CLR(lo, LDAP_BOOL_REFERRALS); 425 } else { 426 LDAP_BOOL_SET(lo, LDAP_BOOL_REFERRALS); 427 } 428 return LDAP_OPT_SUCCESS; 429 430 case LDAP_OPT_RESTART: 431 if(invalue == LDAP_OPT_OFF) { 432 LDAP_BOOL_CLR(lo, LDAP_BOOL_RESTART); 433 } else { 434 LDAP_BOOL_SET(lo, LDAP_BOOL_RESTART); 435 } 436 return LDAP_OPT_SUCCESS; 437 438 case LDAP_OPT_CONNECT_ASYNC: 439 if(invalue == LDAP_OPT_OFF) { 440 LDAP_BOOL_CLR(lo, LDAP_BOOL_CONNECT_ASYNC); 441 } else { 442 LDAP_BOOL_SET(lo, LDAP_BOOL_CONNECT_ASYNC); 443 } 444 return LDAP_OPT_SUCCESS; 445 } 446 447 /* options which can withstand invalue == NULL */ 448 switch ( option ) { 449 case LDAP_OPT_SERVER_CONTROLS: { 450 LDAPControl *const *controls = 451 (LDAPControl *const *) invalue; 452 453 if( lo->ldo_sctrls ) 454 ldap_controls_free( lo->ldo_sctrls ); 455 456 if( controls == NULL || *controls == NULL ) { 457 lo->ldo_sctrls = NULL; 458 return LDAP_OPT_SUCCESS; 459 } 460 461 lo->ldo_sctrls = ldap_controls_dup( controls ); 462 463 if(lo->ldo_sctrls == NULL) { 464 /* memory allocation error ? */ 465 break; 466 } 467 } return LDAP_OPT_SUCCESS; 468 469 case LDAP_OPT_CLIENT_CONTROLS: { 470 LDAPControl *const *controls = 471 (LDAPControl *const *) invalue; 472 473 if( lo->ldo_cctrls ) 474 ldap_controls_free( lo->ldo_cctrls ); 475 476 if( controls == NULL || *controls == NULL ) { 477 lo->ldo_cctrls = NULL; 478 return LDAP_OPT_SUCCESS; 479 } 480 481 lo->ldo_cctrls = ldap_controls_dup( controls ); 482 483 if(lo->ldo_cctrls == NULL) { 484 /* memory allocation error ? */ 485 break; 486 } 487 } return LDAP_OPT_SUCCESS; 488 489 490 case LDAP_OPT_HOST_NAME: { 491 const char *host = (const char *) invalue; 492 LDAPURLDesc *ludlist = NULL; 493 int rc = LDAP_OPT_SUCCESS; 494 495 if(host != NULL) { 496 rc = ldap_url_parsehosts( &ludlist, host, 497 lo->ldo_defport ? lo->ldo_defport : LDAP_PORT ); 498 499 } else if(ld == NULL) { 500 /* 501 * must want global default returned 502 * to initial condition. 503 */ 504 rc = ldap_url_parselist_ext(&ludlist, "ldap://localhost/", NULL, 505 LDAP_PVT_URL_PARSE_NOEMPTY_HOST 506 | LDAP_PVT_URL_PARSE_DEF_PORT ); 507 508 } else { 509 /* 510 * must want the session default 511 * updated to the current global default 512 */ 513 ludlist = ldap_url_duplist( 514 ldap_int_global_options.ldo_defludp); 515 if (ludlist == NULL) 516 rc = LDAP_NO_MEMORY; 517 } 518 519 if (rc == LDAP_OPT_SUCCESS) { 520 if (lo->ldo_defludp != NULL) 521 ldap_free_urllist(lo->ldo_defludp); 522 lo->ldo_defludp = ludlist; 523 } 524 return rc; 525 } 526 527 case LDAP_OPT_URI: { 528 const char *urls = (const char *) invalue; 529 LDAPURLDesc *ludlist = NULL; 530 int rc = LDAP_OPT_SUCCESS; 531 532 if(urls != NULL) { 533 rc = ldap_url_parselist_ext(&ludlist, urls, NULL, 534 LDAP_PVT_URL_PARSE_NOEMPTY_HOST 535 | LDAP_PVT_URL_PARSE_DEF_PORT ); 536 } else if(ld == NULL) { 537 /* 538 * must want global default returned 539 * to initial condition. 540 */ 541 rc = ldap_url_parselist_ext(&ludlist, "ldap://localhost/", NULL, 542 LDAP_PVT_URL_PARSE_NOEMPTY_HOST 543 | LDAP_PVT_URL_PARSE_DEF_PORT ); 544 545 } else { 546 /* 547 * must want the session default 548 * updated to the current global default 549 */ 550 ludlist = ldap_url_duplist( 551 ldap_int_global_options.ldo_defludp); 552 if (ludlist == NULL) 553 rc = LDAP_URL_ERR_MEM; 554 } 555 556 switch (rc) { 557 case LDAP_URL_SUCCESS: /* Success */ 558 rc = LDAP_SUCCESS; 559 break; 560 561 case LDAP_URL_ERR_MEM: /* can't allocate memory space */ 562 rc = LDAP_NO_MEMORY; 563 break; 564 565 case LDAP_URL_ERR_PARAM: /* parameter is bad */ 566 case LDAP_URL_ERR_BADSCHEME: /* URL doesn't begin with "ldap[si]://" */ 567 case LDAP_URL_ERR_BADENCLOSURE: /* URL is missing trailing ">" */ 568 case LDAP_URL_ERR_BADURL: /* URL is bad */ 569 case LDAP_URL_ERR_BADHOST: /* host port is bad */ 570 case LDAP_URL_ERR_BADATTRS: /* bad (or missing) attributes */ 571 case LDAP_URL_ERR_BADSCOPE: /* scope string is invalid (or missing) */ 572 case LDAP_URL_ERR_BADFILTER: /* bad or missing filter */ 573 case LDAP_URL_ERR_BADEXTS: /* bad or missing extensions */ 574 rc = LDAP_PARAM_ERROR; 575 break; 576 } 577 578 if (rc == LDAP_SUCCESS) { 579 if (lo->ldo_defludp != NULL) 580 ldap_free_urllist(lo->ldo_defludp); 581 lo->ldo_defludp = ludlist; 582 } 583 return rc; 584 } 585 586 case LDAP_OPT_DEFBASE: { 587 const char *newbase = (const char *) invalue; 588 char *defbase = NULL; 589 590 if ( newbase != NULL ) { 591 defbase = LDAP_STRDUP( newbase ); 592 if ( defbase == NULL ) return LDAP_NO_MEMORY; 593 594 } else if ( ld != NULL ) { 595 defbase = LDAP_STRDUP( ldap_int_global_options.ldo_defbase ); 596 if ( defbase == NULL ) return LDAP_NO_MEMORY; 597 } 598 599 if ( lo->ldo_defbase != NULL ) 600 LDAP_FREE( lo->ldo_defbase ); 601 lo->ldo_defbase = defbase; 602 } return LDAP_OPT_SUCCESS; 603 604 case LDAP_OPT_DIAGNOSTIC_MESSAGE: { 605 const char *err = (const char *) invalue; 606 607 if(ld == NULL) { 608 /* need a struct ldap */ 609 return LDAP_OPT_ERROR; 610 } 611 612 if( ld->ld_error ) { 613 LDAP_FREE(ld->ld_error); 614 ld->ld_error = NULL; 615 } 616 617 if ( err ) { 618 ld->ld_error = LDAP_STRDUP(err); 619 } 620 } return LDAP_OPT_SUCCESS; 621 622 case LDAP_OPT_MATCHED_DN: { 623 const char *matched = (const char *) invalue; 624 625 if (ld == NULL) { 626 /* need a struct ldap */ 627 return LDAP_OPT_ERROR; 628 } 629 630 if( ld->ld_matched ) { 631 LDAP_FREE(ld->ld_matched); 632 ld->ld_matched = NULL; 633 } 634 635 if ( matched ) { 636 ld->ld_matched = LDAP_STRDUP( matched ); 637 } 638 } return LDAP_OPT_SUCCESS; 639 640 case LDAP_OPT_REFERRAL_URLS: { 641 char *const *referrals = (char *const *) invalue; 642 643 if(ld == NULL) { 644 /* need a struct ldap */ 645 return LDAP_OPT_ERROR; 646 } 647 648 if( ld->ld_referrals ) { 649 LDAP_VFREE(ld->ld_referrals); 650 } 651 652 if ( referrals ) { 653 ld->ld_referrals = ldap_value_dup(referrals); 654 } 655 } return LDAP_OPT_SUCCESS; 656 657 /* Only accessed from inside this function by ldap_set_rebind_proc() */ 658 case LDAP_OPT_REBIND_PROC: { 659 lo->ldo_rebind_proc = (LDAP_REBIND_PROC *)invalue; 660 } return LDAP_OPT_SUCCESS; 661 case LDAP_OPT_REBIND_PARAMS: { 662 lo->ldo_rebind_params = (void *)invalue; 663 } return LDAP_OPT_SUCCESS; 664 665 /* Only accessed from inside this function by ldap_set_nextref_proc() */ 666 case LDAP_OPT_NEXTREF_PROC: { 667 lo->ldo_nextref_proc = (LDAP_NEXTREF_PROC *)invalue; 668 } return LDAP_OPT_SUCCESS; 669 case LDAP_OPT_NEXTREF_PARAMS: { 670 lo->ldo_nextref_params = (void *)invalue; 671 } return LDAP_OPT_SUCCESS; 672 673 /* Only accessed from inside this function by ldap_set_urllist_proc() */ 674 case LDAP_OPT_URLLIST_PROC: { 675 lo->ldo_urllist_proc = (LDAP_URLLIST_PROC *)invalue; 676 } return LDAP_OPT_SUCCESS; 677 case LDAP_OPT_URLLIST_PARAMS: { 678 lo->ldo_urllist_params = (void *)invalue; 679 } return LDAP_OPT_SUCCESS; 680 681 /* read-only options */ 682 case LDAP_OPT_API_INFO: 683 case LDAP_OPT_DESC: 684 case LDAP_OPT_SOCKBUF: 685 case LDAP_OPT_API_FEATURE_INFO: 686 return LDAP_OPT_ERROR; 687 688 /* options which cannot withstand invalue == NULL */ 689 case LDAP_OPT_DEREF: 690 case LDAP_OPT_SIZELIMIT: 691 case LDAP_OPT_TIMELIMIT: 692 case LDAP_OPT_PROTOCOL_VERSION: 693 case LDAP_OPT_RESULT_CODE: 694 case LDAP_OPT_DEBUG_LEVEL: 695 case LDAP_OPT_TIMEOUT: 696 case LDAP_OPT_NETWORK_TIMEOUT: 697 case LDAP_OPT_CONNECT_CB: 698 case LDAP_OPT_X_KEEPALIVE_IDLE: 699 case LDAP_OPT_X_KEEPALIVE_PROBES : 700 case LDAP_OPT_X_KEEPALIVE_INTERVAL : 701 if(invalue == NULL) { 702 /* no place to set from */ 703 return LDAP_OPT_ERROR; 704 } 705 break; 706 707 default: 708 #ifdef HAVE_TLS 709 if ( ldap_pvt_tls_set_option( ld, option, (void *)invalue ) == 0 ) 710 return LDAP_OPT_SUCCESS; 711 #endif 712 #ifdef HAVE_CYRUS_SASL 713 if ( ldap_int_sasl_set_option( ld, option, (void *)invalue ) == 0 ) 714 return LDAP_OPT_SUCCESS; 715 #endif 716 #ifdef HAVE_GSSAPI 717 if ( ldap_int_gssapi_set_option( ld, option, (void *)invalue ) == 0 ) 718 return LDAP_OPT_SUCCESS; 719 #endif 720 /* bad param */ 721 return LDAP_OPT_ERROR; 722 } 723 724 /* options which cannot withstand invalue == NULL */ 725 726 switch(option) { 727 case LDAP_OPT_DEREF: 728 /* FIXME: check value for protocol compliance? */ 729 lo->ldo_deref = * (const int *) invalue; 730 return LDAP_OPT_SUCCESS; 731 732 case LDAP_OPT_SIZELIMIT: 733 /* FIXME: check value for protocol compliance? */ 734 lo->ldo_sizelimit = * (const int *) invalue; 735 return LDAP_OPT_SUCCESS; 736 737 case LDAP_OPT_TIMELIMIT: 738 /* FIXME: check value for protocol compliance? */ 739 lo->ldo_timelimit = * (const int *) invalue; 740 return LDAP_OPT_SUCCESS; 741 742 case LDAP_OPT_TIMEOUT: { 743 const struct timeval *tv = 744 (const struct timeval *) invalue; 745 746 lo->ldo_tm_api = *tv; 747 } return LDAP_OPT_SUCCESS; 748 749 case LDAP_OPT_NETWORK_TIMEOUT: { 750 const struct timeval *tv = 751 (const struct timeval *) invalue; 752 753 lo->ldo_tm_net = *tv; 754 } return LDAP_OPT_SUCCESS; 755 756 case LDAP_OPT_PROTOCOL_VERSION: { 757 int vers = * (const int *) invalue; 758 if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) { 759 /* not supported */ 760 break; 761 } 762 lo->ldo_version = vers; 763 } return LDAP_OPT_SUCCESS; 764 765 case LDAP_OPT_RESULT_CODE: { 766 int err = * (const int *) invalue; 767 768 if(ld == NULL) { 769 /* need a struct ldap */ 770 break; 771 } 772 773 ld->ld_errno = err; 774 } return LDAP_OPT_SUCCESS; 775 776 case LDAP_OPT_DEBUG_LEVEL: 777 lo->ldo_debug = * (const int *) invalue; 778 return LDAP_OPT_SUCCESS; 779 780 case LDAP_OPT_CONNECT_CB: 781 { 782 /* setting pushes the callback */ 783 ldaplist *ll; 784 ll = LDAP_MALLOC( sizeof( *ll )); 785 ll->ll_data = (void *)invalue; 786 ll->ll_next = lo->ldo_conn_cbs; 787 lo->ldo_conn_cbs = ll; 788 } 789 return LDAP_OPT_SUCCESS; 790 case LDAP_OPT_X_KEEPALIVE_IDLE: 791 lo->ldo_keepalive_idle = * (const int *) invalue; 792 return LDAP_OPT_SUCCESS; 793 case LDAP_OPT_X_KEEPALIVE_PROBES : 794 lo->ldo_keepalive_probes = * (const int *) invalue; 795 return LDAP_OPT_SUCCESS; 796 case LDAP_OPT_X_KEEPALIVE_INTERVAL : 797 lo->ldo_keepalive_interval = * (const int *) invalue; 798 return LDAP_OPT_SUCCESS; 799 800 } 801 return LDAP_OPT_ERROR; 802 } 803 804 int 805 ldap_set_rebind_proc( LDAP *ld, LDAP_REBIND_PROC *proc, void *params ) 806 { 807 int rc; 808 rc = ldap_set_option( ld, LDAP_OPT_REBIND_PROC, (void *)proc ); 809 if( rc != LDAP_OPT_SUCCESS ) return rc; 810 811 rc = ldap_set_option( ld, LDAP_OPT_REBIND_PARAMS, (void *)params ); 812 return rc; 813 } 814 815 int 816 ldap_set_nextref_proc( LDAP *ld, LDAP_NEXTREF_PROC *proc, void *params ) 817 { 818 int rc; 819 rc = ldap_set_option( ld, LDAP_OPT_NEXTREF_PROC, (void *)proc ); 820 if( rc != LDAP_OPT_SUCCESS ) return rc; 821 822 rc = ldap_set_option( ld, LDAP_OPT_NEXTREF_PARAMS, (void *)params ); 823 return rc; 824 } 825 826 int 827 ldap_set_urllist_proc( LDAP *ld, LDAP_URLLIST_PROC *proc, void *params ) 828 { 829 int rc; 830 rc = ldap_set_option( ld, LDAP_OPT_URLLIST_PROC, (void *)proc ); 831 if( rc != LDAP_OPT_SUCCESS ) return rc; 832 833 rc = ldap_set_option( ld, LDAP_OPT_URLLIST_PARAMS, (void *)params ); 834 return rc; 835 } 836