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_searchA (WLDAP32.@)
41 *
42 * See ldap_searchW.
43 */
ldap_searchA(WLDAP32_LDAP * ld,PCHAR base,ULONG scope,PCHAR filter,PCHAR attrs[],ULONG attrsonly)44 ULONG CDECL ldap_searchA( WLDAP32_LDAP *ld, PCHAR base, ULONG scope, PCHAR filter,
45 PCHAR attrs[], ULONG attrsonly )
46 {
47 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
48 #ifdef HAVE_LDAP
49 WCHAR *baseW = NULL, *filterW = NULL, **attrsW = NULL;
50
51 ret = WLDAP32_LDAP_NO_MEMORY;
52
53 TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x)\n", ld, debugstr_a(base),
54 scope, debugstr_a(filter), attrs, attrsonly );
55
56 if (!ld) return ~0u;
57
58 if (base) {
59 baseW = strAtoW( base );
60 if (!baseW) goto exit;
61 }
62 if (filter) {
63 filterW = strAtoW( filter );
64 if (!filterW) goto exit;
65 }
66 if (attrs) {
67 attrsW = strarrayAtoW( attrs );
68 if (!attrsW) goto exit;
69 }
70
71 ret = ldap_searchW( ld, baseW, scope, filterW, attrsW, attrsonly );
72
73 exit:
74 strfreeW( baseW );
75 strfreeW( filterW );
76 strarrayfreeW( attrsW );
77
78 #endif
79 return ret;
80 }
81
82 /***********************************************************************
83 * ldap_searchW (WLDAP32.@)
84 *
85 * Search a directory tree (asynchronous operation).
86 *
87 * PARAMS
88 * ld [I] Pointer to an LDAP context.
89 * base [I] Starting point for the search.
90 * scope [I] Search scope. One of LDAP_SCOPE_BASE,
91 * LDAP_SCOPE_ONELEVEL and LDAP_SCOPE_SUBTREE.
92 * filter [I] Search filter.
93 * attrs [I] Attributes to return.
94 * attrsonly [I] Return no values, only attributes.
95 *
96 * RETURNS
97 * Success: Message ID of the search operation.
98 * Failure: ~0u
99 *
100 * NOTES
101 * Call ldap_result with the message ID to get the result of
102 * the operation. Cancel the operation by calling ldap_abandon
103 * with the message ID.
104 */
ldap_searchW(WLDAP32_LDAP * ld,PWCHAR base,ULONG scope,PWCHAR filter,PWCHAR attrs[],ULONG attrsonly)105 ULONG CDECL ldap_searchW( WLDAP32_LDAP *ld, PWCHAR base, ULONG scope, PWCHAR filter,
106 PWCHAR attrs[], ULONG attrsonly )
107 {
108 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
109 #ifdef HAVE_LDAP
110 char *baseU = NULL, *filterU = NULL, **attrsU = NULL;
111 int msg;
112
113 ret = WLDAP32_LDAP_NO_MEMORY;
114
115 TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x)\n", ld, debugstr_w(base),
116 scope, debugstr_w(filter), attrs, attrsonly );
117
118 if (!ld) return ~0u;
119
120 if (base) {
121 baseU = strWtoU( base );
122 if (!baseU) goto exit;
123 }
124 if (filter) {
125 filterU = strWtoU( filter );
126 if (!filterU) goto exit;
127 }
128 if (attrs) {
129 attrsU = strarrayWtoU( attrs );
130 if (!attrsU) goto exit;
131 }
132
133 ret = ldap_search_ext( ld, baseU, scope, filterU, attrsU, attrsonly,
134 NULL, NULL, NULL, 0, &msg );
135
136 if (ret == LDAP_SUCCESS)
137 ret = msg;
138 else
139 ret = ~0u;
140
141 exit:
142 strfreeU( baseU );
143 strfreeU( filterU );
144 strarrayfreeU( attrsU );
145
146 #endif
147 return ret;
148 }
149
150 /***********************************************************************
151 * ldap_search_extA (WLDAP32.@)
152 *
153 * See ldap_search_extW.
154 */
ldap_search_extA(WLDAP32_LDAP * ld,PCHAR base,ULONG scope,PCHAR filter,PCHAR attrs[],ULONG attrsonly,PLDAPControlA * serverctrls,PLDAPControlA * clientctrls,ULONG timelimit,ULONG sizelimit,ULONG * message)155 ULONG CDECL ldap_search_extA( WLDAP32_LDAP *ld, PCHAR base, ULONG scope,
156 PCHAR filter, PCHAR attrs[], ULONG attrsonly, PLDAPControlA *serverctrls,
157 PLDAPControlA *clientctrls, ULONG timelimit, ULONG sizelimit, ULONG *message )
158 {
159 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
160 #ifdef HAVE_LDAP
161 WCHAR *baseW = NULL, *filterW = NULL, **attrsW = NULL;
162 LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
163
164 ret = WLDAP32_LDAP_NO_MEMORY;
165
166 TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, 0x%08x, 0x%08x, %p)\n",
167 ld, debugstr_a(base), scope, debugstr_a(filter), attrs, attrsonly,
168 serverctrls, clientctrls, timelimit, sizelimit, message );
169
170 if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
171
172 if (base) {
173 baseW = strAtoW( base );
174 if (!baseW) goto exit;
175 }
176 if (filter)
177 {
178 filterW = strAtoW( filter );
179 if (!filterW) goto exit;
180 }
181 if (attrs) {
182 attrsW = strarrayAtoW( attrs );
183 if (!attrsW) goto exit;
184 }
185 if (serverctrls) {
186 serverctrlsW = controlarrayAtoW( serverctrls );
187 if (!serverctrlsW) goto exit;
188 }
189 if (clientctrls) {
190 clientctrlsW = controlarrayAtoW( clientctrls );
191 if (!clientctrlsW) goto exit;
192 }
193
194 ret = ldap_search_extW( ld, baseW, scope, filterW, attrsW, attrsonly,
195 serverctrlsW, clientctrlsW, timelimit, sizelimit, message );
196
197 exit:
198 strfreeW( baseW );
199 strfreeW( filterW );
200 strarrayfreeW( attrsW );
201 controlarrayfreeW( serverctrlsW );
202 controlarrayfreeW( clientctrlsW );
203
204 #endif
205 return ret;
206 }
207
208 /***********************************************************************
209 * ldap_search_extW (WLDAP32.@)
210 *
211 * Search a directory tree (asynchronous operation).
212 *
213 * PARAMS
214 * ld [I] Pointer to an LDAP context.
215 * base [I] Starting point for the search.
216 * scope [I] Search scope. One of LDAP_SCOPE_BASE,
217 * LDAP_SCOPE_ONELEVEL and LDAP_SCOPE_SUBTREE.
218 * filter [I] Search filter.
219 * attrs [I] Attributes to return.
220 * attrsonly [I] Return no values, only attributes.
221 * serverctrls [I] Array of LDAP server controls.
222 * clientctrls [I] Array of LDAP client controls.
223 * timelimit [I] Timeout in seconds.
224 * sizelimit [I] Maximum number of entries to return. Zero means unlimited.
225 * message [O] Message ID of the search operation.
226 *
227 * RETURNS
228 * Success: LDAP_SUCCESS
229 * Failure: An LDAP error code.
230 *
231 * NOTES
232 * Call ldap_result with the message ID to get the result of
233 * the operation. Cancel the operation by calling ldap_abandon
234 * with the message ID.
235 */
ldap_search_extW(WLDAP32_LDAP * ld,PWCHAR base,ULONG scope,PWCHAR filter,PWCHAR attrs[],ULONG attrsonly,PLDAPControlW * serverctrls,PLDAPControlW * clientctrls,ULONG timelimit,ULONG sizelimit,ULONG * message)236 ULONG CDECL ldap_search_extW( WLDAP32_LDAP *ld, PWCHAR base, ULONG scope,
237 PWCHAR filter, PWCHAR attrs[], ULONG attrsonly, PLDAPControlW *serverctrls,
238 PLDAPControlW *clientctrls, ULONG timelimit, ULONG sizelimit, ULONG *message )
239 {
240 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
241 #ifdef HAVE_LDAP
242 char *baseU = NULL, *filterU = NULL, **attrsU = NULL;
243 LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
244 struct timeval tv, *tvp = NULL;
245
246 ret = WLDAP32_LDAP_NO_MEMORY;
247
248 TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, 0x%08x, 0x%08x, %p)\n",
249 ld, debugstr_w(base), scope, debugstr_w(filter), attrs, attrsonly,
250 serverctrls, clientctrls, timelimit, sizelimit, message );
251
252 if (!ld) return ~0u;
253
254 if (base) {
255 baseU = strWtoU( base );
256 if (!baseU) goto exit;
257 }
258 if (filter) {
259 filterU = strWtoU( filter );
260 if (!filterU) goto exit;
261 }
262 if (attrs) {
263 attrsU = strarrayWtoU( attrs );
264 if (!attrsU) goto exit;
265 }
266 if (serverctrls) {
267 serverctrlsU = controlarrayWtoU( serverctrls );
268 if (!serverctrlsU) goto exit;
269 }
270 if (clientctrls) {
271 clientctrlsU = controlarrayWtoU( clientctrls );
272 if (!clientctrlsU) goto exit;
273 }
274
275 if (timelimit)
276 {
277 tv.tv_sec = timelimit;
278 tv.tv_usec = 0;
279 tvp = &tv;
280 }
281
282 ret = map_error( ldap_search_ext( ld, baseU, scope, filterU, attrsU, attrsonly,
283 serverctrlsU, clientctrlsU, tvp, sizelimit, (int *)message ));
284
285 exit:
286 strfreeU( baseU );
287 strfreeU( filterU );
288 strarrayfreeU( attrsU );
289 controlarrayfreeU( serverctrlsU );
290 controlarrayfreeU( clientctrlsU );
291
292 #endif
293 return ret;
294 }
295
296 /***********************************************************************
297 * ldap_search_ext_sA (WLDAP32.@)
298 *
299 * See ldap_search_ext_sW.
300 */
ldap_search_ext_sA(WLDAP32_LDAP * ld,PCHAR base,ULONG scope,PCHAR filter,PCHAR attrs[],ULONG attrsonly,PLDAPControlA * serverctrls,PLDAPControlA * clientctrls,struct l_timeval * timeout,ULONG sizelimit,WLDAP32_LDAPMessage ** res)301 ULONG CDECL ldap_search_ext_sA( WLDAP32_LDAP *ld, PCHAR base, ULONG scope,
302 PCHAR filter, PCHAR attrs[], ULONG attrsonly, PLDAPControlA *serverctrls,
303 PLDAPControlA *clientctrls, struct l_timeval* timeout, ULONG sizelimit, WLDAP32_LDAPMessage **res )
304 {
305 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
306 #ifdef HAVE_LDAP
307 WCHAR *baseW = NULL, *filterW = NULL, **attrsW = NULL;
308 LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
309
310 ret = WLDAP32_LDAP_NO_MEMORY;
311
312 TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, %p, 0x%08x, %p)\n",
313 ld, debugstr_a(base), scope, debugstr_a(filter), attrs, attrsonly,
314 serverctrls, clientctrls, timeout, sizelimit, res );
315
316 if (!ld || !res) return WLDAP32_LDAP_PARAM_ERROR;
317
318 if (base) {
319 baseW = strAtoW( base );
320 if (!baseW) goto exit;
321 }
322 if (filter) {
323 filterW = strAtoW( filter );
324 if (!filterW) goto exit;
325 }
326 if (attrs) {
327 attrsW = strarrayAtoW( attrs );
328 if (!attrsW) goto exit;
329 }
330 if (serverctrls) {
331 serverctrlsW = controlarrayAtoW( serverctrls );
332 if (!serverctrlsW) goto exit;
333 }
334 if (clientctrls) {
335 clientctrlsW = controlarrayAtoW( clientctrls );
336 if (!clientctrlsW) goto exit;
337 }
338
339 ret = ldap_search_ext_sW( ld, baseW, scope, filterW, attrsW, attrsonly,
340 serverctrlsW, clientctrlsW, timeout, sizelimit, res );
341
342 exit:
343 strfreeW( baseW );
344 strfreeW( filterW );
345 strarrayfreeW( attrsW );
346 controlarrayfreeW( serverctrlsW );
347 controlarrayfreeW( clientctrlsW );
348
349 #endif
350 return ret;
351 }
352
353 /***********************************************************************
354 * ldap_search_ext_sW (WLDAP32.@)
355 *
356 * Search a directory tree (synchronous operation).
357 *
358 * PARAMS
359 * ld [I] Pointer to an LDAP context.
360 * base [I] Starting point for the search.
361 * scope [I] Search scope. One of LDAP_SCOPE_BASE,
362 * LDAP_SCOPE_ONELEVEL and LDAP_SCOPE_SUBTREE.
363 * filter [I] Search filter.
364 * attrs [I] Attributes to return.
365 * attrsonly [I] Return no values, only attributes.
366 * serverctrls [I] Array of LDAP server controls.
367 * clientctrls [I] Array of LDAP client controls.
368 * timeout [I] Timeout in seconds.
369 * sizelimit [I] Maximum number of entries to return. Zero means unlimited.
370 * res [O] Results of the search operation.
371 *
372 * RETURNS
373 * Success: LDAP_SUCCESS
374 * Failure: An LDAP error code.
375 *
376 * NOTES
377 * Call ldap_msgfree to free the results.
378 */
ldap_search_ext_sW(WLDAP32_LDAP * ld,PWCHAR base,ULONG scope,PWCHAR filter,PWCHAR attrs[],ULONG attrsonly,PLDAPControlW * serverctrls,PLDAPControlW * clientctrls,struct l_timeval * timeout,ULONG sizelimit,WLDAP32_LDAPMessage ** res)379 ULONG CDECL ldap_search_ext_sW( WLDAP32_LDAP *ld, PWCHAR base, ULONG scope,
380 PWCHAR filter, PWCHAR attrs[], ULONG attrsonly, PLDAPControlW *serverctrls,
381 PLDAPControlW *clientctrls, struct l_timeval* timeout, ULONG sizelimit, WLDAP32_LDAPMessage **res )
382 {
383 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
384 #ifdef HAVE_LDAP
385 char *baseU = NULL, *filterU = NULL, **attrsU = NULL;
386 LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
387
388 ret = WLDAP32_LDAP_NO_MEMORY;
389
390 TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, %p, 0x%08x, %p)\n",
391 ld, debugstr_w(base), scope, debugstr_w(filter), attrs, attrsonly,
392 serverctrls, clientctrls, timeout, sizelimit, res );
393
394 if (!ld || !res) return WLDAP32_LDAP_PARAM_ERROR;
395
396 if (base) {
397 baseU = strWtoU( base );
398 if (!baseU) goto exit;
399 }
400 if (filter) {
401 filterU = strWtoU( filter );
402 if (!filterU) goto exit;
403 }
404 if (attrs) {
405 attrsU = strarrayWtoU( attrs );
406 if (!attrsU) goto exit;
407 }
408 if (serverctrls) {
409 serverctrlsU = controlarrayWtoU( serverctrls );
410 if (!serverctrlsU) goto exit;
411 }
412 if (clientctrls) {
413 clientctrlsU = controlarrayWtoU( clientctrls );
414 if (!clientctrlsU) goto exit;
415 }
416
417 ret = map_error( ldap_search_ext_s( ld, baseU, scope, filterU, attrsU, attrsonly,
418 serverctrlsU, clientctrlsU, (struct timeval *)timeout,
419 sizelimit, res ));
420
421 exit:
422 strfreeU( baseU );
423 strfreeU( filterU );
424 strarrayfreeU( attrsU );
425 controlarrayfreeU( serverctrlsU );
426 controlarrayfreeU( clientctrlsU );
427
428 #endif
429 return ret;
430 }
431
432 /***********************************************************************
433 * ldap_search_sA (WLDAP32.@)
434 *
435 * See ldap_search_sW.
436 */
ldap_search_sA(WLDAP32_LDAP * ld,PCHAR base,ULONG scope,PCHAR filter,PCHAR attrs[],ULONG attrsonly,WLDAP32_LDAPMessage ** res)437 ULONG CDECL ldap_search_sA( WLDAP32_LDAP *ld, PCHAR base, ULONG scope, PCHAR filter,
438 PCHAR attrs[], ULONG attrsonly, WLDAP32_LDAPMessage **res )
439 {
440 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
441 #ifdef HAVE_LDAP
442 WCHAR *baseW = NULL, *filterW = NULL, **attrsW = NULL;
443
444 ret = WLDAP32_LDAP_NO_MEMORY;
445
446 TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p)\n", ld, debugstr_a(base),
447 scope, debugstr_a(filter), attrs, attrsonly, res );
448
449 if (!ld || !res) return WLDAP32_LDAP_PARAM_ERROR;
450
451 if (base) {
452 baseW = strAtoW( base );
453 if (!baseW) goto exit;
454 }
455 if (filter) {
456 filterW = strAtoW( filter );
457 if (!filterW) goto exit;
458 }
459 if (attrs) {
460 attrsW = strarrayAtoW( attrs );
461 if (!attrsW) goto exit;
462 }
463
464 ret = ldap_search_sW( ld, baseW, scope, filterW, attrsW, attrsonly, res );
465
466 exit:
467 strfreeW( baseW );
468 strfreeW( filterW );
469 strarrayfreeW( attrsW );
470
471 #endif
472 return ret;
473 }
474
475 /***********************************************************************
476 * ldap_search_sW (WLDAP32.@)
477 *
478 * Search a directory tree (synchronous operation).
479 *
480 * PARAMS
481 * ld [I] Pointer to an LDAP context.
482 * base [I] Starting point for the search.
483 * scope [I] Search scope. One of LDAP_SCOPE_BASE,
484 * LDAP_SCOPE_ONELEVEL and LDAP_SCOPE_SUBTREE.
485 * filter [I] Search filter.
486 * attrs [I] Attributes to return.
487 * attrsonly [I] Return no values, only attributes.
488 * res [O] Results of the search operation.
489 *
490 * RETURNS
491 * Success: LDAP_SUCCESS
492 * Failure: An LDAP error code.
493 *
494 * NOTES
495 * Call ldap_msgfree to free the results.
496 */
ldap_search_sW(WLDAP32_LDAP * ld,PWCHAR base,ULONG scope,PWCHAR filter,PWCHAR attrs[],ULONG attrsonly,WLDAP32_LDAPMessage ** res)497 ULONG CDECL ldap_search_sW( WLDAP32_LDAP *ld, PWCHAR base, ULONG scope, PWCHAR filter,
498 PWCHAR attrs[], ULONG attrsonly, WLDAP32_LDAPMessage **res )
499 {
500 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
501 #ifdef HAVE_LDAP
502 char *baseU = NULL, *filterU = NULL, **attrsU = NULL;
503
504 ret = WLDAP32_LDAP_NO_MEMORY;
505
506 TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p)\n", ld, debugstr_w(base),
507 scope, debugstr_w(filter), attrs, attrsonly, res );
508
509 if (!ld || !res) return WLDAP32_LDAP_PARAM_ERROR;
510
511 if (base) {
512 baseU = strWtoU( base );
513 if (!baseU) goto exit;
514 }
515 if (filter) {
516 filterU = strWtoU( filter );
517 if (!filterU) goto exit;
518 }
519 if (attrs) {
520 attrsU = strarrayWtoU( attrs );
521 if (!attrsU) goto exit;
522 }
523
524 ret = map_error( ldap_search_ext_s( ld, baseU, scope, filterU, attrsU, attrsonly,
525 NULL, NULL, NULL, 0, res ));
526
527 exit:
528 strfreeU( baseU );
529 strfreeU( filterU );
530 strarrayfreeU( attrsU );
531
532 #endif
533 return ret;
534 }
535
536 /***********************************************************************
537 * ldap_search_stA (WLDAP32.@)
538 *
539 * See ldap_search_stW.
540 */
ldap_search_stA(WLDAP32_LDAP * ld,const PCHAR base,ULONG scope,const PCHAR filter,PCHAR attrs[],ULONG attrsonly,struct l_timeval * timeout,WLDAP32_LDAPMessage ** res)541 ULONG CDECL ldap_search_stA( WLDAP32_LDAP *ld, const PCHAR base, ULONG scope,
542 const PCHAR filter, PCHAR attrs[], ULONG attrsonly,
543 struct l_timeval *timeout, WLDAP32_LDAPMessage **res )
544 {
545 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
546 #ifdef HAVE_LDAP
547 WCHAR *baseW = NULL, *filterW = NULL, **attrsW = NULL;
548
549 ret = WLDAP32_LDAP_NO_MEMORY;
550
551 TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p)\n", ld,
552 debugstr_a(base), scope, debugstr_a(filter), attrs,
553 attrsonly, timeout, res );
554
555 if (!ld || !res) return WLDAP32_LDAP_PARAM_ERROR;
556
557 if (base) {
558 baseW = strAtoW( base );
559 if (!baseW) goto exit;
560 }
561 if (filter) {
562 filterW = strAtoW( filter );
563 if (!filterW) goto exit;
564 }
565 if (attrs) {
566 attrsW = strarrayAtoW( attrs );
567 if (!attrsW) goto exit;
568 }
569
570 ret = ldap_search_stW( ld, baseW, scope, filterW, attrsW, attrsonly,
571 timeout, res );
572
573 exit:
574 strfreeW( baseW );
575 strfreeW( filterW );
576 strarrayfreeW( attrsW );
577
578 #endif
579 return ret;
580 }
581
582 /***********************************************************************
583 * ldap_search_stW (WLDAP32.@)
584 *
585 * Search a directory tree (synchronous operation).
586 *
587 * PARAMS
588 * ld [I] Pointer to an LDAP context.
589 * base [I] Starting point for the search.
590 * scope [I] Search scope. One of LDAP_SCOPE_BASE,
591 * LDAP_SCOPE_ONELEVEL and LDAP_SCOPE_SUBTREE.
592 * filter [I] Search filter.
593 * attrs [I] Attributes to return.
594 * attrsonly [I] Return no values, only attributes.
595 * timeout [I] Timeout in seconds.
596 * res [O] Results of the search operation.
597 *
598 * RETURNS
599 * Success: LDAP_SUCCESS
600 * Failure: An LDAP error code.
601 *
602 * NOTES
603 * Call ldap_msgfree to free the results.
604 */
ldap_search_stW(WLDAP32_LDAP * ld,const PWCHAR base,ULONG scope,const PWCHAR filter,PWCHAR attrs[],ULONG attrsonly,struct l_timeval * timeout,WLDAP32_LDAPMessage ** res)605 ULONG CDECL ldap_search_stW( WLDAP32_LDAP *ld, const PWCHAR base, ULONG scope,
606 const PWCHAR filter, PWCHAR attrs[], ULONG attrsonly,
607 struct l_timeval *timeout, WLDAP32_LDAPMessage **res )
608 {
609 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
610 #ifdef HAVE_LDAP
611 char *baseU = NULL, *filterU = NULL, **attrsU = NULL;
612
613 ret = WLDAP32_LDAP_NO_MEMORY;
614
615 TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p)\n", ld,
616 debugstr_w(base), scope, debugstr_w(filter), attrs,
617 attrsonly, timeout, res );
618
619 if (!ld || !res) return WLDAP32_LDAP_PARAM_ERROR;
620
621 if (base) {
622 baseU = strWtoU( base );
623 if (!baseU) goto exit;
624 }
625 if (filter) {
626 filterU = strWtoU( filter );
627 if (!filterU) goto exit;
628 }
629 if (attrs) {
630 attrsU = strarrayWtoU( attrs );
631 if (!attrsU) goto exit;
632 }
633
634 ret = map_error( ldap_search_ext_s( ld, baseU, scope, filterU, attrsU, attrsonly,
635 NULL, NULL, (struct timeval *)timeout, 0, res ));
636
637 exit:
638 strfreeU( baseU );
639 strfreeU( filterU );
640 strarrayfreeU( attrsU );
641
642 #endif
643 return ret;
644 }
645