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_control_freeA (WLDAP32.@)
41 *
42 * See ldap_control_freeW.
43 */
ldap_control_freeA(LDAPControlA * control)44 ULONG CDECL ldap_control_freeA( LDAPControlA *control )
45 {
46 ULONG ret = WLDAP32_LDAP_SUCCESS;
47 #ifdef HAVE_LDAP
48
49 TRACE( "(%p)\n", control );
50 controlfreeA( control );
51
52 #endif
53 return ret;
54 }
55
56 /***********************************************************************
57 * ldap_control_freeW (WLDAP32.@)
58 *
59 * Free an LDAPControl structure.
60 *
61 * PARAMS
62 * control [I] LDAPControl structure to free.
63 *
64 * RETURNS
65 * LDAP_SUCCESS
66 */
ldap_control_freeW(LDAPControlW * control)67 ULONG CDECL ldap_control_freeW( LDAPControlW *control )
68 {
69 ULONG ret = WLDAP32_LDAP_SUCCESS;
70 #ifdef HAVE_LDAP
71
72 TRACE( "(%p)\n", control );
73 controlfreeW( control );
74
75 #endif
76 return ret;
77 }
78
79 /***********************************************************************
80 * ldap_controls_freeA (WLDAP32.@)
81 *
82 * See ldap_controls_freeW.
83 */
ldap_controls_freeA(LDAPControlA ** controls)84 ULONG CDECL ldap_controls_freeA( LDAPControlA **controls )
85 {
86 ULONG ret = WLDAP32_LDAP_SUCCESS;
87 #ifdef HAVE_LDAP
88
89 TRACE( "(%p)\n", controls );
90 controlarrayfreeA( controls );
91
92 #endif
93 return ret;
94 }
95
96 /***********************************************************************
97 * ldap_controls_freeW (WLDAP32.@)
98 *
99 * Free an array of LDAPControl structures.
100 *
101 * PARAMS
102 * controls [I] Array of LDAPControl structures to free.
103 *
104 * RETURNS
105 * LDAP_SUCCESS
106 */
ldap_controls_freeW(LDAPControlW ** controls)107 ULONG CDECL ldap_controls_freeW( LDAPControlW **controls )
108 {
109 ULONG ret = WLDAP32_LDAP_SUCCESS;
110 #ifdef HAVE_LDAP
111
112 TRACE( "(%p)\n", controls );
113 controlarrayfreeW( controls );
114
115 #endif
116 return ret;
117 }
118
119 /***********************************************************************
120 * ldap_create_sort_controlA (WLDAP32.@)
121 *
122 * See ldap_create_sort_controlW.
123 */
ldap_create_sort_controlA(WLDAP32_LDAP * ld,PLDAPSortKeyA * sortkey,UCHAR critical,PLDAPControlA * control)124 ULONG CDECL ldap_create_sort_controlA( WLDAP32_LDAP *ld, PLDAPSortKeyA *sortkey,
125 UCHAR critical, PLDAPControlA *control )
126 {
127 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
128 #ifdef HAVE_LDAP
129 LDAPSortKeyW **sortkeyW = NULL;
130 LDAPControlW *controlW = NULL;
131
132 TRACE( "(%p, %p, 0x%02x, %p)\n", ld, sortkey, critical, control );
133
134 if (!ld || !sortkey || !control)
135 return WLDAP32_LDAP_PARAM_ERROR;
136
137 sortkeyW = sortkeyarrayAtoW( sortkey );
138 if (!sortkeyW) return WLDAP32_LDAP_NO_MEMORY;
139
140 ret = ldap_create_sort_controlW( ld, sortkeyW, critical, &controlW );
141
142 *control = controlWtoA( controlW );
143 if (!*control) ret = WLDAP32_LDAP_NO_MEMORY;
144
145 ldap_control_freeW( controlW );
146 sortkeyarrayfreeW( sortkeyW );
147
148 #endif
149 return ret;
150 }
151
152 /***********************************************************************
153 * ldap_create_sort_controlW (WLDAP32.@)
154 *
155 * Create a control for server sorted search results.
156 *
157 * PARAMS
158 * ld [I] Pointer to an LDAP context.
159 * sortkey [I] Array of LDAPSortKey structures, each specifying an
160 * attribute to use as a sort key, a matching rule and
161 * the sort order (ascending or descending).
162 * critical [I] Tells the server this control is critical to the
163 * search operation.
164 * control [O] LDAPControl created.
165 *
166 * RETURNS
167 * Success: LDAP_SUCCESS
168 * Failure: An LDAP error code.
169 *
170 * NOTES
171 * Pass the created control as a server control in subsequent calls
172 * to ldap_search_ext(_s) to obtain sorted search results.
173 */
ldap_create_sort_controlW(WLDAP32_LDAP * ld,PLDAPSortKeyW * sortkey,UCHAR critical,PLDAPControlW * control)174 ULONG CDECL ldap_create_sort_controlW( WLDAP32_LDAP *ld, PLDAPSortKeyW *sortkey,
175 UCHAR critical, PLDAPControlW *control )
176 {
177 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
178 #ifdef HAVE_LDAP
179 LDAPSortKey **sortkeyU = NULL;
180 LDAPControl *controlU = NULL;
181
182 TRACE( "(%p, %p, 0x%02x, %p)\n", ld, sortkey, critical, control );
183
184 if (!ld || !sortkey || !control)
185 return WLDAP32_LDAP_PARAM_ERROR;
186
187 sortkeyU = sortkeyarrayWtoU( sortkey );
188 if (!sortkeyU) return WLDAP32_LDAP_NO_MEMORY;
189
190 ret = map_error( ldap_create_sort_control( ld, sortkeyU, critical, &controlU ));
191
192 *control = controlUtoW( controlU );
193 if (!*control) ret = WLDAP32_LDAP_NO_MEMORY;
194
195 ldap_control_free( controlU );
196 sortkeyarrayfreeU( sortkeyU );
197
198 #endif
199 return ret;
200 }
201
202 /***********************************************************************
203 * ldap_create_vlv_controlA (WLDAP32.@)
204 *
205 * See ldap_create_vlv_controlW.
206 */
ldap_create_vlv_controlA(WLDAP32_LDAP * ld,WLDAP32_LDAPVLVInfo * info,UCHAR critical,LDAPControlA ** control)207 INT CDECL ldap_create_vlv_controlA( WLDAP32_LDAP *ld, WLDAP32_LDAPVLVInfo *info,
208 UCHAR critical, LDAPControlA **control )
209 {
210 INT ret = WLDAP32_LDAP_NOT_SUPPORTED;
211 #ifdef HAVE_LDAP
212 LDAPControlW *controlW = NULL;
213
214 TRACE( "(%p, %p, 0x%02x, %p)\n", ld, info, critical, control );
215
216 if (!ld || !control) return ~0u;
217
218 ret = ldap_create_vlv_controlW( ld, info, critical, &controlW );
219
220 if (ret == WLDAP32_LDAP_SUCCESS)
221 {
222 *control = controlWtoA( controlW );
223 if (!*control) ret = WLDAP32_LDAP_NO_MEMORY;
224 ldap_control_freeW( controlW );
225 }
226
227 #endif
228 return ret;
229 }
230
231 /***********************************************************************
232 * ldap_create_vlv_controlW (WLDAP32.@)
233 *
234 * Create a virtual list view control.
235 *
236 * PARAMS
237 * ld [I] Pointer to an LDAP context.
238 * info [I] LDAPVLVInfo structure specifying a list view window.
239 * critical [I] Tells the server this control is critical to the
240 * search operation.
241 * control [O] LDAPControl created.
242 *
243 * RETURNS
244 * Success: LDAP_SUCCESS
245 * Failure: An LDAP error code.
246 *
247 * NOTES
248 * Pass the created control in conjunction with a sort control as
249 * server controls in subsequent calls to ldap_search_ext(_s). The
250 * server will then return a sorted, contiguous subset of results
251 * that meets the criteria specified in the LDAPVLVInfo structure.
252 */
ldap_create_vlv_controlW(WLDAP32_LDAP * ld,WLDAP32_LDAPVLVInfo * info,UCHAR critical,LDAPControlW ** control)253 INT CDECL ldap_create_vlv_controlW( WLDAP32_LDAP *ld, WLDAP32_LDAPVLVInfo *info,
254 UCHAR critical, LDAPControlW **control )
255 {
256 INT ret = WLDAP32_LDAP_NOT_SUPPORTED;
257 #ifdef HAVE_LDAP
258 LDAPControl *controlU = NULL;
259
260 TRACE( "(%p, %p, 0x%02x, %p)\n", ld, info, critical, control );
261
262 if (!ld || !control) return ~0u;
263
264 ret = map_error( ldap_create_vlv_control( ld, (LDAPVLVInfo *)info, &controlU ));
265
266 if (ret == WLDAP32_LDAP_SUCCESS)
267 {
268 *control = controlUtoW( controlU );
269 if (!*control) ret = WLDAP32_LDAP_NO_MEMORY;
270 ldap_control_free( controlU );
271 }
272
273 #endif
274 return ret;
275 }
276
bv_val_dup(const struct WLDAP32_berval * src,struct WLDAP32_berval * dst)277 static inline void bv_val_dup( const struct WLDAP32_berval *src, struct WLDAP32_berval *dst )
278 {
279 if ((dst->bv_val = heap_alloc( src->bv_len )))
280 {
281 memcpy( dst->bv_val, src->bv_val, src->bv_len );
282 dst->bv_len = src->bv_len;
283 }
284 else
285 dst->bv_len = 0;
286 }
287
288 /***********************************************************************
289 * ldap_encode_sort_controlA (WLDAP32.@)
290 *
291 * See ldap_encode_sort_controlW.
292 */
ldap_encode_sort_controlA(WLDAP32_LDAP * ld,PLDAPSortKeyA * sortkeys,PLDAPControlA ret,BOOLEAN critical)293 ULONG CDECL ldap_encode_sort_controlA( WLDAP32_LDAP *ld, PLDAPSortKeyA *sortkeys,
294 PLDAPControlA ret, BOOLEAN critical )
295 {
296 LDAPControlA *control = NULL;
297 ULONG result;
298
299 if ((result = ldap_create_sort_controlA( ld, sortkeys, critical, &control )) == WLDAP32_LDAP_SUCCESS)
300 {
301 ret->ldctl_oid = strdupU(control->ldctl_oid);
302 bv_val_dup( &control->ldctl_value, &ret->ldctl_value );
303 ret->ldctl_iscritical = control->ldctl_iscritical;
304 ldap_control_freeA( control );
305 }
306 return result;
307 }
308
309 /***********************************************************************
310 * ldap_encode_sort_controlW (WLDAP32.@)
311 *
312 * Create a control for server sorted search results.
313 *
314 * PARAMS
315 * ld [I] Pointer to an LDAP context.
316 * sortkey [I] Array of LDAPSortKey structures, each specifying an
317 * attribute to use as a sort key, a matching rule and
318 * the sort order (ascending or descending).
319 * critical [I] Tells the server this control is critical to the
320 * search operation.
321 * control [O] LDAPControl created.
322 *
323 * RETURNS
324 * Success: LDAP_SUCCESS
325 * Failure: An LDAP error code.
326 *
327 * NOTES
328 * This function is obsolete. Use its equivalent
329 * ldap_create_sort_control instead.
330 */
ldap_encode_sort_controlW(WLDAP32_LDAP * ld,PLDAPSortKeyW * sortkeys,PLDAPControlW ret,BOOLEAN critical)331 ULONG CDECL ldap_encode_sort_controlW( WLDAP32_LDAP *ld, PLDAPSortKeyW *sortkeys,
332 PLDAPControlW ret, BOOLEAN critical )
333 {
334 LDAPControlW *control = NULL;
335 ULONG result;
336
337 if ((result = ldap_create_sort_controlW( ld, sortkeys, critical, &control )) == WLDAP32_LDAP_SUCCESS)
338 {
339 ret->ldctl_oid = strdupW(control->ldctl_oid);
340 bv_val_dup( &control->ldctl_value, &ret->ldctl_value );
341 ret->ldctl_iscritical = control->ldctl_iscritical;
342 ldap_control_freeW( control );
343 }
344 return result;
345 }
346
347 /***********************************************************************
348 * ldap_free_controlsA (WLDAP32.@)
349 *
350 * See ldap_free_controlsW.
351 */
ldap_free_controlsA(LDAPControlA ** controls)352 ULONG CDECL ldap_free_controlsA( LDAPControlA **controls )
353 {
354 return ldap_controls_freeA( controls );
355 }
356
357 /***********************************************************************
358 * ldap_free_controlsW (WLDAP32.@)
359 *
360 * Free an array of LDAPControl structures.
361 *
362 * PARAMS
363 * controls [I] Array of LDAPControl structures to free.
364 *
365 * RETURNS
366 * LDAP_SUCCESS
367 *
368 * NOTES
369 * Obsolete, use ldap_controls_freeW.
370 */
ldap_free_controlsW(LDAPControlW ** controls)371 ULONG CDECL ldap_free_controlsW( LDAPControlW **controls )
372 {
373 return ldap_controls_freeW( controls );
374 }
375