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