msvcrt: Import fmod implementation from musl.
[wine.git] / dlls / wldap32 / bind.c
blobd45ed5d60e04e23cc1598a5f5154e4f0d00745b6
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 <stdlib.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winnls.h"
26 #include "rpc.h"
27 #include "winldap.h"
29 #include "wine/debug.h"
30 #include "winldap_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
34 /***********************************************************************
35 * ldap_bindA (WLDAP32.@)
37 * See ldap_bindW.
39 ULONG CDECL ldap_bindA( LDAP *ld, char *dn, char *cred, ULONG method )
41 ULONG ret = LDAP_NO_MEMORY;
42 WCHAR *dnW = NULL, *credW = NULL;
44 TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_a(dn), cred, method );
46 if (!ld) return ~0u;
48 if (dn && !(dnW = strAtoW( dn ))) goto exit;
49 if (cred && !(credW = strAtoW( cred ))) goto exit;
51 ret = ldap_bindW( ld, dnW, credW, method );
53 exit:
54 free( dnW );
55 free( credW );
56 return ret;
59 /***********************************************************************
60 * ldap_bindW (WLDAP32.@)
62 * Authenticate with an LDAP server (asynchronous operation).
64 * PARAMS
65 * ld [I] Pointer to an LDAP context.
66 * dn [I] DN of entry to bind as.
67 * cred [I] Credentials (e.g. password string).
68 * method [I] Authentication method.
70 * RETURNS
71 * Success: Message ID of the bind operation.
72 * Failure: An LDAP error code.
74 * NOTES
75 * Only LDAP_AUTH_SIMPLE is supported (just like native).
77 ULONG CDECL ldap_bindW( LDAP *ld, WCHAR *dn, WCHAR *cred, ULONG method )
79 ULONG ret = LDAP_NO_MEMORY;
80 char *dnU = NULL, *credU = NULL;
81 struct bervalU pwd = { 0, NULL };
82 int msg;
84 TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_w(dn), cred, method );
86 if (!ld) return ~0u;
87 if (method != LDAP_AUTH_SIMPLE) return LDAP_PARAM_ERROR;
89 if (dn && !(dnU = strWtoU( dn ))) goto exit;
90 if (cred)
92 if (!(credU = strWtoU( cred ))) goto exit;
93 pwd.bv_len = strlen( credU );
94 pwd.bv_val = credU;
97 ret = map_error( ldap_funcs->fn_ldap_sasl_bind( CTX(ld), dnU, 0, &pwd, NULL, NULL, &msg ) );
98 if (ret == LDAP_SUCCESS)
99 ret = msg;
100 else
101 ret = ~0u;
103 exit:
104 free( dnU );
105 free( credU );
106 return ret;
109 /***********************************************************************
110 * ldap_bind_sA (WLDAP32.@)
112 * See ldap_bind_sW.
114 ULONG CDECL ldap_bind_sA( LDAP *ld, char *dn, char *cred, ULONG method )
116 ULONG ret = LDAP_NO_MEMORY;
117 WCHAR *dnW = NULL, *credW = NULL;
119 TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_a(dn), cred, method );
121 if (!ld) return LDAP_PARAM_ERROR;
123 if (dn && !(dnW = strAtoW( dn ))) goto exit;
124 if (cred)
126 if (method == LDAP_AUTH_SIMPLE)
128 if (!(credW = strAtoW( cred ))) goto exit;
130 else credW = (WCHAR *)cred /* SEC_WINNT_AUTH_IDENTITY_A */;
133 ret = ldap_bind_sW( ld, dnW, credW, method );
135 exit:
136 free( dnW );
137 if (credW != (WCHAR *)cred) free( credW );
138 return ret;
141 int CDECL sasl_interact_cb( void *ld, unsigned flags, void *defaults, void *interact )
143 SEC_WINNT_AUTH_IDENTITY_A *id = defaults;
144 struct sasl_interactU *sasl = interact;
146 TRACE( "(%p, 0x%08x, %p, %p)\n", ld, flags, defaults, interact );
148 while (sasl->id != SASL_CB_LIST_END)
150 TRACE( "sasl->id = %04lx\n", sasl->id );
152 if (sasl->id == SASL_CB_GETREALM)
154 sasl->result = id->Domain;
155 sasl->len = id->DomainLength;
157 else if (sasl->id == SASL_CB_USER)
159 sasl->result = id->User;
160 sasl->len = id->UserLength;
162 else if (sasl->id == SASL_CB_PASS)
164 sasl->result = id->Password;
165 sasl->len = id->PasswordLength;
167 sasl++;
170 return LDAP_SUCCESS;
173 /***********************************************************************
174 * ldap_bind_sW (WLDAP32.@)
176 * Authenticate with an LDAP server (synchronous operation).
178 * PARAMS
179 * ld [I] Pointer to an LDAP context.
180 * dn [I] DN of entry to bind as.
181 * cred [I] Credentials (e.g. password string).
182 * method [I] Authentication method.
184 * RETURNS
185 * Success: LDAP_SUCCESS
186 * Failure: An LDAP error code.
188 ULONG CDECL ldap_bind_sW( LDAP *ld, WCHAR *dn, WCHAR *cred, ULONG method )
190 ULONG ret = LDAP_NO_MEMORY;
191 char *dnU = NULL, *credU = NULL;
192 struct bervalU pwd = { 0, NULL };
194 TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_w(dn), cred, method );
196 if (!ld) return LDAP_PARAM_ERROR;
198 if (method == LDAP_AUTH_SIMPLE)
200 if (dn && !(dnU = strWtoU( dn ))) goto exit;
201 if (cred)
203 if (!(credU = strWtoU( cred ))) goto exit;
204 pwd.bv_len = strlen( credU );
205 pwd.bv_val = credU;
208 ret = map_error( ldap_funcs->fn_ldap_sasl_bind_s( CTX(ld), dnU, 0, &pwd, NULL, NULL, NULL ) );
210 else if (method == LDAP_AUTH_NEGOTIATE)
212 SEC_WINNT_AUTH_IDENTITY_A idU;
213 SEC_WINNT_AUTH_IDENTITY_W idW;
214 SEC_WINNT_AUTH_IDENTITY_W *id = (SEC_WINNT_AUTH_IDENTITY_W *)cred;
216 memset( &idU, 0, sizeof(idU) );
217 if (id)
219 if (id->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI)
221 idW.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
222 idW.Domain = (unsigned short *)strnAtoW( (char *)id->Domain, id->DomainLength, &idW.DomainLength );
223 idW.User = (unsigned short *)strnAtoW( (char *)id->User, id->UserLength, &idW.UserLength );
224 idW.Password = (unsigned short *)strnAtoW( (char *)id->Password, id->PasswordLength, &idW.PasswordLength );
225 id = &idW;
227 idU.Domain = (unsigned char *)strnWtoU( id->Domain, id->DomainLength, &idU.DomainLength );
228 idU.User = (unsigned char *)strnWtoU( id->User, id->UserLength, &idU.UserLength );
229 idU.Password = (unsigned char *)strnWtoU( id->Password, id->PasswordLength, &idU.PasswordLength );
232 ret = map_error( ldap_funcs->fn_ldap_sasl_interactive_bind_s( CTX(ld),
233 NULL /* server will ignore DN anyway */,
234 NULL /* query supportedSASLMechanisms */,
235 NULL, NULL, 2 /* LDAP_SASL_QUIET */, &idU ) );
237 if (id && (id->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI))
239 free( (WCHAR *)idW.Domain );
240 free( (WCHAR *)idW.User );
241 free( (WCHAR *)idW.Password );
244 free( (char *)idU.Domain );
245 free( (char *)idU.User );
246 free( (char *)idU.Password );
248 else
250 FIXME( "method %#x not supported\n", method );
251 return LDAP_PARAM_ERROR;
254 exit:
255 free( dnU );
256 free( credU );
257 return ret;
260 /***********************************************************************
261 * ldap_sasl_bindA (WLDAP32.@)
263 * See ldap_sasl_bindW.
265 ULONG CDECL ldap_sasl_bindA( LDAP *ld, const PCHAR dn, const PCHAR mechanism, const BERVAL *cred,
266 LDAPControlA **serverctrls, LDAPControlA **clientctrls, int *message )
268 ULONG ret = LDAP_NO_MEMORY;
269 WCHAR *dnW, *mechanismW = NULL;
270 LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
272 TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
273 debugstr_a(mechanism), cred, serverctrls, clientctrls, message );
275 if (!ld || !dn || !mechanism || !cred || !message) return LDAP_PARAM_ERROR;
277 if (!(dnW = strAtoW( dn ))) goto exit;
278 if (!(mechanismW = strAtoW( mechanism ))) goto exit;
279 if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
280 if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
282 ret = ldap_sasl_bindW( ld, dnW, mechanismW, cred, serverctrlsW, clientctrlsW, message );
284 exit:
285 free( dnW );
286 free( mechanismW );
287 controlarrayfreeW( serverctrlsW );
288 controlarrayfreeW( clientctrlsW );
289 return ret;
292 /***********************************************************************
293 * ldap_sasl_bindW (WLDAP32.@)
295 * Authenticate with an LDAP server using SASL (asynchronous operation).
297 * PARAMS
298 * ld [I] Pointer to an LDAP context.
299 * dn [I] DN of entry to bind as.
300 * mechanism [I] Authentication method.
301 * cred [I] Credentials.
302 * serverctrls [I] Array of LDAP server controls.
303 * clientctrls [I] Array of LDAP client controls.
304 * message [O] Message ID of the bind operation.
306 * RETURNS
307 * Success: LDAP_SUCCESS
308 * Failure: An LDAP error code.
310 * NOTES
311 * The serverctrls and clientctrls parameters are optional and should
312 * be set to NULL if not used.
314 ULONG CDECL ldap_sasl_bindW( LDAP *ld, const PWCHAR dn, const PWCHAR mechanism, const BERVAL *cred,
315 LDAPControlW **serverctrls, LDAPControlW **clientctrls, int *message )
317 ULONG ret = LDAP_NO_MEMORY;
318 char *dnU, *mechanismU = NULL;
319 LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
320 struct bervalU credU;
322 TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
323 debugstr_w(mechanism), cred, serverctrls, clientctrls, message );
325 if (!ld || !dn || !mechanism || !cred || !message) return LDAP_PARAM_ERROR;
327 if (!(dnU = strWtoU( dn ))) goto exit;
328 if (!(mechanismU = strWtoU( mechanism ))) goto exit;
329 if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
330 if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
332 credU.bv_len = cred->bv_len;
333 credU.bv_val = cred->bv_val;
335 ret = map_error( ldap_funcs->fn_ldap_sasl_bind( CTX(ld), dnU, mechanismU, &credU, serverctrlsU, clientctrlsU,
336 message ) );
338 exit:
339 free( dnU );
340 free( mechanismU );
341 controlarrayfreeU( serverctrlsU );
342 controlarrayfreeU( clientctrlsU );
343 return ret;
346 /***********************************************************************
347 * ldap_sasl_bind_sA (WLDAP32.@)
349 * See ldap_sasl_bind_sW.
351 ULONG CDECL ldap_sasl_bind_sA( LDAP *ld, const PCHAR dn, const PCHAR mechanism, const BERVAL *cred,
352 LDAPControlA **serverctrls, LDAPControlA **clientctrls, BERVAL **serverdata )
354 ULONG ret = LDAP_NO_MEMORY;
355 WCHAR *dnW, *mechanismW = NULL;
356 LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
358 TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
359 debugstr_a(mechanism), cred, serverctrls, clientctrls, serverdata );
361 if (!ld || !dn || !mechanism || !cred || !serverdata) return LDAP_PARAM_ERROR;
363 if (!(dnW = strAtoW( dn ))) goto exit;
364 if (!(mechanismW = strAtoW( mechanism ))) goto exit;
365 if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
366 if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
368 ret = ldap_sasl_bind_sW( ld, dnW, mechanismW, cred, serverctrlsW, clientctrlsW, serverdata );
370 exit:
371 free( dnW );
372 free( mechanismW );
373 controlarrayfreeW( serverctrlsW );
374 controlarrayfreeW( clientctrlsW );
375 return ret;
378 /***********************************************************************
379 * ldap_sasl_bind_sW (WLDAP32.@)
381 * Authenticate with an LDAP server using SASL (synchronous operation).
383 * PARAMS
384 * ld [I] Pointer to an LDAP context.
385 * dn [I] DN of entry to bind as.
386 * mechanism [I] Authentication method.
387 * cred [I] Credentials.
388 * serverctrls [I] Array of LDAP server controls.
389 * clientctrls [I] Array of LDAP client controls.
390 * serverdata [O] Authentication response from the server.
392 * RETURNS
393 * Success: LDAP_SUCCESS
394 * Failure: An LDAP error code.
396 * NOTES
397 * The serverctrls and clientctrls parameters are optional and should
398 * be set to NULL if not used.
400 ULONG CDECL ldap_sasl_bind_sW( LDAP *ld, const PWCHAR dn, const PWCHAR mechanism, const BERVAL *cred,
401 LDAPControlW **serverctrls, LDAPControlW **clientctrls, BERVAL **serverdata )
403 ULONG ret = LDAP_NO_MEMORY;
404 char *dnU, *mechanismU = NULL;
405 LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
406 struct bervalU *dataU, credU;
408 TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
409 debugstr_w(mechanism), cred, serverctrls, clientctrls, serverdata );
411 if (!ld || !dn || !mechanism || !cred || !serverdata) return LDAP_PARAM_ERROR;
413 if (!(dnU = strWtoU( dn ))) goto exit;
414 if (!(mechanismU = strWtoU( mechanism ))) goto exit;
415 if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
416 if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
418 credU.bv_len = cred->bv_len;
419 credU.bv_val = cred->bv_val;
421 ret = map_error( ldap_funcs->fn_ldap_sasl_bind_s( CTX(ld), dnU, mechanismU, &credU, serverctrlsU, clientctrlsU,
422 &dataU ) );
423 if (ret == LDAP_SUCCESS)
425 BERVAL *ptr;
426 if (!(ptr = bervalUtoW( dataU ))) ret = LDAP_NO_MEMORY;
427 else *serverdata = ptr;
428 ldap_funcs->fn_ber_bvfree( dataU );
431 exit:
432 free( dnU );
433 free( mechanismU );
434 controlarrayfreeU( serverctrlsU );
435 controlarrayfreeU( clientctrlsU );
436 return ret;
439 /***********************************************************************
440 * ldap_simple_bindA (WLDAP32.@)
442 * See ldap_simple_bindW.
444 ULONG CDECL ldap_simple_bindA( LDAP *ld, char *dn, char *passwd )
446 ULONG ret = LDAP_NO_MEMORY;
447 WCHAR *dnW = NULL, *passwdW = NULL;
449 TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), passwd );
451 if (!ld) return ~0u;
453 if (dn && !(dnW = strAtoW( dn ))) goto exit;
454 if (passwd && !(passwdW = strAtoW( passwd ))) goto exit;
456 ret = ldap_simple_bindW( ld, dnW, passwdW );
458 exit:
459 free( dnW );
460 free( passwdW );
461 return ret;
464 /***********************************************************************
465 * ldap_simple_bindW (WLDAP32.@)
467 * Authenticate with an LDAP server (asynchronous operation).
469 * PARAMS
470 * ld [I] Pointer to an LDAP context.
471 * dn [I] DN of entry to bind as.
472 * passwd [I] Password string.
474 * RETURNS
475 * Success: Message ID of the bind operation.
476 * Failure: An LDAP error code.
478 * NOTES
479 * Set dn and passwd to NULL to bind as an anonymous user.
481 ULONG CDECL ldap_simple_bindW( LDAP *ld, WCHAR *dn, WCHAR *passwd )
483 ULONG ret = LDAP_NO_MEMORY;
484 char *dnU = NULL, *passwdU = NULL;
485 struct bervalU pwd = { 0, NULL };
486 int msg;
488 TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), passwd );
490 if (!ld) return ~0u;
492 if (dn && !(dnU = strWtoU( dn ))) goto exit;
493 if (passwd)
495 if (!(passwdU = strWtoU( passwd ))) goto exit;
496 pwd.bv_len = strlen( passwdU );
497 pwd.bv_val = passwdU;
500 ret = map_error( ldap_funcs->fn_ldap_sasl_bind( CTX(ld), dnU, 0, &pwd, NULL, NULL, &msg ) );
501 if (ret == LDAP_SUCCESS)
502 ret = msg;
503 else
504 ret = ~0u;
506 exit:
507 free( dnU );
508 free( passwdU );
509 return ret;
512 /***********************************************************************
513 * ldap_simple_bind_sA (WLDAP32.@)
515 * See ldap_simple_bind_sW.
517 ULONG CDECL ldap_simple_bind_sA( LDAP *ld, char *dn, char *passwd )
519 ULONG ret = LDAP_NO_MEMORY;
520 WCHAR *dnW = NULL, *passwdW = NULL;
522 TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), passwd );
524 if (!ld) return LDAP_PARAM_ERROR;
526 if (dn && !(dnW = strAtoW( dn ))) goto exit;
527 if (passwd && !(passwdW = strAtoW( passwd ))) goto exit;
529 ret = ldap_simple_bind_sW( ld, dnW, passwdW );
531 exit:
532 free( dnW );
533 free( passwdW );
534 return ret;
537 /***********************************************************************
538 * ldap_simple_bind_sW (WLDAP32.@)
540 * Authenticate with an LDAP server (synchronous operation).
542 * PARAMS
543 * ld [I] Pointer to an LDAP context.
544 * dn [I] DN of entry to bind as.
545 * passwd [I] Password string.
547 * RETURNS
548 * Success: LDAP_SUCCESS
549 * Failure: An LDAP error code.
551 * NOTES
552 * Set dn and passwd to NULL to bind as an anonymous user.
554 ULONG CDECL ldap_simple_bind_sW( LDAP *ld, WCHAR *dn, WCHAR *passwd )
556 ULONG ret = LDAP_NO_MEMORY;
557 char *dnU = NULL, *passwdU = NULL;
558 struct bervalU pwd = { 0, NULL };
560 TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), passwd );
562 if (!ld) return LDAP_PARAM_ERROR;
564 if (dn && !(dnU = strWtoU( dn ))) goto exit;
565 if (passwd)
567 if (!(passwdU = strWtoU( passwd ))) goto exit;
568 pwd.bv_len = strlen( passwdU );
569 pwd.bv_val = passwdU;
572 ret = map_error( ldap_funcs->fn_ldap_sasl_bind_s( CTX(ld), dnU, 0, &pwd, NULL, NULL, NULL ) );
574 exit:
575 free( dnU );
576 free( passwdU );
577 return ret;
580 /***********************************************************************
581 * ldap_unbind (WLDAP32.@)
583 * Close LDAP connection and free resources (asynchronous operation).
585 * PARAMS
586 * ld [I] Pointer to an LDAP context.
588 * RETURNS
589 * Success: LDAP_SUCCESS
590 * Failure: An LDAP error code.
592 ULONG CDECL ldap_unbind( LDAP *ld )
594 ULONG ret;
596 TRACE( "(%p)\n", ld );
598 if (!ld) return LDAP_PARAM_ERROR;
600 ret = map_error( ldap_funcs->fn_ldap_unbind_ext( CTX(ld), NULL, NULL ));
601 if (SERVER_CTRLS(ld)) ldap_funcs->fn_ldap_value_free_len( SERVER_CTRLS(ld) );
603 free( ld );
604 return ret;
607 /***********************************************************************
608 * ldap_unbind_s (WLDAP32.@)
610 * Close LDAP connection and free resources (synchronous operation).
612 * PARAMS
613 * ld [I] Pointer to an LDAP context.
615 * RETURNS
616 * Success: LDAP_SUCCESS
617 * Failure: An LDAP error code.
619 ULONG CDECL ldap_unbind_s( LDAP *ld )
621 ULONG ret;
623 TRACE( "(%p)\n", ld );
625 if (!ld) return LDAP_PARAM_ERROR;
627 ret = map_error( ldap_funcs->fn_ldap_unbind_ext_s( CTX(ld), NULL, NULL ) );
628 if (SERVER_CTRLS(ld)) ldap_funcs->fn_ldap_value_free_len( SERVER_CTRLS(ld) );
630 free( ld );
631 return ret;