mf/evr: Post sink marker events.
[wine.git] / dlls / wldap32 / option.c
blobec3830d4ab3ffdb7c6cbae67f216a7bb716c5b25
1 /*
2 * WLDAP32 - LDAP support for Wine
4 * Copyright 2005 Hans Leidekker
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include "windef.h"
23 #include "winbase.h"
24 #include "winnls.h"
25 #include "winldap.h"
27 #include "wine/debug.h"
28 #include "winldap_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
32 #ifndef LDAP_OPT_SERVER_CONTROLS
33 #define LDAP_OPT_SERVER_CONTROLS 0x0012
34 #endif
36 /***********************************************************************
37 * ldap_get_optionA (WLDAP32.@)
39 * See ldap_get_optionW.
41 ULONG CDECL ldap_get_optionA( LDAP *ld, int option, void *value )
43 ULONG ret;
45 TRACE( "(%p, 0x%08x, %p)\n", ld, option, value );
47 if (!ld || !value) return LDAP_PARAM_ERROR;
49 switch (option)
51 case LDAP_OPT_API_FEATURE_INFO:
53 LDAPAPIFeatureInfoW featureW;
54 LDAPAPIFeatureInfoA *featureA = value;
56 if (!featureA->ldapaif_name) return LDAP_PARAM_ERROR;
58 featureW.ldapaif_info_version = featureA->ldapaif_info_version;
59 if (!(featureW.ldapaif_name = strAtoW( featureA->ldapaif_name ))) return LDAP_NO_MEMORY;
60 featureW.ldapaif_version = 0;
62 ret = ldap_get_optionW( ld, option, &featureW );
64 if (ret == LDAP_SUCCESS) featureA->ldapaif_version = featureW.ldapaif_version;
65 free( featureW.ldapaif_name );
66 return ret;
68 case LDAP_OPT_API_INFO:
70 LDAPAPIInfoW infoW;
71 LDAPAPIInfoA *infoA = value;
73 memset( &infoW, 0, sizeof(infoW) );
74 infoW.ldapai_info_version = infoA->ldapai_info_version;
76 ret = ldap_get_optionW( ld, option, &infoW );
77 if (ret == LDAP_SUCCESS)
79 infoA->ldapai_api_version = infoW.ldapai_api_version;
80 infoA->ldapai_protocol_version = infoW.ldapai_protocol_version;
82 if (infoW.ldapai_extensions && !(infoA->ldapai_extensions = strarrayWtoA( infoW.ldapai_extensions )))
83 return LDAP_NO_MEMORY;
84 if (infoW.ldapai_vendor_name && !(infoA->ldapai_vendor_name = strWtoA( infoW.ldapai_vendor_name )))
86 ldap_value_freeW( infoW.ldapai_extensions );
87 return LDAP_NO_MEMORY;
89 infoA->ldapai_vendor_version = infoW.ldapai_vendor_version;
91 ldap_value_freeW( infoW.ldapai_extensions );
92 ldap_memfreeW( infoW.ldapai_vendor_name );
94 return ret;
97 case LDAP_OPT_DEREF:
98 case LDAP_OPT_DESC:
99 case LDAP_OPT_ERROR_NUMBER:
100 case LDAP_OPT_PROTOCOL_VERSION:
101 case LDAP_OPT_REFERRALS:
102 case LDAP_OPT_SIZELIMIT:
103 case LDAP_OPT_TIMELIMIT:
104 return ldap_get_optionW( ld, option, value );
106 case LDAP_OPT_CACHE_ENABLE:
107 case LDAP_OPT_CACHE_FN_PTRS:
108 case LDAP_OPT_CACHE_STRATEGY:
109 case LDAP_OPT_IO_FN_PTRS:
110 case LDAP_OPT_REBIND_ARG:
111 case LDAP_OPT_REBIND_FN:
112 case LDAP_OPT_RESTART:
113 case LDAP_OPT_THREAD_FN_PTRS:
114 return LDAP_LOCAL_ERROR;
116 case LDAP_OPT_AREC_EXCLUSIVE:
117 case LDAP_OPT_AUTO_RECONNECT:
118 case LDAP_OPT_CLIENT_CERTIFICATE:
119 case LDAP_OPT_DNSDOMAIN_NAME:
120 case LDAP_OPT_ENCRYPT:
121 case LDAP_OPT_ERROR_STRING:
122 case LDAP_OPT_FAST_CONCURRENT_BIND:
123 case LDAP_OPT_GETDSNAME_FLAGS:
124 case LDAP_OPT_HOST_NAME:
125 case LDAP_OPT_HOST_REACHABLE:
126 case LDAP_OPT_PING_KEEP_ALIVE:
127 case LDAP_OPT_PING_LIMIT:
128 case LDAP_OPT_PING_WAIT_TIME:
129 case LDAP_OPT_PROMPT_CREDENTIALS:
130 case LDAP_OPT_REF_DEREF_CONN_PER_MSG:
131 case LDAP_OPT_REFERRAL_CALLBACK:
132 case LDAP_OPT_REFERRAL_HOP_LIMIT:
133 case LDAP_OPT_ROOTDSE_CACHE:
134 case LDAP_OPT_SASL_METHOD:
135 case LDAP_OPT_SECURITY_CONTEXT:
136 case LDAP_OPT_SEND_TIMEOUT:
137 case LDAP_OPT_SERVER_CERTIFICATE:
138 case LDAP_OPT_SERVER_CONTROLS:
139 case LDAP_OPT_SERVER_ERROR:
140 case LDAP_OPT_SERVER_EXT_ERROR:
141 case LDAP_OPT_SIGN:
142 case LDAP_OPT_SSL:
143 case LDAP_OPT_SSL_INFO:
144 case LDAP_OPT_SSPI_FLAGS:
145 case LDAP_OPT_TCP_KEEPALIVE:
146 FIXME( "Unsupported option: 0x%02x\n", option );
147 return LDAP_NOT_SUPPORTED;
149 default:
150 FIXME( "Unknown option: 0x%02x\n", option );
151 return LDAP_LOCAL_ERROR;
155 /***********************************************************************
156 * ldap_get_optionW (WLDAP32.@)
158 * Retrieve option values for a given LDAP context.
160 * PARAMS
161 * ld [I] Pointer to an LDAP context.
162 * option [I] Option to get values for.
163 * value [O] Pointer to option values.
165 * RETURNS
166 * Success: LDAP_SUCCESS
167 * Failure: An LDAP error code.
169 ULONG CDECL ldap_get_optionW( LDAP *ld, int option, void *value )
171 ULONG ret;
173 TRACE( "(%p, 0x%08x, %p)\n", ld, option, value );
175 if (!ld || !value) return LDAP_PARAM_ERROR;
177 switch (option)
179 case LDAP_OPT_API_FEATURE_INFO:
181 LDAPAPIFeatureInfoU featureU;
182 LDAPAPIFeatureInfoW *featureW = value;
184 if (!featureW->ldapaif_name) return LDAP_PARAM_ERROR;
186 featureU.ldapaif_info_version = featureW->ldapaif_info_version;
187 if (!(featureU.ldapaif_name = strWtoU( featureW->ldapaif_name ))) return LDAP_NO_MEMORY;
188 featureU.ldapaif_version = 0;
190 ret = map_error( ldap_funcs->fn_ldap_get_option( CTX(ld), option, &featureU ) );
192 if (ret == LDAP_SUCCESS) featureW->ldapaif_version = featureU.ldapaif_version;
193 free( featureU.ldapaif_name );
194 return ret;
196 case LDAP_OPT_API_INFO:
198 LDAPAPIInfoU infoU;
199 LDAPAPIInfoW *infoW = value;
201 memset( &infoU, 0, sizeof(infoU) );
202 infoU.ldapai_info_version = infoW->ldapai_info_version;
204 ret = map_error( ldap_funcs->fn_ldap_get_option( CTX(ld), option, &infoU ) );
205 if (ret == LDAP_SUCCESS)
207 infoW->ldapai_api_version = infoU.ldapai_api_version;
208 infoW->ldapai_protocol_version = infoU.ldapai_protocol_version;
210 if (infoU.ldapai_extensions && !(infoW->ldapai_extensions = strarrayUtoW( infoU.ldapai_extensions )))
211 return LDAP_NO_MEMORY;
212 if (infoU.ldapai_vendor_name && !(infoW->ldapai_vendor_name = strUtoW( infoU.ldapai_vendor_name )))
214 ldap_funcs->fn_ldap_memvfree( (void **)infoU.ldapai_extensions );
215 return LDAP_NO_MEMORY;
217 infoW->ldapai_vendor_version = infoU.ldapai_vendor_version;
219 ldap_funcs->fn_ldap_memvfree( (void **)infoU.ldapai_extensions );
220 ldap_funcs->fn_ldap_memfree( infoU.ldapai_vendor_name );
222 return ret;
225 case LDAP_OPT_DEREF:
226 case LDAP_OPT_DESC:
227 case LDAP_OPT_ERROR_NUMBER:
228 case LDAP_OPT_PROTOCOL_VERSION:
229 case LDAP_OPT_REFERRALS:
230 case LDAP_OPT_SIZELIMIT:
231 case LDAP_OPT_TIMELIMIT:
232 return map_error( ldap_funcs->fn_ldap_get_option( CTX(ld), option, value ));
234 case LDAP_OPT_CACHE_ENABLE:
235 case LDAP_OPT_CACHE_FN_PTRS:
236 case LDAP_OPT_CACHE_STRATEGY:
237 case LDAP_OPT_IO_FN_PTRS:
238 case LDAP_OPT_REBIND_ARG:
239 case LDAP_OPT_REBIND_FN:
240 case LDAP_OPT_RESTART:
241 case LDAP_OPT_THREAD_FN_PTRS:
242 return LDAP_LOCAL_ERROR;
244 case LDAP_OPT_AREC_EXCLUSIVE:
245 case LDAP_OPT_AUTO_RECONNECT:
246 case LDAP_OPT_CLIENT_CERTIFICATE:
247 case LDAP_OPT_DNSDOMAIN_NAME:
248 case LDAP_OPT_ENCRYPT:
249 case LDAP_OPT_ERROR_STRING:
250 case LDAP_OPT_FAST_CONCURRENT_BIND:
251 case LDAP_OPT_GETDSNAME_FLAGS:
252 case LDAP_OPT_HOST_NAME:
253 case LDAP_OPT_HOST_REACHABLE:
254 case LDAP_OPT_PING_KEEP_ALIVE:
255 case LDAP_OPT_PING_LIMIT:
256 case LDAP_OPT_PING_WAIT_TIME:
257 case LDAP_OPT_PROMPT_CREDENTIALS:
258 case LDAP_OPT_REF_DEREF_CONN_PER_MSG:
259 case LDAP_OPT_REFERRAL_CALLBACK:
260 case LDAP_OPT_REFERRAL_HOP_LIMIT:
261 case LDAP_OPT_ROOTDSE_CACHE:
262 case LDAP_OPT_SASL_METHOD:
263 case LDAP_OPT_SECURITY_CONTEXT:
264 case LDAP_OPT_SEND_TIMEOUT:
265 case LDAP_OPT_SERVER_CERTIFICATE:
266 case LDAP_OPT_SERVER_CONTROLS:
267 case LDAP_OPT_SERVER_ERROR:
268 case LDAP_OPT_SERVER_EXT_ERROR:
269 case LDAP_OPT_SIGN:
270 case LDAP_OPT_SSL:
271 case LDAP_OPT_SSL_INFO:
272 case LDAP_OPT_SSPI_FLAGS:
273 case LDAP_OPT_TCP_KEEPALIVE:
274 FIXME( "Unsupported option: 0x%02x\n", option );
275 return LDAP_NOT_SUPPORTED;
277 default:
278 FIXME( "Unknown option: 0x%02x\n", option );
279 return LDAP_LOCAL_ERROR;
283 /***********************************************************************
284 * ldap_set_optionA (WLDAP32.@)
286 * See ldap_set_optionW.
288 ULONG CDECL ldap_set_optionA( LDAP *ld, int option, void *value )
290 ULONG ret;
292 TRACE( "(%p, 0x%08x, %p)\n", ld, option, value );
294 if (!ld) return LDAP_PARAM_ERROR;
296 switch (option)
298 case LDAP_OPT_SERVER_CONTROLS:
300 LDAPControlW **ctrlsW;
301 if (!(ctrlsW = controlarrayAtoW( value ))) return LDAP_NO_MEMORY;
302 ret = ldap_set_optionW( ld, option, ctrlsW );
303 controlarrayfreeW( ctrlsW );
304 return ret;
306 case LDAP_OPT_DEREF:
307 case LDAP_OPT_DESC:
308 case LDAP_OPT_ERROR_NUMBER:
309 case LDAP_OPT_PROTOCOL_VERSION:
310 case LDAP_OPT_REFERRALS:
311 case LDAP_OPT_SIZELIMIT:
312 case LDAP_OPT_TIMELIMIT:
313 return ldap_set_optionW( ld, option, value );
315 case LDAP_OPT_CACHE_ENABLE:
316 case LDAP_OPT_CACHE_FN_PTRS:
317 case LDAP_OPT_CACHE_STRATEGY:
318 case LDAP_OPT_IO_FN_PTRS:
319 case LDAP_OPT_REBIND_ARG:
320 case LDAP_OPT_REBIND_FN:
321 case LDAP_OPT_RESTART:
322 case LDAP_OPT_THREAD_FN_PTRS:
323 return LDAP_LOCAL_ERROR;
325 case LDAP_OPT_API_FEATURE_INFO:
326 case LDAP_OPT_API_INFO:
327 return LDAP_UNWILLING_TO_PERFORM;
329 case LDAP_OPT_AREC_EXCLUSIVE:
330 case LDAP_OPT_AUTO_RECONNECT:
331 case LDAP_OPT_CLIENT_CERTIFICATE:
332 case LDAP_OPT_DNSDOMAIN_NAME:
333 case LDAP_OPT_ENCRYPT:
334 case LDAP_OPT_ERROR_STRING:
335 case LDAP_OPT_FAST_CONCURRENT_BIND:
336 case LDAP_OPT_GETDSNAME_FLAGS:
337 case LDAP_OPT_HOST_NAME:
338 case LDAP_OPT_HOST_REACHABLE:
339 case LDAP_OPT_PING_KEEP_ALIVE:
340 case LDAP_OPT_PING_LIMIT:
341 case LDAP_OPT_PING_WAIT_TIME:
342 case LDAP_OPT_PROMPT_CREDENTIALS:
343 case LDAP_OPT_REF_DEREF_CONN_PER_MSG:
344 case LDAP_OPT_REFERRAL_CALLBACK:
345 case LDAP_OPT_REFERRAL_HOP_LIMIT:
346 case LDAP_OPT_ROOTDSE_CACHE:
347 case LDAP_OPT_SASL_METHOD:
348 case LDAP_OPT_SECURITY_CONTEXT:
349 case LDAP_OPT_SEND_TIMEOUT:
350 case LDAP_OPT_SERVER_CERTIFICATE:
351 case LDAP_OPT_SERVER_ERROR:
352 case LDAP_OPT_SERVER_EXT_ERROR:
353 case LDAP_OPT_SIGN:
354 case LDAP_OPT_SSL:
355 case LDAP_OPT_SSL_INFO:
356 case LDAP_OPT_SSPI_FLAGS:
357 case LDAP_OPT_TCP_KEEPALIVE:
358 FIXME( "Unsupported option: 0x%02x\n", option );
359 return LDAP_NOT_SUPPORTED;
361 default:
362 FIXME( "Unknown option: 0x%02x\n", option );
363 return LDAP_LOCAL_ERROR;
367 static BOOL query_supported_server_ctrls( LDAP *ld )
369 char *attrs[] = { (char *)"supportedControl", NULL };
370 void *res, *entry;
371 struct bervalU **ctrls = SERVER_CTRLS(ld);
372 ULONG ret;
374 if (ctrls) return TRUE;
376 ret = map_error( ldap_funcs->fn_ldap_search_ext_s( CTX(ld), (char *)"", LDAP_SCOPE_BASE, (char *)"(objectClass=*)",
377 attrs, FALSE, NULL, NULL, NULL, 0, &res ) );
378 if (ret != LDAP_SUCCESS) return FALSE;
380 entry = ldap_funcs->fn_ldap_first_entry( CTX(ld), res );
381 if (entry)
383 ULONG count, i;
384 ctrls = ldap_funcs->fn_ldap_get_values_len( CTX(ld), entry, attrs[0] );
385 count = ldap_funcs->fn_ldap_count_values_len( ctrls );
386 for (i = 0; i < count; i++) TRACE("%u: %s\n", i, debugstr_an( ctrls[i]->bv_val, ctrls[i]->bv_len ));
387 *(struct bervalU ***)&SERVER_CTRLS(ld) = ctrls;
390 ldap_funcs->fn_ldap_msgfree( res );
391 return ctrls != NULL;
394 static BOOL is_supported_server_ctrls( LDAP *ld, LDAPControlU **ctrls )
396 ULONG user_count, server_count, i, n, supported = 0;
398 if (!query_supported_server_ctrls( ld ))
399 return TRUE; /* can't verify, let the server handle it on next query */
401 user_count = controlarraylenU( ctrls );
402 server_count = ldap_funcs->fn_ldap_count_values_len( SERVER_CTRLS(ld) );
404 for (n = 0; n < user_count; n++)
406 TRACE("looking for %s\n", debugstr_a(ctrls[n]->ldctl_oid));
408 for (i = 0; i < server_count; i++)
410 struct bervalU **server_ctrls = SERVER_CTRLS(ld);
411 if (!strncmp( ctrls[n]->ldctl_oid, server_ctrls[i]->bv_val, server_ctrls[i]->bv_len))
413 supported++;
414 break;
419 return supported == user_count;
422 /***********************************************************************
423 * ldap_set_optionW (WLDAP32.@)
425 * Set option values for a given LDAP context.
427 * PARAMS
428 * ld [I] Pointer to an LDAP context.
429 * option [I] Option to set values for.
430 * value [I] Pointer to option values.
432 * RETURNS
433 * Success: LDAP_SUCCESS
434 * Failure: An LDAP error code.
436 * NOTES
437 * Set value to LDAP_OPT_ON or LDAP_OPT_OFF for on/off options.
439 ULONG CDECL ldap_set_optionW( LDAP *ld, int option, void *value )
441 ULONG ret;
443 TRACE( "(%p, 0x%08x, %p)\n", ld, option, value );
445 if (!ld) return LDAP_PARAM_ERROR;
447 switch (option)
449 case LDAP_OPT_SERVER_CONTROLS:
451 LDAPControlU **ctrlsU;
453 if (!(ctrlsU = controlarrayWtoU( value ))) return LDAP_NO_MEMORY;
455 if (!is_supported_server_ctrls( ld, ctrlsU ))
456 ret = LDAP_PARAM_ERROR;
457 else
458 ret = map_error( ldap_funcs->fn_ldap_set_option( CTX(ld), option, ctrlsU ) );
459 controlarrayfreeU( ctrlsU );
460 return ret;
462 case LDAP_OPT_REFERRALS:
464 void *openldap_referral = LDAP_OPT_ON;
465 if (value == LDAP_OPT_OFF)
466 openldap_referral = LDAP_OPT_OFF;
467 else
468 FIXME("upgrading referral value %p to LDAP_OPT_ON (OpenLDAP lacks sufficient granularity)\n", value);
469 return map_error( ldap_funcs->fn_ldap_set_option( CTX(ld), option, openldap_referral ) );
471 case LDAP_OPT_DEREF:
472 case LDAP_OPT_DESC:
473 case LDAP_OPT_ERROR_NUMBER:
474 case LDAP_OPT_PROTOCOL_VERSION:
475 case LDAP_OPT_SIZELIMIT:
476 case LDAP_OPT_TIMELIMIT:
477 return map_error( ldap_funcs->fn_ldap_set_option( CTX(ld), option, value ));
479 case LDAP_OPT_CACHE_ENABLE:
480 case LDAP_OPT_CACHE_FN_PTRS:
481 case LDAP_OPT_CACHE_STRATEGY:
482 case LDAP_OPT_IO_FN_PTRS:
483 case LDAP_OPT_REBIND_ARG:
484 case LDAP_OPT_REBIND_FN:
485 case LDAP_OPT_RESTART:
486 case LDAP_OPT_THREAD_FN_PTRS:
487 return LDAP_LOCAL_ERROR;
489 case LDAP_OPT_API_FEATURE_INFO:
490 case LDAP_OPT_API_INFO:
491 return LDAP_UNWILLING_TO_PERFORM;
493 case LDAP_OPT_AREC_EXCLUSIVE:
494 case LDAP_OPT_AUTO_RECONNECT:
495 case LDAP_OPT_CLIENT_CERTIFICATE:
496 case LDAP_OPT_DNSDOMAIN_NAME:
497 case LDAP_OPT_ENCRYPT:
498 case LDAP_OPT_ERROR_STRING:
499 case LDAP_OPT_FAST_CONCURRENT_BIND:
500 case LDAP_OPT_GETDSNAME_FLAGS:
501 case LDAP_OPT_HOST_NAME:
502 case LDAP_OPT_HOST_REACHABLE:
503 case LDAP_OPT_PING_KEEP_ALIVE:
504 case LDAP_OPT_PING_LIMIT:
505 case LDAP_OPT_PING_WAIT_TIME:
506 case LDAP_OPT_PROMPT_CREDENTIALS:
507 case LDAP_OPT_REF_DEREF_CONN_PER_MSG:
508 case LDAP_OPT_REFERRAL_CALLBACK:
509 case LDAP_OPT_REFERRAL_HOP_LIMIT:
510 case LDAP_OPT_ROOTDSE_CACHE:
511 case LDAP_OPT_SASL_METHOD:
512 case LDAP_OPT_SECURITY_CONTEXT:
513 case LDAP_OPT_SEND_TIMEOUT:
514 case LDAP_OPT_SERVER_CERTIFICATE:
515 case LDAP_OPT_SERVER_ERROR:
516 case LDAP_OPT_SERVER_EXT_ERROR:
517 case LDAP_OPT_SIGN:
518 case LDAP_OPT_SSL:
519 case LDAP_OPT_SSL_INFO:
520 case LDAP_OPT_SSPI_FLAGS:
521 case LDAP_OPT_TCP_KEEPALIVE:
522 FIXME( "Unsupported option: 0x%02x\n", option );
523 return LDAP_NOT_SUPPORTED;
525 default:
526 FIXME( "Unknown option: 0x%02x\n", option );
527 return LDAP_LOCAL_ERROR;