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