]> git.sur5r.net Git - openldap/blob - libraries/libldap/options.c
149c83cc30dbc0f6b2b9efd3418f06b27732446e
[openldap] / libraries / libldap / options.c
1 /*
2  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  */
5
6 #include "portable.h"
7
8 #include <stdio.h>
9 #include <stdlib.h>
10
11 #include <ac/socket.h>
12 #include <ac/string.h>
13
14 #include "ldap-int.h"
15
16 static const LDAPAPIFeatureInfo features[] = {
17 #ifdef LDAP_API_FEATURE_X_OPENLDAP
18         {       /* OpenLDAP Extensions API Feature */
19                 LDAP_FEATURE_INFO_VERSION,
20                 "X_OPENLDAP",
21                 LDAP_API_FEATURE_X_OPENLDAP
22         },
23 #endif
24
25 #ifdef LDAP_API_FEATURE_THREAD_SAFE
26         {       /* Basic Thread Safe */
27                 LDAP_FEATURE_INFO_VERSION,
28                 "THREAD_SAFE",
29                 LDAP_API_FEATURE_THREAD_SAFE
30         },
31 #endif
32 #ifdef LDAP_API_FEATURE_SESSION_THREAD_SAFE
33         {       /* Session Thread Safe */
34                 LDAP_FEATURE_INFO_VERSION,
35                 "SESSION_THREAD_SAFE",
36                 LDAP_API_FEATURE_SESSION_THREAD_SAFE
37         },
38 #endif
39 #ifdef LDAP_API_FEATURE_OPERATION_THREAD_SAFE
40         {       /* Operation Thread Safe */
41                 LDAP_FEATURE_INFO_VERSION,
42                 "OPERATION_THREAD_SAFE",
43                 LDAP_API_FEATURE_OPERATION_THREAD_SAFE
44         },
45 #endif
46 #ifdef LDAP_API_FEATURE_X_OPENLDAP_REENTRANT
47         {       /* OpenLDAP Reentrant */
48                 LDAP_FEATURE_INFO_VERSION,
49                 "X_OPENLDAP_REENTRANT",
50                 LDAP_API_FEATURE_X_OPENLDAP_REENTRANT
51         },
52 #endif
53 #if defined( LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE ) && \
54         defined( LDAP_THREAD_SAFE )
55         {       /* OpenLDAP Thread Safe */
56                 LDAP_FEATURE_INFO_VERSION,
57                 "X_OPENLDAP_THREAD_SAFE",
58                 LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE
59         },
60 #endif
61 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
62         {       /* DNS */
63                 LDAP_FEATURE_INFO_VERSION,
64                 "X_OPENLDAP_V2_DNS",
65                 LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
66         },
67 #endif
68 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
69         {       /* V2 Referrals */
70                 LDAP_FEATURE_INFO_VERSION,
71                 "X_OPENLDAP_V2_REFERRALS",
72                 LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS
73         },
74 #endif
75         {0, NULL, 0}
76 };
77
78 int
79 ldap_get_option(
80         LDAP    *ld,
81         int             option,
82         void    *outvalue)
83 {
84         struct ldapoptions *lo;
85
86         if( ldap_int_global_options.ldo_valid != LDAP_INITIALIZED ) {
87                 ldap_int_initialize();
88         }
89
90         if(outvalue == NULL) {
91                 /* no place to get to */
92                 return LDAP_OPT_ERROR;
93         }
94
95         if(ld == NULL) {
96                 lo = &ldap_int_global_options;
97
98         } else {
99                 assert( LDAP_VALID( ld ) );
100
101                 if( !LDAP_VALID( ld ) ) {
102                         return LDAP_OPT_ERROR;
103                 }
104
105                 lo = &ld->ld_options;
106         }
107
108         switch(option) {
109         case LDAP_OPT_API_INFO: {
110                         struct ldapapiinfo *info = (struct ldapapiinfo *) outvalue;
111
112                         if(info == NULL) {
113                                 /* outvalue must point to an apiinfo structure */
114                                 return LDAP_OPT_ERROR;
115                         }
116
117                         if(info->ldapai_info_version != LDAP_API_INFO_VERSION) {
118                                 /* api info version mismatch */
119                                 info->ldapai_info_version = LDAP_API_INFO_VERSION;
120                                 return LDAP_OPT_ERROR;
121                         }
122
123                         info->ldapai_api_version = LDAP_API_VERSION;
124                         info->ldapai_api_version = LDAP_API_VERSION;
125                         info->ldapai_protocol_version = LDAP_VERSION_MAX;
126
127                         if(features[0].ldapaif_name == NULL) {
128                                 info->ldapai_extensions = NULL;
129                         } else {
130                                 int i;
131                                 info->ldapai_extensions = LDAP_MALLOC(sizeof(char *) *
132                                         sizeof(features)/sizeof(LDAPAPIFeatureInfo));
133
134                                 for(i=0; features[i].ldapaif_name != NULL; i++) {
135                                         info->ldapai_extensions[i] =
136                                                 strdup(features[i].ldapaif_name);
137                                 }
138
139                                 info->ldapai_extensions[i] = NULL;
140                         }
141
142                         info->ldapai_vendor_name = strdup(LDAP_VENDOR_NAME);
143                         info->ldapai_vendor_version = LDAP_VENDOR_VERSION;
144
145                         return LDAP_OPT_SUCCESS;
146                 } break;
147
148         case LDAP_OPT_DESC:
149                 if(ld == NULL) {
150                         /* bad param */
151                         break;
152                 } 
153
154                 * (int *) outvalue = ber_pvt_sb_get_desc( &(ld->ld_sb) );
155                 return LDAP_OPT_SUCCESS;
156
157         case LDAP_OPT_DEREF:
158                 * (int *) outvalue = lo->ldo_deref;
159                 return LDAP_OPT_SUCCESS;
160
161         case LDAP_OPT_SIZELIMIT:
162                 * (int *) outvalue = lo->ldo_sizelimit;
163                 return LDAP_OPT_SUCCESS;
164
165         case LDAP_OPT_TIMELIMIT:
166                 * (int *) outvalue = lo->ldo_timelimit;
167                 return LDAP_OPT_SUCCESS;
168
169         case LDAP_OPT_REFERRALS:
170                 * (int *) outvalue = (LDAP_BOOL_GET(lo, LDAP_BOOL_REFERRALS) ==
171                                       LDAP_OPT_ON);
172                 return LDAP_OPT_SUCCESS;
173                 
174         case LDAP_OPT_RESTART:
175                 * (int *) outvalue = (LDAP_BOOL_GET(lo, LDAP_BOOL_RESTART) ==
176                                       LDAP_OPT_ON);
177                 return LDAP_OPT_SUCCESS;
178
179         case LDAP_OPT_DNS:      /* LDAPv2 */
180                 * (int *) outvalue = (LDAP_BOOL_GET(lo, LDAP_BOOL_DNS) ==
181                                       LDAP_OPT_ON);
182                 return LDAP_OPT_SUCCESS;
183
184         case LDAP_OPT_PROTOCOL_VERSION:
185                 if ((ld != NULL) && ld->ld_version) {
186                         * (int *) outvalue = ld->ld_version;
187                 } else { 
188                         * (int *) outvalue = lo->ldo_version;
189                 }
190                 return LDAP_OPT_SUCCESS;
191
192         case LDAP_OPT_SERVER_CONTROLS:
193                 * (LDAPControl ***) outvalue =
194                         ldap_controls_dup( lo->ldo_sctrls );
195
196                 return LDAP_OPT_SUCCESS;
197
198         case LDAP_OPT_CLIENT_CONTROLS:
199                 * (LDAPControl ***) outvalue =
200                         ldap_controls_dup( lo->ldo_cctrls );
201
202                 return LDAP_OPT_SUCCESS;
203
204         case LDAP_OPT_HOST_NAME:
205                 /*
206                  * draft-ietf-ldapext-ldap-c-api-01 doesn't state
207                  * whether caller has to free host names or not,
208                  * we do.
209                  */
210
211                 * (char **) outvalue = strdup(lo->ldo_defhost);
212                 return LDAP_OPT_SUCCESS;
213
214         case LDAP_OPT_ERROR_NUMBER:
215                 if(ld == NULL) {
216                         /* bad param */
217                         break;
218                 } 
219                 * (int *) outvalue = ld->ld_errno;
220                 return LDAP_OPT_SUCCESS;
221
222         case LDAP_OPT_ERROR_STRING:
223                 if(ld == NULL) {
224                         /* bad param */
225                         break;
226                 } 
227
228                 /*
229                  * draft-ietf-ldapext-ldap-c-api-01 doesn't require
230                  *      the client to have to free error strings, we do
231                  */
232
233                 if( ld->ld_error == NULL ) {
234                         * (char **) outvalue = NULL;
235                 } else {
236                         * (char **) outvalue = strdup(ld->ld_error);
237                 }
238
239                 return LDAP_OPT_SUCCESS;
240
241         case LDAP_OPT_MATCH_STRING:
242                 if(ld == NULL) {
243                         /* bad param */
244                         break;
245                 } 
246
247                 /*
248                  * draft-ietf-ldapext-ldap-c-api-01 doesn't require
249                  *      the client to have to free error strings, we do
250                  */
251
252                 if( ld->ld_matched == NULL ) {
253                         * (char **) outvalue = NULL;
254                 } else {
255                         * (char **) outvalue = strdup(ld->ld_matched);
256                 }
257
258                 return 0;
259
260         case LDAP_OPT_API_FEATURE_INFO: {
261                         LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue;
262                         int i;
263
264                         if(info == NULL) return LDAP_OPT_ERROR;
265
266                         if(info->ldapaif_info_version != LDAP_FEATURE_INFO_VERSION) {
267                                 /* api info version mismatch */
268                                 info->ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
269                                 return LDAP_OPT_ERROR;
270                         }
271
272                         if(info->ldapaif_name == NULL) return LDAP_OPT_ERROR;
273
274                         for(i=0; features[i].ldapaif_name != NULL; i++) {
275                                 if(!strcmp(info->ldapaif_name, features[i].ldapaif_name)) {
276                                         info->ldapaif_version =
277                                                 features[i].ldapaif_version;
278                                         return LDAP_OPT_SUCCESS;
279                                 }
280                         }
281                 }
282                 break;
283
284         case LDAP_OPT_DEBUG_LEVEL:
285                 * (int *) outvalue = lo->ldo_debug;
286                 return LDAP_OPT_SUCCESS;
287
288         default:
289                 /* bad param */
290                 break;
291         }
292
293         return LDAP_OPT_ERROR;
294 }
295
296 int
297 ldap_set_option(
298         LDAP    *ld,
299         int             option,
300         LDAP_CONST void *invalue)
301 {
302         struct ldapoptions *lo;
303
304         if( ldap_int_global_options.ldo_valid != LDAP_INITIALIZED ) {
305                 ldap_int_initialize();
306         }
307
308         if(ld == NULL) {
309                 lo = &ldap_int_global_options;
310
311         } else {
312                 assert( LDAP_VALID( ld ) );
313
314                 if( !LDAP_VALID( ld ) ) {
315                         return LDAP_OPT_ERROR;
316                 }
317
318                 lo = &ld->ld_options;
319         }
320
321         switch(option) {
322         case LDAP_OPT_REFERRALS:
323                 if(invalue == LDAP_OPT_ON) {
324                         LDAP_BOOL_SET(lo, LDAP_BOOL_REFERRALS);
325                 } else {
326                         LDAP_BOOL_CLR(lo, LDAP_BOOL_REFERRALS);
327                 }
328                 return LDAP_OPT_SUCCESS;
329
330         case LDAP_OPT_RESTART:
331                 if(invalue == LDAP_OPT_ON) {
332                         LDAP_BOOL_SET(lo, LDAP_BOOL_RESTART);
333                 } else {
334                         LDAP_BOOL_CLR(lo, LDAP_BOOL_RESTART);
335                 }
336                 return LDAP_OPT_SUCCESS;
337         }
338
339         if(invalue == NULL) {
340                 /* no place to set from */
341                 return LDAP_OPT_ERROR;
342         }
343
344         switch(option) {
345         case LDAP_OPT_API_INFO:
346         case LDAP_OPT_DESC:
347                 /* READ ONLY */
348                 break;
349
350         case LDAP_OPT_DEREF:
351                 lo->ldo_deref = * (int *) invalue;
352                 return LDAP_OPT_SUCCESS;
353
354         case LDAP_OPT_SIZELIMIT:
355                 lo->ldo_sizelimit = * (int *) invalue;
356                 return LDAP_OPT_SUCCESS;
357
358         case LDAP_OPT_TIMELIMIT:
359                 lo->ldo_timelimit = * (int *) invalue;
360                 return LDAP_OPT_SUCCESS;
361
362         case LDAP_OPT_PROTOCOL_VERSION: {
363                         int vers = * (int *) invalue;
364                         if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) {
365                                 /* not supported */
366                                 break;
367                         }
368                         ld->ld_version = vers;
369                 } return LDAP_OPT_SUCCESS;
370
371         case LDAP_OPT_SERVER_CONTROLS: {
372                         LDAPControl **controls = (LDAPControl **) invalue;
373
374                         ldap_controls_free( lo->ldo_sctrls );
375
376                         if( controls == NULL || *controls == NULL ) {
377                                 lo->ldo_sctrls = NULL;
378                                 return LDAP_OPT_SUCCESS;
379                         }
380                                 
381                         lo->ldo_sctrls =
382                                 ldap_controls_dup( (LDAPControl **) invalue );
383
384                         if(lo->ldo_sctrls == NULL) {
385                                 /* memory allocation error ? */
386                                 break;
387                         }
388                 } return LDAP_OPT_SUCCESS;
389
390         case LDAP_OPT_CLIENT_CONTROLS: {
391                         LDAPControl **controls = (LDAPControl **) invalue;
392
393                         ldap_controls_free( lo->ldo_cctrls );
394
395                         if( controls == NULL || *controls == NULL ) {
396                                 lo->ldo_cctrls = NULL;
397                                 return LDAP_OPT_SUCCESS;
398                         }
399                                 
400                         lo->ldo_cctrls =
401                                 ldap_controls_dup( (LDAPControl **) invalue );
402
403                         if(lo->ldo_cctrls == NULL) {
404                                 /* memory allocation error ? */
405                                 break;
406                         }
407                 } return LDAP_OPT_SUCCESS;
408
409         case LDAP_OPT_HOST_NAME: {
410                         char* host = (char *) invalue;
411
412                         if(lo->ldo_defhost != NULL) {
413                                 LDAP_FREE(lo->ldo_defhost);
414                                 lo->ldo_defhost = NULL;
415                         }
416
417                         if(host != NULL) {
418                                 lo->ldo_defhost = strdup(host);
419                                 return LDAP_OPT_SUCCESS;
420                         }
421
422                         if(ld == NULL) {
423                                 /*
424                                  * must want global default returned
425                                  * to initial condition.
426                                  */
427                                 lo->ldo_defhost = strdup("localhost");
428
429                         } else {
430                                 /*
431                                  * must want the session default
432                                  *   updated to the current global default
433                                  */
434                                 lo->ldo_defhost = strdup(
435                                         ldap_int_global_options.ldo_defhost);
436                         }
437                 } return LDAP_OPT_SUCCESS;
438
439         case LDAP_OPT_ERROR_NUMBER: {
440                         int err = * (int *) invalue;
441
442                         if(ld == NULL) {
443                                 /* need a struct ldap */
444                                 break;
445                         }
446
447                         ld->ld_errno = err;
448                 } return LDAP_OPT_SUCCESS;
449
450         case LDAP_OPT_ERROR_STRING: {
451                         char* err = (char *) invalue;
452
453                         if(ld == NULL) {
454                                 /* need a struct ldap */
455                                 break;
456                         }
457
458                         if( ld->ld_error ) {
459                                 LDAP_FREE(ld->ld_error);
460                         }
461
462                         ld->ld_error = strdup(err);
463                 } return LDAP_OPT_SUCCESS;
464
465         case LDAP_OPT_API_FEATURE_INFO:
466                 /* read-only */
467                 break;
468
469         case LDAP_OPT_DEBUG_LEVEL:
470                 lo->ldo_debug = * (int *) invalue;
471                 return LDAP_OPT_SUCCESS;
472
473         default:
474                 /* bad param */
475                 break;
476         }
477         return LDAP_OPT_ERROR;
478 }