]> git.sur5r.net Git - openldap/blob - libraries/libldap/options.c
rename ldap_pvt_init_utils() to ldap_int_utils_init() and provide
[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(!openldap_ldap_initialized) {
87                 openldap_ldap_initialize();
88         }
89
90         if(outvalue == NULL) {
91                 /* no place to get to */
92                 return -1;
93         }
94
95         if(ld == NULL) {
96                 lo = &openldap_ldap_global_options;
97         } else {
98                 lo = &ld->ld_options;
99         }
100
101         switch(option) {
102         case LDAP_OPT_API_INFO: {
103                         struct ldapapiinfo *info = (struct ldapapiinfo *) outvalue;
104
105                         if(info == NULL) {
106                                 /* outvalue must point to an apiinfo structure */
107                                 return -1;
108                         }
109
110                         if(info->ldapai_info_version != LDAP_API_INFO_VERSION) {
111                                 /* api info version mismatch */
112                                 info->ldapai_info_version = LDAP_API_INFO_VERSION;
113                                 return -1;
114                         }
115
116                         info->ldapai_api_version = LDAP_API_VERSION;
117                         info->ldapai_api_version = LDAP_API_VERSION;
118                         info->ldapai_protocol_version = LDAP_VERSION_MAX;
119
120                         if(features[0].ldapaif_name == NULL) {
121                                 info->ldapai_extensions = NULL;
122                         } else {
123                                 int i;
124                                 info->ldapai_extensions = malloc(sizeof(char *) *
125                                         sizeof(features)/sizeof(LDAPAPIFeatureInfo));
126
127                                 for(i=0; features[i].ldapaif_name != NULL; i++) {
128                                         info->ldapai_extensions[i] =
129                                                 strdup(features[i].ldapaif_name);
130                                 }
131
132                                 info->ldapai_extensions[i] = NULL;
133                         }
134
135                         info->ldapai_vendor_name = strdup(LDAP_VENDOR_NAME);
136                         info->ldapai_vendor_version = LDAP_VENDOR_VERSION;
137
138                         return 0;
139                 } break;
140
141         case LDAP_OPT_DESC:
142                 if(ld == NULL) {
143                         /* bad param */
144                         break;
145                 } 
146
147                 * (int *) outvalue = ber_pvt_sb_get_desc( &(ld->ld_sb) );
148                 return 0;
149
150         case LDAP_OPT_DEREF:
151                 * (int *) outvalue = lo->ldo_deref;
152                 return 0;
153
154         case LDAP_OPT_SIZELIMIT:
155                 * (int *) outvalue = lo->ldo_sizelimit;
156                 return 0;
157
158         case LDAP_OPT_TIMELIMIT:
159                 * (int *) outvalue = lo->ldo_timelimit;
160                 return 0;
161
162         case LDAP_OPT_REFERRALS:
163                 * (int *) outvalue = (LDAP_BOOL_GET(lo, LDAP_BOOL_REFERRALS) ==
164                                       LDAP_OPT_ON);
165                 return 0;
166                 
167         case LDAP_OPT_RESTART:
168                 * (int *) outvalue = (LDAP_BOOL_GET(lo, LDAP_BOOL_RESTART) ==
169                                       LDAP_OPT_ON);
170                 return 0;
171
172         case LDAP_OPT_DNS:      /* LDAPv2 */
173                 * (int *) outvalue = (LDAP_BOOL_GET(lo, LDAP_BOOL_DNS) ==
174                                       LDAP_OPT_ON);
175                 return 0;
176
177         case LDAP_OPT_PROTOCOL_VERSION:
178                 if ((ld != NULL) && ld->ld_version) {
179                         * (int *) outvalue = ld->ld_version;
180                 } else { 
181                         * (int *) outvalue = lo->ldo_version;
182                 }
183                 return 0;
184
185         case LDAP_OPT_SERVER_CONTROLS:
186                 * (LDAPControl ***) outvalue =
187                         ldap_controls_dup( lo->ldo_sctrls );
188
189                 return 0;
190
191         case LDAP_OPT_CLIENT_CONTROLS:
192                 * (LDAPControl ***) outvalue =
193                         ldap_controls_dup( lo->ldo_cctrls );
194
195                 return 0;
196
197         case LDAP_OPT_HOST_NAME:
198                 /*
199                  * draft-ietf-ldapext-ldap-c-api-01 doesn't state
200                  * whether caller has to free host names or not,
201                  * we do.
202                  */
203
204                 * (char **) outvalue = strdup(lo->ldo_defhost);
205                 return 0;
206
207         case LDAP_OPT_ERROR_NUMBER:
208                 if(ld == NULL) {
209                         /* bad param */
210                         break;
211                 } 
212                 * (int *) outvalue = ld->ld_errno;
213                 return 0;
214
215         case LDAP_OPT_ERROR_STRING:
216                 if(ld == NULL) {
217                         /* bad param */
218                         break;
219                 } 
220
221                 /*
222                  * draft-ietf-ldapext-ldap-c-api-01 doesn't require
223                  *      the client to have to free error strings, we do
224                  */
225
226                 if( ld->ld_error == NULL ) {
227                         * (char **) outvalue = NULL;
228                 } else {
229                         * (char **) outvalue = strdup(ld->ld_error);
230                 }
231
232                 return 0;
233
234         case LDAP_OPT_MATCH_STRING:
235                 if(ld == NULL) {
236                         /* bad param */
237                         break;
238                 } 
239
240                 /*
241                  * draft-ietf-ldapext-ldap-c-api-01 doesn't require
242                  *      the client to have to free error strings, we do
243                  */
244
245                 if( ld->ld_matched == NULL ) {
246                         * (char **) outvalue = NULL;
247                 } else {
248                         * (char **) outvalue = strdup(ld->ld_matched);
249                 }
250
251                 return 0;
252
253         case LDAP_OPT_API_FEATURE_INFO: {
254                         LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue;
255                         int i;
256
257                         if(info == NULL) return -1;
258
259                         if(info->ldapaif_info_version != LDAP_FEATURE_INFO_VERSION) {
260                                 /* api info version mismatch */
261                                 info->ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
262                                 return -1;
263                         }
264
265                         if(info->ldapaif_name == NULL) return -1;
266
267                         for(i=0; features[i].ldapaif_name != NULL; i++) {
268                                 if(!strcmp(info->ldapaif_name, features[i].ldapaif_name)) {
269                                         info->ldapaif_version =
270                                                 features[i].ldapaif_version;
271                                         return 0;
272                                 }
273                         }
274                 }
275                 break;
276
277         case LDAP_OPT_DEBUG_LEVEL:
278                 * (int *) outvalue = lo->ldo_debug;
279                 return 0;
280
281         default:
282                 /* bad param */
283                 break;
284         }
285
286         return -1;
287 }
288
289 int
290 ldap_set_option(
291         LDAP    *ld,
292         int             option,
293         LDAP_CONST void *invalue)
294 {
295         struct ldapoptions *lo;
296
297         if(!openldap_ldap_initialized) {
298                 openldap_ldap_initialize();
299         }
300
301         if(ld == NULL) {
302                 lo = &openldap_ldap_global_options;
303         } else {
304                 lo = &ld->ld_options;
305         }
306
307         switch(option) {
308         case LDAP_OPT_REFERRALS:
309                 if(invalue == LDAP_OPT_ON) {
310                         LDAP_BOOL_SET(lo, LDAP_BOOL_REFERRALS);
311                 } else {
312                         LDAP_BOOL_CLR(lo, LDAP_BOOL_REFERRALS);
313                 }
314                 return 0;
315
316         case LDAP_OPT_RESTART:
317                 if(invalue == LDAP_OPT_ON) {
318                         LDAP_BOOL_SET(lo, LDAP_BOOL_RESTART);
319                 } else {
320                         LDAP_BOOL_CLR(lo, LDAP_BOOL_RESTART);
321                 }
322                 return 0;
323         }
324
325         if(invalue == NULL) {
326                 /* no place to set from */
327                 return -1;
328         }
329
330         switch(option) {
331         case LDAP_OPT_API_INFO:
332         case LDAP_OPT_DESC:
333                 /* READ ONLY */
334                 break;
335
336         case LDAP_OPT_DEREF:
337                 lo->ldo_deref = * (int *) invalue;
338                 return 0;
339
340         case LDAP_OPT_SIZELIMIT:
341                 lo->ldo_sizelimit = * (int *) invalue;
342                 return 0;
343
344         case LDAP_OPT_TIMELIMIT:
345                 lo->ldo_timelimit = * (int *) invalue;
346                 return 0;
347
348         case LDAP_OPT_PROTOCOL_VERSION: {
349                         int vers = * (int *) invalue;
350                         if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) {
351                                 /* not supported */
352                                 break;
353                         }
354                         ld->ld_version = vers;
355                 } return 0;
356
357         case LDAP_OPT_SERVER_CONTROLS: {
358                         LDAPControl **controls = (LDAPControl **) invalue;
359
360                         ldap_controls_free( lo->ldo_sctrls );
361
362                         if( controls == NULL || *controls == NULL ) {
363                                 lo->ldo_sctrls = NULL;
364                                 return 0;
365                         }
366                                 
367                         lo->ldo_sctrls =
368                                 ldap_controls_dup( (LDAPControl **) invalue );
369
370                         if(lo->ldo_sctrls == NULL) {
371                                 /* memory allocation error ? */
372                                 break;
373                         }
374                 } return 0;
375
376         case LDAP_OPT_CLIENT_CONTROLS: {
377                         LDAPControl **controls = (LDAPControl **) invalue;
378
379                         ldap_controls_free( lo->ldo_cctrls );
380
381                         if( controls == NULL || *controls == NULL ) {
382                                 lo->ldo_cctrls = NULL;
383                                 return 0;
384                         }
385                                 
386                         lo->ldo_cctrls =
387                                 ldap_controls_dup( (LDAPControl **) invalue );
388
389                         if(lo->ldo_cctrls == NULL) {
390                                 /* memory allocation error ? */
391                                 break;
392                         }
393                 } return 0;
394
395         case LDAP_OPT_HOST_NAME: {
396                         char* host = (char *) invalue;
397
398                         if(lo->ldo_defhost != NULL) {
399                                 free(lo->ldo_defhost);
400                                 lo->ldo_defhost = NULL;
401                         }
402
403                         if(host != NULL) {
404                                 lo->ldo_defhost = strdup(host);
405                                 return 0;
406                         }
407
408                         if(ld == NULL) {
409                                 /*
410                                  * must want global default returned
411                                  * to initial condition.
412                                  */
413                                 lo->ldo_defhost = strdup("localhost");
414
415                         } else {
416                                 /*
417                                  * must want the session default
418                                  *   updated to the current global default
419                                  */
420                                 lo->ldo_defhost = strdup(
421                                         openldap_ldap_global_options.ldo_defhost);
422                         }
423                 } return 0;
424
425         case LDAP_OPT_ERROR_NUMBER: {
426                         int err = * (int *) invalue;
427
428                         if(ld == NULL) {
429                                 /* need a struct ldap */
430                                 break;
431                         }
432
433                         ld->ld_errno = err;
434                 } return 0;
435
436         case LDAP_OPT_ERROR_STRING: {
437                         char* err = (char *) invalue;
438
439                         if(ld == NULL) {
440                                 /* need a struct ldap */
441                                 break;
442                         }
443
444                         if( ld->ld_error ) {
445                                 free(ld->ld_error);
446                         }
447
448                         ld->ld_error = strdup(err);
449                 } return 0;
450
451         case LDAP_OPT_API_FEATURE_INFO:
452                 /* read-only */
453                 break;
454
455         case LDAP_OPT_DEBUG_LEVEL:
456                 lo->ldo_debug = * (int *) invalue;
457                 return 0;
458
459         default:
460                 /* bad param */
461                 break;
462         }
463         return -1;
464 }