2 * WLDAP32 - LDAP support for Wine
4 * Copyright 2005 Hans Leidekker
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.
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.
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
22 #include "wine/port.h"
33 #include "winldap_private.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(wldap32
);
39 /***********************************************************************
40 * ldap_parse_extended_resultA (WLDAP32.@)
42 * See ldap_parse_extended_resultW.
44 ULONG CDECL
ldap_parse_extended_resultA( WLDAP32_LDAP
*ld
, WLDAP32_LDAPMessage
*result
,
45 PCHAR
*oid
, struct WLDAP32_berval
**data
, BOOLEAN free
)
47 ULONG ret
= WLDAP32_LDAP_NOT_SUPPORTED
;
51 TRACE( "(%p, %p, %p, %p, 0x%02x)\n", ld
, result
, oid
, data
, free
);
53 if (!ld
) return WLDAP32_LDAP_PARAM_ERROR
;
54 if (!result
) return WLDAP32_LDAP_NO_RESULTS_RETURNED
;
56 ret
= ldap_parse_extended_resultW( ld
, result
, &oidW
, data
, free
);
59 *oid
= strWtoA( oidW
);
60 if (!*oid
) ret
= WLDAP32_LDAP_NO_MEMORY
;
61 ldap_memfreeW( oidW
);
68 /***********************************************************************
69 * ldap_parse_extended_resultW (WLDAP32.@)
71 * Parse the result of an extended operation.
74 * ld [I] Pointer to an LDAP context.
75 * result [I] Result message from an extended operation.
76 * oid [O] OID of the extended operation.
77 * data [O] Result data.
78 * free [I] Free the result message?
81 * Success: LDAP_SUCCESS
82 * Failure: An LDAP error code.
85 * Free the OID and result data with ldap_memfree. Pass a nonzero
86 * value for 'free' or call ldap_msgfree to free the result message.
88 ULONG CDECL
ldap_parse_extended_resultW( WLDAP32_LDAP
*ld
, WLDAP32_LDAPMessage
*result
,
89 PWCHAR
*oid
, struct WLDAP32_berval
**data
, BOOLEAN free
)
91 ULONG ret
= WLDAP32_LDAP_NOT_SUPPORTED
;
95 TRACE( "(%p, %p, %p, %p, 0x%02x)\n", ld
, result
, oid
, data
, free
);
97 if (!ld
) return WLDAP32_LDAP_PARAM_ERROR
;
98 if (!result
) return WLDAP32_LDAP_NO_RESULTS_RETURNED
;
100 ret
= map_error( ldap_parse_extended_result( ld
, result
, &oidU
, (struct berval
**)data
, free
) );
103 *oid
= strUtoW( oidU
);
104 if (!*oid
) ret
= WLDAP32_LDAP_NO_MEMORY
;
105 ldap_memfree( oidU
);
112 /***********************************************************************
113 * ldap_parse_referenceA (WLDAP32.@)
115 * See ldap_parse_referenceW.
117 ULONG CDECL
ldap_parse_referenceA( WLDAP32_LDAP
*ld
, WLDAP32_LDAPMessage
*message
,
120 ULONG ret
= WLDAP32_LDAP_NOT_SUPPORTED
;
122 WCHAR
**referralsW
= NULL
;
124 TRACE( "(%p, %p, %p)\n", ld
, message
, referrals
);
128 ret
= ldap_parse_referenceW( ld
, message
, &referralsW
);
130 *referrals
= strarrayWtoA( referralsW
);
131 ldap_value_freeW( referralsW
);
137 /***********************************************************************
138 * ldap_parse_referenceW (WLDAP32.@)
140 * Return any referrals from a result message.
143 * ld [I] Pointer to an LDAP context.
144 * result [I] Result message.
145 * referrals [O] Array of referral URLs.
148 * Success: LDAP_SUCCESS
149 * Failure: An LDAP error code.
152 * Free the referrals with ldap_value_free.
154 ULONG CDECL
ldap_parse_referenceW( WLDAP32_LDAP
*ld
, WLDAP32_LDAPMessage
*message
,
157 ULONG ret
= WLDAP32_LDAP_NOT_SUPPORTED
;
158 #ifdef HAVE_LDAP_PARSE_REFERENCE
159 char **referralsU
= NULL
;
161 TRACE( "(%p, %p, %p)\n", ld
, message
, referrals
);
165 ret
= map_error( ldap_parse_reference( ld
, message
, &referralsU
, NULL
, 0 ));
167 *referrals
= strarrayUtoW( referralsU
);
168 ldap_memfree( referralsU
);
174 /***********************************************************************
175 * ldap_parse_resultA (WLDAP32.@)
177 * See ldap_parse_resultW.
179 ULONG CDECL
ldap_parse_resultA( WLDAP32_LDAP
*ld
, WLDAP32_LDAPMessage
*result
,
180 ULONG
*retcode
, PCHAR
*matched
, PCHAR
*error
, PCHAR
**referrals
,
181 PLDAPControlA
**serverctrls
, BOOLEAN free
)
183 ULONG ret
= WLDAP32_LDAP_NOT_SUPPORTED
;
185 WCHAR
*matchedW
= NULL
, *errorW
= NULL
, **referralsW
= NULL
;
186 LDAPControlW
**serverctrlsW
= NULL
;
188 TRACE( "(%p, %p, %p, %p, %p, %p, %p, 0x%02x)\n", ld
, result
, retcode
,
189 matched
, error
, referrals
, serverctrls
, free
);
191 if (!ld
) return WLDAP32_LDAP_PARAM_ERROR
;
193 ret
= ldap_parse_resultW( ld
, result
, retcode
, &matchedW
, &errorW
,
194 &referralsW
, &serverctrlsW
, free
);
196 if (matched
) *matched
= strWtoA( matchedW
);
197 if (error
) *error
= strWtoA( errorW
);
199 if (referrals
) *referrals
= strarrayWtoA( referralsW
);
200 if (serverctrls
) *serverctrls
= controlarrayWtoA( serverctrlsW
);
202 ldap_memfreeW( matchedW
);
203 ldap_memfreeW( errorW
);
204 ldap_value_freeW( referralsW
);
205 ldap_controls_freeW( serverctrlsW
);
211 /***********************************************************************
212 * ldap_parse_resultW (WLDAP32.@)
214 * Parse a result message.
217 * ld [I] Pointer to an LDAP context.
218 * result [I] Result message.
219 * retcode [O] Return code for the server operation.
220 * matched [O] DNs matched in the operation.
221 * error [O] Error message for the operation.
222 * referrals [O] Referrals found in the result message.
223 * serverctrls [O] Controls used in the operation.
224 * free [I] Free the result message?
227 * Success: LDAP_SUCCESS
228 * Failure: An LDAP error code.
231 * Free the DNs and error message with ldap_memfree. Free
232 * the referrals with ldap_value_free and the controls with
233 * ldap_controls_free. Pass a nonzero value for 'free' or call
234 * ldap_msgfree to free the result message.
236 ULONG CDECL
ldap_parse_resultW( WLDAP32_LDAP
*ld
, WLDAP32_LDAPMessage
*result
,
237 ULONG
*retcode
, PWCHAR
*matched
, PWCHAR
*error
, PWCHAR
**referrals
,
238 PLDAPControlW
**serverctrls
, BOOLEAN free
)
240 ULONG ret
= WLDAP32_LDAP_NOT_SUPPORTED
;
242 char *matchedU
= NULL
, *errorU
= NULL
, **referralsU
= NULL
;
243 LDAPControl
**serverctrlsU
= NULL
;
245 TRACE( "(%p, %p, %p, %p, %p, %p, %p, 0x%02x)\n", ld
, result
, retcode
,
246 matched
, error
, referrals
, serverctrls
, free
);
248 if (!ld
) return WLDAP32_LDAP_PARAM_ERROR
;
250 ret
= map_error( ldap_parse_result( ld
, result
, (int *)retcode
, &matchedU
, &errorU
,
251 &referralsU
, &serverctrlsU
, free
));
253 if (matched
) *matched
= strUtoW( matchedU
);
254 if (error
) *error
= strUtoW( errorU
);
256 if (referrals
) *referrals
= strarrayUtoW( referralsU
);
257 if (serverctrls
) *serverctrls
= controlarrayUtoW( serverctrlsU
);
259 ldap_memfree( matchedU
);
260 ldap_memfree( errorU
);
261 strarrayfreeU( referralsU
);
262 ldap_controls_free( serverctrlsU
);
268 /***********************************************************************
269 * ldap_parse_sort_controlA (WLDAP32.@)
271 * See ldap_parse_sort_controlW.
273 ULONG CDECL
ldap_parse_sort_controlA( WLDAP32_LDAP
*ld
, PLDAPControlA
*control
,
274 ULONG
*result
, PCHAR
*attr
)
276 ULONG ret
= WLDAP32_LDAP_NOT_SUPPORTED
;
279 LDAPControlW
**controlW
= NULL
;
281 TRACE( "(%p, %p, %p, %p)\n", ld
, control
, result
, attr
);
283 if (!ld
) return WLDAP32_LDAP_PARAM_ERROR
;
284 if (!control
) return WLDAP32_LDAP_CONTROL_NOT_FOUND
;
286 controlW
= controlarrayAtoW( control
);
287 if (!controlW
) return WLDAP32_LDAP_NO_MEMORY
;
289 ret
= ldap_parse_sort_controlW( ld
, controlW
, result
, &attrW
);
291 *attr
= strWtoA( attrW
);
292 controlarrayfreeW( controlW
);
298 /***********************************************************************
299 * ldap_parse_sort_controlW (WLDAP32.@)
301 * Parse a sort control.
304 * ld [I] Pointer to an LDAP context.
305 * control [I] Control obtained from a result message.
306 * result [O] Result code.
307 * attr [O] Failing attribute.
310 * Success: LDAP_SUCCESS
311 * Failure: An LDAP error code.
314 * If the function fails, free the failing attribute with ldap_memfree.
316 ULONG CDECL
ldap_parse_sort_controlW( WLDAP32_LDAP
*ld
, PLDAPControlW
*control
,
317 ULONG
*result
, PWCHAR
*attr
)
319 ULONG ret
= WLDAP32_LDAP_NOT_SUPPORTED
;
322 LDAPControl
**controlU
= NULL
;
323 #ifdef HAVE_LDAP_PARSE_SORT_CONTROL
325 #elif defined(HAVE_LDAP_PARSE_SORTRESPONSE_CONTROL)
327 LDAPControl
*sortcontrol
= NULL
;
331 TRACE( "(%p, %p, %p, %p)\n", ld
, control
, result
, attr
);
333 if (!ld
) return WLDAP32_LDAP_PARAM_ERROR
;
334 if (!control
) return WLDAP32_LDAP_CONTROL_NOT_FOUND
;
336 controlU
= controlarrayWtoU( control
);
337 if (!controlU
) return WLDAP32_LDAP_NO_MEMORY
;
339 #ifdef HAVE_LDAP_PARSE_SORT_CONTROL
340 if (!(ret
= ldap_parse_sort_control( ld
, controlU
, &res
, &attrU
)))
343 *attr
= strUtoW( attrU
);
345 #elif defined(HAVE_LDAP_PARSE_SORTRESPONSE_CONTROL)
346 for (i
= 0; controlU
[i
]; i
++)
348 if (!strcmp( LDAP_SERVER_RESP_SORT_OID
, controlU
[i
]->ldctl_oid
))
349 sortcontrol
= controlU
[i
];
353 controlarrayfreeU( controlU
);
354 return WLDAP32_LDAP_CONTROL_NOT_FOUND
;
356 if (!(ret
= ldap_parse_sortresponse_control( ld
, sortcontrol
, &res
, &attrU
)))
359 *attr
= strUtoW( attrU
);
362 controlarrayfreeU( controlU
);
365 return map_error( ret
);
368 /***********************************************************************
369 * ldap_parse_vlv_controlA (WLDAP32.@)
371 * See ldap_parse_vlv_controlW.
373 INT CDECL
ldap_parse_vlv_controlA( WLDAP32_LDAP
*ld
, PLDAPControlA
*control
,
374 PULONG targetpos
, PULONG listcount
,
375 struct WLDAP32_berval
**context
, PINT errcode
)
377 int ret
= WLDAP32_LDAP_NOT_SUPPORTED
;
379 LDAPControlW
**controlW
= NULL
;
381 TRACE( "(%p, %p, %p, %p, %p, %p)\n", ld
, control
, targetpos
,
382 listcount
, context
, errcode
);
387 controlW
= controlarrayAtoW( control
);
388 if (!controlW
) return WLDAP32_LDAP_NO_MEMORY
;
391 ret
= ldap_parse_vlv_controlW( ld
, controlW
, targetpos
, listcount
,
394 controlarrayfreeW( controlW
);
400 /***********************************************************************
401 * ldap_parse_vlv_controlW (WLDAP32.@)
403 * Parse a virtual list view control.
406 * ld [I] Pointer to an LDAP context.
407 * control [I] Controls obtained from a result message.
408 * targetpos [O] Position of the target in the result list.
409 * listcount [O] Estimate of the number of results in the list.
410 * context [O] Server side context.
411 * errcode [O] Error code from the listview operation.
414 * Success: LDAP_SUCCESS
415 * Failure: An LDAP error code.
418 * Free the server context with ber_bvfree.
420 INT CDECL
ldap_parse_vlv_controlW( WLDAP32_LDAP
*ld
, PLDAPControlW
*control
,
421 PULONG targetpos
, PULONG listcount
,
422 struct WLDAP32_berval
**context
, PINT errcode
)
424 int ret
= WLDAP32_LDAP_NOT_SUPPORTED
;
426 LDAPControl
**controlU
= NULL
;
427 #ifdef HAVE_LDAP_PARSE_VLV_CONTROL
428 unsigned long pos
, count
;
429 #elif defined(HAVE_LDAP_PARSE_VLVRESPONSE_CONTROL)
430 ber_int_t pos
, count
;
431 LDAPControl
*vlvcontrol
= NULL
;
435 TRACE( "(%p, %p, %p, %p, %p, %p)\n", ld
, control
, targetpos
,
436 listcount
, context
, errcode
);
438 if (!ld
|| !control
) return ~0u;
440 controlU
= controlarrayWtoU( control
);
441 if (!controlU
) return WLDAP32_LDAP_NO_MEMORY
;
443 #ifdef HAVE_LDAP_PARSE_VLV_CONTROL
444 if (!(ret
= ldap_parse_vlv_control( ld
, controlU
, &pos
, &count
,
450 #elif defined(HAVE_LDAP_PARSE_VLVRESPONSE_CONTROL)
451 for (i
= 0; controlU
[i
]; i
++)
453 if (!strcmp( LDAP_CONTROL_VLVRESPONSE
, controlU
[i
]->ldctl_oid
))
454 vlvcontrol
= controlU
[i
];
458 controlarrayfreeU( controlU
);
459 return WLDAP32_LDAP_CONTROL_NOT_FOUND
;
461 if (!(ret
= ldap_parse_vlvresponse_control( ld
, vlvcontrol
, &pos
, &count
,
462 (struct berval
**)context
, errcode
)))
468 controlarrayfreeU( controlU
);
471 return map_error( ret
);