msxml3: Fix VARIANT_from_xmlChar implementation.
[wine] / dlls / wldap32 / modify.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 "config.h"
22
23 #include "wine/port.h"
24 #include "wine/debug.h"
25
26 #include <stdarg.h>
27
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winnls.h"
31
32 #ifdef HAVE_LDAP_H
33 #include <ldap.h>
34 #endif
35
36 #include "winldap_private.h"
37 #include "wldap32.h"
38
39 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
40
41 #ifdef HAVE_LDAP
42 static LDAPMod *nullmods[] = { NULL };
43 #endif
44
45 /***********************************************************************
46  *      ldap_modifyA     (WLDAP32.@)
47  *
48  * See ldap_modifyW.
49  */
50 ULONG CDECL ldap_modifyA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *mods[] )
51 {
52     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
53 #ifdef HAVE_LDAP
54     WCHAR *dnW = NULL;
55     LDAPModW **modsW = NULL;
56     
57     ret = WLDAP32_LDAP_NO_MEMORY;
58
59     TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), mods );
60
61     if (!ld) return ~0u;
62
63     if (dn) {
64         dnW = strAtoW( dn );
65         if (!dnW) goto exit;
66     }
67     if (mods) {
68         modsW = modarrayAtoW( mods );
69         if (!modsW) goto exit;
70     }
71
72     ret = ldap_modifyW( ld, dnW, modsW );
73
74 exit:
75     strfreeW( dnW );
76     modarrayfreeW( modsW );
77
78 #endif
79     return ret;
80 }
81
82 /***********************************************************************
83  *      ldap_modifyW     (WLDAP32.@)
84  *
85  * Change an entry in a directory tree (asynchronous operation).
86  *
87  * PARAMS
88  *  ld     [I] Pointer to an LDAP context.
89  *  dn     [I] DN of the entry to change.
90  *  mods   [I] Pointer to an array of LDAPModW structures, each
91  *             specifying an attribute and its values to change.
92  *
93  * RETURNS
94  *  Success: Message ID of the modify operation.
95  *  Failure: An LDAP error code.
96  *
97  * NOTES
98  *  Call ldap_result with the message ID to get the result of
99  *  the operation. Cancel the operation by calling ldap_abandon
100  *  with the message ID.
101  */
102 ULONG CDECL ldap_modifyW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *mods[] )
103 {
104     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
105 #ifdef HAVE_LDAP
106     char *dnU = NULL;
107     LDAPMod **modsU = NULL;
108     int msg;
109
110     ret = WLDAP32_LDAP_NO_MEMORY;
111
112     TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), mods );
113
114     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
115
116     if (dn) {
117         dnU = strWtoU( dn );
118         if (!dnU) goto exit;
119     }
120     if (mods) {
121         modsU = modarrayWtoU( mods );
122         if (!modsU) goto exit;
123     }
124
125     ret = ldap_modify_ext( ld, dn ? dnU : "", mods ? modsU : nullmods,
126                            NULL, NULL, &msg );
127
128     if (ret == LDAP_SUCCESS)
129         ret = msg;
130     else
131         ret = ~0u;
132
133 exit:
134     strfreeU( dnU );
135     modarrayfreeU( modsU );
136
137 #endif
138     return ret;
139 }
140
141 /***********************************************************************
142  *      ldap_modify_extA     (WLDAP32.@)
143  *
144  * See ldap_modify_extW.
145  */
146 ULONG CDECL ldap_modify_extA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *mods[],
147     PLDAPControlA *serverctrls, PLDAPControlA *clientctrls, ULONG *message )
148 {
149     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
150 #ifdef HAVE_LDAP
151     WCHAR *dnW = NULL;
152     LDAPModW **modsW = NULL;
153     LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
154
155     ret = WLDAP32_LDAP_NO_MEMORY;
156
157     TRACE( "(%p, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn), mods,
158            serverctrls, clientctrls, message );
159
160     if (!ld) return ~0u;
161
162     if (dn) {
163         dnW = strAtoW( dn );
164         if (!dnW) goto exit;
165     }
166     if (mods) {
167         modsW = modarrayAtoW( mods );
168         if (!modsW) goto exit;
169     }
170     if (serverctrls) {
171         serverctrlsW = controlarrayAtoW( serverctrls );
172         if (!serverctrlsW) goto exit;
173     }
174     if (clientctrls) {
175         clientctrlsW = controlarrayAtoW( clientctrls );
176         if (!clientctrlsW) goto exit;
177     }
178
179     ret = ldap_modify_extW( ld, dnW, modsW, serverctrlsW, clientctrlsW, message );
180
181 exit:
182     strfreeW( dnW );
183     modarrayfreeW( modsW );
184     controlarrayfreeW( serverctrlsW );
185     controlarrayfreeW( clientctrlsW );
186
187 #endif
188     return ret;
189 }
190
191 /***********************************************************************
192  *      ldap_modify_extW     (WLDAP32.@)
193  *
194  * Change an entry in a directory tree (asynchronous operation).
195  *
196  * PARAMS
197  *  ld          [I] Pointer to an LDAP context.
198  *  dn          [I] DN of the entry to change.
199  *  mods        [I] Pointer to an array of LDAPModW structures, each
200  *                  specifying an attribute and its values to change.
201  *  serverctrls [I] Array of LDAP server controls.
202  *  clientctrls [I] Array of LDAP client controls.
203  *  message     [O] Message ID of the modify operation.
204  *
205  * RETURNS
206  *  Success: LDAP_SUCCESS
207  *  Failure: An LDAP error code.
208  *
209  * NOTES
210  *  Call ldap_result with the message ID to get the result of
211  *  the operation. The serverctrls and clientctrls parameters are
212  *  optional and should be set to NULL if not used.
213  */
214 ULONG CDECL ldap_modify_extW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *mods[],
215     PLDAPControlW *serverctrls, PLDAPControlW *clientctrls, ULONG *message )
216 {
217     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
218 #ifdef HAVE_LDAP
219     char *dnU = NULL;
220     LDAPMod **modsU = NULL;
221     LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
222     int dummy;
223
224     ret = WLDAP32_LDAP_NO_MEMORY;
225
226     TRACE( "(%p, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn), mods,
227            serverctrls, clientctrls, message );
228
229     if (!ld) return ~0u;
230
231     if (dn) {
232         dnU = strWtoU( dn );
233         if (!dnU) goto exit;
234     }
235     if (mods) {
236         modsU = modarrayWtoU( mods );
237         if (!modsU) goto exit;
238     }
239     if (serverctrls) {
240         serverctrlsU = controlarrayWtoU( serverctrls );
241         if (!serverctrlsU) goto exit;
242     }
243     if (clientctrls) {
244         clientctrlsU = controlarrayWtoU( clientctrls );
245         if (!clientctrlsU) goto exit;
246     }
247
248     ret = map_error( ldap_modify_ext( ld, dn ? dnU : "", mods ? modsU : nullmods, serverctrlsU,
249                                       clientctrlsU, message ? (int *)message : &dummy ));
250
251 exit:
252     strfreeU( dnU );
253     modarrayfreeU( modsU );
254     controlarrayfreeU( serverctrlsU );
255     controlarrayfreeU( clientctrlsU );
256
257 #endif
258     return ret;
259 }
260
261 /***********************************************************************
262  *      ldap_modify_ext_sA     (WLDAP32.@)
263  *
264  * See ldap_modify_ext_sW.
265  */
266 ULONG CDECL ldap_modify_ext_sA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *mods[],
267     PLDAPControlA *serverctrls, PLDAPControlA *clientctrls )
268 {
269     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
270 #ifdef HAVE_LDAP
271     WCHAR *dnW = NULL;
272     LDAPModW **modsW = NULL;
273     LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
274
275     ret = WLDAP32_LDAP_NO_MEMORY;
276
277     TRACE( "(%p, %s, %p, %p, %p)\n", ld, debugstr_a(dn), mods,
278            serverctrls, clientctrls );
279
280     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
281
282     if (dn) {
283         dnW = strAtoW( dn );
284         if (!dnW) goto exit;
285     }
286     if (mods) {
287         modsW = modarrayAtoW( mods );
288         if (!modsW) goto exit;
289     }
290     if (serverctrls) {
291         serverctrlsW = controlarrayAtoW( serverctrls );
292         if (!serverctrlsW) goto exit;
293     }
294     if (clientctrls) {
295         clientctrlsW = controlarrayAtoW( clientctrls );
296         if (!clientctrlsW) goto exit;
297     }
298
299     ret = ldap_modify_ext_sW( ld, dnW, modsW, serverctrlsW, clientctrlsW );
300
301 exit:
302     strfreeW( dnW );
303     modarrayfreeW( modsW );
304     controlarrayfreeW( serverctrlsW );
305     controlarrayfreeW( clientctrlsW );
306
307 #endif
308     return ret;
309 }
310
311 /***********************************************************************
312  *      ldap_modify_ext_sW     (WLDAP32.@)
313  *
314  * Change an entry in a directory tree (synchronous operation).
315  *
316  * PARAMS
317  *  ld          [I] Pointer to an LDAP context.
318  *  dn          [I] DN of the entry to change.
319  *  mods        [I] Pointer to an array of LDAPModW structures, each
320  *                  specifying an attribute and its values to change.
321  *  serverctrls [I] Array of LDAP server controls.
322  *  clientctrls [I] Array of LDAP client controls.
323  *
324  * RETURNS
325  *  Success: LDAP_SUCCESS
326  *  Failure: An LDAP error code.
327  *
328  * NOTES
329  *  The serverctrls and clientctrls parameters are optional and
330  *  should be set to NULL if not used.
331  */
332 ULONG CDECL ldap_modify_ext_sW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *mods[],
333     PLDAPControlW *serverctrls, PLDAPControlW *clientctrls )
334 {
335     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
336 #ifdef HAVE_LDAP
337     char *dnU = NULL;
338     LDAPMod **modsU = NULL;
339     LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
340
341     ret = WLDAP32_LDAP_NO_MEMORY;
342
343     TRACE( "(%p, %s, %p, %p, %p)\n", ld, debugstr_w(dn), mods,
344            serverctrls, clientctrls );
345
346     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
347
348     if (dn) {
349         dnU = strWtoU( dn );
350         if (!dnU) goto exit;
351     }
352     if (mods) {
353         modsU = modarrayWtoU( mods );
354         if (!modsU) goto exit;
355     }
356     if (serverctrls) {
357         serverctrlsU = controlarrayWtoU( serverctrls );
358         if (!serverctrlsU) goto exit;
359     }
360     if (clientctrls) {
361         clientctrlsU = controlarrayWtoU( clientctrls );
362         if (!clientctrlsU) goto exit;
363     }
364
365     ret = map_error( ldap_modify_ext_s( ld, dn ? dnU : "", mods ? modsU : nullmods,
366                                         serverctrlsU, clientctrlsU ));
367
368 exit:
369     strfreeU( dnU );
370     modarrayfreeU( modsU );
371     controlarrayfreeU( serverctrlsU );
372     controlarrayfreeU( clientctrlsU );
373
374 #endif
375     return ret;
376 }
377
378 /***********************************************************************
379  *      ldap_modify_sA     (WLDAP32.@)
380  *
381  * See ldap_modify_sW.
382  */
383 ULONG CDECL ldap_modify_sA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *mods[] )
384 {
385     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
386 #ifdef HAVE_LDAP
387     WCHAR *dnW = NULL;
388     LDAPModW **modsW = NULL;
389
390     ret = WLDAP32_LDAP_NO_MEMORY;
391
392     TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), mods );
393
394     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
395
396     if (dn) {
397         dnW = strAtoW( dn );
398         if (!dnW) goto exit;
399     }
400     if (mods) {
401         modsW = modarrayAtoW( mods );
402         if (!modsW) goto exit;
403     }
404
405     ret = ldap_modify_sW( ld, dnW, modsW );
406
407 exit:
408     strfreeW( dnW );
409     modarrayfreeW( modsW );
410
411 #endif
412     return ret;
413 }
414
415 /***********************************************************************
416  *      ldap_modify_sW     (WLDAP32.@)
417  *
418  * Change an entry in a directory tree (synchronous operation).
419  *
420  * PARAMS
421  *  ld      [I] Pointer to an LDAP context.
422  *  dn      [I] DN of the entry to change.
423  *  attrs   [I] Pointer to an array of LDAPModW structures, each
424  *              specifying an attribute and its values to change.
425  *
426  * RETURNS
427  *  Success: LDAP_SUCCESS
428  *  Failure: An LDAP error code.
429  */
430 ULONG CDECL ldap_modify_sW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *mods[] )
431 {
432     ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
433 #ifdef HAVE_LDAP
434     char *dnU = NULL;
435     LDAPMod **modsU = NULL;
436
437     ret = WLDAP32_LDAP_NO_MEMORY;
438
439     TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), mods );
440
441     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
442
443     if (dn) {
444         dnU = strWtoU( dn );
445         if (!dnU) goto exit;
446     }
447     if (mods) {
448         modsU = modarrayWtoU( mods );
449         if (!modsU) goto exit;
450     }
451
452     ret = map_error( ldap_modify_ext_s( ld, dn ? dnU : "", mods ? modsU : nullmods, NULL, NULL ));
453
454 exit:
455     strfreeU( dnU );
456     modarrayfreeU( modsU );
457
458 #endif
459     return ret;
460 }