ole32: Return an error in CoMarshalInterface if pStream is NULL.
[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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 CDECL 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%08x)\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 CDECL 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%08x)\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 CDECL 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%08x)\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 CDECL 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%08x)\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 CDECL 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 CDECL 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     struct berval credU;
307
308     ret = WLDAP32_LDAP_NO_MEMORY;
309
310     TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
311            debugstr_w(mechanism), cred, serverctrls, clientctrls, message );
312
313     if (!ld || !dn || !mechanism || !cred || !message)
314         return WLDAP32_LDAP_PARAM_ERROR;
315
316     dnU = strWtoU( dn );
317     if (!dnU) goto exit;
318
319     mechanismU = strWtoU( mechanism );
320     if (!mechanismU) goto exit;
321
322     if (serverctrls) {
323         serverctrlsU = controlarrayWtoU( serverctrls );
324         if (!serverctrlsU) goto exit;
325     }
326     if (clientctrls) {
327         clientctrlsU = controlarrayWtoU( clientctrls );
328         if (!clientctrlsU) goto exit;
329     }
330
331     credU.bv_len = cred->bv_len;
332     credU.bv_val = cred->bv_val;
333
334     ret = ldap_sasl_bind( ld, dnU, mechanismU, &credU,
335                           serverctrlsU, clientctrlsU, message );
336
337 exit:
338     strfreeU( dnU );
339     strfreeU( mechanismU );
340     controlarrayfreeU( serverctrlsU );
341     controlarrayfreeU( clientctrlsU );
342
343 #endif
344     return ret;
345 }
346
347 /***********************************************************************
348  *      ldap_sasl_bind_sA     (WLDAP32.@)
349  *
350  * See ldap_sasl_bind_sW.
351  */
352 ULONG CDECL ldap_sasl_bind_sA( WLDAP32_LDAP *ld, const PCHAR dn,
353     const PCHAR mechanism, const BERVAL *cred, PLDAPControlA *serverctrls,
354     PLDAPControlA *clientctrls, PBERVAL *serverdata )
355 {
356     ULONG ret = LDAP_NOT_SUPPORTED;
357 #ifdef HAVE_LDAP
358     WCHAR *dnW, *mechanismW = NULL;
359     LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
360
361     ret = WLDAP32_LDAP_NO_MEMORY;
362
363     TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
364            debugstr_a(mechanism), cred, serverctrls, clientctrls, serverdata );
365
366     if (!ld || !dn || !mechanism || !cred || !serverdata)
367         return WLDAP32_LDAP_PARAM_ERROR;
368
369     dnW = strAtoW( dn );
370     if (!dnW) goto exit;
371
372     mechanismW = strAtoW( mechanism );
373     if (!mechanismW) goto exit;
374
375     if (serverctrls) {
376         serverctrlsW = controlarrayAtoW( serverctrls );
377         if (!serverctrlsW) goto exit;
378     }
379     if (clientctrls) {
380         clientctrlsW = controlarrayAtoW( clientctrls );
381         if (!clientctrlsW) goto exit;
382     }
383
384     ret = ldap_sasl_bind_sW( ld, dnW, mechanismW, cred, serverctrlsW, clientctrlsW, serverdata );
385
386 exit:
387     strfreeW( dnW );
388     strfreeW( mechanismW );
389     controlarrayfreeW( serverctrlsW );
390     controlarrayfreeW( clientctrlsW );
391
392 #endif
393     return ret;
394 }
395
396 /***********************************************************************
397  *      ldap_sasl_bind_sW     (WLDAP32.@)
398  *
399  * Authenticate with an LDAP server using SASL (synchronous operation).
400  *
401  * PARAMS
402  *  ld          [I] Pointer to an LDAP context.
403  *  dn          [I] DN of entry to bind as.
404  *  mechanism   [I] Authentication method.
405  *  cred        [I] Credentials.
406  *  serverctrls [I] Array of LDAP server controls.
407  *  clientctrls [I] Array of LDAP client controls.
408  *  serverdata  [O] Authentication response from the server.
409  *
410  * RETURNS
411  *  Success: LDAP_SUCCESS
412  *  Failure: An LDAP error code.
413  *
414  * NOTES
415  *  The serverctrls and clientctrls parameters are optional and should
416  *  be set to NULL if not used.
417  */
418 ULONG CDECL ldap_sasl_bind_sW( WLDAP32_LDAP *ld, const PWCHAR dn,
419     const PWCHAR mechanism, const BERVAL *cred, PLDAPControlW *serverctrls,
420     PLDAPControlW *clientctrls, PBERVAL *serverdata )
421 {
422     ULONG ret = LDAP_NOT_SUPPORTED;
423 #ifdef HAVE_LDAP
424     char *dnU, *mechanismU = NULL;
425     LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
426     struct berval credU;
427
428     ret = WLDAP32_LDAP_NO_MEMORY;
429
430     TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
431            debugstr_w(mechanism), cred, serverctrls, clientctrls, serverdata );
432
433     if (!ld || !dn || !mechanism || !cred || !serverdata)
434         return WLDAP32_LDAP_PARAM_ERROR;
435
436     dnU = strWtoU( dn );
437     if (!dnU) goto exit;
438
439     mechanismU = strWtoU( mechanism );
440     if (!mechanismU) goto exit;
441
442     if (serverctrls) {
443         serverctrlsU = controlarrayWtoU( serverctrls );
444         if (!serverctrlsU) goto exit;
445     }
446     if (clientctrls) {
447         clientctrlsU = controlarrayWtoU( clientctrls );
448         if (!clientctrlsU) goto exit;
449     }
450
451     credU.bv_len = cred->bv_len;
452     credU.bv_val = cred->bv_val;
453
454     ret = ldap_sasl_bind_s( ld, dnU, mechanismU, &credU,
455                             serverctrlsU, clientctrlsU, (struct berval **)serverdata );
456
457 exit:
458     strfreeU( dnU );
459     strfreeU( mechanismU );
460     controlarrayfreeU( serverctrlsU );
461     controlarrayfreeU( clientctrlsU );
462
463 #endif
464     return ret;
465 }
466
467 /***********************************************************************
468  *      ldap_simple_bindA     (WLDAP32.@)
469  *
470  * See ldap_simple_bindW.
471  */
472 ULONG CDECL ldap_simple_bindA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR passwd )
473 {
474     ULONG ret = LDAP_NOT_SUPPORTED;
475 #ifdef HAVE_LDAP
476     WCHAR *dnW = NULL, *passwdW = NULL;
477
478     ret = WLDAP32_LDAP_NO_MEMORY;
479
480     TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), passwd );
481
482     if (!ld) return ~0UL;
483
484     if (dn) {
485         dnW = strAtoW( dn );
486         if (!dnW) goto exit;
487     }
488     if (passwd) {
489         passwdW = strAtoW( passwd );
490         if (!passwdW) goto exit;
491     }
492
493     ret = ldap_simple_bindW( ld, dnW, passwdW );
494
495 exit:
496     strfreeW( dnW );
497     strfreeW( passwdW );
498
499 #endif
500     return ret;
501 }
502
503 /***********************************************************************
504  *      ldap_simple_bindW     (WLDAP32.@)
505  *
506  * Authenticate with an LDAP server (asynchronous operation).
507  *
508  * PARAMS
509  *  ld      [I] Pointer to an LDAP context.
510  *  dn      [I] DN of entry to bind as.
511  *  passwd  [I] Password string.
512  *
513  * RETURNS
514  *  Success: Message ID of the bind operation.
515  *  Failure: An LDAP error code.
516  *
517  * NOTES
518  *  Set dn and passwd to NULL to bind as an anonymous user. 
519  */
520 ULONG CDECL ldap_simple_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR passwd )
521 {
522     ULONG ret = LDAP_NOT_SUPPORTED;
523 #ifdef HAVE_LDAP
524     char *dnU = NULL, *passwdU = NULL;
525     struct berval pwd = { 0, NULL };
526     int msg;
527
528     ret = WLDAP32_LDAP_NO_MEMORY;
529
530     TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), passwd );
531
532     if (!ld) return ~0UL;
533
534     if (dn) {
535         dnU = strWtoU( dn );
536         if (!dnU) goto exit;
537     }
538     if (passwd) {
539         passwdU = strWtoU( passwd );
540         if (!passwdU) goto exit;
541
542         pwd.bv_len = strlen( passwdU );
543         pwd.bv_val = passwdU;
544     }
545
546     ret = ldap_sasl_bind( ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, &msg );
547
548     if (ret == LDAP_SUCCESS)
549         ret = msg;
550     else
551         ret = ~0UL;
552
553 exit:
554     strfreeU( dnU );
555     strfreeU( passwdU );
556
557 #endif
558     return ret;
559 }
560
561 /***********************************************************************
562  *      ldap_simple_bind_sA     (WLDAP32.@)
563  *
564  * See ldap_simple_bind_sW.
565  */
566 ULONG CDECL ldap_simple_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR passwd )
567 {
568     ULONG ret = LDAP_NOT_SUPPORTED;
569 #ifdef HAVE_LDAP
570     WCHAR *dnW = NULL, *passwdW = NULL;
571
572     ret = WLDAP32_LDAP_NO_MEMORY;
573
574     TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), passwd );
575
576     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
577
578     if (dn) {
579         dnW = strAtoW( dn );
580         if (!dnW) goto exit;
581     }
582     if (passwd) {
583         passwdW = strAtoW( passwd );
584         if (!passwdW) goto exit;
585     }
586
587     ret = ldap_simple_bind_sW( ld, dnW, passwdW );
588
589 exit:
590     strfreeW( dnW );
591     strfreeW( passwdW );
592
593 #endif
594     return ret;
595 }
596
597 /***********************************************************************
598  *      ldap_simple_bind_sW     (WLDAP32.@)
599  *
600  * Authenticate with an LDAP server (synchronous operation).
601  *
602  * PARAMS
603  *  ld      [I] Pointer to an LDAP context.
604  *  dn      [I] DN of entry to bind as.
605  *  passwd  [I] Password string.
606  *
607  * RETURNS
608  *  Success: LDAP_SUCCESS
609  *  Failure: An LDAP error code.
610  *
611  * NOTES
612  *  Set dn and passwd to NULL to bind as an anonymous user. 
613  */
614 ULONG CDECL ldap_simple_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR passwd )
615 {
616     ULONG ret = LDAP_NOT_SUPPORTED;
617 #ifdef HAVE_LDAP
618     char *dnU = NULL, *passwdU = NULL;
619     struct berval pwd = { 0, NULL };
620
621     ret = WLDAP32_LDAP_NO_MEMORY;
622
623     TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), passwd );
624
625     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
626
627     if (dn) {
628         dnU = strWtoU( dn );
629         if (!dnU) goto exit;
630     }
631     if (passwd) {
632         passwdU = strWtoU( passwd );
633         if (!passwdU) goto exit;
634
635         pwd.bv_len = strlen( passwdU );
636         pwd.bv_val = passwdU;
637     }
638
639     ret = ldap_sasl_bind_s( ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, NULL );
640
641 exit:
642     strfreeU( dnU );
643     strfreeU( passwdU );
644
645 #endif
646     return ret;
647 }
648
649 /***********************************************************************
650  *      ldap_unbind     (WLDAP32.@)
651  *
652  * Close LDAP connection and free resources (asynchronous operation).
653  *
654  * PARAMS
655  *  ld  [I] Pointer to an LDAP context.
656  *
657  * RETURNS
658  *  Success: LDAP_SUCCESS
659  *  Failure: An LDAP error code.
660  */
661 ULONG CDECL WLDAP32_ldap_unbind( WLDAP32_LDAP *ld )
662 {
663     ULONG ret = LDAP_NOT_SUPPORTED;
664 #ifdef HAVE_LDAP
665
666     TRACE( "(%p)\n", ld );
667
668     if (ld)
669         ret = ldap_unbind_ext( ld, NULL, NULL );
670     else
671         ret = WLDAP32_LDAP_PARAM_ERROR;
672
673 #endif
674     return ret;
675 }
676
677 /***********************************************************************
678  *      ldap_unbind_s     (WLDAP32.@)
679  *
680  * Close LDAP connection and free resources (synchronous operation).
681  *
682  * PARAMS
683  *  ld  [I] Pointer to an LDAP context.
684  *
685  * RETURNS
686  *  Success: LDAP_SUCCESS
687  *  Failure: An LDAP error code.
688  */
689 ULONG CDECL WLDAP32_ldap_unbind_s( WLDAP32_LDAP *ld )
690 {
691     ULONG ret = LDAP_NOT_SUPPORTED;
692 #ifdef HAVE_LDAP
693
694     TRACE( "(%p)\n", ld );
695
696     if (ld)
697         ret = ldap_unbind_ext_s( ld, NULL, NULL );
698     else
699         ret = WLDAP32_LDAP_PARAM_ERROR;
700
701 #endif
702     return ret;
703 }