[PATCH 3/5] wldap32: Move support for bind functions to the Unix library.

Hans Leidekker hans at codeweavers.com
Wed Apr 14 02:40:27 CDT 2021


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/wldap32/bind.c            | 419 ++++++++++-----------------------
 dlls/wldap32/libldap.c         |  58 ++++-
 dlls/wldap32/libldap.h         |  52 +++-
 dlls/wldap32/main.c            |   6 +-
 dlls/wldap32/option.c          |   6 +-
 dlls/wldap32/winldap_private.h |   2 +-
 6 files changed, 234 insertions(+), 309 deletions(-)

diff --git a/dlls/wldap32/bind.c b/dlls/wldap32/bind.c
index 1498dc49fe6..0078b532e66 100644
--- a/dlls/wldap32/bind.c
+++ b/dlls/wldap32/bind.c
@@ -18,63 +18,40 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "config.h"
-#include "wine/port.h"
-
 #include <stdarg.h>
-#ifdef HAVE_LDAP_H
-#include <ldap.h>
-#endif
-#ifdef HAVE_SASL_SASL_H
-#include <sasl/sasl.h>
-#endif
-
 #include "windef.h"
 #include "winbase.h"
 #include "winnls.h"
 #include "rpc.h"
 
-#include "winldap_private.h"
-#include "wldap32.h"
 #include "wine/debug.h"
+#include "wine/heap.h"
+#include "winldap_private.h"
 
-#ifdef HAVE_LDAP
 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
-#endif
 
 /***********************************************************************
  *      ldap_bindA     (WLDAP32.@)
  *
  * See ldap_bindW.
  */
-ULONG CDECL ldap_bindA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR cred, ULONG method )
+ULONG CDECL ldap_bindA( WLDAP32_LDAP *ld, char *dn, char *cred, ULONG method )
 {
-    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+    ULONG ret = WLDAP32_LDAP_NO_MEMORY;
     WCHAR *dnW = NULL, *credW = NULL;
 
-    ret = WLDAP32_LDAP_NO_MEMORY;
-
     TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_a(dn), cred, method );
 
     if (!ld) return ~0u;
 
-    if (dn) {
-        dnW = strAtoW( dn );
-        if (!dnW) goto exit;
-    }
-    if (cred) {
-        credW = strAtoW( cred );
-        if (!credW) goto exit;
-    }
+    if (dn && !(dnW = strAtoW( dn ))) goto exit;
+    if (cred && !(credW = strAtoW( cred ))) goto exit;
 
     ret = ldap_bindW( ld, dnW, credW, method );
 
 exit:
     strfreeW( dnW );
     strfreeW( credW );
-
-#endif
     return ret;
 }
 
@@ -96,36 +73,28 @@ exit:
  * NOTES
  *  Only LDAP_AUTH_SIMPLE is supported (just like native).
  */
-ULONG CDECL ldap_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method )
+ULONG CDECL ldap_bindW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *cred, ULONG method )
 {
-    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+    ULONG ret = WLDAP32_LDAP_NO_MEMORY;
     char *dnU = NULL, *credU = NULL;
-    struct berval pwd = { 0, NULL };
+    struct bervalU pwd = { 0, NULL };
     int msg;
 
-    ret = WLDAP32_LDAP_NO_MEMORY;
-
     TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_w(dn), cred, method );
 
     if (!ld) return ~0u;
-    if (method != LDAP_AUTH_SIMPLE) return WLDAP32_LDAP_PARAM_ERROR;
-
-    if (dn) {
-        dnU = strWtoU( dn );
-        if (!dnU) goto exit;
-    }
-    if (cred) {
-        credU = strWtoU( cred );
-        if (!credU) goto exit;
+    if (method != WLDAP32_LDAP_AUTH_SIMPLE) return WLDAP32_LDAP_PARAM_ERROR;
 
+    if (dn && !(dnU = strWtoU( dn ))) goto exit;
+    if (cred)
+    {
+        if (!(credU = strWtoU( cred ))) goto exit;
         pwd.bv_len = strlen( credU );
         pwd.bv_val = credU;
     }
 
-    ret = ldap_sasl_bind( ld->ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, &msg );
-
-    if (ret == LDAP_SUCCESS)
+    ret = map_error( ldap_funcs->ldap_sasl_bind( ld->ld, dnU, 0, &pwd, NULL, NULL, &msg ) );
+    if (ret == WLDAP32_LDAP_SUCCESS)
         ret = msg;
     else
         ret = ~0u;
@@ -133,8 +102,6 @@ ULONG CDECL ldap_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method )
 exit:
     strfreeU( dnU );
     strfreeU( credU );
-
-#endif
     return ret;
 }
 
@@ -143,30 +110,23 @@ exit:
  *
  * See ldap_bind_sW.
  */
-ULONG CDECL ldap_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR cred, ULONG method )
+ULONG CDECL ldap_bind_sA( WLDAP32_LDAP *ld, char *dn, char *cred, ULONG method )
 {
-    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+    ULONG ret = WLDAP32_LDAP_NO_MEMORY;
     WCHAR *dnW = NULL, *credW = NULL;
 
-    ret = WLDAP32_LDAP_NO_MEMORY;
-
     TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_a(dn), cred, method );
 
     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
 
-    if (dn) {
-        dnW = strAtoW( dn );
-        if (!dnW) goto exit;
-    }
-    if (cred) {
-        if (method == LDAP_AUTH_SIMPLE)
+    if (dn && !(dnW = strAtoW( dn ))) goto exit;
+    if (cred)
+    {
+        if (method == WLDAP32_LDAP_AUTH_SIMPLE)
         {
-            credW = strAtoW( cred );
-            if (!credW) goto exit;
+            if (!(credW = strAtoW( cred ))) goto exit;
         }
-        else
-            credW = (WCHAR *)cred /* SEC_WINNT_AUTH_IDENTITY_A */;
+        else credW = (WCHAR *)cred /* SEC_WINNT_AUTH_IDENTITY_A */;
     }
 
     ret = ldap_bind_sW( ld, dnW, credW, method );
@@ -174,24 +134,19 @@ ULONG CDECL ldap_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR cred, ULONG method )
 exit:
     strfreeW( dnW );
     if (credW != (WCHAR *)cred) strfreeW( credW );
-
-#endif
     return ret;
 }
 
-#ifdef HAVE_LDAP
-
-static int sasl_interact( LDAP *ld, unsigned flags, void *defaults, void *interact )
+int CDECL sasl_interact_cb( void *ld, unsigned flags, void *defaults, void *interact )
 {
-#ifdef HAVE_SASL_SASL_H
     SEC_WINNT_AUTH_IDENTITY_A *id = defaults;
-    sasl_interact_t *sasl = interact;
+    struct sasl_interactU *sasl = interact;
 
-    TRACE( "%p,%08x,%p,%p\n", ld, flags, defaults, interact );
+    TRACE( "(%p, 0x%08x, %p, %p)\n", ld, flags, defaults, interact );
 
     while (sasl->id != SASL_CB_LIST_END)
     {
-        TRACE("sasl->id = %04lx\n", sasl->id);
+        TRACE( "sasl->id = %04lx\n", sasl->id );
 
         if (sasl->id == SASL_CB_GETREALM)
         {
@@ -208,19 +163,12 @@ static int sasl_interact( LDAP *ld, unsigned flags, void *defaults, void *intera
             sasl->result = id->Password;
             sasl->len = id->PasswordLength;
         }
-
         sasl++;
     }
 
-    return LDAP_SUCCESS;
-#else
-    FIXME( "%p,%08x,%p,%p: stub\n", ld, flags, defaults, interact );
-    return LDAP_SUCCESS;
-#endif /* HAVE_SASL_SASL_H */
+    return WLDAP32_LDAP_SUCCESS;
 }
 
-#endif /* HAVE_LDAP */
-
 /***********************************************************************
  *      ldap_bind_sW     (WLDAP32.@)
  *
@@ -236,36 +184,27 @@ static int sasl_interact( LDAP *ld, unsigned flags, void *defaults, void *intera
  *  Success: LDAP_SUCCESS
  *  Failure: An LDAP error code.
  */
-ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method )
+ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *cred, ULONG method )
 {
-    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+    ULONG ret = WLDAP32_LDAP_NO_MEMORY;
     char *dnU = NULL, *credU = NULL;
-    struct berval pwd = { 0, NULL };
-
-    ret = WLDAP32_LDAP_NO_MEMORY;
+    struct bervalU pwd = { 0, NULL };
 
     TRACE( "(%p, %s, %p, 0x%08x)\n", ld, debugstr_w(dn), cred, method );
 
     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
 
-    if (method == LDAP_AUTH_SIMPLE)
+    if (method == WLDAP32_LDAP_AUTH_SIMPLE)
     {
-        if (dn)
-        {
-            dnU = strWtoU( dn );
-            if (!dnU) goto exit;
-        }
+        if (dn && !(dnU = strWtoU( dn ))) goto exit;
         if (cred)
         {
-            credU = strWtoU( cred );
-            if (!credU) goto exit;
-
+            if (!(credU = strWtoU( cred ))) goto exit;
             pwd.bv_len = strlen( credU );
             pwd.bv_val = credU;
         }
 
-        ret = map_error( ldap_sasl_bind_s( ld->ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, NULL ));
+        ret = map_error( ldap_funcs->ldap_sasl_bind_s( ld->ld, dnU, 0, &pwd, NULL, NULL, NULL ) );
     }
     else if (method == WLDAP32_LDAP_AUTH_NEGOTIATE)
     {
@@ -274,7 +213,6 @@ ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method
         SEC_WINNT_AUTH_IDENTITY_W *id = (SEC_WINNT_AUTH_IDENTITY_W *)cred;
 
         memset( &idU, 0, sizeof(idU) );
-
         if (id)
         {
             if (id->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI)
@@ -283,19 +221,17 @@ ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method
                 idW.Domain = (unsigned short *)strnAtoW( (char *)id->Domain, id->DomainLength, &idW.DomainLength );
                 idW.User = (unsigned short *)strnAtoW( (char *)id->User, id->UserLength, &idW.UserLength );
                 idW.Password = (unsigned short *)strnAtoW( (char *)id->Password, id->PasswordLength, &idW.PasswordLength );
-
                 id = &idW;
             }
-
             idU.Domain = (unsigned char *)strnWtoU( id->Domain, id->DomainLength, &idU.DomainLength );
             idU.User = (unsigned char *)strnWtoU( id->User, id->UserLength, &idU.UserLength );
             idU.Password = (unsigned char *)strnWtoU( id->Password, id->PasswordLength, &idU.PasswordLength );
         }
 
-        ret = map_error( ldap_sasl_interactive_bind_s( ld->ld,
-                             NULL /* server will ignore DN anyway */,
-                             NULL /* query supportedSASLMechanisms */,
-                             NULL, NULL, LDAP_SASL_QUIET, sasl_interact, &idU ));
+        ret = map_error( ldap_funcs->ldap_sasl_interactive_bind_s( ld->ld,
+                                                                   NULL /* server will ignore DN anyway */,
+                                                                   NULL /* query supportedSASLMechanisms */,
+                                                                   NULL, NULL, 2 /* LDAP_SASL_QUIET */, &idU ) );
 
         if (id && (id->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI))
         {
@@ -317,8 +253,6 @@ ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method
 exit:
     strfreeU( dnU );
     strfreeU( credU );
-
-#endif
     return ret;
 }
 
@@ -327,37 +261,23 @@ exit:
  *
  * See ldap_sasl_bindW.
  */
-ULONG CDECL ldap_sasl_bindA( WLDAP32_LDAP *ld, const PCHAR dn,
-    const PCHAR mechanism, const BERVAL *cred, PLDAPControlA *serverctrls,
-    PLDAPControlA *clientctrls, int *message )
+ULONG CDECL ldap_sasl_bindA( WLDAP32_LDAP *ld, const PCHAR dn, const PCHAR mechanism, const BERVAL *cred,
+    LDAPControlA **serverctrls, LDAPControlA **clientctrls, int *message )
 {
-    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+    ULONG ret = WLDAP32_LDAP_NO_MEMORY;
     WCHAR *dnW, *mechanismW = NULL;
     LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
 
-    ret = WLDAP32_LDAP_NO_MEMORY;
-
     TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
            debugstr_a(mechanism), cred, serverctrls, clientctrls, message );
 
     if (!ld || !dn || !mechanism || !cred || !message)
         return WLDAP32_LDAP_PARAM_ERROR;
 
-    dnW = strAtoW( dn );
-    if (!dnW) goto exit;
-
-    mechanismW = strAtoW( mechanism );
-    if (!mechanismW) goto exit;
-
-    if (serverctrls) {
-        serverctrlsW = controlarrayAtoW( serverctrls );
-        if (!serverctrlsW) goto exit;
-    }
-    if (clientctrls) {
-        clientctrlsW = controlarrayAtoW( clientctrls );
-        if (!clientctrlsW) goto exit;
-    }
+    if (!(dnW = strAtoW( dn ))) goto exit;
+    if (!(mechanismW = strAtoW( mechanism ))) goto exit;
+    if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
+    if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
 
     ret = ldap_sasl_bindW( ld, dnW, mechanismW, cred, serverctrlsW, clientctrlsW, message );
 
@@ -366,8 +286,6 @@ exit:
     strfreeW( mechanismW );
     controlarrayfreeW( serverctrlsW );
     controlarrayfreeW( clientctrlsW );
-
-#endif
     return ret;
 }
 
@@ -383,7 +301,7 @@ exit:
  *  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. 
+ *  message     [O] Message ID of the bind operation.
  *
  * RETURNS
  *  Success: LDAP_SUCCESS
@@ -393,17 +311,13 @@ exit:
  *  The serverctrls and clientctrls parameters are optional and should
  *  be set to NULL if not used.
  */
-ULONG CDECL ldap_sasl_bindW( WLDAP32_LDAP *ld, const PWCHAR dn,
-    const PWCHAR mechanism, const BERVAL *cred, PLDAPControlW *serverctrls,
-    PLDAPControlW *clientctrls, int *message )
+ULONG CDECL ldap_sasl_bindW( WLDAP32_LDAP *ld, const PWCHAR dn, const PWCHAR mechanism, const BERVAL *cred,
+    LDAPControlW **serverctrls, LDAPControlW **clientctrls, int *message )
 {
-    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+    ULONG ret = WLDAP32_LDAP_NO_MEMORY;
     char *dnU, *mechanismU = NULL;
-    LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
-    struct berval credU;
-
-    ret = WLDAP32_LDAP_NO_MEMORY;
+    LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
+    struct bervalU credU;
 
     TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
            debugstr_w(mechanism), cred, serverctrls, clientctrls, message );
@@ -411,34 +325,21 @@ ULONG CDECL ldap_sasl_bindW( WLDAP32_LDAP *ld, const PWCHAR dn,
     if (!ld || !dn || !mechanism || !cred || !message)
         return WLDAP32_LDAP_PARAM_ERROR;
 
-    dnU = strWtoU( dn );
-    if (!dnU) goto exit;
-
-    mechanismU = strWtoU( mechanism );
-    if (!mechanismU) goto exit;
-
-    if (serverctrls) {
-        serverctrlsU = controlarrayWtoU( serverctrls );
-        if (!serverctrlsU) goto exit;
-    }
-    if (clientctrls) {
-        clientctrlsU = controlarrayWtoU( clientctrls );
-        if (!clientctrlsU) goto exit;
-    }
+    if (!(dnU = strWtoU( dn ))) goto exit;
+    if (!(mechanismU = strWtoU( mechanism ))) goto exit;
+    if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
+    if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
 
     credU.bv_len = cred->bv_len;
     credU.bv_val = cred->bv_val;
 
-    ret = map_error( ldap_sasl_bind( ld->ld, dnU, mechanismU, &credU,
-                                     serverctrlsU, clientctrlsU, message ));
+    ret = map_error( ldap_funcs->ldap_sasl_bind( ld->ld, dnU, mechanismU, &credU, serverctrlsU, clientctrlsU, message ) );
 
 exit:
     strfreeU( dnU );
     strfreeU( mechanismU );
     controlarrayfreeU( serverctrlsU );
     controlarrayfreeU( clientctrlsU );
-
-#endif
     return ret;
 }
 
@@ -447,37 +348,23 @@ exit:
  *
  * See ldap_sasl_bind_sW.
  */
-ULONG CDECL ldap_sasl_bind_sA( WLDAP32_LDAP *ld, const PCHAR dn,
-    const PCHAR mechanism, const BERVAL *cred, PLDAPControlA *serverctrls,
-    PLDAPControlA *clientctrls, PBERVAL *serverdata )
+ULONG CDECL ldap_sasl_bind_sA( WLDAP32_LDAP *ld, const PCHAR dn, const PCHAR mechanism, const BERVAL *cred,
+    LDAPControlA **serverctrls, LDAPControlA **clientctrls, BERVAL **serverdata )
 {
-    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+    ULONG ret = WLDAP32_LDAP_NO_MEMORY;
     WCHAR *dnW, *mechanismW = NULL;
     LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL;
 
-    ret = WLDAP32_LDAP_NO_MEMORY;
-
     TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn),
            debugstr_a(mechanism), cred, serverctrls, clientctrls, serverdata );
 
     if (!ld || !dn || !mechanism || !cred || !serverdata)
         return WLDAP32_LDAP_PARAM_ERROR;
 
-    dnW = strAtoW( dn );
-    if (!dnW) goto exit;
-
-    mechanismW = strAtoW( mechanism );
-    if (!mechanismW) goto exit;
-
-    if (serverctrls) {
-        serverctrlsW = controlarrayAtoW( serverctrls );
-        if (!serverctrlsW) goto exit;
-    }
-    if (clientctrls) {
-        clientctrlsW = controlarrayAtoW( clientctrls );
-        if (!clientctrlsW) goto exit;
-    }
+    if (!(dnW = strAtoW( dn ))) goto exit;
+    if (!(mechanismW = strAtoW( mechanism ))) goto exit;
+    if (serverctrls && !(serverctrlsW = controlarrayAtoW( serverctrls ))) goto exit;
+    if (clientctrls && !(clientctrlsW = controlarrayAtoW( clientctrls ))) goto exit;
 
     ret = ldap_sasl_bind_sW( ld, dnW, mechanismW, cred, serverctrlsW, clientctrlsW, serverdata );
 
@@ -486,8 +373,6 @@ exit:
     strfreeW( mechanismW );
     controlarrayfreeW( serverctrlsW );
     controlarrayfreeW( clientctrlsW );
-
-#endif
     return ret;
 }
 
@@ -514,16 +399,13 @@ exit:
  *  be set to NULL if not used.
  */
 ULONG CDECL ldap_sasl_bind_sW( WLDAP32_LDAP *ld, const PWCHAR dn,
-    const PWCHAR mechanism, const BERVAL *cred, PLDAPControlW *serverctrls,
-    PLDAPControlW *clientctrls, PBERVAL *serverdata )
+    const PWCHAR mechanism, const BERVAL *cred, LDAPControlW **serverctrls,
+    LDAPControlW **clientctrls, BERVAL **serverdata )
 {
-    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+    ULONG ret = WLDAP32_LDAP_NO_MEMORY;
     char *dnU, *mechanismU = NULL;
-    LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL;
-    struct berval credU;
-
-    ret = WLDAP32_LDAP_NO_MEMORY;
+    LDAPControlU **serverctrlsU = NULL, **clientctrlsU = NULL;
+    struct bervalU *dataU, credU;
 
     TRACE( "(%p, %s, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn),
            debugstr_w(mechanism), cred, serverctrls, clientctrls, serverdata );
@@ -531,34 +413,28 @@ ULONG CDECL ldap_sasl_bind_sW( WLDAP32_LDAP *ld, const PWCHAR dn,
     if (!ld || !dn || !mechanism || !cred || !serverdata)
         return WLDAP32_LDAP_PARAM_ERROR;
 
-    dnU = strWtoU( dn );
-    if (!dnU) goto exit;
-
-    mechanismU = strWtoU( mechanism );
-    if (!mechanismU) goto exit;
-
-    if (serverctrls) {
-        serverctrlsU = controlarrayWtoU( serverctrls );
-        if (!serverctrlsU) goto exit;
-    }
-    if (clientctrls) {
-        clientctrlsU = controlarrayWtoU( clientctrls );
-        if (!clientctrlsU) goto exit;
-    }
+    if (!(dnU = strWtoU( dn ))) goto exit;
+    if (!(mechanismU = strWtoU( mechanism ))) goto exit;
+    if (serverctrls && !(serverctrlsU = controlarrayWtoU( serverctrls ))) goto exit;
+    if (clientctrls && !(clientctrlsU = controlarrayWtoU( clientctrls ))) goto exit;
 
     credU.bv_len = cred->bv_len;
     credU.bv_val = cred->bv_val;
 
-    ret = map_error( ldap_sasl_bind_s( ld->ld, dnU, mechanismU, &credU,
-                                       serverctrlsU, clientctrlsU, (struct berval **)serverdata ));
+    ret = map_error( ldap_funcs->ldap_sasl_bind_s( ld->ld, dnU, mechanismU, &credU, serverctrlsU, clientctrlsU, &dataU ) );
+    if (ret == WLDAP32_LDAP_SUCCESS)
+    {
+        BERVAL *ptr;
+        if (!(ptr = bervalUtoW( dataU ))) ret = WLDAP32_LDAP_NO_MEMORY;
+        else *serverdata = ptr;
+        ldap_funcs->ber_bvfree( dataU );
+    }
 
 exit:
     strfreeU( dnU );
     strfreeU( mechanismU );
     controlarrayfreeU( serverctrlsU );
     controlarrayfreeU( clientctrlsU );
-
-#endif
     return ret;
 }
 
@@ -567,34 +443,23 @@ exit:
  *
  * See ldap_simple_bindW.
  */
-ULONG CDECL ldap_simple_bindA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR passwd )
+ULONG CDECL ldap_simple_bindA( WLDAP32_LDAP *ld, char *dn, char *passwd )
 {
-    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+    ULONG ret = WLDAP32_LDAP_NO_MEMORY;
     WCHAR *dnW = NULL, *passwdW = NULL;
 
-    ret = WLDAP32_LDAP_NO_MEMORY;
-
     TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), passwd );
 
     if (!ld) return ~0u;
 
-    if (dn) {
-        dnW = strAtoW( dn );
-        if (!dnW) goto exit;
-    }
-    if (passwd) {
-        passwdW = strAtoW( passwd );
-        if (!passwdW) goto exit;
-    }
+    if (dn && !(dnW = strAtoW( dn ))) goto exit;
+    if (passwd && !(passwdW = strAtoW( passwd ))) goto exit;
 
     ret = ldap_simple_bindW( ld, dnW, passwdW );
 
 exit:
     strfreeW( dnW );
     strfreeW( passwdW );
-
-#endif
     return ret;
 }
 
@@ -613,37 +478,29 @@ exit:
  *  Failure: An LDAP error code.
  *
  * NOTES
- *  Set dn and passwd to NULL to bind as an anonymous user. 
+ *  Set dn and passwd to NULL to bind as an anonymous user.
  */
-ULONG CDECL ldap_simple_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR passwd )
+ULONG CDECL ldap_simple_bindW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *passwd )
 {
-    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+    ULONG ret = WLDAP32_LDAP_NO_MEMORY;
     char *dnU = NULL, *passwdU = NULL;
-    struct berval pwd = { 0, NULL };
+    struct bervalU pwd = { 0, NULL };
     int msg;
 
-    ret = WLDAP32_LDAP_NO_MEMORY;
-
     TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), passwd );
 
     if (!ld) return ~0u;
 
-    if (dn) {
-        dnU = strWtoU( dn );
-        if (!dnU) goto exit;
-    }
-    if (passwd) {
-        passwdU = strWtoU( passwd );
-        if (!passwdU) goto exit;
-
+    if (dn && !(dnU = strWtoU( dn ))) goto exit;
+    if (passwd)
+    {
+        if (!(passwdU = strWtoU( passwd ))) goto exit;
         pwd.bv_len = strlen( passwdU );
         pwd.bv_val = passwdU;
     }
 
-    ret = ldap_sasl_bind( ld->ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, &msg );
-
-    if (ret == LDAP_SUCCESS)
+    ret = map_error( ldap_funcs->ldap_sasl_bind( ld->ld, dnU, 0, &pwd, NULL, NULL, &msg ) );
+    if (ret == WLDAP32_LDAP_SUCCESS)
         ret = msg;
     else
         ret = ~0u;
@@ -651,8 +508,6 @@ ULONG CDECL ldap_simple_bindW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR passwd )
 exit:
     strfreeU( dnU );
     strfreeU( passwdU );
-
-#endif
     return ret;
 }
 
@@ -661,34 +516,23 @@ exit:
  *
  * See ldap_simple_bind_sW.
  */
-ULONG CDECL ldap_simple_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR passwd )
+ULONG CDECL ldap_simple_bind_sA( WLDAP32_LDAP *ld, char *dn, char *passwd )
 {
-    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+    ULONG ret = WLDAP32_LDAP_NO_MEMORY;
     WCHAR *dnW = NULL, *passwdW = NULL;
 
-    ret = WLDAP32_LDAP_NO_MEMORY;
-
     TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), passwd );
 
     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
 
-    if (dn) {
-        dnW = strAtoW( dn );
-        if (!dnW) goto exit;
-    }
-    if (passwd) {
-        passwdW = strAtoW( passwd );
-        if (!passwdW) goto exit;
-    }
+    if (dn && !(dnW = strAtoW( dn ))) goto exit;
+    if (passwd && !(passwdW = strAtoW( passwd ))) goto exit;
 
     ret = ldap_simple_bind_sW( ld, dnW, passwdW );
 
 exit:
     strfreeW( dnW );
     strfreeW( passwdW );
-
-#endif
     return ret;
 }
 
@@ -707,40 +551,31 @@ exit:
  *  Failure: An LDAP error code.
  *
  * NOTES
- *  Set dn and passwd to NULL to bind as an anonymous user. 
+ *  Set dn and passwd to NULL to bind as an anonymous user.
  */
-ULONG CDECL ldap_simple_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR passwd )
+ULONG CDECL ldap_simple_bind_sW( WLDAP32_LDAP *ld, WCHAR *dn, WCHAR *passwd )
 {
-    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+    ULONG ret = WLDAP32_LDAP_NO_MEMORY;
     char *dnU = NULL, *passwdU = NULL;
-    struct berval pwd = { 0, NULL };
-
-    ret = WLDAP32_LDAP_NO_MEMORY;
+    struct bervalU pwd = { 0, NULL };
 
     TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), passwd );
 
     if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
 
-    if (dn) {
-        dnU = strWtoU( dn );
-        if (!dnU) goto exit;
-    }
-    if (passwd) {
-        passwdU = strWtoU( passwd );
-        if (!passwdU) goto exit;
-
+    if (dn && !(dnU = strWtoU( dn ))) goto exit;
+    if (passwd)
+    {
+        if (!(passwdU = strWtoU( passwd ))) goto exit;
         pwd.bv_len = strlen( passwdU );
         pwd.bv_val = passwdU;
     }
 
-    ret = map_error( ldap_sasl_bind_s( ld->ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, NULL ));
+    ret = map_error( ldap_funcs->ldap_sasl_bind_s( ld->ld, dnU, 0, &pwd, NULL, NULL, NULL ) );
 
 exit:
     strfreeU( dnU );
     strfreeU( passwdU );
-
-#endif
     return ret;
 }
 
@@ -758,22 +593,16 @@ exit:
  */
 ULONG CDECL WLDAP32_ldap_unbind( WLDAP32_LDAP *ld )
 {
-    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+    ULONG ret;
 
     TRACE( "(%p)\n", ld );
 
-    if (ld)
-    {
-        ret = map_error( ldap_unbind_ext( ld->ld, NULL, NULL ));
-        if ( ld->ld_server_ctrls )
-            ldap_value_free_len( ld->ld_server_ctrls );
-        heap_free( ld );
-    }
-    else
-        ret = WLDAP32_LDAP_PARAM_ERROR;
+    if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
+
+    ret = map_error( ldap_funcs->ldap_unbind_ext( ld->ld, NULL, NULL ));
+    if (ld->ld_server_ctrls) ldap_funcs->ldap_value_free_len( ld->ld_server_ctrls );
 
-#endif
+    heap_free( ld );
     return ret;
 }
 
@@ -791,21 +620,15 @@ ULONG CDECL WLDAP32_ldap_unbind( WLDAP32_LDAP *ld )
  */
 ULONG CDECL WLDAP32_ldap_unbind_s( WLDAP32_LDAP *ld )
 {
-    ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED;
-#ifdef HAVE_LDAP
+    ULONG ret;
 
     TRACE( "(%p)\n", ld );
 
-    if (ld)
-    {
-        ret = map_error( ldap_unbind_ext_s( ld->ld, NULL, NULL ));
-        if ( ld->ld_server_ctrls )
-            ldap_value_free_len( ld->ld_server_ctrls );
-        heap_free( ld );
-    }
-    else
-        ret = WLDAP32_LDAP_PARAM_ERROR;
+    if (!ld) return WLDAP32_LDAP_PARAM_ERROR;
+
+    ret = map_error( ldap_funcs->ldap_unbind_ext_s( ld->ld, NULL, NULL ) );
+    if (ld->ld_server_ctrls) ldap_funcs->ldap_value_free_len( ld->ld_server_ctrls );
 
-#endif
+    heap_free( ld );
     return ret;
 }
diff --git a/dlls/wldap32/libldap.c b/dlls/wldap32/libldap.c
index 3436cffc4a1..380c589257b 100644
--- a/dlls/wldap32/libldap.c
+++ b/dlls/wldap32/libldap.c
@@ -52,6 +52,8 @@ C_ASSERT( sizeof(LDAPVLVInfoU) == sizeof(LDAPVLVInfo) );
 
 static LDAPMod *nullattrs[] = { NULL };
 
+static const struct ldap_callbacks *callbacks;
+
 void * CDECL wrap_ber_alloc_t( int options )
 {
     return ber_alloc_t( options );
@@ -292,7 +294,7 @@ int WINAPIV wrap_ber_scanf( void *ber, char *fmt, ... )
     return ret;
 }
 
-int CDECL wrap_ldap_add_ext( void *ld, char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
+int CDECL wrap_ldap_add_ext( void *ld, const char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
                              LDAPControlU **clientctrls, ULONG *msg )
 {
     int dummy;
@@ -300,7 +302,7 @@ int CDECL wrap_ldap_add_ext( void *ld, char *dn, LDAPModU **attrs, LDAPControlU
                          (LDAPControl **)clientctrls, msg ? (int *)msg : &dummy );
 }
 
-int CDECL wrap_ldap_add_ext_s( void *ld, char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
+int CDECL wrap_ldap_add_ext_s( void *ld, const char *dn, LDAPModU **attrs, LDAPControlU **serverctrls,
                                LDAPControlU **clientctrls )
 {
     return ldap_add_ext_s( ld, dn ? dn : "", attrs ? (LDAPMod **)attrs : nullattrs, (LDAPControl **)serverctrls,
@@ -312,6 +314,51 @@ void CDECL wrap_ldap_memfree( void *ptr )
     return ldap_memfree( ptr );
 }
 
+int CDECL wrap_ldap_sasl_bind( void *ld, const char *dn, const char *mech, struct bervalU *cred,
+                               LDAPControlU **serverctrls, LDAPControlU **clientctrls, int *msgid )
+{
+    return ldap_sasl_bind( ld, dn, mech, (struct berval *)cred, (LDAPControl **)serverctrls,
+                           (LDAPControl **)clientctrls, msgid );
+}
+
+int CDECL wrap_ldap_sasl_bind_s( void *ld, const char *dn, const char *mech, struct bervalU *cred,
+                                 LDAPControlU **serverctrls, LDAPControlU **clientctrls, struct bervalU **servercred )
+{
+    return ldap_sasl_bind_s( ld, dn, mech, (struct berval *)cred, (LDAPControl **)serverctrls,
+                             (LDAPControl **)clientctrls, (struct berval **)servercred );
+}
+
+static int wrap_sasl_interact( LDAP *ld, unsigned int flags, void *defaults, void *interact )
+{
+#ifdef HAVE_SASL_SASL_H
+    C_ASSERT( sizeof(struct sasl_interactU) == sizeof(struct sasl_interact) );
+    return callbacks->sasl_interact( ld, flags, defaults, interact );
+#endif
+    return -1;
+}
+
+int CDECL wrap_ldap_sasl_interactive_bind_s( void *ld, const char *dn, const char *mech, LDAPControlU **serverctrls,
+                                             LDAPControlU **clientctrls, unsigned int flags, void *defaults )
+{
+    return ldap_sasl_interactive_bind_s( ld, dn, mech, (LDAPControl **)serverctrls, (LDAPControl **)clientctrls, flags,
+                                         wrap_sasl_interact, defaults );
+}
+
+int CDECL wrap_ldap_unbind_ext( void *ld, LDAPControlU **serverctrls, LDAPControlU **clientctrls )
+{
+    return ldap_unbind_ext( ld, (LDAPControl **)serverctrls, (LDAPControl **)clientctrls );
+}
+
+int CDECL wrap_ldap_unbind_ext_s( void *ld, LDAPControlU **serverctrls, LDAPControlU **clientctrls )
+{
+    return ldap_unbind_ext_s( ld, (LDAPControl **)serverctrls, (LDAPControl **)clientctrls );
+}
+
+void CDECL wrap_ldap_value_free_len( struct bervalU **values )
+{
+    ldap_value_free_len( (struct berval **)values );
+}
+
 static const struct ldap_funcs funcs =
 {
     wrap_ber_alloc_t,
@@ -329,11 +376,18 @@ static const struct ldap_funcs funcs =
     wrap_ldap_add_ext,
     wrap_ldap_add_ext_s,
     wrap_ldap_memfree,
+    wrap_ldap_sasl_bind,
+    wrap_ldap_sasl_bind_s,
+    wrap_ldap_sasl_interactive_bind_s,
+    wrap_ldap_unbind_ext,
+    wrap_ldap_unbind_ext_s,
+    wrap_ldap_value_free_len,
 };
 
 NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
 {
     if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS;
+    callbacks = ptr_in;
     *(const struct ldap_funcs **)ptr_out = &funcs;
     return STATUS_SUCCESS;
 }
diff --git a/dlls/wldap32/libldap.h b/dlls/wldap32/libldap.h
index 4ca90d298a0..9b4f941d677 100644
--- a/dlls/wldap32/libldap.h
+++ b/dlls/wldap32/libldap.h
@@ -60,6 +60,23 @@ typedef struct
     void           *ldvlv_extradata;
 } LDAPVLVInfoU;
 
+#ifndef SASL_CB_LIST_END
+#define SASL_CB_LIST_END    0
+#define SASL_CB_USER        0x4001
+#define SASL_CB_PASS        0x4004
+#define SASL_CB_GETREALM    0x4008
+#endif
+
+typedef struct sasl_interactU
+{
+    unsigned long id;
+    const char   *challenge;
+    const char   *prompt;
+    const char   *defresult;
+    const void   *result;
+    unsigned int  len;
+} sasl_interact_tU;
+
 extern void * CDECL wrap_ber_alloc_t(int) DECLSPEC_HIDDEN;
 extern void CDECL wrap_ber_bvecfree(struct bervalU **) DECLSPEC_HIDDEN;
 extern void CDECL wrap_ber_bvfree(struct bervalU *) DECLSPEC_HIDDEN;
@@ -73,9 +90,20 @@ extern unsigned int CDECL wrap_ber_skip_tag(void *, unsigned int *) DECLSPEC_HID
 extern int WINAPIV wrap_ber_printf(void *, char *, ...) DECLSPEC_HIDDEN;
 extern int WINAPIV wrap_ber_scanf(void *, char *, ...) DECLSPEC_HIDDEN;
 
-extern int CDECL wrap_ldap_add_ext(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *) DECLSPEC_HIDDEN;
-extern int CDECL wrap_ldap_add_ext_s(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_add_ext(void *, const char *, LDAPModU **, LDAPControlU **, LDAPControlU **,
+                                   ULONG *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_add_ext_s(void *, const char *, LDAPModU **, LDAPControlU **,
+                                     LDAPControlU **) DECLSPEC_HIDDEN;
 extern void CDECL wrap_ldap_memfree(void *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_sasl_bind(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+                                     LDAPControlU **, int *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_sasl_bind_s(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+                                       LDAPControlU **, struct bervalU **) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_sasl_interactive_bind_s(void *, const char *, const char *, LDAPControlU **,
+                                                   LDAPControlU **, unsigned int, void *) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_unbind_ext(void *, LDAPControlU **, LDAPControlU **) DECLSPEC_HIDDEN;
+extern int CDECL wrap_ldap_unbind_ext_s(void *, LDAPControlU **, LDAPControlU **) DECLSPEC_HIDDEN;
+extern void CDECL wrap_ldap_value_free_len(struct bervalU **) DECLSPEC_HIDDEN;
 
 struct ldap_funcs
 {
@@ -92,9 +120,25 @@ struct ldap_funcs
     int (WINAPIV *ber_printf)(void *, char *, ...);
     int (WINAPIV *ber_scanf)(void *, char *, ...);
 
-    int (CDECL *ldap_add_ext)(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *);
-    int (CDECL *ldap_add_ext_s)(void *, char *, LDAPModU **, LDAPControlU **, LDAPControlU **);
+    int (CDECL *ldap_add_ext)(void *, const char *, LDAPModU **, LDAPControlU **, LDAPControlU **, ULONG *);
+    int (CDECL *ldap_add_ext_s)(void *, const char *, LDAPModU **, LDAPControlU **, LDAPControlU **);
     void (CDECL *ldap_memfree)(void *);
+    int (CDECL *ldap_sasl_bind)(void *, const char *, const char *, struct bervalU *, LDAPControlU **, LDAPControlU **,
+                                int *);
+    int (CDECL *ldap_sasl_bind_s)(void *, const char *, const char *, struct bervalU *, LDAPControlU **,
+                                  LDAPControlU **, struct bervalU **);
+    int (CDECL *ldap_sasl_interactive_bind_s)(void *, const char *, const char *, LDAPControlU **, LDAPControlU **,
+                                              unsigned int, void *);
+    int (CDECL *ldap_unbind_ext)(void *, LDAPControlU **, LDAPControlU **);
+    int (CDECL *ldap_unbind_ext_s)(void *, LDAPControlU **, LDAPControlU **);
+    void (CDECL *ldap_value_free_len)(struct bervalU **);
+};
+
+extern int CDECL sasl_interact_cb(void *, unsigned int, void *, void *) DECLSPEC_HIDDEN;
+
+struct ldap_callbacks
+{
+    int (CDECL *sasl_interact)(void *, unsigned int, void *, void *);
 };
 
 extern const struct ldap_funcs *ldap_funcs;
diff --git a/dlls/wldap32/main.c b/dlls/wldap32/main.c
index 55a08c9bad5..c2fdf30f820 100644
--- a/dlls/wldap32/main.c
+++ b/dlls/wldap32/main.c
@@ -31,6 +31,10 @@ HINSTANCE hwldap32;
 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
 
 const struct ldap_funcs *ldap_funcs = NULL;
+const struct ldap_callbacks ldap_callbacks =
+{
+    sasl_interact_cb
+};
 
 BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
 {
@@ -41,7 +45,7 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
     case DLL_PROCESS_ATTACH:
         hwldap32 = hinst;
         DisableThreadLibraryCalls( hinst );
-        if (__wine_init_unix_lib( hinst, reason, NULL, &ldap_funcs ))
+        if (__wine_init_unix_lib( hinst, reason, &ldap_callbacks, &ldap_funcs ))
             ERR( "No libldap support, expect problems\n" );
         break;
     }
diff --git a/dlls/wldap32/option.c b/dlls/wldap32/option.c
index 388432a442c..8398dff67e4 100644
--- a/dlls/wldap32/option.c
+++ b/dlls/wldap32/option.c
@@ -416,8 +416,8 @@ static BOOL query_supported_server_ctrls( WLDAP32_LDAP *ld )
     {
         ULONG count, i;
 
-        ld->ld_server_ctrls = ldap_get_values_len( ld->ld, entry, attrs[0] );
-        count = ldap_count_values_len( ld->ld_server_ctrls );
+        ld->ld_server_ctrls = (struct bervalU **)ldap_get_values_len( ld->ld, entry, attrs[0] );
+        count = ldap_count_values_len( (struct berval **)ld->ld_server_ctrls );
         for (i = 0; i < count; i++)
             TRACE("%u: %s\n", i, debugstr_an( ld->ld_server_ctrls[i]->bv_val, ld->ld_server_ctrls[i]->bv_len ));
     }
@@ -435,7 +435,7 @@ static BOOL is_supported_server_ctrls( WLDAP32_LDAP *ld, LDAPControl **ctrls )
         return TRUE; /* can't verify, let the server handle it on next query */
 
     user_count = controlarraylenU( ctrls );
-    server_count = ldap_count_values_len( ld->ld_server_ctrls );
+    server_count = ldap_count_values_len( (struct berval **)ld->ld_server_ctrls );
 
     for (n = 0; n < user_count; n++)
     {
diff --git a/dlls/wldap32/winldap_private.h b/dlls/wldap32/winldap_private.h
index 22e981cb26d..20fc676c7e2 100644
--- a/dlls/wldap32/winldap_private.h
+++ b/dlls/wldap32/winldap_private.h
@@ -144,7 +144,7 @@ typedef struct wldap32
     ULONG ld_refhoplimit;
     ULONG ld_options;
     /* internal LDAP context */
-    struct berval **ld_server_ctrls;
+    struct bervalU **ld_server_ctrls;
     void *ld;
 } WLDAP32_LDAP, *WLDAP32_PLDAP;
 
-- 
2.30.2




More information about the wine-devel mailing list