Sync with trunk r63192.
[reactos.git] / dll / win32 / 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 "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 }