dbghelp: Properly fail on PDB files generated by MSVC compiler version 14.31.
[wine.git] / dlls / wldap32 / option.c
blobefd0d4586b93d549b6d197a3ac7b30a145ae6e7c
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 )))
189 struct ldap_get_option_params params = { CTX(ld), option, &featureU };
190 featureU.ldapaif_version = 0;
191 ret = map_error( LDAP_CALL( ldap_get_option, &params ));
193 else return LDAP_NO_MEMORY;
195 if (ret == LDAP_SUCCESS) featureW->ldapaif_version = featureU.ldapaif_version;
196 free( featureU.ldapaif_name );
197 return ret;
199 case LDAP_OPT_API_INFO:
201 LDAPAPIInfoU infoU;
202 LDAPAPIInfoW *infoW = value;
203 struct ldap_get_option_params params = { CTX(ld), option, &infoU };
205 memset( &infoU, 0, sizeof(infoU) );
206 infoU.ldapai_info_version = infoW->ldapai_info_version;
208 ret = map_error( LDAP_CALL( ldap_get_option, &params ));
209 if (ret == LDAP_SUCCESS)
211 infoW->ldapai_api_version = infoU.ldapai_api_version;
212 infoW->ldapai_protocol_version = infoU.ldapai_protocol_version;
214 if (infoU.ldapai_extensions && !(infoW->ldapai_extensions = strarrayUtoW( infoU.ldapai_extensions )))
215 return LDAP_NO_MEMORY;
216 if (infoU.ldapai_vendor_name && !(infoW->ldapai_vendor_name = strUtoW( infoU.ldapai_vendor_name )))
218 LDAP_CALL( ldap_memvfree, infoU.ldapai_extensions );
219 return LDAP_NO_MEMORY;
221 infoW->ldapai_vendor_version = infoU.ldapai_vendor_version;
223 LDAP_CALL( ldap_memvfree, infoU.ldapai_extensions );
224 LDAP_CALL( ldap_memfree, infoU.ldapai_vendor_name );
226 return ret;
229 case LDAP_OPT_DEREF:
230 case LDAP_OPT_DESC:
231 case LDAP_OPT_ERROR_NUMBER:
232 case LDAP_OPT_PROTOCOL_VERSION:
233 case LDAP_OPT_REFERRALS:
234 case LDAP_OPT_SIZELIMIT:
235 case LDAP_OPT_TIMELIMIT:
237 struct ldap_get_option_params params = { CTX(ld), option, value };
238 return map_error( LDAP_CALL( ldap_get_option, &params ));
241 case LDAP_OPT_CACHE_ENABLE:
242 case LDAP_OPT_CACHE_FN_PTRS:
243 case LDAP_OPT_CACHE_STRATEGY:
244 case LDAP_OPT_IO_FN_PTRS:
245 case LDAP_OPT_REBIND_ARG:
246 case LDAP_OPT_REBIND_FN:
247 case LDAP_OPT_RESTART:
248 case LDAP_OPT_THREAD_FN_PTRS:
249 return LDAP_LOCAL_ERROR;
251 case LDAP_OPT_AREC_EXCLUSIVE:
252 case LDAP_OPT_AUTO_RECONNECT:
253 case LDAP_OPT_CLIENT_CERTIFICATE:
254 case LDAP_OPT_DNSDOMAIN_NAME:
255 case LDAP_OPT_ENCRYPT:
256 case LDAP_OPT_ERROR_STRING:
257 case LDAP_OPT_FAST_CONCURRENT_BIND:
258 case LDAP_OPT_GETDSNAME_FLAGS:
259 case LDAP_OPT_HOST_NAME:
260 case LDAP_OPT_HOST_REACHABLE:
261 case LDAP_OPT_PING_KEEP_ALIVE:
262 case LDAP_OPT_PING_LIMIT:
263 case LDAP_OPT_PING_WAIT_TIME:
264 case LDAP_OPT_PROMPT_CREDENTIALS:
265 case LDAP_OPT_REF_DEREF_CONN_PER_MSG:
266 case LDAP_OPT_REFERRAL_CALLBACK:
267 case LDAP_OPT_REFERRAL_HOP_LIMIT:
268 case LDAP_OPT_ROOTDSE_CACHE:
269 case LDAP_OPT_SASL_METHOD:
270 case LDAP_OPT_SECURITY_CONTEXT:
271 case LDAP_OPT_SEND_TIMEOUT:
272 case LDAP_OPT_SERVER_CERTIFICATE:
273 case LDAP_OPT_SERVER_CONTROLS:
274 case LDAP_OPT_SERVER_ERROR:
275 case LDAP_OPT_SERVER_EXT_ERROR:
276 case LDAP_OPT_SIGN:
277 case LDAP_OPT_SSL:
278 case LDAP_OPT_SSL_INFO:
279 case LDAP_OPT_SSPI_FLAGS:
280 case LDAP_OPT_TCP_KEEPALIVE:
281 FIXME( "Unsupported option: 0x%02x\n", option );
282 return LDAP_NOT_SUPPORTED;
284 default:
285 FIXME( "Unknown option: 0x%02x\n", option );
286 return LDAP_LOCAL_ERROR;
290 /***********************************************************************
291 * ldap_set_optionA (WLDAP32.@)
293 * See ldap_set_optionW.
295 ULONG CDECL ldap_set_optionA( LDAP *ld, int option, void *value )
297 ULONG ret;
299 TRACE( "(%p, 0x%08x, %p)\n", ld, option, value );
301 if (!ld) return LDAP_PARAM_ERROR;
303 switch (option)
305 case LDAP_OPT_SERVER_CONTROLS:
307 LDAPControlW **ctrlsW;
308 if (!(ctrlsW = controlarrayAtoW( value ))) return LDAP_NO_MEMORY;
309 ret = ldap_set_optionW( ld, option, ctrlsW );
310 controlarrayfreeW( ctrlsW );
311 return ret;
313 case LDAP_OPT_DEREF:
314 case LDAP_OPT_DESC:
315 case LDAP_OPT_ERROR_NUMBER:
316 case LDAP_OPT_PROTOCOL_VERSION:
317 case LDAP_OPT_REFERRALS:
318 case LDAP_OPT_SIZELIMIT:
319 case LDAP_OPT_TIMELIMIT:
320 return ldap_set_optionW( ld, option, value );
322 case LDAP_OPT_CACHE_ENABLE:
323 case LDAP_OPT_CACHE_FN_PTRS:
324 case LDAP_OPT_CACHE_STRATEGY:
325 case LDAP_OPT_IO_FN_PTRS:
326 case LDAP_OPT_REBIND_ARG:
327 case LDAP_OPT_REBIND_FN:
328 case LDAP_OPT_RESTART:
329 case LDAP_OPT_THREAD_FN_PTRS:
330 return LDAP_LOCAL_ERROR;
332 case LDAP_OPT_API_FEATURE_INFO:
333 case LDAP_OPT_API_INFO:
334 return LDAP_UNWILLING_TO_PERFORM;
336 case LDAP_OPT_AREC_EXCLUSIVE:
337 case LDAP_OPT_AUTO_RECONNECT:
338 case LDAP_OPT_CLIENT_CERTIFICATE:
339 case LDAP_OPT_DNSDOMAIN_NAME:
340 case LDAP_OPT_ENCRYPT:
341 case LDAP_OPT_ERROR_STRING:
342 case LDAP_OPT_FAST_CONCURRENT_BIND:
343 case LDAP_OPT_GETDSNAME_FLAGS:
344 case LDAP_OPT_HOST_NAME:
345 case LDAP_OPT_HOST_REACHABLE:
346 case LDAP_OPT_PING_KEEP_ALIVE:
347 case LDAP_OPT_PING_LIMIT:
348 case LDAP_OPT_PING_WAIT_TIME:
349 case LDAP_OPT_PROMPT_CREDENTIALS:
350 case LDAP_OPT_REF_DEREF_CONN_PER_MSG:
351 case LDAP_OPT_REFERRAL_CALLBACK:
352 case LDAP_OPT_REFERRAL_HOP_LIMIT:
353 case LDAP_OPT_ROOTDSE_CACHE:
354 case LDAP_OPT_SASL_METHOD:
355 case LDAP_OPT_SECURITY_CONTEXT:
356 case LDAP_OPT_SEND_TIMEOUT:
357 case LDAP_OPT_SERVER_CERTIFICATE:
358 case LDAP_OPT_SERVER_ERROR:
359 case LDAP_OPT_SERVER_EXT_ERROR:
360 case LDAP_OPT_SIGN:
361 case LDAP_OPT_SSL:
362 case LDAP_OPT_SSL_INFO:
363 case LDAP_OPT_SSPI_FLAGS:
364 case LDAP_OPT_TCP_KEEPALIVE:
365 FIXME( "Unsupported option: 0x%02x\n", option );
366 return LDAP_NOT_SUPPORTED;
368 default:
369 FIXME( "Unknown option: 0x%02x\n", option );
370 return LDAP_LOCAL_ERROR;
374 static BOOL query_supported_server_ctrls( LDAP *ld )
376 char *attrs[] = { (char *)"supportedControl", NULL };
377 void *res, *entry;
378 struct bervalU **ctrls = SERVER_CTRLS(ld);
379 ULONG ret;
381 if (!ctrls)
383 struct ldap_search_ext_s_params params = { CTX(ld), (char *)"", LDAP_SCOPE_BASE,
384 (char *)"(objectClass=*)", attrs, FALSE, NULL, NULL, NULL, 0, &res };
385 ret = map_error( LDAP_CALL( ldap_search_ext_s, &params ));
387 else return TRUE;
389 if (ret == LDAP_SUCCESS)
391 struct ldap_first_entry_params params = { CTX(ld), res, &entry };
392 if (!LDAP_CALL( ldap_first_entry, &params ))
394 ULONG count, i;
395 struct ldap_get_values_len_params get_params = { CTX(ld), entry, attrs[0], &ctrls };
396 LDAP_CALL( ldap_get_values_len, &get_params );
397 count = LDAP_CALL( ldap_count_values_len, ctrls );
398 for (i = 0; i < count; i++) TRACE( "%lu: %s\n", i, debugstr_an( ctrls[i]->bv_val, ctrls[i]->bv_len ) );
399 *(struct bervalU ***)&SERVER_CTRLS(ld) = ctrls;
402 else return FALSE;
404 LDAP_CALL( ldap_msgfree, res );
405 return ctrls != NULL;
408 static BOOL is_supported_server_ctrls( LDAP *ld, LDAPControlU **ctrls )
410 ULONG user_count, server_count, i, n, supported = 0;
412 if (!query_supported_server_ctrls( ld ))
413 return TRUE; /* can't verify, let the server handle it on next query */
415 user_count = controlarraylenU( ctrls );
416 server_count = LDAP_CALL( ldap_count_values_len, SERVER_CTRLS(ld) );
418 for (n = 0; n < user_count; n++)
420 TRACE("looking for %s\n", debugstr_a(ctrls[n]->ldctl_oid));
422 for (i = 0; i < server_count; i++)
424 struct bervalU **server_ctrls = SERVER_CTRLS(ld);
425 if (!strncmp( ctrls[n]->ldctl_oid, server_ctrls[i]->bv_val, server_ctrls[i]->bv_len))
427 supported++;
428 break;
433 return supported == user_count;
436 /***********************************************************************
437 * ldap_set_optionW (WLDAP32.@)
439 * Set option values for a given LDAP context.
441 * PARAMS
442 * ld [I] Pointer to an LDAP context.
443 * option [I] Option to set values for.
444 * value [I] Pointer to option values.
446 * RETURNS
447 * Success: LDAP_SUCCESS
448 * Failure: An LDAP error code.
450 * NOTES
451 * Set value to LDAP_OPT_ON or LDAP_OPT_OFF for on/off options.
453 ULONG CDECL ldap_set_optionW( LDAP *ld, int option, void *value )
455 ULONG ret;
457 TRACE( "(%p, 0x%08x, %p)\n", ld, option, value );
459 if (!ld) return LDAP_PARAM_ERROR;
461 switch (option)
463 case LDAP_OPT_SERVER_CONTROLS:
465 LDAPControlU **ctrlsU;
467 if (!(ctrlsU = controlarrayWtoU( value ))) return LDAP_NO_MEMORY;
469 if (!is_supported_server_ctrls( ld, ctrlsU ))
470 ret = LDAP_PARAM_ERROR;
471 else
473 struct ldap_set_option_params params = { CTX(ld), option, ctrlsU };
474 ret = map_error( LDAP_CALL( ldap_set_option, &params ));
476 controlarrayfreeU( ctrlsU );
477 return ret;
479 case LDAP_OPT_REFERRALS:
481 struct ldap_set_option_params params = { CTX(ld), option, LDAP_OPT_ON };
482 if (value == LDAP_OPT_OFF)
483 params.value = LDAP_OPT_OFF;
484 else
485 FIXME("upgrading referral value %p to LDAP_OPT_ON (OpenLDAP lacks sufficient granularity)\n", value);
486 return map_error( LDAP_CALL( ldap_set_option, &params ));
488 case LDAP_OPT_DEREF:
489 case LDAP_OPT_DESC:
490 case LDAP_OPT_ERROR_NUMBER:
491 case LDAP_OPT_PROTOCOL_VERSION:
492 case LDAP_OPT_SIZELIMIT:
493 case LDAP_OPT_TIMELIMIT:
495 struct ldap_set_option_params params = { CTX(ld), option, value };
496 return map_error( LDAP_CALL( ldap_set_option, &params ));
499 case LDAP_OPT_CACHE_ENABLE:
500 case LDAP_OPT_CACHE_FN_PTRS:
501 case LDAP_OPT_CACHE_STRATEGY:
502 case LDAP_OPT_IO_FN_PTRS:
503 case LDAP_OPT_REBIND_ARG:
504 case LDAP_OPT_REBIND_FN:
505 case LDAP_OPT_RESTART:
506 case LDAP_OPT_THREAD_FN_PTRS:
507 return LDAP_LOCAL_ERROR;
509 case LDAP_OPT_API_FEATURE_INFO:
510 case LDAP_OPT_API_INFO:
511 return LDAP_UNWILLING_TO_PERFORM;
513 case LDAP_OPT_AREC_EXCLUSIVE:
514 case LDAP_OPT_AUTO_RECONNECT:
515 case LDAP_OPT_CLIENT_CERTIFICATE:
516 case LDAP_OPT_DNSDOMAIN_NAME:
517 case LDAP_OPT_ENCRYPT:
518 case LDAP_OPT_ERROR_STRING:
519 case LDAP_OPT_FAST_CONCURRENT_BIND:
520 case LDAP_OPT_GETDSNAME_FLAGS:
521 case LDAP_OPT_HOST_NAME:
522 case LDAP_OPT_HOST_REACHABLE:
523 case LDAP_OPT_PING_KEEP_ALIVE:
524 case LDAP_OPT_PING_LIMIT:
525 case LDAP_OPT_PING_WAIT_TIME:
526 case LDAP_OPT_PROMPT_CREDENTIALS:
527 case LDAP_OPT_REF_DEREF_CONN_PER_MSG:
528 case LDAP_OPT_REFERRAL_CALLBACK:
529 case LDAP_OPT_REFERRAL_HOP_LIMIT:
530 case LDAP_OPT_ROOTDSE_CACHE:
531 case LDAP_OPT_SASL_METHOD:
532 case LDAP_OPT_SECURITY_CONTEXT:
533 case LDAP_OPT_SEND_TIMEOUT:
534 case LDAP_OPT_SERVER_CERTIFICATE:
535 case LDAP_OPT_SERVER_ERROR:
536 case LDAP_OPT_SERVER_EXT_ERROR:
537 case LDAP_OPT_SIGN:
538 case LDAP_OPT_SSL:
539 case LDAP_OPT_SSL_INFO:
540 case LDAP_OPT_SSPI_FLAGS:
541 case LDAP_OPT_TCP_KEEPALIVE:
542 FIXME( "Unsupported option: 0x%02x\n", option );
543 return LDAP_NOT_SUPPORTED;
545 default:
546 FIXME( "Unknown option: 0x%02x\n", option );
547 return LDAP_LOCAL_ERROR;