xref: /reactos/dll/win32/wldap32/control.c (revision cc439606)
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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 
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  */
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  */
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  */
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  */
371 ULONG CDECL ldap_free_controlsW( LDAPControlW **controls )
372 {
373     return ldap_controls_freeW( controls );
374 }
375