]> git.sur5r.net Git - openldap/blob - libraries/libldap/options.c
3c99686ff37d4dec363012b233aad70fa4184e69
[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(invalue == NULL) {
243                 /* no place to set from */
244                 return -1;
245         }
246
247         if(ld == NULL) {
248                 lo = &openldap_ldap_global_options;
249         } else {
250                 lo = &ld->ld_options;
251         }
252
253         switch(option) {
254         case LDAP_OPT_API_INFO:
255         case LDAP_OPT_DESC:
256                 /* READ ONLY */
257                 break;
258
259         case LDAP_OPT_DEREF:
260                 lo->ldo_deref = * (int *) invalue;
261                 return 0;
262
263         case LDAP_OPT_SIZELIMIT:
264                 lo->ldo_sizelimit = * (int *) invalue;
265                 return 0;
266
267         case LDAP_OPT_TIMELIMIT:
268                 lo->ldo_timelimit = * (int *) invalue;
269                 return 0;
270
271         case LDAP_OPT_REFERRALS:
272                 if(invalue == LDAP_OPT_ON) {
273                         LDAP_BOOL_SET(lo, LDAP_BOOL_REFERRALS);
274                 } else {
275                         LDAP_BOOL_CLR(lo, LDAP_BOOL_REFERRALS);
276                 }
277                 return 0;
278
279         case LDAP_OPT_RESTART:
280                 if(invalue == LDAP_OPT_ON) {
281                         LDAP_BOOL_SET(lo, LDAP_BOOL_RESTART);
282                 } else {
283                         LDAP_BOOL_CLR(lo, LDAP_BOOL_RESTART);
284                 }
285                 return 0;
286
287         case LDAP_OPT_PROTOCOL_VERSION: {
288                         int vers = * (int *) invalue;
289                         if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) {
290                                 /* not supported */
291                                 break;
292                         }
293                         ld->ld_version = vers;
294                 } return 0;
295
296         case LDAP_OPT_SERVER_CONTROLS: {
297                         LDAPControl **controls = (LDAPControl **) invalue;
298
299                         ldap_controls_free( lo->ldo_server_controls );
300
301                         if( controls == NULL || *controls == NULL ) {
302                                 lo->ldo_server_controls = NULL;
303                                 return 0;
304                         }
305                                 
306                         lo->ldo_server_controls =
307                                 ldap_controls_dup( (LDAPControl **) invalue );
308
309                         if(lo->ldo_server_controls == NULL) {
310                                 /* memory allocation error ? */
311                                 break;
312                         }
313                 } return 0;
314
315         case LDAP_OPT_CLIENT_CONTROLS: {
316                         LDAPControl **controls = (LDAPControl **) invalue;
317
318                         ldap_controls_free( lo->ldo_client_controls );
319
320                         if( controls == NULL || *controls == NULL ) {
321                                 lo->ldo_client_controls = NULL;
322                                 return 0;
323                         }
324                                 
325                         lo->ldo_client_controls =
326                                 ldap_controls_dup( (LDAPControl **) invalue );
327
328                         if(lo->ldo_client_controls == NULL) {
329                                 /* memory allocation error ? */
330                                 break;
331                         }
332                 } return 0;
333
334         case LDAP_OPT_HOST_NAME: {
335                         char* host = (char *) invalue;
336
337                         if(lo->ldo_defhost != NULL) {
338                                 free(lo->ldo_defhost);
339                                 lo->ldo_defhost = NULL;
340                         }
341
342                         if(host != NULL) {
343                                 lo->ldo_defhost = strdup(host);
344                                 return 0;
345                         }
346
347                         if(ld == NULL) {
348                                 /*
349                                  * must want global default returned
350                                  * to initial condition.
351                                  */
352                                 lo->ldo_defhost = strdup("localhost");
353
354                         } else {
355                                 /*
356                                  * must want the session default
357                                  *   updated to the current global default
358                                  */
359                                 lo->ldo_defhost = strdup(
360                                         openldap_ldap_global_options.ldo_defhost);
361                         }
362                 } return 0;
363
364         case LDAP_OPT_ERROR_NUMBER: {
365                         int err = * (int *) invalue;
366
367                         if(ld == NULL) {
368                                 /* need a struct ldap */
369                                 break;
370                         }
371
372                         ld->ld_errno = err;
373                 } return 0;
374
375         case LDAP_OPT_ERROR_STRING: {
376                         char* err = (char *) invalue;
377
378                         if(ld == NULL) {
379                                 /* need a struct ldap */
380                                 break;
381                         }
382
383                         if( ld->ld_error ) {
384                                 free(ld->ld_error);
385                         }
386
387                         ld->ld_error = strdup(err);
388                 } return 0;
389
390         case LDAP_OPT_API_FEATURE_INFO:
391                 /* read-only */
392                 break;
393
394         case LDAP_OPT_DEBUG_LEVEL:
395                 lo->ldo_debug = * (int *) invalue;
396                 return 0;
397
398         default:
399                 /* bad param */
400                 break;
401         }
402         return -1;
403 }