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