msi: Move the file sequence check out of ready_media_info to avoid an unnecessary...
[wine] / dlls / wldap32 / parse.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_NOT_SUPPORTED  0x5c
36 #endif
37
38 #include "winldap_private.h"
39 #include "wldap32.h"
40
41 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
42
43 /***********************************************************************
44  *      ldap_parse_extended_resultA     (WLDAP32.@)
45  *
46  * See ldap_parse_extended_resultW.
47  */
48 ULONG CDECL ldap_parse_extended_resultA( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *result,
49     PCHAR *oid, struct WLDAP32_berval **data, BOOLEAN free )
50 {
51     ULONG ret = LDAP_NOT_SUPPORTED;
52 #ifdef HAVE_LDAP
53     WCHAR *oidW = NULL;
54
55     TRACE( "(%p, %p, %p, %p, 0x%02x)\n", ld, result, oid, data, free );
56
57     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
58     if (!result) return WLDAP32_LDAP_NO_RESULTS_RETURNED;
59
60     ret = ldap_parse_extended_resultW( ld, result, &oidW, data, free );
61
62     if (oid) {
63         *oid = strWtoA( oidW );
64         if (!*oid) ret = WLDAP32_LDAP_NO_MEMORY;
65         ldap_memfreeW( oidW );
66     }
67
68 #endif
69     return ret;
70 }
71
72 /***********************************************************************
73  *      ldap_parse_extended_resultW     (WLDAP32.@)
74  *
75  * Parse the result of an extended operation. 
76  *
77  * PARAMS
78  *  ld      [I] Pointer to an LDAP context.
79  *  result  [I] Result message from an extended operation.
80  *  oid     [O] OID of the extended operation.
81  *  data    [O] Result data.
82  *  free    [I] Free the result message?
83  *
84  * RETURNS
85  *  Success: LDAP_SUCCESS
86  *  Failure: An LDAP error code.
87  *
88  * NOTES
89  *  Free the OID and result data with ldap_memfree. Pass a nonzero
90  *  value for 'free' or call ldap_msgfree to free the result message.
91  */
92 ULONG CDECL ldap_parse_extended_resultW( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *result,
93     PWCHAR *oid, struct WLDAP32_berval **data, BOOLEAN free )
94 {
95     ULONG ret = LDAP_NOT_SUPPORTED;
96 #ifdef HAVE_LDAP
97     char *oidU = NULL;
98
99     TRACE( "(%p, %p, %p, %p, 0x%02x)\n", ld, result, oid, data, free );
100
101     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
102     if (!result) return WLDAP32_LDAP_NO_RESULTS_RETURNED;
103
104     ret = ldap_parse_extended_result( ld, result, &oidU, (struct berval **)data, free );
105
106     if (oid) {
107         *oid = strUtoW( oidU );
108         if (!*oid) ret = WLDAP32_LDAP_NO_MEMORY;
109         ldap_memfree( oidU );
110     }
111
112 #endif
113     return ret;
114 }
115
116 /***********************************************************************
117  *      ldap_parse_referenceA     (WLDAP32.@)
118  *
119  * See ldap_parse_referenceW.
120  */
121 ULONG CDECL ldap_parse_referenceA( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *message,
122     PCHAR **referrals )
123 {
124     ULONG ret = LDAP_NOT_SUPPORTED;
125 #ifdef HAVE_LDAP
126     WCHAR **referralsW = NULL;
127
128     TRACE( "(%p, %p, %p)\n", ld, message, referrals );
129
130     if (!ld) return ~0UL;
131
132     ret = ldap_parse_referenceW( ld, message, &referralsW );
133
134     *referrals = strarrayWtoA( referralsW );
135     ldap_value_freeW( referralsW );
136
137 #endif 
138     return ret;
139 }
140
141 /***********************************************************************
142  *      ldap_parse_referenceW     (WLDAP32.@)
143  *
144  * Return any referrals from a result message.
145  *
146  * PARAMS
147  *  ld         [I] Pointer to an LDAP context.
148  *  result     [I] Result message.
149  *  referrals  [O] Array of referral URLs.
150  *
151  * RETURNS
152  *  Success: LDAP_SUCCESS
153  *  Failure: An LDAP error code.
154  *
155  * NOTES
156  *  Free the referrals with ldap_value_free.
157  */
158 ULONG CDECL ldap_parse_referenceW( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *message,
159     PWCHAR **referrals )
160 {
161     ULONG ret = LDAP_NOT_SUPPORTED;
162 #ifdef HAVE_LDAP_PARSE_REFERENCE
163     char **referralsU = NULL;
164
165     TRACE( "(%p, %p, %p)\n", ld, message, referrals );
166
167     if (!ld) return ~0UL;
168     
169     ret = ldap_parse_reference( ld, message, &referralsU, NULL, 0 );
170
171     *referrals = strarrayUtoW( referralsU );
172     ldap_memfree( referralsU );
173
174 #endif
175     return ret;
176 }
177
178 /***********************************************************************
179  *      ldap_parse_resultA     (WLDAP32.@)
180  *
181  * See ldap_parse_resultW.
182  */
183 ULONG CDECL ldap_parse_resultA( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *result,
184     ULONG *retcode, PCHAR *matched, PCHAR *error, PCHAR **referrals,
185     PLDAPControlA **serverctrls, BOOLEAN free )
186 {
187     ULONG ret = LDAP_NOT_SUPPORTED;
188 #ifdef HAVE_LDAP
189     WCHAR **matchedW = NULL, **errorW = NULL, **referralsW = NULL;
190     LDAPControlW **serverctrlsW = NULL;
191
192     TRACE( "(%p, %p, %p, %p, %p, %p, %p, 0x%02x)\n", ld, result, retcode,
193            matched, error, referrals, serverctrls, free );
194
195     if (!ld) return ~0UL;
196
197     ret = ldap_parse_resultW( ld, result, retcode, matchedW, errorW,
198                               &referralsW, &serverctrlsW, free );
199
200     matched = strarrayWtoA( matchedW );
201     error = strarrayWtoA( errorW );
202
203     *referrals = strarrayWtoA( referralsW );
204     *serverctrls = controlarrayWtoA( serverctrlsW );
205
206     ldap_value_freeW( matchedW );
207     ldap_value_freeW( errorW );
208     ldap_value_freeW( referralsW );
209     ldap_controls_freeW( serverctrlsW );
210
211 #endif
212     return ret;
213 }
214
215 /***********************************************************************
216  *      ldap_parse_resultW     (WLDAP32.@)
217  *
218  * Parse a result message. 
219  *
220  * PARAMS
221  *  ld           [I] Pointer to an LDAP context.
222  *  result       [I] Result message.
223  *  retcode      [O] Return code for the server operation.
224  *  matched      [O] DNs matched in the operation.
225  *  error        [O] Error message for the operation.
226  *  referrals    [O] Referrals found in the result message.
227  *  serverctrls  [O] Controls used in the operation.
228  *  free         [I] Free the result message?
229  *
230  * RETURNS
231  *  Success: LDAP_SUCCESS
232  *  Failure: An LDAP error code.
233  *
234  * NOTES
235  *  Free the DNs and error message with ldap_memfree. Free
236  *  the referrals with ldap_value_free and the controls with
237  *  ldap_controls_free. Pass a nonzero value for 'free' or call
238  *  ldap_msgfree to free the result message.
239  */
240 ULONG CDECL ldap_parse_resultW( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *result,
241     ULONG *retcode, PWCHAR *matched, PWCHAR *error, PWCHAR **referrals,
242     PLDAPControlW **serverctrls, BOOLEAN free )
243 {
244     ULONG ret = LDAP_NOT_SUPPORTED;
245 #ifdef HAVE_LDAP
246     char **matchedU = NULL, **errorU = NULL, **referralsU = NULL;
247     LDAPControl **serverctrlsU = NULL;
248
249     TRACE( "(%p, %p, %p, %p, %p, %p, %p, 0x%02x)\n", ld, result, retcode,
250            matched, error, referrals, serverctrls, free );
251
252     if (!ld) return ~0UL;
253
254     ret = ldap_parse_result( ld, result, (int *)retcode, matchedU, errorU,
255                              &referralsU, &serverctrlsU, free );
256
257     matched = strarrayUtoW( matchedU );
258     error = strarrayUtoW( errorU );
259
260     *referrals = strarrayUtoW( referralsU );
261     *serverctrls = controlarrayUtoW( serverctrlsU );
262
263     ldap_memfree( matchedU );
264     ldap_memfree( errorU );
265     ldap_memfree( referralsU );
266     ldap_controls_free( serverctrlsU );
267
268 #endif
269     return ret;
270 }
271
272 /***********************************************************************
273  *      ldap_parse_sort_controlA     (WLDAP32.@)
274  *
275  * See ldap_parse_sort_controlW.
276  */
277 ULONG CDECL ldap_parse_sort_controlA( WLDAP32_LDAP *ld, PLDAPControlA *control,
278     ULONG *result, PCHAR *attr )
279 {
280     ULONG ret = LDAP_NOT_SUPPORTED;
281 #ifdef HAVE_LDAP
282     WCHAR *attrW = NULL;
283     LDAPControlW **controlW = NULL;
284
285     TRACE( "(%p, %p, %p, %p)\n", ld, control, result, attr );
286
287     if (!ld) return ~0UL;
288
289     if (control) {
290         controlW = controlarrayAtoW( control );
291         if (!controlW) return WLDAP32_LDAP_NO_MEMORY;
292     }
293
294     ret = ldap_parse_sort_controlW( ld, controlW, result, &attrW );
295
296     *attr = strWtoA( attrW );
297     controlarrayfreeW( controlW );
298
299 #endif
300     return ret;
301 }
302
303 /***********************************************************************
304  *      ldap_parse_sort_controlW     (WLDAP32.@)
305  *
306  * Parse a sort control.
307  *
308  * PARAMS
309  *  ld       [I] Pointer to an LDAP context.
310  *  control  [I] Control obtained from a result message.
311  *  result   [O] Result code.
312  *  attr     [O] Failing attribute.
313  *
314  * RETURNS
315  *  Success: LDAP_SUCCESS
316  *  Failure: An LDAP error code.
317  *
318  * NOTES
319  *  If the function fails, free the failing attribute with ldap_memfree.
320  */
321 ULONG CDECL ldap_parse_sort_controlW( WLDAP32_LDAP *ld, PLDAPControlW *control,
322     ULONG *result, PWCHAR *attr )
323 {
324     ULONG ret = LDAP_NOT_SUPPORTED;
325 #ifdef HAVE_LDAP
326     char *attrU = NULL;
327     LDAPControl **controlU = NULL;
328     unsigned long res;
329
330     TRACE( "(%p, %p, %p, %p)\n", ld, control, result, attr );
331
332     if (!ld) return ~0UL;
333
334     if (control) {
335         controlU = controlarrayWtoU( control );
336         if (!controlU) return WLDAP32_LDAP_NO_MEMORY;
337     }
338
339     ret = ldap_parse_sort_control( ld, controlU, &res, &attrU );
340
341     *result = res;
342     *attr = strUtoW( attrU );
343     controlarrayfreeU( controlU );
344
345 #endif
346     return ret;
347 }
348
349 /***********************************************************************
350  *      ldap_parse_vlv_controlA     (WLDAP32.@)
351  *
352  * See ldap_parse_vlv_controlW.
353  */
354 INT CDECL ldap_parse_vlv_controlA( WLDAP32_LDAP *ld, PLDAPControlA *control,
355     PULONG targetpos, PULONG listcount,
356     struct WLDAP32_berval **context, PINT errcode )
357 {
358     int ret = LDAP_NOT_SUPPORTED;
359 #ifdef HAVE_LDAP
360     LDAPControlW **controlW = NULL;
361
362     TRACE( "(%p, %p, %p, %p, %p, %p)\n", ld, control, targetpos,
363            listcount, context, errcode );
364
365     if (!ld) return ~0UL;
366
367     if (control) {
368         controlW = controlarrayAtoW( control );
369         if (!controlW) return WLDAP32_LDAP_NO_MEMORY;
370     }
371
372     ret = ldap_parse_vlv_controlW( ld, controlW, targetpos, listcount,
373                                    context, errcode );
374
375     controlarrayfreeW( controlW );
376
377 #endif
378     return ret;
379 }
380
381 /***********************************************************************
382  *      ldap_parse_vlv_controlW     (WLDAP32.@)
383  *
384  * Parse a virtual list view control.
385  *
386  * PARAMS
387  *  ld         [I] Pointer to an LDAP context.
388  *  control    [I] Controls obtained from a result message.
389  *  targetpos  [O] Positition of the target in the result list. 
390  *  listcount  [O] Estimate of the number of results in the list.
391  *  context    [O] Server side context.
392  *  errcode    [O] Error code from the listview operation.
393  *
394  * RETURNS
395  *  Success: LDAP_SUCCESS
396  *  Failure: An LDAP error code.
397  *
398  * NOTES
399  *  Free the server context with ber_bvfree.
400  */
401 INT CDECL ldap_parse_vlv_controlW( WLDAP32_LDAP *ld, PLDAPControlW *control,
402     PULONG targetpos, PULONG listcount,
403     struct WLDAP32_berval **context, PINT errcode )
404 {
405     int ret = LDAP_NOT_SUPPORTED;
406 #ifdef HAVE_LDAP
407     LDAPControl **controlU = NULL;
408     unsigned long pos, count;
409
410     TRACE( "(%p, %p, %p, %p, %p, %p)\n", ld, control, targetpos,
411            listcount, context, errcode );
412
413     if (!ld) return ~0UL;
414
415     if (control) {
416         controlU = controlarrayWtoU( control );
417         if (!controlU) return WLDAP32_LDAP_NO_MEMORY;
418     }
419
420     ret = ldap_parse_vlv_control( ld, controlU, &pos, &count,
421                                   (struct berval **)context, errcode );
422
423     *targetpos = pos;
424     *listcount = count;
425     controlarrayfreeU( controlU );
426
427 #endif
428     return ret;
429 }