]> git.sur5r.net Git - openldap/blob - libraries/libldap/options.c
Initial incomplete and broken version.
[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_API_FEATURE_INFO: {
235                         LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue;
236                         int i;
237
238                         if(info == NULL) return -1;
239
240                         if(info->ldapaif_info_version != LDAP_FEATURE_INFO_VERSION) {
241                                 /* api info version mismatch */
242                                 info->ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
243                                 return -1;
244                         }
245
246                         if(info->ldapaif_name == NULL) return -1;
247
248                         for(i=0; features[i].ldapaif_name != NULL; i++) {
249                                 if(!strcmp(info->ldapaif_name, features[i].ldapaif_name)) {
250                                         info->ldapaif_version =
251                                                 features[i].ldapaif_version;
252                                         return 0;
253                                 }
254                         }
255                 }
256                 break;
257
258         case LDAP_OPT_DEBUG_LEVEL:
259                 * (int *) outvalue = lo->ldo_debug;
260                 return 0;
261
262         default:
263                 /* bad param */
264                 break;
265         }
266
267         return -1;
268 }
269
270 int
271 ldap_set_option(
272         LDAP    *ld,
273         int             option,
274         LDAP_CONST void *invalue)
275 {
276         struct ldapoptions *lo;
277
278         if(!openldap_ldap_initialized) {
279                 openldap_ldap_initialize();
280         }
281
282         if(ld == NULL) {
283                 lo = &openldap_ldap_global_options;
284         } else {
285                 lo = &ld->ld_options;
286         }
287
288         switch(option) {
289         case LDAP_OPT_REFERRALS:
290                 if(invalue == LDAP_OPT_ON) {
291                         LDAP_BOOL_SET(lo, LDAP_BOOL_REFERRALS);
292                 } else {
293                         LDAP_BOOL_CLR(lo, LDAP_BOOL_REFERRALS);
294                 }
295                 return 0;
296
297         case LDAP_OPT_RESTART:
298                 if(invalue == LDAP_OPT_ON) {
299                         LDAP_BOOL_SET(lo, LDAP_BOOL_RESTART);
300                 } else {
301                         LDAP_BOOL_CLR(lo, LDAP_BOOL_RESTART);
302                 }
303                 return 0;
304         }
305
306         if(invalue == NULL) {
307                 /* no place to set from */
308                 return -1;
309         }
310
311         switch(option) {
312         case LDAP_OPT_API_INFO:
313         case LDAP_OPT_DESC:
314                 /* READ ONLY */
315                 break;
316
317         case LDAP_OPT_DEREF:
318                 lo->ldo_deref = * (int *) invalue;
319                 return 0;
320
321         case LDAP_OPT_SIZELIMIT:
322                 lo->ldo_sizelimit = * (int *) invalue;
323                 return 0;
324
325         case LDAP_OPT_TIMELIMIT:
326                 lo->ldo_timelimit = * (int *) invalue;
327                 return 0;
328
329         case LDAP_OPT_PROTOCOL_VERSION: {
330                         int vers = * (int *) invalue;
331                         if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) {
332                                 /* not supported */
333                                 break;
334                         }
335                         ld->ld_version = vers;
336                 } return 0;
337
338         case LDAP_OPT_SERVER_CONTROLS: {
339                         LDAPControl **controls = (LDAPControl **) invalue;
340
341                         ldap_controls_free( lo->ldo_sctrls );
342
343                         if( controls == NULL || *controls == NULL ) {
344                                 lo->ldo_sctrls = NULL;
345                                 return 0;
346                         }
347                                 
348                         lo->ldo_sctrls =
349                                 ldap_controls_dup( (LDAPControl **) invalue );
350
351                         if(lo->ldo_sctrls == NULL) {
352                                 /* memory allocation error ? */
353                                 break;
354                         }
355                 } return 0;
356
357         case LDAP_OPT_CLIENT_CONTROLS: {
358                         LDAPControl **controls = (LDAPControl **) invalue;
359
360                         ldap_controls_free( lo->ldo_cctrls );
361
362                         if( controls == NULL || *controls == NULL ) {
363                                 lo->ldo_cctrls = NULL;
364                                 return 0;
365                         }
366                                 
367                         lo->ldo_cctrls =
368                                 ldap_controls_dup( (LDAPControl **) invalue );
369
370                         if(lo->ldo_cctrls == NULL) {
371                                 /* memory allocation error ? */
372                                 break;
373                         }
374                 } return 0;
375
376         case LDAP_OPT_HOST_NAME: {
377                         char* host = (char *) invalue;
378
379                         if(lo->ldo_defhost != NULL) {
380                                 free(lo->ldo_defhost);
381                                 lo->ldo_defhost = NULL;
382                         }
383
384                         if(host != NULL) {
385                                 lo->ldo_defhost = strdup(host);
386                                 return 0;
387                         }
388
389                         if(ld == NULL) {
390                                 /*
391                                  * must want global default returned
392                                  * to initial condition.
393                                  */
394                                 lo->ldo_defhost = strdup("localhost");
395
396                         } else {
397                                 /*
398                                  * must want the session default
399                                  *   updated to the current global default
400                                  */
401                                 lo->ldo_defhost = strdup(
402                                         openldap_ldap_global_options.ldo_defhost);
403                         }
404                 } return 0;
405
406         case LDAP_OPT_ERROR_NUMBER: {
407                         int err = * (int *) invalue;
408
409                         if(ld == NULL) {
410                                 /* need a struct ldap */
411                                 break;
412                         }
413
414                         ld->ld_errno = err;
415                 } return 0;
416
417         case LDAP_OPT_ERROR_STRING: {
418                         char* err = (char *) invalue;
419
420                         if(ld == NULL) {
421                                 /* need a struct ldap */
422                                 break;
423                         }
424
425                         if( ld->ld_error ) {
426                                 free(ld->ld_error);
427                         }
428
429                         ld->ld_error = strdup(err);
430                 } return 0;
431
432         case LDAP_OPT_API_FEATURE_INFO:
433                 /* read-only */
434                 break;
435
436         case LDAP_OPT_DEBUG_LEVEL:
437                 lo->ldo_debug = * (int *) invalue;
438                 return 0;
439
440         default:
441                 /* bad param */
442                 break;
443         }
444         return -1;
445 }