search.c 15.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * WLDAP32 - LDAP support for Wine
 *
 * Copyright 2005 Hans Leidekker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * 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 <stdarg.h>
22
#include <stdlib.h>
23 24 25
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
26
#include "winldap.h"
27

28
#include "wine/debug.h"
29
#include "winldap_private.h"
30 31 32

WINE_DEFAULT_DEBUG_CHANNEL(wldap32);

33 34 35 36 37
/***********************************************************************
 *      ldap_searchA     (WLDAP32.@)
 *
 * See ldap_searchW.
 */
38
ULONG CDECL ldap_searchA( LDAP *ld, char *base, ULONG scope, char *filter, char **attrs, ULONG attrsonly )
39
{
40
    ULONG ret = LDAP_NO_MEMORY;
41
    WCHAR *baseW = NULL, *filterW = NULL, **attrsW = NULL;
42

43
    TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x)\n", ld, debugstr_a(base), scope, debugstr_a(filter), attrs, attrsonly );
44

45
    if (!ld) return ~0u;
46

47 48 49
    if (base && !(baseW = strAtoW( base ))) goto exit;
    if (filter && !(filterW = strAtoW( filter ))) goto exit;
    if (attrs && !(attrsW = strarrayAtoW( attrs ))) goto exit;
50 51 52

    ret = ldap_searchW( ld, baseW, scope, filterW, attrsW, attrsonly );

53
exit:
54 55
    free( baseW );
    free( filterW );
56 57 58 59
    strarrayfreeW( attrsW );
    return ret;
}

60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
/***********************************************************************
 *      ldap_searchW     (WLDAP32.@)
 *
 * Search a directory tree (asynchronous operation).
 *
 * PARAMS
 *  ld        [I] Pointer to an LDAP context.
 *  base      [I] Starting point for the search.
 *  scope     [I] Search scope. One of LDAP_SCOPE_BASE,
 *                LDAP_SCOPE_ONELEVEL and LDAP_SCOPE_SUBTREE.
 *  filter    [I] Search filter.
 *  attrs     [I] Attributes to return.
 *  attrsonly [I] Return no values, only attributes.
 *
 * RETURNS
 *  Success: Message ID of the search operation.
76
 *  Failure: ~0u
77 78 79 80 81 82
 *
 * NOTES
 *  Call ldap_result with the message ID to get the result of
 *  the operation. Cancel the operation by calling ldap_abandon
 *  with the message ID.
 */
83
ULONG CDECL ldap_searchW( LDAP *ld, WCHAR *base, ULONG scope, WCHAR *filter, WCHAR **attrs, ULONG attrsonly )
84
{
85 86
    ULONG ret, msg;
    TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x)\n", ld, debugstr_w(base), scope, debugstr_w(filter), attrs, attrsonly );
87

88
    ret = ldap_search_extW( ld, base, scope, filter, attrs, attrsonly, NULL, NULL, 0, 0, &msg );
89
    if (ret == LDAP_SUCCESS) return msg;
90
    return ~0u;
91 92
}

93 94 95 96 97
/***********************************************************************
 *      ldap_search_extA     (WLDAP32.@)
 *
 * See ldap_search_extW.
 */
98
ULONG CDECL ldap_search_extA( LDAP *ld, char *base, ULONG scope, char *filter, char **attrs, ULONG attrsonly,
99
    LDAPControlA **serverctrls, LDAPControlA **clientctrls, ULONG timelimit, ULONG sizelimit, ULONG *message )
100
{
101
    ULONG ret = LDAP_NO_MEMORY;
102 103
    WCHAR *baseW = NULL, *filterW = NULL, **attrsW = NULL;
    LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
104

105 106
    TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, 0x%08x, 0x%08x, %p)\n", ld, debugstr_a(base), scope,
           debugstr_a(filter), attrs, attrsonly, serverctrls, clientctrls, timelimit, sizelimit, message );
107

108
    if (!ld) return LDAP_PARAM_ERROR;
109

110 111 112 113 114
    if (base && !(baseW = strAtoW( base ))) goto exit;
    if (filter && !(filterW = strAtoW( filter ))) goto exit;
    if (attrs && !(attrsW = strarrayAtoW( attrs ))) goto exit;
    if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
    if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
115

116 117
    ret = ldap_search_extW( ld, baseW, scope, filterW, attrsW, attrsonly, serverctrlsW, clientctrlsW, timelimit,
                            sizelimit, message );
118

119
exit:
120 121
    free( baseW );
    free( filterW );
122 123 124 125 126 127
    strarrayfreeW( attrsW );
    controlarrayfreeW( serverctrlsW );
    controlarrayfreeW( clientctrlsW );
    return ret;
}

128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
/***********************************************************************
 *      ldap_search_extW     (WLDAP32.@)
 *
 * Search a directory tree (asynchronous operation).
 *
 * PARAMS
 *  ld          [I] Pointer to an LDAP context.
 *  base        [I] Starting point for the search.
 *  scope       [I] Search scope. One of LDAP_SCOPE_BASE,
 *                  LDAP_SCOPE_ONELEVEL and LDAP_SCOPE_SUBTREE.
 *  filter      [I] Search filter.
 *  attrs       [I] Attributes to return.
 *  attrsonly   [I] Return no values, only attributes.
 *  serverctrls [I] Array of LDAP server controls.
 *  clientctrls [I] Array of LDAP client controls.
 *  timelimit   [I] Timeout in seconds.
 *  sizelimit   [I] Maximum number of entries to return. Zero means unlimited.
 *  message     [O] Message ID of the search operation.
 *
 * RETURNS
 *  Success: LDAP_SUCCESS
 *  Failure: An LDAP error code.
 *
 * NOTES
 *  Call ldap_result with the message ID to get the result of
 *  the operation. Cancel the operation by calling ldap_abandon
 *  with the message ID.
 */
156
ULONG CDECL ldap_search_extW( LDAP *ld, WCHAR *base, ULONG scope, WCHAR *filter, WCHAR **attrs,
157 158
    ULONG attrsonly, LDAPControlW **serverctrls, LDAPControlW **clientctrls, ULONG timelimit, ULONG sizelimit,
    ULONG *message )
159
{
160
    ULONG ret = LDAP_NO_MEMORY;
161
    char *baseU = NULL, *filterU = NULL, **attrsU = NULL;
162 163
    LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
    struct timevalU timevalU;
164

165 166
    TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, 0x%08x, 0x%08x, %p)\n", ld, debugstr_w(base), scope,
           debugstr_w(filter), attrs, attrsonly, serverctrls, clientctrls, timelimit, sizelimit, message );
167

168
    if (!ld) return ~0u;
169

170 171 172 173 174
    if (base && !(baseU = strWtoU( base ))) goto exit;
    if (filter && !(filterU = strWtoU( filter ))) goto exit;
    if (attrs && !(attrsU = strarrayWtoU( attrs ))) goto exit;
    if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
    if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
175

176 177
    timevalU.tv_sec = timelimit;
    timevalU.tv_usec = 0;
178

179 180 181 182 183
    {
        struct ldap_search_ext_params params = { CTX(ld), baseU, scope, filterU, attrsU, attrsonly,
                serverctrlsU, clientctrlsU, timelimit ? &timevalU : NULL, sizelimit, message };
        ret = map_error( LDAP_CALL( ldap_search_ext, &params ));
    }
184
exit:
185 186
    free( baseU );
    free( filterU );
187 188 189 190 191 192
    strarrayfreeU( attrsU );
    controlarrayfreeU( serverctrlsU );
    controlarrayfreeU( clientctrlsU );
    return ret;
}

193 194 195 196 197
/***********************************************************************
 *      ldap_search_ext_sA     (WLDAP32.@)
 *
 * See ldap_search_ext_sW.
 */
198
ULONG CDECL ldap_search_ext_sA( LDAP *ld, char *base, ULONG scope, char *filter, char **attrs,
199
    ULONG attrsonly, LDAPControlA **serverctrls, LDAPControlA **clientctrls, struct l_timeval *timeout,
200
    ULONG sizelimit, LDAPMessage **res )
201
{
202
    ULONG ret = LDAP_NO_MEMORY;
203 204
    WCHAR *baseW = NULL, *filterW = NULL, **attrsW = NULL;
    LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
205

206 207
    TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, %p, 0x%08x, %p)\n", ld, debugstr_a(base), scope,
           debugstr_a(filter), attrs, attrsonly, serverctrls, clientctrls, timeout, sizelimit, res );
208

209
    if (!ld || !res) return LDAP_PARAM_ERROR;
210

211 212 213 214 215
    if (base && !(baseW = strAtoW( base ))) goto exit;
    if (filter && !(filterW = strAtoW( filter ))) goto exit;
    if (attrs && !(attrsW = strarrayAtoW( attrs ))) goto exit;
    if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
    if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
216

217 218
    ret = ldap_search_ext_sW( ld, baseW, scope, filterW, attrsW, attrsonly, serverctrlsW, clientctrlsW, timeout,
                              sizelimit, res );
219

220
exit:
221 222
    free( baseW );
    free( filterW );
223 224 225 226 227 228
    strarrayfreeW( attrsW );
    controlarrayfreeW( serverctrlsW );
    controlarrayfreeW( clientctrlsW );
    return ret;
}

229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
/***********************************************************************
 *      ldap_search_ext_sW     (WLDAP32.@)
 *
 * Search a directory tree (synchronous operation).
 *
 * PARAMS
 *  ld          [I] Pointer to an LDAP context.
 *  base        [I] Starting point for the search.
 *  scope       [I] Search scope. One of LDAP_SCOPE_BASE,
 *                  LDAP_SCOPE_ONELEVEL and LDAP_SCOPE_SUBTREE.
 *  filter      [I] Search filter.
 *  attrs       [I] Attributes to return.
 *  attrsonly   [I] Return no values, only attributes.
 *  serverctrls [I] Array of LDAP server controls.
 *  clientctrls [I] Array of LDAP client controls.
 *  timeout     [I] Timeout in seconds.
 *  sizelimit   [I] Maximum number of entries to return. Zero means unlimited.
 *  res         [O] Results of the search operation.
 *
 * RETURNS
 *  Success: LDAP_SUCCESS
 *  Failure: An LDAP error code.
 *
 * NOTES
 *  Call ldap_msgfree to free the results.
 */
255
ULONG CDECL ldap_search_ext_sW( LDAP *ld, WCHAR *base, ULONG scope, WCHAR *filter, WCHAR **attrs,
256
    ULONG attrsonly, LDAPControlW **serverctrls, LDAPControlW **clientctrls, struct l_timeval *timeout,
257
    ULONG sizelimit, LDAPMessage **res )
258
{
259
    ULONG ret = LDAP_NO_MEMORY;
260
    char *baseU = NULL, *filterU = NULL, **attrsU = NULL;
261 262 263
    LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
    struct timevalU timevalU;
    void *msgU = NULL;
264

265 266
    TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p, %p, 0x%08x, %p)\n", ld, debugstr_w(base), scope,
           debugstr_w(filter), attrs, attrsonly, serverctrls, clientctrls, timeout, sizelimit, res );
267

268
    if (!ld || !res) return LDAP_PARAM_ERROR;
269

270 271 272 273 274 275 276 277 278 279
    if (base && !(baseU = strWtoU( base ))) goto exit;
    if (filter && !(filterU = strWtoU( filter ))) goto exit;
    if (attrs && !(attrsU = strarrayWtoU( attrs ))) goto exit;
    if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
    if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;

    if (timeout)
    {
        timevalU.tv_sec = timeout->tv_sec;
        timevalU.tv_usec = timeout->tv_usec;
280
    }
281

282 283 284 285 286 287
    {
        struct ldap_search_ext_s_params params = { CTX(ld), baseU, scope, filterU, attrsU, attrsonly,
            serverctrlsU, clientctrlsU, timeout ? &timevalU : NULL, sizelimit, &msgU };
        ret = map_error( LDAP_CALL( ldap_search_ext_s, &params ));
    }

288 289
    if (msgU)
    {
290
        LDAPMessage *msg = calloc( 1, sizeof(*msg) );
291 292
        if (msg)
        {
293
            MSG(msg) = msgU;
294 295 296 297
            *res = msg;
        }
        else
        {
298
            LDAP_CALL( ldap_msgfree, msgU );
299
            ret = LDAP_NO_MEMORY;
300 301
        }
    }
302

303
exit:
304 305
    free( baseU );
    free( filterU );
306 307 308 309 310 311
    strarrayfreeU( attrsU );
    controlarrayfreeU( serverctrlsU );
    controlarrayfreeU( clientctrlsU );
    return ret;
}

312 313 314 315 316
/***********************************************************************
 *      ldap_search_sA     (WLDAP32.@)
 *
 * See ldap_search_sW.
 */
317 318
ULONG CDECL ldap_search_sA( LDAP *ld, char *base, ULONG scope, char *filter, char **attrs, ULONG attrsonly,
    LDAPMessage **res )
319
{
320
    ULONG ret = LDAP_NO_MEMORY;
321
    WCHAR *baseW = NULL, *filterW = NULL, **attrsW = NULL;
322

323 324
    TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p)\n", ld, debugstr_a(base), scope, debugstr_a(filter), attrs,
           attrsonly, res );
325

326
    if (!ld || !res) return LDAP_PARAM_ERROR;
327

328 329 330
    if (base && !(baseW = strAtoW( base ))) goto exit;
    if (filter && !(filterW = strAtoW( filter ))) goto exit;
    if (attrs && !(attrsW = strarrayAtoW( attrs ))) goto exit;
331 332 333

    ret = ldap_search_sW( ld, baseW, scope, filterW, attrsW, attrsonly, res );

334
exit:
335 336
    free( baseW );
    free( filterW );
337 338 339 340
    strarrayfreeW( attrsW );
    return ret;
}

341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
/***********************************************************************
 *      ldap_search_sW     (WLDAP32.@)
 *
 * Search a directory tree (synchronous operation).
 *
 * PARAMS
 *  ld        [I] Pointer to an LDAP context.
 *  base      [I] Starting point for the search.
 *  scope     [I] Search scope. One of LDAP_SCOPE_BASE,
 *                LDAP_SCOPE_ONELEVEL and LDAP_SCOPE_SUBTREE.
 *  filter    [I] Search filter.
 *  attrs     [I] Attributes to return.
 *  attrsonly [I] Return no values, only attributes.
 *  res       [O] Results of the search operation.
 *
 * RETURNS
 *  Success: LDAP_SUCCESS
 *  Failure: An LDAP error code.
 *
 * NOTES
 *  Call ldap_msgfree to free the results.
 */
363 364
ULONG CDECL ldap_search_sW( LDAP *ld, WCHAR *base, ULONG scope, WCHAR *filter, WCHAR **attrs, ULONG attrsonly,
    LDAPMessage **res )
365
{
366 367 368
    TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p)\n", ld, debugstr_w(base), scope, debugstr_w(filter), attrs,
           attrsonly, res );
    return ldap_search_ext_sW( ld, base, scope, filter, attrs, attrsonly, NULL, NULL, NULL, 0, res );
369 370
}

371 372 373 374 375
/***********************************************************************
 *      ldap_search_stA     (WLDAP32.@)
 *
 * See ldap_search_stW.
 */
376 377
ULONG CDECL ldap_search_stA( LDAP *ld, const PCHAR base, ULONG scope, const PCHAR filter, char **attrs,
    ULONG attrsonly, struct l_timeval *timeout, LDAPMessage **res )
378
{
379
    ULONG ret = LDAP_NO_MEMORY;
380
    WCHAR *baseW = NULL, *filterW = NULL, **attrsW = NULL;
381

382
    TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p)\n", ld, debugstr_a(base), scope, debugstr_a(filter), attrs,
383 384
           attrsonly, timeout, res );

385
    if (!ld || !res) return LDAP_PARAM_ERROR;
386

387 388 389
    if (base && !(baseW = strAtoW( base ))) goto exit;
    if (filter && !(filterW = strAtoW( filter ))) goto exit;
    if (attrs && !(attrsW = strarrayAtoW( attrs ))) goto exit;
390

391
    ret = ldap_search_stW( ld, baseW, scope, filterW, attrsW, attrsonly, timeout, res );
392

393
exit:
394 395
    free( baseW );
    free( filterW );
396 397 398 399
    strarrayfreeW( attrsW );
    return ret;
}

400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
/***********************************************************************
 *      ldap_search_stW     (WLDAP32.@)
 *
 * Search a directory tree (synchronous operation).
 *
 * PARAMS
 *  ld        [I] Pointer to an LDAP context.
 *  base      [I] Starting point for the search.
 *  scope     [I] Search scope. One of LDAP_SCOPE_BASE,
 *                LDAP_SCOPE_ONELEVEL and LDAP_SCOPE_SUBTREE.
 *  filter    [I] Search filter.
 *  attrs     [I] Attributes to return.
 *  attrsonly [I] Return no values, only attributes.
 *  timeout   [I] Timeout in seconds.
 *  res       [O] Results of the search operation.
 *
 * RETURNS
 *  Success: LDAP_SUCCESS
 *  Failure: An LDAP error code.
 *
 * NOTES
 *  Call ldap_msgfree to free the results.
 */
423 424
ULONG CDECL ldap_search_stW( LDAP *ld, const PWCHAR base, ULONG scope, const PWCHAR filter, WCHAR **attrs,
    ULONG attrsonly, struct l_timeval *timeout, LDAPMessage **res )
425
{
426
    TRACE( "(%p, %s, 0x%08x, %s, %p, 0x%08x, %p, %p)\n", ld, debugstr_w(base), scope, debugstr_w(filter), attrs,
427
           attrsonly, timeout, res );
428
    return ldap_search_ext_sW( ld, base, scope, filter, attrs, attrsonly, NULL, NULL, timeout, 0, res );
429
}