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