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