bind.c 17.3 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 22 23 24 25 26 27 28 29 30 31
 */

#include "config.h"

#include "wine/port.h"
#include "wine/debug.h"

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winnls.h"

32
#ifdef HAVE_LDAP_H
33 34 35 36 37 38 39 40
#include <ldap.h>
#endif

#include "winldap_private.h"
#include "wldap32.h"

WINE_DEFAULT_DEBUG_CHANNEL(wldap32);

41 42 43 44 45
/***********************************************************************
 *      ldap_bindA     (WLDAP32.@)
 *
 * See ldap_bindW.
 */
46
ULONG CDECL ldap_bindA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR cred, ULONG method )
47
{
48
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
49
#ifdef HAVE_LDAP
50
    WCHAR *dnW = NULL, *credW = NULL;
51 52

    ret = WLDAP32_LDAP_NO_MEMORY;
53

54
    TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_a(dn), cred, method );
55

56
    if (!ld) return ~0u;
57

58 59 60 61 62 63 64 65
    if (dn) {
        dnW = strAtoW( dn );
        if (!dnW) goto exit;
    }
    if (cred) {
        credW = strAtoW( cred );
        if (!credW) goto exit;
    }
66 67 68

    ret = ldap_bindW( ld, dnW, credW, method );

69
exit:
70 71 72 73 74 75 76
    strfreeW( dnW );
    strfreeW( credW );

#endif
    return ret;
}

77 78 79 80 81
/***********************************************************************
 *      ldap_bindW     (WLDAP32.@)
 *
 * Authenticate with an LDAP server (asynchronous operation).
 *
82
 * PARAMS
83 84 85 86 87 88 89 90 91 92
 *  ld      [I] Pointer to an LDAP context.
 *  dn      [I] DN of entry to bind as.
 *  cred    [I] Credentials (e.g. password string).
 *  method  [I] Authentication method.
 *
 * RETURNS
 *  Success: Message ID of the bind operation.
 *  Failure: An LDAP error code.
 *
 * NOTES
93
 *  Only LDAP_AUTH_SIMPLE is supported (just like native).
94
 */
95
ULONG CDECL ldap_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method )
96
{
97
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
98
#ifdef HAVE_LDAP
99
    char *dnU = NULL, *credU = NULL;
100 101
    struct berval pwd = { 0, NULL };
    int msg;
102 103

    ret = WLDAP32_LDAP_NO_MEMORY;
104

105
    TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_w(dn), cred, method );
106

107
    if (!ld) return ~0u;
108
    if (method != LDAP_AUTH_SIMPLE) return WLDAP32_LDAP_PARAM_ERROR;
109

110 111 112 113 114 115 116
    if (dn) {
        dnU = strWtoU( dn );
        if (!dnU) goto exit;
    }
    if (cred) {
        credU = strWtoU( cred );
        if (!credU) goto exit;
117 118 119

        pwd.bv_len = strlen( credU );
        pwd.bv_val = credU;
120
    }
121

122 123 124 125 126
    ret = ldap_sasl_bind( ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, &msg );

    if (ret == LDAP_SUCCESS)
        ret = msg;
    else
127
        ret = ~0u;
128

129
exit:
130 131 132 133 134 135 136
    strfreeU( dnU );
    strfreeU( credU );

#endif
    return ret;
}

137 138 139 140 141
/***********************************************************************
 *      ldap_bind_sA     (WLDAP32.@)
 *
 * See ldap_bind_sW.
 */
142
ULONG CDECL ldap_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR cred, ULONG method )
143
{
144
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
145
#ifdef HAVE_LDAP
146
    WCHAR *dnW = NULL, *credW = NULL;
147 148

    ret = WLDAP32_LDAP_NO_MEMORY;
149

150
    TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_a(dn), cred, method );
151

152
    if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
153

154 155 156 157 158 159 160 161
    if (dn) {
        dnW = strAtoW( dn );
        if (!dnW) goto exit;
    }
    if (cred) {
        credW = strAtoW( cred );
        if (!credW) goto exit;
    }
162 163 164

    ret = ldap_bind_sW( ld, dnW, credW, method );

165
exit:
166 167 168 169 170 171 172
    strfreeW( dnW );
    strfreeW( credW );

#endif
    return ret;
}

173 174 175 176 177
/***********************************************************************
 *      ldap_bind_sW     (WLDAP32.@)
 *
 * Authenticate with an LDAP server (synchronous operation).
 *
178
 * PARAMS
179 180 181 182 183 184 185 186 187
 *  ld      [I] Pointer to an LDAP context.
 *  dn      [I] DN of entry to bind as.
 *  cred    [I] Credentials (e.g. password string).
 *  method  [I] Authentication method.
 *
 * RETURNS
 *  Success: LDAP_SUCCESS
 *  Failure: An LDAP error code.
 */
188
ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method )
189
{
190
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
191
#ifdef HAVE_LDAP
192
    char *dnU = NULL, *credU = NULL;
193
    struct berval pwd = { 0, NULL };
194 195

    ret = WLDAP32_LDAP_NO_MEMORY;
196

197
    TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_w(dn), cred, method );
198

199
    if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
200
    if (method != LDAP_AUTH_SIMPLE) return WLDAP32_LDAP_PARAM_ERROR;
201

202 203 204 205 206 207 208
    if (dn) {
        dnU = strWtoU( dn );
        if (!dnU) goto exit;
    }
    if (cred) {
        credU = strWtoU( cred );
        if (!credU) goto exit;
209 210 211

        pwd.bv_len = strlen( credU );
        pwd.bv_val = credU;
212
    }
213

214
    ret = map_error( ldap_sasl_bind_s( ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, NULL ));
215

216
exit:
217 218 219 220 221 222
    strfreeU( dnU );
    strfreeU( credU );

#endif
    return ret;
}
223

224 225 226 227 228
/***********************************************************************
 *      ldap_sasl_bindA     (WLDAP32.@)
 *
 * See ldap_sasl_bindW.
 */
229
ULONG CDECL ldap_sasl_bindA( WLDAP32_LDAP *ld, const PCHAR dn,
230 231 232
    const PCHAR mechanism, const BERVAL *cred, PLDAPControlA *serverctrls,
    PLDAPControlA *clientctrls, int *message )
{
233
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
234
#ifdef HAVE_LDAP
235 236
    WCHAR *dnW, *mechanismW = NULL;
    LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
237 238

    ret = WLDAP32_LDAP_NO_MEMORY;
239 240 241 242

    TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
           debugstr_a(mechanism), cred, serverctrls, clientctrls, message );

243 244 245
    if (!ld || !dn || !mechanism || !cred || !message)
        return WLDAP32_LDAP_PARAM_ERROR;

246
    dnW = strAtoW( dn );
247
    if (!dnW) goto exit;
248 249

    mechanismW = strAtoW( mechanism );
250
    if (!mechanismW) goto exit;
251

252 253 254 255 256 257 258 259
    if (serverctrls) {
        serverctrlsW = controlarrayAtoW( serverctrls );
        if (!serverctrlsW) goto exit;
    }
    if (clientctrls) {
        clientctrlsW = controlarrayAtoW( clientctrls );
        if (!clientctrlsW) goto exit;
    }
260 261 262

    ret = ldap_sasl_bindW( ld, dnW, mechanismW, cred, serverctrlsW, clientctrlsW, message );

263
exit:
264 265 266 267 268 269 270 271 272
    strfreeW( dnW );
    strfreeW( mechanismW );
    controlarrayfreeW( serverctrlsW );
    controlarrayfreeW( clientctrlsW );

#endif
    return ret;
}

273 274 275 276 277
/***********************************************************************
 *      ldap_sasl_bindW     (WLDAP32.@)
 *
 * Authenticate with an LDAP server using SASL (asynchronous operation).
 *
278
 * PARAMS
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
 *  ld          [I] Pointer to an LDAP context.
 *  dn          [I] DN of entry to bind as.
 *  mechanism   [I] Authentication method.
 *  cred        [I] Credentials.
 *  serverctrls [I] Array of LDAP server controls.
 *  clientctrls [I] Array of LDAP client controls.
 *  message     [O] Message ID of the bind operation. 
 *
 * RETURNS
 *  Success: LDAP_SUCCESS
 *  Failure: An LDAP error code.
 *
 * NOTES
 *  The serverctrls and clientctrls parameters are optional and should
 *  be set to NULL if not used.
 */
295
ULONG CDECL ldap_sasl_bindW( WLDAP32_LDAP *ld, const PWCHAR dn,
296 297 298
    const PWCHAR mechanism, const BERVAL *cred, PLDAPControlW *serverctrls,
    PLDAPControlW *clientctrls, int *message )
{
299
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
300
#ifdef HAVE_LDAP
301 302
    char *dnU, *mechanismU = NULL;
    LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
303
    struct berval credU;
304 305

    ret = WLDAP32_LDAP_NO_MEMORY;
306 307 308 309

    TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
           debugstr_w(mechanism), cred, serverctrls, clientctrls, message );

310 311 312
    if (!ld || !dn || !mechanism || !cred || !message)
        return WLDAP32_LDAP_PARAM_ERROR;

313
    dnU = strWtoU( dn );
314
    if (!dnU) goto exit;
315 316

    mechanismU = strWtoU( mechanism );
317
    if (!mechanismU) goto exit;
318

319 320 321 322 323 324 325 326
    if (serverctrls) {
        serverctrlsU = controlarrayWtoU( serverctrls );
        if (!serverctrlsU) goto exit;
    }
    if (clientctrls) {
        clientctrlsU = controlarrayWtoU( clientctrls );
        if (!clientctrlsU) goto exit;
    }
327

328 329 330
    credU.bv_len = cred->bv_len;
    credU.bv_val = cred->bv_val;

331 332
    ret = map_error( ldap_sasl_bind( ld, dnU, mechanismU, &credU,
                                     serverctrlsU, clientctrlsU, message ));
333

334
exit:
335 336 337 338 339 340 341 342 343
    strfreeU( dnU );
    strfreeU( mechanismU );
    controlarrayfreeU( serverctrlsU );
    controlarrayfreeU( clientctrlsU );

#endif
    return ret;
}

344 345 346 347 348
/***********************************************************************
 *      ldap_sasl_bind_sA     (WLDAP32.@)
 *
 * See ldap_sasl_bind_sW.
 */
349
ULONG CDECL ldap_sasl_bind_sA( WLDAP32_LDAP *ld, const PCHAR dn,
350 351 352
    const PCHAR mechanism, const BERVAL *cred, PLDAPControlA *serverctrls,
    PLDAPControlA *clientctrls, PBERVAL *serverdata )
{
353
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
354
#ifdef HAVE_LDAP
355 356
    WCHAR *dnW, *mechanismW = NULL;
    LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
357 358

    ret = WLDAP32_LDAP_NO_MEMORY;
359 360 361 362

    TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
           debugstr_a(mechanism), cred, serverctrls, clientctrls, serverdata );

363 364 365
    if (!ld || !dn || !mechanism || !cred || !serverdata)
        return WLDAP32_LDAP_PARAM_ERROR;

366
    dnW = strAtoW( dn );
367
    if (!dnW) goto exit;
368 369

    mechanismW = strAtoW( mechanism );
370
    if (!mechanismW) goto exit;
371

372 373 374 375 376 377 378 379
    if (serverctrls) {
        serverctrlsW = controlarrayAtoW( serverctrls );
        if (!serverctrlsW) goto exit;
    }
    if (clientctrls) {
        clientctrlsW = controlarrayAtoW( clientctrls );
        if (!clientctrlsW) goto exit;
    }
380 381 382

    ret = ldap_sasl_bind_sW( ld, dnW, mechanismW, cred, serverctrlsW, clientctrlsW, serverdata );

383
exit:
384 385 386 387 388 389 390 391 392
    strfreeW( dnW );
    strfreeW( mechanismW );
    controlarrayfreeW( serverctrlsW );
    controlarrayfreeW( clientctrlsW );

#endif
    return ret;
}

393 394 395 396 397
/***********************************************************************
 *      ldap_sasl_bind_sW     (WLDAP32.@)
 *
 * Authenticate with an LDAP server using SASL (synchronous operation).
 *
398
 * PARAMS
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
 *  ld          [I] Pointer to an LDAP context.
 *  dn          [I] DN of entry to bind as.
 *  mechanism   [I] Authentication method.
 *  cred        [I] Credentials.
 *  serverctrls [I] Array of LDAP server controls.
 *  clientctrls [I] Array of LDAP client controls.
 *  serverdata  [O] Authentication response from the server.
 *
 * RETURNS
 *  Success: LDAP_SUCCESS
 *  Failure: An LDAP error code.
 *
 * NOTES
 *  The serverctrls and clientctrls parameters are optional and should
 *  be set to NULL if not used.
 */
415
ULONG CDECL ldap_sasl_bind_sW( WLDAP32_LDAP *ld, const PWCHAR dn,
416 417 418
    const PWCHAR mechanism, const BERVAL *cred, PLDAPControlW *serverctrls,
    PLDAPControlW *clientctrls, PBERVAL *serverdata )
{
419
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
420
#ifdef HAVE_LDAP
421 422
    char *dnU, *mechanismU = NULL;
    LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
423
    struct berval credU;
424 425

    ret = WLDAP32_LDAP_NO_MEMORY;
426 427 428 429

    TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
           debugstr_w(mechanism), cred, serverctrls, clientctrls, serverdata );

430 431 432
    if (!ld || !dn || !mechanism || !cred || !serverdata)
        return WLDAP32_LDAP_PARAM_ERROR;

433
    dnU = strWtoU( dn );
434
    if (!dnU) goto exit;
435 436

    mechanismU = strWtoU( mechanism );
437
    if (!mechanismU) goto exit;
438

439 440 441 442 443 444 445 446
    if (serverctrls) {
        serverctrlsU = controlarrayWtoU( serverctrls );
        if (!serverctrlsU) goto exit;
    }
    if (clientctrls) {
        clientctrlsU = controlarrayWtoU( clientctrls );
        if (!clientctrlsU) goto exit;
    }
447

448 449 450
    credU.bv_len = cred->bv_len;
    credU.bv_val = cred->bv_val;

451 452
    ret = map_error( ldap_sasl_bind_s( ld, dnU, mechanismU, &credU,
                                       serverctrlsU, clientctrlsU, (struct berval **)serverdata ));
453

454
exit:
455 456 457 458 459 460 461 462 463
    strfreeU( dnU );
    strfreeU( mechanismU );
    controlarrayfreeU( serverctrlsU );
    controlarrayfreeU( clientctrlsU );

#endif
    return ret;
}

464 465 466 467 468
/***********************************************************************
 *      ldap_simple_bindA     (WLDAP32.@)
 *
 * See ldap_simple_bindW.
 */
469
ULONG CDECL ldap_simple_bindA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR passwd )
470
{
471
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
472
#ifdef HAVE_LDAP
473
    WCHAR *dnW = NULL, *passwdW = NULL;
474 475

    ret = WLDAP32_LDAP_NO_MEMORY;
476 477 478

    TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), passwd );

479
    if (!ld) return ~0u;
480

481 482 483 484 485 486 487 488
    if (dn) {
        dnW = strAtoW( dn );
        if (!dnW) goto exit;
    }
    if (passwd) {
        passwdW = strAtoW( passwd );
        if (!passwdW) goto exit;
    }
489 490 491

    ret = ldap_simple_bindW( ld, dnW, passwdW );

492
exit:
493 494 495 496 497 498 499
    strfreeW( dnW );
    strfreeW( passwdW );

#endif
    return ret;
}

500 501 502 503 504
/***********************************************************************
 *      ldap_simple_bindW     (WLDAP32.@)
 *
 * Authenticate with an LDAP server (asynchronous operation).
 *
505
 * PARAMS
506 507 508 509 510 511 512 513 514 515 516
 *  ld      [I] Pointer to an LDAP context.
 *  dn      [I] DN of entry to bind as.
 *  passwd  [I] Password string.
 *
 * RETURNS
 *  Success: Message ID of the bind operation.
 *  Failure: An LDAP error code.
 *
 * NOTES
 *  Set dn and passwd to NULL to bind as an anonymous user. 
 */
517
ULONG CDECL ldap_simple_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR passwd )
518
{
519
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
520
#ifdef HAVE_LDAP
521
    char *dnU = NULL, *passwdU = NULL;
522 523
    struct berval pwd = { 0, NULL };
    int msg;
524 525

    ret = WLDAP32_LDAP_NO_MEMORY;
526 527 528

    TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), passwd );

529
    if (!ld) return ~0u;
530

531 532 533 534 535 536 537
    if (dn) {
        dnU = strWtoU( dn );
        if (!dnU) goto exit;
    }
    if (passwd) {
        passwdU = strWtoU( passwd );
        if (!passwdU) goto exit;
538 539 540

        pwd.bv_len = strlen( passwdU );
        pwd.bv_val = passwdU;
541
    }
542

543 544 545 546 547
    ret = ldap_sasl_bind( ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, &msg );

    if (ret == LDAP_SUCCESS)
        ret = msg;
    else
548
        ret = ~0u;
549

550
exit:
551 552 553 554 555 556 557
    strfreeU( dnU );
    strfreeU( passwdU );

#endif
    return ret;
}

558 559 560 561 562
/***********************************************************************
 *      ldap_simple_bind_sA     (WLDAP32.@)
 *
 * See ldap_simple_bind_sW.
 */
563
ULONG CDECL ldap_simple_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR passwd )
564
{
565
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
566
#ifdef HAVE_LDAP
567
    WCHAR *dnW = NULL, *passwdW = NULL;
568 569

    ret = WLDAP32_LDAP_NO_MEMORY;
570 571 572

    TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), passwd );

573
    if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
574

575 576 577 578 579 580 581 582
    if (dn) {
        dnW = strAtoW( dn );
        if (!dnW) goto exit;
    }
    if (passwd) {
        passwdW = strAtoW( passwd );
        if (!passwdW) goto exit;
    }
583 584 585

    ret = ldap_simple_bind_sW( ld, dnW, passwdW );

586
exit:
587 588 589 590 591 592 593
    strfreeW( dnW );
    strfreeW( passwdW );

#endif
    return ret;
}

594 595 596 597 598
/***********************************************************************
 *      ldap_simple_bind_sW     (WLDAP32.@)
 *
 * Authenticate with an LDAP server (synchronous operation).
 *
599
 * PARAMS
600 601 602 603 604 605 606 607 608 609 610
 *  ld      [I] Pointer to an LDAP context.
 *  dn      [I] DN of entry to bind as.
 *  passwd  [I] Password string.
 *
 * RETURNS
 *  Success: LDAP_SUCCESS
 *  Failure: An LDAP error code.
 *
 * NOTES
 *  Set dn and passwd to NULL to bind as an anonymous user. 
 */
611
ULONG CDECL ldap_simple_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR passwd )
612
{
613
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
614
#ifdef HAVE_LDAP
615
    char *dnU = NULL, *passwdU = NULL;
616
    struct berval pwd = { 0, NULL };
617 618

    ret = WLDAP32_LDAP_NO_MEMORY;
619 620 621

    TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), passwd );

622
    if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
623

624 625 626 627 628 629 630
    if (dn) {
        dnU = strWtoU( dn );
        if (!dnU) goto exit;
    }
    if (passwd) {
        passwdU = strWtoU( passwd );
        if (!passwdU) goto exit;
631 632 633

        pwd.bv_len = strlen( passwdU );
        pwd.bv_val = passwdU;
634
    }
635

636
    ret = map_error( ldap_sasl_bind_s( ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, NULL ));
637

638
exit:
639 640 641 642 643 644 645
    strfreeU( dnU );
    strfreeU( passwdU );

#endif
    return ret;
}

646 647 648 649 650
/***********************************************************************
 *      ldap_unbind     (WLDAP32.@)
 *
 * Close LDAP connection and free resources (asynchronous operation).
 *
651
 * PARAMS
652 653 654 655 656 657
 *  ld  [I] Pointer to an LDAP context.
 *
 * RETURNS
 *  Success: LDAP_SUCCESS
 *  Failure: An LDAP error code.
 */
658
ULONG CDECL WLDAP32_ldap_unbind( WLDAP32_LDAP *ld )
659
{
660
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
661 662 663
#ifdef HAVE_LDAP

    TRACE( "(%p)\n", ld );
664 665

    if (ld)
666
        ret = map_error( ldap_unbind_ext( ld, NULL, NULL ));
667 668
    else
        ret = WLDAP32_LDAP_PARAM_ERROR;
669 670 671 672 673

#endif
    return ret;
}

674 675 676 677 678
/***********************************************************************
 *      ldap_unbind_s     (WLDAP32.@)
 *
 * Close LDAP connection and free resources (synchronous operation).
 *
679
 * PARAMS
680 681 682 683 684 685
 *  ld  [I] Pointer to an LDAP context.
 *
 * RETURNS
 *  Success: LDAP_SUCCESS
 *  Failure: An LDAP error code.
 */
686
ULONG CDECL WLDAP32_ldap_unbind_s( WLDAP32_LDAP *ld )
687
{
688
    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
689 690 691
#ifdef HAVE_LDAP

    TRACE( "(%p)\n", ld );
692 693

    if (ld)
694
        ret = map_error( ldap_unbind_ext_s( ld, NULL, NULL ));
695 696
    else
        ret = WLDAP32_LDAP_PARAM_ERROR;
697 698 699 700

#endif
    return ret;
}