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