msvcrt: Use the msvcrt version of printf everywhere.
[wine] / dlls / wldap32 / bind.c
1 /*
2  * WLDAP32 - LDAP support for Wine
3  *
4  * Copyright 2005 Hans Leidekker
5  *
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.
10  *
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.
15  *
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22
23 #include "wine/port.h"
24 #include "wine/debug.h"
25
26 #include <stdarg.h>
27
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winnls.h"
31
32 #ifdef HAVE_LDAP_H
33 #include <ldap.h>
34 #else
35 #define LDAP_SUCCESS        0x00
36 #define LDAP_NOT_SUPPORTED  0x5c
37 #endif
38
39 #include "winldap_private.h"
40 #include "wldap32.h"
41
42 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
43
44 /***********************************************************************
45  *      ldap_bindA     (WLDAP32.@)
46  *
47  * See ldap_bindW.
48  */
49 ULONG ldap_bindA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR cred, ULONG method )
50 {
51     ULONG ret = LDAP_NOT_SUPPORTED;
52 #ifdef HAVE_LDAP
53     WCHAR *dnW = NULL, *credW = NULL;
54
55     ret = WLDAP32_LDAP_NO_MEMORY;
56
57     TRACE( "(%p, %s, %p, 0x%08lx)\n", ld, debugstr_a(dn), cred, method );
58
59     if (!ld) return ~0UL;
60
61     if (dn) {
62         dnW = strAtoW( dn );
63         if (!dnW) goto exit;
64     }
65     if (cred) {
66         credW = strAtoW( cred );
67         if (!credW) goto exit;
68     }
69
70     ret = ldap_bindW( ld, dnW, credW, method );
71
72 exit:
73     strfreeW( dnW );
74     strfreeW( credW );
75
76 #endif
77     return ret;
78 }
79
80 /***********************************************************************
81  *      ldap_bindW     (WLDAP32.@)
82  *
83  * Authenticate with an LDAP server (asynchronous operation).
84  *
85  * PARAMS
86  *  ld      [I] Pointer to an LDAP context.
87  *  dn      [I] DN of entry to bind as.
88  *  cred    [I] Credentials (e.g. password string).
89  *  method  [I] Authentication method.
90  *
91  * RETURNS
92  *  Success: Message ID of the bind operation.
93  *  Failure: An LDAP error code.
94  *
95  * NOTES
96  *  Only LDAP_AUTH_SIMPLE is supported (just like native).
97  */
98 ULONG ldap_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method )
99 {
100     ULONG ret = LDAP_NOT_SUPPORTED;
101 #ifdef HAVE_LDAP
102     char *dnU = NULL, *credU = NULL;
103     struct berval pwd = { 0, NULL };
104     int msg;
105
106     ret = WLDAP32_LDAP_NO_MEMORY;
107
108     TRACE( "(%p, %s, %p, 0x%08lx)\n", ld, debugstr_w(dn), cred, method );
109
110     if (!ld) return ~0UL;
111     if (method != LDAP_AUTH_SIMPLE) return WLDAP32_LDAP_PARAM_ERROR;
112
113     if (dn) {
114         dnU = strWtoU( dn );
115         if (!dnU) goto exit;
116     }
117     if (cred) {
118         credU = strWtoU( cred );
119         if (!credU) goto exit;
120
121         pwd.bv_len = strlen( credU );
122         pwd.bv_val = credU;
123     }
124
125     ret = ldap_sasl_bind( ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, &msg );
126
127     if (ret == LDAP_SUCCESS)
128         ret = msg;
129     else
130         ret = ~0UL;
131
132 exit:
133     strfreeU( dnU );
134     strfreeU( credU );
135
136 #endif
137     return ret;
138 }
139
140 /***********************************************************************
141  *      ldap_bind_sA     (WLDAP32.@)
142  *
143  * See ldap_bind_sW.
144  */
145 ULONG ldap_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR cred, ULONG method )
146 {
147     ULONG ret = LDAP_NOT_SUPPORTED;
148 #ifdef HAVE_LDAP
149     WCHAR *dnW = NULL, *credW = NULL;
150
151     ret = WLDAP32_LDAP_NO_MEMORY;
152
153     TRACE( "(%p, %s, %p, 0x%08lx)\n", ld, debugstr_a(dn), cred, method );
154
155     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
156
157     if (dn) {
158         dnW = strAtoW( dn );
159         if (!dnW) goto exit;
160     }
161     if (cred) {
162         credW = strAtoW( cred );
163         if (!credW) goto exit;
164     }
165
166     ret = ldap_bind_sW( ld, dnW, credW, method );
167
168 exit:
169     strfreeW( dnW );
170     strfreeW( credW );
171
172 #endif
173     return ret;
174 }
175
176 /***********************************************************************
177  *      ldap_bind_sW     (WLDAP32.@)
178  *
179  * Authenticate with an LDAP server (synchronous operation).
180  *
181  * PARAMS
182  *  ld      [I] Pointer to an LDAP context.
183  *  dn      [I] DN of entry to bind as.
184  *  cred    [I] Credentials (e.g. password string).
185  *  method  [I] Authentication method.
186  *
187  * RETURNS
188  *  Success: LDAP_SUCCESS
189  *  Failure: An LDAP error code.
190  */
191 ULONG ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method )
192 {
193     ULONG ret = LDAP_NOT_SUPPORTED;
194 #ifdef HAVE_LDAP
195     char *dnU = NULL, *credU = NULL;
196     struct berval pwd = { 0, NULL };
197
198     ret = WLDAP32_LDAP_NO_MEMORY;
199
200     TRACE( "(%p, %s, %p, 0x%08lx)\n", ld, debugstr_w(dn), cred, method );
201
202     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
203     if (method != LDAP_AUTH_SIMPLE) return WLDAP32_LDAP_PARAM_ERROR;
204
205     if (dn) {
206         dnU = strWtoU( dn );
207         if (!dnU) goto exit;
208     }
209     if (cred) {
210         credU = strWtoU( cred );
211         if (!credU) goto exit;
212
213         pwd.bv_len = strlen( credU );
214         pwd.bv_val = credU;
215     }
216
217     ret = ldap_sasl_bind_s( ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, NULL );
218
219 exit:
220     strfreeU( dnU );
221     strfreeU( credU );
222
223 #endif
224     return ret;
225 }
226
227 /***********************************************************************
228  *      ldap_sasl_bindA     (WLDAP32.@)
229  *
230  * See ldap_sasl_bindW.
231  */
232 ULONG ldap_sasl_bindA( WLDAP32_LDAP *ld, const PCHAR dn,
233     const PCHAR mechanism, const BERVAL *cred, PLDAPControlA *serverctrls,
234     PLDAPControlA *clientctrls, int *message )
235 {
236     ULONG ret = LDAP_NOT_SUPPORTED;
237 #ifdef HAVE_LDAP
238     WCHAR *dnW, *mechanismW = NULL;
239     LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
240
241     ret = WLDAP32_LDAP_NO_MEMORY;
242
243     TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
244            debugstr_a(mechanism), cred, serverctrls, clientctrls, message );
245
246     if (!ld || !dn || !mechanism || !cred || !message)
247         return WLDAP32_LDAP_PARAM_ERROR;
248
249     dnW = strAtoW( dn );
250     if (!dnW) goto exit;
251
252     mechanismW = strAtoW( mechanism );
253     if (!mechanismW) goto exit;
254
255     if (serverctrls) {
256         serverctrlsW = controlarrayAtoW( serverctrls );
257         if (!serverctrlsW) goto exit;
258     }
259     if (clientctrls) {
260         clientctrlsW = controlarrayAtoW( clientctrls );
261         if (!clientctrlsW) goto exit;
262     }
263
264     ret = ldap_sasl_bindW( ld, dnW, mechanismW, cred, serverctrlsW, clientctrlsW, message );
265
266 exit:
267     strfreeW( dnW );
268     strfreeW( mechanismW );
269     controlarrayfreeW( serverctrlsW );
270     controlarrayfreeW( clientctrlsW );
271
272 #endif
273     return ret;
274 }
275
276 /***********************************************************************
277  *      ldap_sasl_bindW     (WLDAP32.@)
278  *
279  * Authenticate with an LDAP server using SASL (asynchronous operation).
280  *
281  * PARAMS
282  *  ld          [I] Pointer to an LDAP context.
283  *  dn          [I] DN of entry to bind as.
284  *  mechanism   [I] Authentication method.
285  *  cred        [I] Credentials.
286  *  serverctrls [I] Array of LDAP server controls.
287  *  clientctrls [I] Array of LDAP client controls.
288  *  message     [O] Message ID of the bind operation. 
289  *
290  * RETURNS
291  *  Success: LDAP_SUCCESS
292  *  Failure: An LDAP error code.
293  *
294  * NOTES
295  *  The serverctrls and clientctrls parameters are optional and should
296  *  be set to NULL if not used.
297  */
298 ULONG ldap_sasl_bindW( WLDAP32_LDAP *ld, const PWCHAR dn,
299     const PWCHAR mechanism, const BERVAL *cred, PLDAPControlW *serverctrls,
300     PLDAPControlW *clientctrls, int *message )
301 {
302     ULONG ret = LDAP_NOT_SUPPORTED;
303 #ifdef HAVE_LDAP
304     char *dnU, *mechanismU = NULL;
305     LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
306
307     ret = WLDAP32_LDAP_NO_MEMORY;
308
309     TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
310            debugstr_w(mechanism), cred, serverctrls, clientctrls, message );
311
312     if (!ld || !dn || !mechanism || !cred || !message)
313         return WLDAP32_LDAP_PARAM_ERROR;
314
315     dnU = strWtoU( dn );
316     if (!dnU) goto exit;
317
318     mechanismU = strWtoU( mechanism );
319     if (!mechanismU) goto exit;
320
321     if (serverctrls) {
322         serverctrlsU = controlarrayWtoU( serverctrls );
323         if (!serverctrlsU) goto exit;
324     }
325     if (clientctrls) {
326         clientctrlsU = controlarrayWtoU( clientctrls );
327         if (!clientctrlsU) goto exit;
328     }
329
330     ret = ldap_sasl_bind( ld, dnU, mechanismU, (struct berval *)cred,
331                           serverctrlsU, clientctrlsU, message );
332
333 exit:
334     strfreeU( dnU );
335     strfreeU( mechanismU );
336     controlarrayfreeU( serverctrlsU );
337     controlarrayfreeU( clientctrlsU );
338
339 #endif
340     return ret;
341 }
342
343 /***********************************************************************
344  *      ldap_sasl_bind_sA     (WLDAP32.@)
345  *
346  * See ldap_sasl_bind_sW.
347  */
348 ULONG ldap_sasl_bind_sA( WLDAP32_LDAP *ld, const PCHAR dn,
349     const PCHAR mechanism, const BERVAL *cred, PLDAPControlA *serverctrls,
350     PLDAPControlA *clientctrls, PBERVAL *serverdata )
351 {
352     ULONG ret = LDAP_NOT_SUPPORTED;
353 #ifdef HAVE_LDAP
354     WCHAR *dnW, *mechanismW = NULL;
355     LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
356
357     ret = WLDAP32_LDAP_NO_MEMORY;
358
359     TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
360            debugstr_a(mechanism), cred, serverctrls, clientctrls, serverdata );
361
362     if (!ld || !dn || !mechanism || !cred || !serverdata)
363         return WLDAP32_LDAP_PARAM_ERROR;
364
365     dnW = strAtoW( dn );
366     if (!dnW) goto exit;
367
368     mechanismW = strAtoW( mechanism );
369     if (!mechanismW) goto exit;
370
371     if (serverctrls) {
372         serverctrlsW = controlarrayAtoW( serverctrls );
373         if (!serverctrlsW) goto exit;
374     }
375     if (clientctrls) {
376         clientctrlsW = controlarrayAtoW( clientctrls );
377         if (!clientctrlsW) goto exit;
378     }
379
380     ret = ldap_sasl_bind_sW( ld, dnW, mechanismW, cred, serverctrlsW, clientctrlsW, serverdata );
381
382 exit:
383     strfreeW( dnW );
384     strfreeW( mechanismW );
385     controlarrayfreeW( serverctrlsW );
386     controlarrayfreeW( clientctrlsW );
387
388 #endif
389     return ret;
390 }
391
392 /***********************************************************************
393  *      ldap_sasl_bind_sW     (WLDAP32.@)
394  *
395  * Authenticate with an LDAP server using SASL (synchronous operation).
396  *
397  * PARAMS
398  *  ld          [I] Pointer to an LDAP context.
399  *  dn          [I] DN of entry to bind as.
400  *  mechanism   [I] Authentication method.
401  *  cred        [I] Credentials.
402  *  serverctrls [I] Array of LDAP server controls.
403  *  clientctrls [I] Array of LDAP client controls.
404  *  serverdata  [O] Authentication response from the server.
405  *
406  * RETURNS
407  *  Success: LDAP_SUCCESS
408  *  Failure: An LDAP error code.
409  *
410  * NOTES
411  *  The serverctrls and clientctrls parameters are optional and should
412  *  be set to NULL if not used.
413  */
414 ULONG ldap_sasl_bind_sW( WLDAP32_LDAP *ld, const PWCHAR dn,
415     const PWCHAR mechanism, const BERVAL *cred, PLDAPControlW *serverctrls,
416     PLDAPControlW *clientctrls, PBERVAL *serverdata )
417 {
418     ULONG ret = LDAP_NOT_SUPPORTED;
419 #ifdef HAVE_LDAP
420     char *dnU, *mechanismU = NULL;
421     LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
422
423     ret = WLDAP32_LDAP_NO_MEMORY;
424
425     TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
426            debugstr_w(mechanism), cred, serverctrls, clientctrls, serverdata );
427
428     if (!ld || !dn || !mechanism || !cred || !serverdata)
429         return WLDAP32_LDAP_PARAM_ERROR;
430
431     dnU = strWtoU( dn );
432     if (!dnU) goto exit;
433
434     mechanismU = strWtoU( mechanism );
435     if (!mechanismU) goto exit;
436
437     if (serverctrls) {
438         serverctrlsU = controlarrayWtoU( serverctrls );
439         if (!serverctrlsU) goto exit;
440     }
441     if (clientctrls) {
442         clientctrlsU = controlarrayWtoU( clientctrls );
443         if (!clientctrlsU) goto exit;
444     }
445
446     ret = ldap_sasl_bind_s( ld, dnU, mechanismU, (struct berval *)cred,
447                             serverctrlsU, clientctrlsU, (struct berval **)serverdata );
448
449 exit:
450     strfreeU( dnU );
451     strfreeU( mechanismU );
452     controlarrayfreeU( serverctrlsU );
453     controlarrayfreeU( clientctrlsU );
454
455 #endif
456     return ret;
457 }
458
459 /***********************************************************************
460  *      ldap_simple_bindA     (WLDAP32.@)
461  *
462  * See ldap_simple_bindW.
463  */
464 ULONG ldap_simple_bindA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR passwd )
465 {
466     ULONG ret = LDAP_NOT_SUPPORTED;
467 #ifdef HAVE_LDAP
468     WCHAR *dnW = NULL, *passwdW = NULL;
469
470     ret = WLDAP32_LDAP_NO_MEMORY;
471
472     TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), passwd );
473
474     if (!ld) return ~0UL;
475
476     if (dn) {
477         dnW = strAtoW( dn );
478         if (!dnW) goto exit;
479     }
480     if (passwd) {
481         passwdW = strAtoW( passwd );
482         if (!passwdW) goto exit;
483     }
484
485     ret = ldap_simple_bindW( ld, dnW, passwdW );
486
487 exit:
488     strfreeW( dnW );
489     strfreeW( passwdW );
490
491 #endif
492     return ret;
493 }
494
495 /***********************************************************************
496  *      ldap_simple_bindW     (WLDAP32.@)
497  *
498  * Authenticate with an LDAP server (asynchronous operation).
499  *
500  * PARAMS
501  *  ld      [I] Pointer to an LDAP context.
502  *  dn      [I] DN of entry to bind as.
503  *  passwd  [I] Password string.
504  *
505  * RETURNS
506  *  Success: Message ID of the bind operation.
507  *  Failure: An LDAP error code.
508  *
509  * NOTES
510  *  Set dn and passwd to NULL to bind as an anonymous user. 
511  */
512 ULONG ldap_simple_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR passwd )
513 {
514     ULONG ret = LDAP_NOT_SUPPORTED;
515 #ifdef HAVE_LDAP
516     char *dnU = NULL, *passwdU = NULL;
517     struct berval pwd = { 0, NULL };
518     int msg;
519
520     ret = WLDAP32_LDAP_NO_MEMORY;
521
522     TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), passwd );
523
524     if (!ld) return ~0UL;
525
526     if (dn) {
527         dnU = strWtoU( dn );
528         if (!dnU) goto exit;
529     }
530     if (passwd) {
531         passwdU = strWtoU( passwd );
532         if (!passwdU) goto exit;
533
534         pwd.bv_len = strlen( passwdU );
535         pwd.bv_val = passwdU;
536     }
537
538     ret = ldap_sasl_bind( ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, &msg );
539
540     if (ret == LDAP_SUCCESS)
541         ret = msg;
542     else
543         ret = ~0UL;
544
545 exit:
546     strfreeU( dnU );
547     strfreeU( passwdU );
548
549 #endif
550     return ret;
551 }
552
553 /***********************************************************************
554  *      ldap_simple_bind_sA     (WLDAP32.@)
555  *
556  * See ldap_simple_bind_sW.
557  */
558 ULONG ldap_simple_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR passwd )
559 {
560     ULONG ret = LDAP_NOT_SUPPORTED;
561 #ifdef HAVE_LDAP
562     WCHAR *dnW = NULL, *passwdW = NULL;
563
564     ret = WLDAP32_LDAP_NO_MEMORY;
565
566     TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), passwd );
567
568     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
569
570     if (dn) {
571         dnW = strAtoW( dn );
572         if (!dnW) goto exit;
573     }
574     if (passwd) {
575         passwdW = strAtoW( passwd );
576         if (!passwdW) goto exit;
577     }
578
579     ret = ldap_simple_bind_sW( ld, dnW, passwdW );
580
581 exit:
582     strfreeW( dnW );
583     strfreeW( passwdW );
584
585 #endif
586     return ret;
587 }
588
589 /***********************************************************************
590  *      ldap_simple_bind_sW     (WLDAP32.@)
591  *
592  * Authenticate with an LDAP server (synchronous operation).
593  *
594  * PARAMS
595  *  ld      [I] Pointer to an LDAP context.
596  *  dn      [I] DN of entry to bind as.
597  *  passwd  [I] Password string.
598  *
599  * RETURNS
600  *  Success: LDAP_SUCCESS
601  *  Failure: An LDAP error code.
602  *
603  * NOTES
604  *  Set dn and passwd to NULL to bind as an anonymous user. 
605  */
606 ULONG ldap_simple_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR passwd )
607 {
608     ULONG ret = LDAP_NOT_SUPPORTED;
609 #ifdef HAVE_LDAP
610     char *dnU = NULL, *passwdU = NULL;
611     struct berval pwd = { 0, NULL };
612
613     ret = WLDAP32_LDAP_NO_MEMORY;
614
615     TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), passwd );
616
617     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
618
619     if (dn) {
620         dnU = strWtoU( dn );
621         if (!dnU) goto exit;
622     }
623     if (passwd) {
624         passwdU = strWtoU( passwd );
625         if (!passwdU) goto exit;
626
627         pwd.bv_len = strlen( passwdU );
628         pwd.bv_val = passwdU;
629     }
630
631     ret = ldap_sasl_bind_s( ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, NULL );
632
633 exit:
634     strfreeU( dnU );
635     strfreeU( passwdU );
636
637 #endif
638     return ret;
639 }
640
641 /***********************************************************************
642  *      ldap_unbind     (WLDAP32.@)
643  *
644  * Close LDAP connection and free resources (asynchronous operation).
645  *
646  * PARAMS
647  *  ld  [I] Pointer to an LDAP context.
648  *
649  * RETURNS
650  *  Success: LDAP_SUCCESS
651  *  Failure: An LDAP error code.
652  */
653 ULONG WLDAP32_ldap_unbind( WLDAP32_LDAP *ld )
654 {
655     ULONG ret = LDAP_NOT_SUPPORTED;
656 #ifdef HAVE_LDAP
657
658     TRACE( "(%p)\n", ld );
659
660     if (ld)
661         ret = ldap_unbind_ext( ld, NULL, NULL );
662     else
663         ret = WLDAP32_LDAP_PARAM_ERROR;
664
665 #endif
666     return ret;
667 }
668
669 /***********************************************************************
670  *      ldap_unbind_s     (WLDAP32.@)
671  *
672  * Close LDAP connection and free resources (synchronous operation).
673  *
674  * PARAMS
675  *  ld  [I] Pointer to an LDAP context.
676  *
677  * RETURNS
678  *  Success: LDAP_SUCCESS
679  *  Failure: An LDAP error code.
680  */
681 ULONG WLDAP32_ldap_unbind_s( WLDAP32_LDAP *ld )
682 {
683     ULONG ret = LDAP_NOT_SUPPORTED;
684 #ifdef HAVE_LDAP
685
686     TRACE( "(%p)\n", ld );
687
688     if (ld)
689         ret = ldap_unbind_ext_s( ld, NULL, NULL );
690     else
691         ret = WLDAP32_LDAP_PARAM_ERROR;
692
693 #endif
694     return ret;
695 }