Release 1.5.29.
[wine] / dlls / wldap32 / compare.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 #include "wine/port.h"
23
24 #include <stdarg.h>
25 #ifdef HAVE_LDAP_H
26 #include <ldap.h>
27 #endif
28
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winnls.h"
32
33 #include "winldap_private.h"
34 #include "wldap32.h"
35 #include "wine/debug.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
38
39 /***********************************************************************
40  *      ldap_compareA     (WLDAP32.@)
41  *
42  * See ldap_compareW.
43  */
44 ULONG CDECL ldap_compareA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value )
45 {
46     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
47 #ifdef HAVE_LDAP
48     WCHAR *dnW = NULL, *attrW = NULL, *valueW = NULL;
49
50     ret = ~0u;
51
52     TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_a(dn), debugstr_a(attr),
53            debugstr_a(value) );
54
55     if (!ld || !attr) return ~0u;
56
57     if (dn) {
58         dnW = strAtoW( dn );
59         if (!dnW) goto exit;
60     }
61
62     attrW = strAtoW( attr );
63     if (!attrW) goto exit;
64
65     if (value) {
66         valueW = strAtoW( value );
67         if (!valueW) goto exit;
68     }
69
70     ret = ldap_compareW( ld, dnW, attrW, valueW );
71
72 exit:
73     strfreeW( dnW );
74     strfreeW( attrW );
75     strfreeW( valueW );
76
77 #endif
78     return ret;
79 }
80
81 /***********************************************************************
82  *      ldap_compareW     (WLDAP32.@)
83  *
84  * Check if an attribute has a certain value (asynchronous operation).
85  *
86  * PARAMS
87  *  ld      [I] Pointer to an LDAP context.
88  *  dn      [I] DN of entry to compare value for.
89  *  attr    [I] Attribute to compare value for.
90  *  value   [I] Value to compare.
91  *
92  * RETURNS
93  *  Success: Message ID of the compare operation.
94  *  Failure: An LDAP error code.
95  */
96 ULONG CDECL ldap_compareW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value )
97 {
98     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
99 #ifdef HAVE_LDAP
100     char *dnU = NULL, *attrU = NULL, *valueU = NULL;
101     struct berval val = { 0, NULL };
102     int msg;
103
104     ret = ~0u;
105
106     TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_w(dn), debugstr_w(attr),
107            debugstr_w(value) );
108
109     if (!ld || !attr) return ~0u;
110
111     if (dn) {
112         dnU = strWtoU( dn );
113         if (!dnU) goto exit;
114     }
115
116     attrU = strWtoU( attr );
117     if (!attrU) goto exit;
118
119     if (value) {
120         valueU = strWtoU( value );
121         if (!valueU) goto exit;
122
123         val.bv_len = strlen( valueU );
124         val.bv_val = valueU;
125     }
126
127     ret = ldap_compare_ext( ld, dn ? dnU : "", attrU, &val, NULL, NULL, &msg );
128
129     if (ret == LDAP_SUCCESS)
130         ret = msg;
131     else
132         ret = ~0u;
133
134 exit:
135     strfreeU( dnU );
136     strfreeU( attrU );
137     strfreeU( valueU );
138
139 #endif
140     return ret;
141 }
142
143 /***********************************************************************
144  *      ldap_compare_extA     (WLDAP32.@)
145  *
146  * See ldap_compare_extW.
147  */
148 ULONG CDECL ldap_compare_extA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value,
149     struct WLDAP32_berval *data, PLDAPControlA *serverctrls, PLDAPControlA *clientctrls,
150     ULONG *message )
151 {
152     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
153 #ifdef HAVE_LDAP
154     WCHAR *dnW = NULL, *attrW = NULL, *valueW = NULL;
155     LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
156
157     ret = WLDAP32_LDAP_NO_MEMORY;
158
159     TRACE( "(%p, %s, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
160            debugstr_a(attr), debugstr_a(value), data, serverctrls,
161            clientctrls, message );
162
163     if (!ld || !message) return WLDAP32_LDAP_PARAM_ERROR;
164
165     if (dn) {
166         dnW = strAtoW( dn );
167         if (!dnW) goto exit;
168     }
169     if (attr) {
170         attrW = strAtoW( attr );
171         if (!attrW) goto exit;
172     }
173     if (value) {
174         valueW = strAtoW( value );
175         if (!valueW) goto exit;
176     }
177     if (serverctrls) {
178         serverctrlsW = controlarrayAtoW( serverctrls );
179         if (!serverctrlsW) goto exit;
180     }
181     if (clientctrls) {
182         clientctrlsW = controlarrayAtoW( clientctrls );
183         if (!clientctrlsW) goto exit;
184     }
185
186     ret = ldap_compare_extW( ld, dnW, attrW, valueW, data,
187                              serverctrlsW, clientctrlsW, message );
188
189 exit:
190     strfreeW( dnW );
191     strfreeW( attrW );
192     strfreeW( valueW );
193     controlarrayfreeW( serverctrlsW );
194     controlarrayfreeW( clientctrlsW );
195
196 #endif
197     return ret;
198 }
199
200 /***********************************************************************
201  *      ldap_compare_extW     (WLDAP32.@)
202  *
203  * Check if an attribute has a certain value (asynchronous operation).
204  *
205  * PARAMS
206  *  ld          [I] Pointer to an LDAP context.
207  *  dn          [I] DN of entry to compare value for.
208  *  attr        [I] Attribute to compare value for.
209  *  value       [I] string encoded value to compare.
210  *  data        [I] berval encoded value to compare.
211  *  serverctrls [I] Array of LDAP server controls.
212  *  clientctrls [I] Array of LDAP client controls.
213  *  message     [O] Message ID of the compare operation.
214  *
215  * RETURNS
216  *  Success: LDAP_SUCCESS
217  *  Failure: An LDAP error code.
218  *
219  * NOTES
220  *  Set value to compare strings or data to compare binary values. If
221  *  both are non-NULL, data will be used. The serverctrls and clientctrls
222  *  parameters are optional and should be set to NULL if not used.
223  */
224 ULONG CDECL ldap_compare_extW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value,
225     struct WLDAP32_berval *data, PLDAPControlW *serverctrls, PLDAPControlW *clientctrls,
226     ULONG *message )
227 {
228     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
229 #ifdef HAVE_LDAP
230     char *dnU = NULL, *attrU = NULL, *valueU = NULL;
231     LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
232     struct berval val = { 0, NULL };
233
234     ret = WLDAP32_LDAP_NO_MEMORY;
235
236     TRACE( "(%p, %s, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
237            debugstr_w(attr), debugstr_w(value), data, serverctrls,
238            clientctrls, message );
239
240     if (!ld || !message) return WLDAP32_LDAP_PARAM_ERROR;
241     if (!attr) return WLDAP32_LDAP_NO_MEMORY;
242
243     if (dn) {
244         dnU = strWtoU( dn );
245         if (!dnU) goto exit;
246     }
247
248     attrU = strWtoU( attr );
249     if (!attrU) goto exit;
250
251     if (!data) {
252         if (value) {
253             valueU = strWtoU( value );
254             if (!valueU) goto exit;
255
256             val.bv_len = strlen( valueU );
257             val.bv_val = valueU;
258         }
259     }
260     if (serverctrls) {
261         serverctrlsU = controlarrayWtoU( serverctrls );
262         if (!serverctrlsU) goto exit;
263     }
264     if (clientctrls) {
265         clientctrlsU = controlarrayWtoU( clientctrls );
266         if (!clientctrlsU) goto exit;
267     }
268
269     ret = map_error( ldap_compare_ext( ld, dn ? dnU : "", attrU, data ? (struct berval *)data : &val,
270                                        serverctrlsU, clientctrlsU, (int *)message ));
271
272 exit:
273     strfreeU( dnU );
274     strfreeU( attrU );
275     strfreeU( valueU );
276     controlarrayfreeU( serverctrlsU );
277     controlarrayfreeU( clientctrlsU );
278
279 #endif
280     return ret;
281 }
282
283 /***********************************************************************
284  *      ldap_compare_ext_sA     (WLDAP32.@)
285  *
286  * See ldap_compare_ext_sW.
287  */
288 ULONG CDECL ldap_compare_ext_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value,
289     struct WLDAP32_berval *data, PLDAPControlA *serverctrls, PLDAPControlA *clientctrls )
290 {
291     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
292 #ifdef HAVE_LDAP
293     WCHAR *dnW = NULL, *attrW = NULL, *valueW = NULL;
294     LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
295
296     ret = WLDAP32_LDAP_NO_MEMORY;
297
298     TRACE( "(%p, %s, %s, %s, %p, %p, %p)\n", ld, debugstr_a(dn),
299            debugstr_a(attr), debugstr_a(value), data, serverctrls,
300            clientctrls );
301
302     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
303
304     if (dn) {
305         dnW = strAtoW( dn );
306         if (!dnW) goto exit;
307     }
308     if (attr) {
309         attrW = strAtoW( attr );
310         if (!attrW) goto exit;
311     }
312     if (value) {
313         valueW = strAtoW( value );
314         if (!valueW) goto exit;
315     }
316     if (serverctrls) {
317         serverctrlsW = controlarrayAtoW( serverctrls );
318         if (!serverctrlsW) goto exit;
319     }
320     if (clientctrls) {
321         clientctrlsW = controlarrayAtoW( clientctrls );
322         if (!clientctrlsW) goto exit;
323     }
324
325     ret = ldap_compare_ext_sW( ld, dnW, attrW, valueW, data, serverctrlsW,
326                                clientctrlsW );
327
328 exit:
329     strfreeW( dnW );
330     strfreeW( attrW );
331     strfreeW( valueW );
332     controlarrayfreeW( serverctrlsW );
333     controlarrayfreeW( clientctrlsW );
334
335 #endif
336     return ret;
337 }
338
339 /***********************************************************************
340  *      ldap_compare_ext_sW     (WLDAP32.@)
341  *
342  * Check if an attribute has a certain value (synchronous operation).
343  *
344  * PARAMS
345  *  ld          [I] Pointer to an LDAP context.
346  *  dn          [I] DN of entry to compare value for.
347  *  attr        [I] Attribute to compare value for.
348  *  value       [I] string encoded value to compare.
349  *  data        [I] berval encoded value to compare.
350  *  serverctrls [I] Array of LDAP server controls.
351  *  clientctrls [I] Array of LDAP client controls.
352  *
353  * RETURNS
354  *  Success: LDAP_SUCCESS
355  *  Failure: An LDAP error code.
356  *
357  * NOTES
358  *  Set value to compare strings or data to compare binary values. If
359  *  both are non-NULL, data will be used. The serverctrls and clientctrls
360  *  parameters are optional and should be set to NULL if not used.
361  */
362 ULONG CDECL ldap_compare_ext_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value,
363     struct WLDAP32_berval *data, PLDAPControlW *serverctrls, PLDAPControlW *clientctrls )
364 {
365     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
366 #ifdef HAVE_LDAP
367     char *dnU = NULL, *attrU = NULL, *valueU = NULL;
368     LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
369     struct berval val = { 0, NULL };
370
371     ret = WLDAP32_LDAP_NO_MEMORY;
372
373     TRACE( "(%p, %s, %s, %s, %p, %p, %p)\n", ld, debugstr_w(dn),
374            debugstr_w(attr), debugstr_w(value), data, serverctrls,
375            clientctrls );
376
377     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
378
379     if (dn) {
380         dnU = strWtoU( dn );
381         if (!dnU) goto exit;
382     }
383     if (attr) {
384         attrU = strWtoU( attr );
385         if (!attrU) goto exit;
386     }
387     if (!data) {
388         if (value) {
389             valueU = strWtoU( value );
390             if (!valueU) goto exit;
391
392             val.bv_len = strlen( valueU );
393             val.bv_val = valueU;
394         }
395     }
396     if (serverctrls) {
397         serverctrlsU = controlarrayWtoU( serverctrls );
398         if (!serverctrlsU) goto exit;
399     }
400     if (clientctrls) {
401         clientctrlsU = controlarrayWtoU( clientctrls );
402         if (!clientctrlsU) goto exit;
403     }
404
405     ret = map_error( ldap_compare_ext_s( ld, dn ? dnU : "", attr ? attrU : "",
406                                          data ? (struct berval *)data : &val,
407                                          serverctrlsU, clientctrlsU ));
408
409 exit:
410     strfreeU( dnU );
411     strfreeU( attrU );
412     strfreeU( valueU );
413     controlarrayfreeU( serverctrlsU );
414     controlarrayfreeU( clientctrlsU );
415
416 #endif
417     return ret;
418 }
419
420 /***********************************************************************
421  *      ldap_compare_sA     (WLDAP32.@)
422  *
423  * See ldap_compare_sW.
424  */
425 ULONG CDECL ldap_compare_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR attr, PCHAR value )
426 {
427     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
428 #ifdef HAVE_LDAP
429     WCHAR *dnW = NULL, *attrW = NULL, *valueW = NULL;
430
431     ret = WLDAP32_LDAP_NO_MEMORY;
432
433     TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_a(dn), debugstr_a(attr),
434            debugstr_a(value) );
435
436     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
437
438     if (dn) {
439         dnW = strAtoW( dn );
440         if (!dnW) goto exit;
441     }
442     if (attr) {
443         attrW = strAtoW( attr );
444         if (!attrW) goto exit;
445     }
446     if (value) {
447         valueW = strAtoW( value );
448         if (!valueW) goto exit;
449     }
450
451     ret = ldap_compare_sW( ld, dnW, attrW, valueW );
452
453 exit:
454     strfreeW( dnW );
455     strfreeW( attrW );
456     strfreeW( valueW );
457
458 #endif
459     return ret;
460 }
461
462 /***********************************************************************
463  *      ldap_compare_sW     (WLDAP32.@)
464  *
465  * Check if an attribute has a certain value (synchronous operation).
466  *
467  * PARAMS
468  *  ld      [I] Pointer to an LDAP context.
469  *  dn      [I] DN of entry to compare value for.
470  *  attr    [I] Attribute to compare value for.
471  *  value   [I] Value to compare.
472  *
473  * RETURNS
474  *  Success: LDAP_SUCCESS
475  *  Failure: An LDAP error code.
476  */
477 ULONG CDECL ldap_compare_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR attr, PWCHAR value )
478 {
479     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
480 #ifdef HAVE_LDAP
481     char *dnU = NULL, *attrU = NULL, *valueU = NULL;
482     struct berval val = { 0, NULL };
483
484     ret = WLDAP32_LDAP_NO_MEMORY;
485
486     TRACE( "(%p, %s, %s, %s)\n", ld, debugstr_w(dn), debugstr_w(attr),
487            debugstr_w(value) );
488
489     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
490
491     if (dn) {
492         dnU = strWtoU( dn );
493         if (!dnU) goto exit;
494     }
495     if (attr) {
496         attrU = strWtoU( attr );
497         if (!attrU) goto exit;
498     }
499     if (value) {
500         valueU = strWtoU( value );
501         if (!valueU) goto exit;
502
503         val.bv_len = strlen( valueU );
504         val.bv_val = valueU;
505     }
506
507     ret = map_error( ldap_compare_ext_s( ld, dn ? dnU : "", attr ? attrU : "", &val, NULL, NULL ));
508
509 exit:
510     strfreeU( dnU );
511     strfreeU( attrU );
512     strfreeU( valueU );
513
514 #endif
515     return ret;
516 }