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
28 #include "wine/debug.h"
29 #include "winldap_private.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(wldap32
);
33 /***********************************************************************
34 * ldap_bindA (WLDAP32.@)
36 ULONG CDECL
ldap_bindA( LDAP
*ld
, char *dn
, char *cred
, ULONG method
)
38 ULONG ret
= WLDAP32_LDAP_NO_MEMORY
;
39 WCHAR
*dnW
= NULL
, *credW
= NULL
;
41 TRACE( "(%p, %s, %p, %#lx)\n", ld
, debugstr_a(dn
), cred
, method
);
45 if (dn
&& !(dnW
= strAtoW( dn
))) goto exit
;
46 if (cred
&& !(credW
= strAtoW( cred
))) goto exit
;
48 ret
= ldap_bindW( ld
, dnW
, credW
, method
);
56 /***********************************************************************
57 * ldap_bindW (WLDAP32.@)
59 ULONG CDECL
ldap_bindW( LDAP
*ld
, WCHAR
*dn
, WCHAR
*cred
, ULONG method
)
62 char *dnU
= NULL
, *credU
= NULL
;
63 struct berval pwd
= { 0, NULL
};
66 TRACE( "(%p, %s, %p, %#lx)\n", ld
, debugstr_w(dn
), cred
, method
);
69 if (method
!= WLDAP32_LDAP_AUTH_SIMPLE
) return WLDAP32_LDAP_PARAM_ERROR
;
70 if ((ret
= WLDAP32_ldap_connect( ld
, NULL
))) return ret
;
72 ret
= WLDAP32_LDAP_NO_MEMORY
;
73 if (dn
&& !(dnU
= strWtoU( dn
))) goto exit
;
76 if (!(credU
= strWtoU( cred
))) goto exit
;
77 pwd
.bv_len
= strlen( credU
);
81 ret
= map_error( ldap_sasl_bind( CTX(ld
), dnU
, 0, &pwd
, NULL
, NULL
, &msg
) );
82 if (ret
== WLDAP32_LDAP_SUCCESS
)
93 /***********************************************************************
94 * ldap_bind_sA (WLDAP32.@)
96 ULONG CDECL
ldap_bind_sA( LDAP
*ld
, char *dn
, char *cred
, ULONG method
)
98 ULONG ret
= WLDAP32_LDAP_NO_MEMORY
;
99 WCHAR
*dnW
= NULL
, *credW
= NULL
;
101 TRACE( "(%p, %s, %p, %#lx)\n", ld
, debugstr_a(dn
), cred
, method
);
103 if (!ld
) return WLDAP32_LDAP_PARAM_ERROR
;
105 if (dn
&& !(dnW
= strAtoW( dn
))) goto exit
;
108 if (method
== WLDAP32_LDAP_AUTH_SIMPLE
)
110 if (!(credW
= strAtoW( cred
))) goto exit
;
112 else credW
= (WCHAR
*)cred
/* SEC_WINNT_AUTH_IDENTITY_A */;
115 ret
= ldap_bind_sW( ld
, dnW
, credW
, method
);
119 if (credW
!= (WCHAR
*)cred
) free( credW
);
123 #define SASL_CB_LIST_END 0
124 #define SASL_CB_AUTHNAME 0x4002
125 #define SASL_CB_PASS 0x4004
126 #define SASL_CB_GETREALM 0x4008
131 const char *challenge
;
133 const char *defresult
;
138 static int interact_callback( LDAP
*ld
, unsigned flags
, void *defaults
, void *sasl_interact
)
140 SEC_WINNT_AUTH_IDENTITY_W
*id
= defaults
;
141 struct sasl_interact
*ptr
= sasl_interact
;
143 TRACE( "%p, %08xlx, %p, %p\n", ld
, flags
, defaults
, sasl_interact
);
145 while (ptr
&& ptr
->id
!= SASL_CB_LIST_END
)
149 case SASL_CB_AUTHNAME
:
150 ptr
->result
= id
->User
;
151 ptr
->len
= id
->UserLength
;
153 case SASL_CB_GETREALM
:
154 ptr
->result
= id
->Domain
;
155 ptr
->len
= id
->DomainLength
;
158 ptr
->result
= id
->Password
;
159 ptr
->len
= id
->PasswordLength
;
162 ERR( "unexpected callback %#lx\n", ptr
->id
);
171 /***********************************************************************
172 * ldap_bind_sW (WLDAP32.@)
174 ULONG CDECL
ldap_bind_sW( LDAP
*ld
, WCHAR
*dn
, WCHAR
*cred
, ULONG method
)
177 char *dnU
= NULL
, *credU
= NULL
;
178 struct berval pwd
= { 0, NULL
};
180 TRACE( "(%p, %s, %p, %#lx)\n", ld
, debugstr_w(dn
), cred
, method
);
182 if (!ld
) return WLDAP32_LDAP_PARAM_ERROR
;
183 if ((ret
= WLDAP32_ldap_connect( ld
, NULL
))) return ret
;
185 ret
= WLDAP32_LDAP_NO_MEMORY
;
186 if (method
== WLDAP32_LDAP_AUTH_SIMPLE
)
188 if (dn
&& !(dnU
= strWtoU( dn
))) goto exit
;
191 if (!(credU
= strWtoU( cred
))) goto exit
;
192 pwd
.bv_len
= strlen( credU
);
196 ret
= map_error( ldap_sasl_bind_s( CTX(ld
), dnU
, 0, &pwd
, NULL
, NULL
, NULL
) );
198 else if (method
== WLDAP32_LDAP_AUTH_NEGOTIATE
)
200 SEC_WINNT_AUTH_IDENTITY_W
*id
= (SEC_WINNT_AUTH_IDENTITY_W
*)cred
, idW
;
202 if (id
&& (id
->Flags
& SEC_WINNT_AUTH_IDENTITY_ANSI
))
204 idW
.User
= (unsigned short *)strnAtoW( (char *)id
->User
, id
->UserLength
, &idW
.UserLength
);
205 idW
.Domain
= (unsigned short *)strnAtoW( (char *)id
->Domain
, id
->DomainLength
, &idW
.DomainLength
);
206 idW
.Password
= (unsigned short *)strnAtoW( (char *)id
->Password
, id
->PasswordLength
, &idW
.PasswordLength
);
210 ret
= map_error( ldap_sasl_interactive_bind_s( CTX(ld
), NULL
, NULL
, NULL
, NULL
, LDAP_SASL_QUIET
,
211 interact_callback
, id
) );
212 if (id
&& (id
->Flags
& SEC_WINNT_AUTH_IDENTITY_ANSI
))
216 free( idW
.Password
);
221 FIXME( "method %#lx not supported\n", method
);
222 return WLDAP32_LDAP_PARAM_ERROR
;
231 /***********************************************************************
232 * ldap_sasl_bindA (WLDAP32.@)
234 ULONG CDECL
ldap_sasl_bindA( LDAP
*ld
, const PCHAR dn
, const PCHAR mechanism
, const BERVAL
*cred
,
235 LDAPControlA
**serverctrls
, LDAPControlA
**clientctrls
, int *message
)
237 ULONG ret
= WLDAP32_LDAP_NO_MEMORY
;
238 WCHAR
*dnW
, *mechanismW
= NULL
;
239 LDAPControlW
**serverctrlsW
= NULL
, **clientctrlsW
= NULL
;
241 TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld
, debugstr_a(dn
),
242 debugstr_a(mechanism
), cred
, serverctrls
, clientctrls
, message
);
244 if (!ld
|| !dn
|| !mechanism
|| !cred
|| !message
) return WLDAP32_LDAP_PARAM_ERROR
;
246 if (!(dnW
= strAtoW( dn
))) goto exit
;
247 if (!(mechanismW
= strAtoW( mechanism
))) goto exit
;
248 if (serverctrls
&& !(serverctrlsW
= controlarrayAtoW( serverctrls
))) goto exit
;
249 if (clientctrls
&& !(clientctrlsW
= controlarrayAtoW( clientctrls
))) goto exit
;
251 ret
= ldap_sasl_bindW( ld
, dnW
, mechanismW
, cred
, serverctrlsW
, clientctrlsW
, message
);
256 controlarrayfreeW( serverctrlsW
);
257 controlarrayfreeW( clientctrlsW
);
261 /***********************************************************************
262 * ldap_sasl_bindW (WLDAP32.@)
264 ULONG CDECL
ldap_sasl_bindW( LDAP
*ld
, const PWCHAR dn
, const PWCHAR mechanism
, const BERVAL
*cred
,
265 LDAPControlW
**serverctrls
, LDAPControlW
**clientctrls
, int *message
)
268 char *dnU
, *mechanismU
= NULL
;
269 LDAPControl
**serverctrlsU
= NULL
, **clientctrlsU
= NULL
;
272 TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld
, debugstr_w(dn
),
273 debugstr_w(mechanism
), cred
, serverctrls
, clientctrls
, message
);
275 if (!ld
|| !dn
|| !mechanism
|| !cred
|| !message
) return WLDAP32_LDAP_PARAM_ERROR
;
276 if ((ret
= WLDAP32_ldap_connect( ld
, NULL
))) return ret
;
278 ret
= WLDAP32_LDAP_NO_MEMORY
;
279 if (!(dnU
= strWtoU( dn
))) goto exit
;
280 if (!(mechanismU
= strWtoU( mechanism
))) goto exit
;
281 if (serverctrls
&& !(serverctrlsU
= controlarrayWtoU( serverctrls
))) goto exit
;
282 if (clientctrls
&& !(clientctrlsU
= controlarrayWtoU( clientctrls
))) goto exit
;
285 credU
.bv_len
= cred
->bv_len
;
286 credU
.bv_val
= cred
->bv_val
;
287 ret
= map_error( ldap_sasl_bind( CTX(ld
), dnU
, mechanismU
, &credU
, serverctrlsU
, clientctrlsU
, message
) );
293 controlarrayfreeU( serverctrlsU
);
294 controlarrayfreeU( clientctrlsU
);
298 /***********************************************************************
299 * ldap_sasl_bind_sA (WLDAP32.@)
301 ULONG CDECL
ldap_sasl_bind_sA( LDAP
*ld
, const PCHAR dn
, const PCHAR mechanism
, const BERVAL
*cred
,
302 LDAPControlA
**serverctrls
, LDAPControlA
**clientctrls
, BERVAL
**serverdata
)
304 ULONG ret
= WLDAP32_LDAP_NO_MEMORY
;
305 WCHAR
*dnW
, *mechanismW
= NULL
;
306 LDAPControlW
**serverctrlsW
= NULL
, **clientctrlsW
= NULL
;
308 TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld
, debugstr_a(dn
),
309 debugstr_a(mechanism
), cred
, serverctrls
, clientctrls
, serverdata
);
311 if (!ld
|| !dn
|| !mechanism
|| !cred
|| !serverdata
) return WLDAP32_LDAP_PARAM_ERROR
;
313 if (!(dnW
= strAtoW( dn
))) goto exit
;
314 if (!(mechanismW
= strAtoW( mechanism
))) goto exit
;
315 if (serverctrls
&& !(serverctrlsW
= controlarrayAtoW( serverctrls
))) goto exit
;
316 if (clientctrls
&& !(clientctrlsW
= controlarrayAtoW( clientctrls
))) goto exit
;
318 ret
= ldap_sasl_bind_sW( ld
, dnW
, mechanismW
, cred
, serverctrlsW
, clientctrlsW
, serverdata
);
323 controlarrayfreeW( serverctrlsW
);
324 controlarrayfreeW( clientctrlsW
);
328 /***********************************************************************
329 * ldap_sasl_bind_sW (WLDAP32.@)
331 ULONG CDECL
ldap_sasl_bind_sW( LDAP
*ld
, const PWCHAR dn
, const PWCHAR mechanism
, const BERVAL
*cred
,
332 LDAPControlW
**serverctrls
, LDAPControlW
**clientctrls
, BERVAL
**serverdata
)
335 char *dnU
, *mechanismU
= NULL
;
336 LDAPControl
**serverctrlsU
= NULL
, **clientctrlsU
= NULL
;
337 struct berval
*dataU
, credU
;
339 TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld
, debugstr_w(dn
),
340 debugstr_w(mechanism
), cred
, serverctrls
, clientctrls
, serverdata
);
342 if (!ld
|| !dn
|| !mechanism
|| !cred
|| !serverdata
) return WLDAP32_LDAP_PARAM_ERROR
;
343 if ((ret
= WLDAP32_ldap_connect( ld
, NULL
))) return ret
;
345 ret
= WLDAP32_LDAP_NO_MEMORY
;
346 if (!(dnU
= strWtoU( dn
))) goto exit
;
347 if (!(mechanismU
= strWtoU( mechanism
))) goto exit
;
348 if (serverctrls
&& !(serverctrlsU
= controlarrayWtoU( serverctrls
))) goto exit
;
349 if (clientctrls
&& !(clientctrlsU
= controlarrayWtoU( clientctrls
))) goto exit
;
351 credU
.bv_len
= cred
->bv_len
;
352 credU
.bv_val
= cred
->bv_val
;
353 ret
= map_error( ldap_sasl_bind_s( CTX(ld
), dnU
, mechanismU
, &credU
, serverctrlsU
, clientctrlsU
, &dataU
) );
355 if (ret
== WLDAP32_LDAP_SUCCESS
)
358 if (!(ptr
= bervalUtoW( dataU
))) ret
= WLDAP32_LDAP_NO_MEMORY
;
359 else *serverdata
= ptr
;
366 controlarrayfreeU( serverctrlsU
);
367 controlarrayfreeU( clientctrlsU
);
371 /***********************************************************************
372 * ldap_simple_bindA (WLDAP32.@)
374 ULONG CDECL
ldap_simple_bindA( LDAP
*ld
, char *dn
, char *passwd
)
376 ULONG ret
= WLDAP32_LDAP_NO_MEMORY
;
377 WCHAR
*dnW
= NULL
, *passwdW
= NULL
;
379 TRACE( "(%p, %s, %p)\n", ld
, debugstr_a(dn
), passwd
);
383 if (dn
&& !(dnW
= strAtoW( dn
))) goto exit
;
384 if (passwd
&& !(passwdW
= strAtoW( passwd
))) goto exit
;
386 ret
= ldap_simple_bindW( ld
, dnW
, passwdW
);
394 /***********************************************************************
395 * ldap_simple_bindW (WLDAP32.@)
397 ULONG CDECL
ldap_simple_bindW( LDAP
*ld
, WCHAR
*dn
, WCHAR
*passwd
)
399 ULONG ret
= WLDAP32_LDAP_NO_MEMORY
;
400 char *dnU
= NULL
, *passwdU
= NULL
;
401 struct berval pwd
= { 0, NULL
};
404 TRACE( "(%p, %s, %p)\n", ld
, debugstr_w(dn
), passwd
);
406 if (!ld
|| WLDAP32_ldap_connect( ld
, NULL
) != WLDAP32_LDAP_SUCCESS
) return ~0u;
408 if (dn
&& !(dnU
= strWtoU( dn
))) goto exit
;
411 if (!(passwdU
= strWtoU( passwd
))) goto exit
;
412 pwd
.bv_len
= strlen( passwdU
);
413 pwd
.bv_val
= passwdU
;
416 ret
= map_error( ldap_sasl_bind( CTX(ld
), dnU
, 0, &pwd
, NULL
, NULL
, &msg
) );
417 if (ret
== WLDAP32_LDAP_SUCCESS
)
428 /***********************************************************************
429 * ldap_simple_bind_sA (WLDAP32.@)
431 ULONG CDECL
ldap_simple_bind_sA( LDAP
*ld
, char *dn
, char *passwd
)
433 ULONG ret
= WLDAP32_LDAP_NO_MEMORY
;
434 WCHAR
*dnW
= NULL
, *passwdW
= NULL
;
436 TRACE( "(%p, %s, %p)\n", ld
, debugstr_a(dn
), passwd
);
438 if (!ld
) return WLDAP32_LDAP_PARAM_ERROR
;
440 if (dn
&& !(dnW
= strAtoW( dn
))) goto exit
;
441 if (passwd
&& !(passwdW
= strAtoW( passwd
))) goto exit
;
443 ret
= ldap_simple_bind_sW( ld
, dnW
, passwdW
);
451 /***********************************************************************
452 * ldap_simple_bind_sW (WLDAP32.@)
454 ULONG CDECL
ldap_simple_bind_sW( LDAP
*ld
, WCHAR
*dn
, WCHAR
*passwd
)
457 char *dnU
= NULL
, *passwdU
= NULL
;
458 struct berval pwd
= { 0, NULL
};
460 TRACE( "(%p, %s, %p)\n", ld
, debugstr_w(dn
), passwd
);
462 if (!ld
) return WLDAP32_LDAP_PARAM_ERROR
;
463 if ((ret
= WLDAP32_ldap_connect( ld
, NULL
))) return ret
;
465 ret
= WLDAP32_LDAP_NO_MEMORY
;
466 if (dn
&& !(dnU
= strWtoU( dn
))) goto exit
;
469 if (!(passwdU
= strWtoU( passwd
))) goto exit
;
470 pwd
.bv_len
= strlen( passwdU
);
471 pwd
.bv_val
= passwdU
;
474 ret
= map_error( ldap_sasl_bind_s( CTX(ld
), dnU
, 0, &pwd
, NULL
, NULL
, NULL
) );
482 /***********************************************************************
483 * ldap_unbind (WLDAP32.@)
485 ULONG CDECL
WLDAP32_ldap_unbind( LDAP
*ld
)
489 TRACE( "(%p)\n", ld
);
491 if (ld
) ret
= map_error( ldap_unbind_ext( CTX(ld
), NULL
, NULL
) );
492 else return WLDAP32_LDAP_PARAM_ERROR
;
494 if (SERVER_CTRLS(ld
)) ldap_value_free_len( SERVER_CTRLS(ld
) );
500 /***********************************************************************
501 * ldap_unbind_s (WLDAP32.@)
503 ULONG CDECL
WLDAP32_ldap_unbind_s( LDAP
*ld
)
507 TRACE( "(%p)\n", ld
);
509 if (ld
) ret
= map_error( ldap_unbind_ext_s( CTX(ld
), NULL
, NULL
) );
510 else return WLDAP32_LDAP_PARAM_ERROR
;
512 if (SERVER_CTRLS(ld
)) ldap_value_free_len( SERVER_CTRLS(ld
) );