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
);
98 struct ldap_sasl_bind_params params
= { CTX(ld
), dnU
, 0, &pwd
, NULL
, NULL
, &msg
};
99 ret
= map_error( LDAP_CALL( ldap_sasl_bind
, ¶ms
));
101 if (ret
== LDAP_SUCCESS
)
112 /***********************************************************************
113 * ldap_bind_sA (WLDAP32.@)
117 ULONG CDECL
ldap_bind_sA( LDAP
*ld
, char *dn
, char *cred
, ULONG method
)
119 ULONG ret
= LDAP_NO_MEMORY
;
120 WCHAR
*dnW
= NULL
, *credW
= NULL
;
122 TRACE( "(%p, %s, %p, 0x%08x)\n", ld
, debugstr_a(dn
), cred
, method
);
124 if (!ld
) return LDAP_PARAM_ERROR
;
126 if (dn
&& !(dnW
= strAtoW( dn
))) goto exit
;
129 if (method
== LDAP_AUTH_SIMPLE
)
131 if (!(credW
= strAtoW( cred
))) goto exit
;
133 else credW
= (WCHAR
*)cred
/* SEC_WINNT_AUTH_IDENTITY_A */;
136 ret
= ldap_bind_sW( ld
, dnW
, credW
, method
);
140 if (credW
!= (WCHAR
*)cred
) free( credW
);
144 /***********************************************************************
145 * ldap_bind_sW (WLDAP32.@)
147 * Authenticate with an LDAP server (synchronous operation).
150 * ld [I] Pointer to an LDAP context.
151 * dn [I] DN of entry to bind as.
152 * cred [I] Credentials (e.g. password string).
153 * method [I] Authentication method.
156 * Success: LDAP_SUCCESS
157 * Failure: An LDAP error code.
159 ULONG CDECL
ldap_bind_sW( LDAP
*ld
, WCHAR
*dn
, WCHAR
*cred
, ULONG method
)
161 ULONG ret
= LDAP_NO_MEMORY
;
162 char *dnU
= NULL
, *credU
= NULL
;
163 struct bervalU pwd
= { 0, NULL
};
165 TRACE( "(%p, %s, %p, 0x%08x)\n", ld
, debugstr_w(dn
), cred
, method
);
167 if (!ld
) return LDAP_PARAM_ERROR
;
169 if (method
== LDAP_AUTH_SIMPLE
)
171 if (dn
&& !(dnU
= strWtoU( dn
))) goto exit
;
174 if (!(credU
= strWtoU( cred
))) goto exit
;
175 pwd
.bv_len
= strlen( credU
);
180 struct ldap_sasl_bind_s_params params
= { CTX(ld
), dnU
, 0, &pwd
, NULL
, NULL
, NULL
};
181 ret
= map_error( LDAP_CALL( ldap_sasl_bind_s
, ¶ms
));
184 else if (method
== LDAP_AUTH_NEGOTIATE
)
186 SEC_WINNT_AUTH_IDENTITY_A idU
;
187 SEC_WINNT_AUTH_IDENTITY_W idW
;
188 SEC_WINNT_AUTH_IDENTITY_W
*id
= (SEC_WINNT_AUTH_IDENTITY_W
*)cred
;
190 memset( &idU
, 0, sizeof(idU
) );
193 if (id
->Flags
& SEC_WINNT_AUTH_IDENTITY_ANSI
)
195 idW
.Flags
= SEC_WINNT_AUTH_IDENTITY_UNICODE
;
196 idW
.Domain
= (unsigned short *)strnAtoW( (char *)id
->Domain
, id
->DomainLength
, &idW
.DomainLength
);
197 idW
.User
= (unsigned short *)strnAtoW( (char *)id
->User
, id
->UserLength
, &idW
.UserLength
);
198 idW
.Password
= (unsigned short *)strnAtoW( (char *)id
->Password
, id
->PasswordLength
, &idW
.PasswordLength
);
201 idU
.Domain
= (unsigned char *)strnWtoU( id
->Domain
, id
->DomainLength
, &idU
.DomainLength
);
202 idU
.User
= (unsigned char *)strnWtoU( id
->User
, id
->UserLength
, &idU
.UserLength
);
203 idU
.Password
= (unsigned char *)strnWtoU( id
->Password
, id
->PasswordLength
, &idU
.PasswordLength
);
207 struct ldap_sasl_interactive_bind_s_params params
= { CTX(ld
),
208 NULL
/* server will ignore DN anyway */,
209 NULL
/* query supportedSASLMechanisms */,
210 NULL
, NULL
, 2 /* LDAP_SASL_QUIET */, &idU
};
211 ret
= map_error( LDAP_CALL( ldap_sasl_interactive_bind_s
, ¶ms
));
214 if (id
&& (id
->Flags
& SEC_WINNT_AUTH_IDENTITY_ANSI
))
216 free( (WCHAR
*)idW
.Domain
);
217 free( (WCHAR
*)idW
.User
);
218 free( (WCHAR
*)idW
.Password
);
221 free( (char *)idU
.Domain
);
222 free( (char *)idU
.User
);
223 free( (char *)idU
.Password
);
227 FIXME( "method %#x not supported\n", method
);
228 return LDAP_PARAM_ERROR
;
237 /***********************************************************************
238 * ldap_sasl_bindA (WLDAP32.@)
240 * See ldap_sasl_bindW.
242 ULONG CDECL
ldap_sasl_bindA( LDAP
*ld
, const PCHAR dn
, const PCHAR mechanism
, const BERVAL
*cred
,
243 LDAPControlA
**serverctrls
, LDAPControlA
**clientctrls
, int *message
)
245 ULONG ret
= LDAP_NO_MEMORY
;
246 WCHAR
*dnW
, *mechanismW
= NULL
;
247 LDAPControlW
**serverctrlsW
= NULL
, **clientctrlsW
= NULL
;
249 TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld
, debugstr_a(dn
),
250 debugstr_a(mechanism
), cred
, serverctrls
, clientctrls
, message
);
252 if (!ld
|| !dn
|| !mechanism
|| !cred
|| !message
) return LDAP_PARAM_ERROR
;
254 if (!(dnW
= strAtoW( dn
))) goto exit
;
255 if (!(mechanismW
= strAtoW( mechanism
))) goto exit
;
256 if (serverctrls
&& !(serverctrlsW
= controlarrayAtoW( serverctrls
))) goto exit
;
257 if (clientctrls
&& !(clientctrlsW
= controlarrayAtoW( clientctrls
))) goto exit
;
259 ret
= ldap_sasl_bindW( ld
, dnW
, mechanismW
, cred
, serverctrlsW
, clientctrlsW
, message
);
264 controlarrayfreeW( serverctrlsW
);
265 controlarrayfreeW( clientctrlsW
);
269 /***********************************************************************
270 * ldap_sasl_bindW (WLDAP32.@)
272 * Authenticate with an LDAP server using SASL (asynchronous operation).
275 * ld [I] Pointer to an LDAP context.
276 * dn [I] DN of entry to bind as.
277 * mechanism [I] Authentication method.
278 * cred [I] Credentials.
279 * serverctrls [I] Array of LDAP server controls.
280 * clientctrls [I] Array of LDAP client controls.
281 * message [O] Message ID of the bind operation.
284 * Success: LDAP_SUCCESS
285 * Failure: An LDAP error code.
288 * The serverctrls and clientctrls parameters are optional and should
289 * be set to NULL if not used.
291 ULONG CDECL
ldap_sasl_bindW( LDAP
*ld
, const PWCHAR dn
, const PWCHAR mechanism
, const BERVAL
*cred
,
292 LDAPControlW
**serverctrls
, LDAPControlW
**clientctrls
, int *message
)
294 ULONG ret
= LDAP_NO_MEMORY
;
295 char *dnU
, *mechanismU
= NULL
;
296 LDAPControlU
**serverctrlsU
= NULL
, **clientctrlsU
= NULL
;
297 struct bervalU credU
;
299 TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld
, debugstr_w(dn
),
300 debugstr_w(mechanism
), cred
, serverctrls
, clientctrls
, message
);
302 if (!ld
|| !dn
|| !mechanism
|| !cred
|| !message
) return LDAP_PARAM_ERROR
;
304 if (!(dnU
= strWtoU( dn
))) goto exit
;
305 if (!(mechanismU
= strWtoU( mechanism
))) goto exit
;
306 if (serverctrls
&& !(serverctrlsU
= controlarrayWtoU( serverctrls
))) goto exit
;
307 if (clientctrls
&& !(clientctrlsU
= controlarrayWtoU( clientctrls
))) goto exit
;
310 struct ldap_sasl_bind_params params
= { CTX(ld
), dnU
, mechanismU
, &credU
, serverctrlsU
, clientctrlsU
, message
};
311 credU
.bv_len
= cred
->bv_len
;
312 credU
.bv_val
= cred
->bv_val
;
313 ret
= map_error( LDAP_CALL( ldap_sasl_bind
, ¶ms
));
319 controlarrayfreeU( serverctrlsU
);
320 controlarrayfreeU( clientctrlsU
);
324 /***********************************************************************
325 * ldap_sasl_bind_sA (WLDAP32.@)
327 * See ldap_sasl_bind_sW.
329 ULONG CDECL
ldap_sasl_bind_sA( LDAP
*ld
, const PCHAR dn
, const PCHAR mechanism
, const BERVAL
*cred
,
330 LDAPControlA
**serverctrls
, LDAPControlA
**clientctrls
, BERVAL
**serverdata
)
332 ULONG ret
= LDAP_NO_MEMORY
;
333 WCHAR
*dnW
, *mechanismW
= NULL
;
334 LDAPControlW
**serverctrlsW
= NULL
, **clientctrlsW
= NULL
;
336 TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld
, debugstr_a(dn
),
337 debugstr_a(mechanism
), cred
, serverctrls
, clientctrls
, serverdata
);
339 if (!ld
|| !dn
|| !mechanism
|| !cred
|| !serverdata
) return LDAP_PARAM_ERROR
;
341 if (!(dnW
= strAtoW( dn
))) goto exit
;
342 if (!(mechanismW
= strAtoW( mechanism
))) goto exit
;
343 if (serverctrls
&& !(serverctrlsW
= controlarrayAtoW( serverctrls
))) goto exit
;
344 if (clientctrls
&& !(clientctrlsW
= controlarrayAtoW( clientctrls
))) goto exit
;
346 ret
= ldap_sasl_bind_sW( ld
, dnW
, mechanismW
, cred
, serverctrlsW
, clientctrlsW
, serverdata
);
351 controlarrayfreeW( serverctrlsW
);
352 controlarrayfreeW( clientctrlsW
);
356 /***********************************************************************
357 * ldap_sasl_bind_sW (WLDAP32.@)
359 * Authenticate with an LDAP server using SASL (synchronous operation).
362 * ld [I] Pointer to an LDAP context.
363 * dn [I] DN of entry to bind as.
364 * mechanism [I] Authentication method.
365 * cred [I] Credentials.
366 * serverctrls [I] Array of LDAP server controls.
367 * clientctrls [I] Array of LDAP client controls.
368 * serverdata [O] Authentication response from the server.
371 * Success: LDAP_SUCCESS
372 * Failure: An LDAP error code.
375 * The serverctrls and clientctrls parameters are optional and should
376 * be set to NULL if not used.
378 ULONG CDECL
ldap_sasl_bind_sW( LDAP
*ld
, const PWCHAR dn
, const PWCHAR mechanism
, const BERVAL
*cred
,
379 LDAPControlW
**serverctrls
, LDAPControlW
**clientctrls
, BERVAL
**serverdata
)
381 ULONG ret
= LDAP_NO_MEMORY
;
382 char *dnU
, *mechanismU
= NULL
;
383 LDAPControlU
**serverctrlsU
= NULL
, **clientctrlsU
= NULL
;
384 struct bervalU
*dataU
, credU
;
386 TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld
, debugstr_w(dn
),
387 debugstr_w(mechanism
), cred
, serverctrls
, clientctrls
, serverdata
);
389 if (!ld
|| !dn
|| !mechanism
|| !cred
|| !serverdata
) return LDAP_PARAM_ERROR
;
391 if (!(dnU
= strWtoU( dn
))) goto exit
;
392 if (!(mechanismU
= strWtoU( mechanism
))) goto exit
;
393 if (serverctrls
&& !(serverctrlsU
= controlarrayWtoU( serverctrls
))) goto exit
;
394 if (clientctrls
&& !(clientctrlsU
= controlarrayWtoU( clientctrls
))) goto exit
;
396 credU
.bv_len
= cred
->bv_len
;
397 credU
.bv_val
= cred
->bv_val
;
400 struct ldap_sasl_bind_s_params params
= { CTX(ld
), dnU
, mechanismU
, &credU
, serverctrlsU
, clientctrlsU
, &dataU
};
401 ret
= map_error( LDAP_CALL( ldap_sasl_bind_s
, ¶ms
));
403 if (ret
== LDAP_SUCCESS
)
406 if (!(ptr
= bervalUtoW( dataU
))) ret
= LDAP_NO_MEMORY
;
407 else *serverdata
= ptr
;
408 LDAP_CALL( ber_bvfree
, dataU
);
414 controlarrayfreeU( serverctrlsU
);
415 controlarrayfreeU( clientctrlsU
);
419 /***********************************************************************
420 * ldap_simple_bindA (WLDAP32.@)
422 * See ldap_simple_bindW.
424 ULONG CDECL
ldap_simple_bindA( LDAP
*ld
, char *dn
, char *passwd
)
426 ULONG ret
= LDAP_NO_MEMORY
;
427 WCHAR
*dnW
= NULL
, *passwdW
= NULL
;
429 TRACE( "(%p, %s, %p)\n", ld
, debugstr_a(dn
), passwd
);
433 if (dn
&& !(dnW
= strAtoW( dn
))) goto exit
;
434 if (passwd
&& !(passwdW
= strAtoW( passwd
))) goto exit
;
436 ret
= ldap_simple_bindW( ld
, dnW
, passwdW
);
444 /***********************************************************************
445 * ldap_simple_bindW (WLDAP32.@)
447 * Authenticate with an LDAP server (asynchronous operation).
450 * ld [I] Pointer to an LDAP context.
451 * dn [I] DN of entry to bind as.
452 * passwd [I] Password string.
455 * Success: Message ID of the bind operation.
456 * Failure: An LDAP error code.
459 * Set dn and passwd to NULL to bind as an anonymous user.
461 ULONG CDECL
ldap_simple_bindW( LDAP
*ld
, WCHAR
*dn
, WCHAR
*passwd
)
463 ULONG ret
= LDAP_NO_MEMORY
;
464 char *dnU
= NULL
, *passwdU
= NULL
;
465 struct bervalU pwd
= { 0, NULL
};
468 TRACE( "(%p, %s, %p)\n", ld
, debugstr_w(dn
), passwd
);
472 if (dn
&& !(dnU
= strWtoU( dn
))) goto exit
;
475 if (!(passwdU
= strWtoU( passwd
))) goto exit
;
476 pwd
.bv_len
= strlen( passwdU
);
477 pwd
.bv_val
= passwdU
;
481 struct ldap_sasl_bind_params params
= { CTX(ld
), dnU
, 0, &pwd
, NULL
, NULL
, &msg
};
482 ret
= map_error( LDAP_CALL( ldap_sasl_bind
, ¶ms
));
484 if (ret
== LDAP_SUCCESS
)
495 /***********************************************************************
496 * ldap_simple_bind_sA (WLDAP32.@)
498 * See ldap_simple_bind_sW.
500 ULONG CDECL
ldap_simple_bind_sA( LDAP
*ld
, char *dn
, char *passwd
)
502 ULONG ret
= LDAP_NO_MEMORY
;
503 WCHAR
*dnW
= NULL
, *passwdW
= NULL
;
505 TRACE( "(%p, %s, %p)\n", ld
, debugstr_a(dn
), passwd
);
507 if (!ld
) return LDAP_PARAM_ERROR
;
509 if (dn
&& !(dnW
= strAtoW( dn
))) goto exit
;
510 if (passwd
&& !(passwdW
= strAtoW( passwd
))) goto exit
;
512 ret
= ldap_simple_bind_sW( ld
, dnW
, passwdW
);
520 /***********************************************************************
521 * ldap_simple_bind_sW (WLDAP32.@)
523 * Authenticate with an LDAP server (synchronous operation).
526 * ld [I] Pointer to an LDAP context.
527 * dn [I] DN of entry to bind as.
528 * passwd [I] Password string.
531 * Success: LDAP_SUCCESS
532 * Failure: An LDAP error code.
535 * Set dn and passwd to NULL to bind as an anonymous user.
537 ULONG CDECL
ldap_simple_bind_sW( LDAP
*ld
, WCHAR
*dn
, WCHAR
*passwd
)
539 ULONG ret
= LDAP_NO_MEMORY
;
540 char *dnU
= NULL
, *passwdU
= NULL
;
541 struct bervalU pwd
= { 0, NULL
};
543 TRACE( "(%p, %s, %p)\n", ld
, debugstr_w(dn
), passwd
);
545 if (!ld
) return LDAP_PARAM_ERROR
;
547 if (dn
&& !(dnU
= strWtoU( dn
))) goto exit
;
550 if (!(passwdU
= strWtoU( passwd
))) goto exit
;
551 pwd
.bv_len
= strlen( passwdU
);
552 pwd
.bv_val
= passwdU
;
556 struct ldap_sasl_bind_s_params params
= { CTX(ld
), dnU
, 0, &pwd
, NULL
, NULL
, NULL
};
557 ret
= map_error( LDAP_CALL( ldap_sasl_bind_s
, ¶ms
));
566 /***********************************************************************
567 * ldap_unbind (WLDAP32.@)
569 * Close LDAP connection and free resources (asynchronous operation).
572 * ld [I] Pointer to an LDAP context.
575 * Success: LDAP_SUCCESS
576 * Failure: An LDAP error code.
578 ULONG CDECL
ldap_unbind( LDAP
*ld
)
582 TRACE( "(%p)\n", ld
);
586 struct ldap_unbind_ext_params params
= { CTX(ld
), NULL
, NULL
};
587 ret
= map_error( LDAP_CALL( ldap_unbind_ext
, ¶ms
));
589 else return LDAP_PARAM_ERROR
;
591 if (SERVER_CTRLS(ld
)) LDAP_CALL( ldap_value_free_len
, SERVER_CTRLS(ld
) );
597 /***********************************************************************
598 * ldap_unbind_s (WLDAP32.@)
600 * Close LDAP connection and free resources (synchronous operation).
603 * ld [I] Pointer to an LDAP context.
606 * Success: LDAP_SUCCESS
607 * Failure: An LDAP error code.
609 ULONG CDECL
ldap_unbind_s( LDAP
*ld
)
613 TRACE( "(%p)\n", ld
);
617 struct ldap_unbind_ext_s_params params
= { CTX(ld
), NULL
, NULL
};
618 ret
= map_error( LDAP_CALL( ldap_unbind_ext_s
, ¶ms
));
620 else return LDAP_PARAM_ERROR
;
622 if (SERVER_CTRLS(ld
)) LDAP_CALL( ldap_value_free_len
, SERVER_CTRLS(ld
) );