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
29 #include "wine/debug.h"
30 #include "winldap_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(wldap32
);
34 /***********************************************************************
35 * ldap_bindA (WLDAP32.@)
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
);
48 if (dn
&& !(dnW
= strAtoW( dn
))) goto exit
;
49 if (cred
&& !(credW
= strAtoW( cred
))) goto exit
;
51 ret
= ldap_bindW( ld
, dnW
, credW
, method
);
59 /***********************************************************************
60 * ldap_bindW (WLDAP32.@)
62 * Authenticate with an LDAP server (asynchronous operation).
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.
71 * Success: Message ID of the bind operation.
72 * Failure: An LDAP error code.
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
};
84 TRACE( "(%p, %s, %p, 0x%08x)\n", ld
, debugstr_w(dn
), cred
, method
);
87 if (method
!= LDAP_AUTH_SIMPLE
) return LDAP_PARAM_ERROR
;
89 if (dn
&& !(dnU
= strWtoU( dn
))) goto exit
;
92 if (!(credU
= strWtoU( cred
))) goto exit
;
93 pwd
.bv_len
= strlen( credU
);
97 ret
= map_error( ldap_funcs
->fn_ldap_sasl_bind( CTX(ld
), dnU
, 0, &pwd
, NULL
, NULL
, &msg
) );
98 if (ret
== LDAP_SUCCESS
)
109 /***********************************************************************
110 * ldap_bind_sA (WLDAP32.@)
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
;
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
);
137 if (credW
!= (WCHAR
*)cred
) free( credW
);
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
;
173 /***********************************************************************
174 * ldap_bind_sW (WLDAP32.@)
176 * Authenticate with an LDAP server (synchronous operation).
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.
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
;
203 if (!(credU
= strWtoU( cred
))) goto exit
;
204 pwd
.bv_len
= strlen( 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
) );
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
);
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
);
250 FIXME( "method %#x not supported\n", method
);
251 return LDAP_PARAM_ERROR
;
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
);
287 controlarrayfreeW( serverctrlsW
);
288 controlarrayfreeW( clientctrlsW
);
292 /***********************************************************************
293 * ldap_sasl_bindW (WLDAP32.@)
295 * Authenticate with an LDAP server using SASL (asynchronous operation).
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.
307 * Success: LDAP_SUCCESS
308 * Failure: An LDAP error code.
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
,
341 controlarrayfreeU( serverctrlsU
);
342 controlarrayfreeU( clientctrlsU
);
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
);
373 controlarrayfreeW( serverctrlsW
);
374 controlarrayfreeW( clientctrlsW
);
378 /***********************************************************************
379 * ldap_sasl_bind_sW (WLDAP32.@)
381 * Authenticate with an LDAP server using SASL (synchronous operation).
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.
393 * Success: LDAP_SUCCESS
394 * Failure: An LDAP error code.
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
,
423 if (ret
== LDAP_SUCCESS
)
426 if (!(ptr
= bervalUtoW( dataU
))) ret
= LDAP_NO_MEMORY
;
427 else *serverdata
= ptr
;
428 ldap_funcs
->fn_ber_bvfree( dataU
);
434 controlarrayfreeU( serverctrlsU
);
435 controlarrayfreeU( clientctrlsU
);
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
);
453 if (dn
&& !(dnW
= strAtoW( dn
))) goto exit
;
454 if (passwd
&& !(passwdW
= strAtoW( passwd
))) goto exit
;
456 ret
= ldap_simple_bindW( ld
, dnW
, passwdW
);
464 /***********************************************************************
465 * ldap_simple_bindW (WLDAP32.@)
467 * Authenticate with an LDAP server (asynchronous operation).
470 * ld [I] Pointer to an LDAP context.
471 * dn [I] DN of entry to bind as.
472 * passwd [I] Password string.
475 * Success: Message ID of the bind operation.
476 * Failure: An LDAP error code.
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
};
488 TRACE( "(%p, %s, %p)\n", ld
, debugstr_w(dn
), passwd
);
492 if (dn
&& !(dnU
= strWtoU( dn
))) goto exit
;
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
)
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
);
537 /***********************************************************************
538 * ldap_simple_bind_sW (WLDAP32.@)
540 * Authenticate with an LDAP server (synchronous operation).
543 * ld [I] Pointer to an LDAP context.
544 * dn [I] DN of entry to bind as.
545 * passwd [I] Password string.
548 * Success: LDAP_SUCCESS
549 * Failure: An LDAP error code.
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
;
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
) );
580 /***********************************************************************
581 * ldap_unbind (WLDAP32.@)
583 * Close LDAP connection and free resources (asynchronous operation).
586 * ld [I] Pointer to an LDAP context.
589 * Success: LDAP_SUCCESS
590 * Failure: An LDAP error code.
592 ULONG CDECL
ldap_unbind( LDAP
*ld
)
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
) );
607 /***********************************************************************
608 * ldap_unbind_s (WLDAP32.@)
610 * Close LDAP connection and free resources (synchronous operation).
613 * ld [I] Pointer to an LDAP context.
616 * Success: LDAP_SUCCESS
617 * Failure: An LDAP error code.
619 ULONG CDECL
ldap_unbind_s( LDAP
*ld
)
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
) );