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