[PATCH 1/8] wldap32: Add support for ldap_bind_s(LDAP_AUTH_NEGOTIATE). (resend)
Dmitry Timoshkov
dmitry at baikal.ru
Fri Mar 20 02:21:21 CDT 2020
Signed-off-by: Dmitry Timoshkov <dmitry at baikal.ru>
---
configure.ac | 1 +
dlls/wldap32/bind.c | 121 +++++++++++++++++++++++++++++----
dlls/wldap32/winldap_private.h | 2 +
dlls/wldap32/wldap32.h | 16 +++++
include/config.h.in | 3 +
5 files changed, 128 insertions(+), 15 deletions(-)
diff --git a/configure.ac b/configure.ac
index 7096e2fb66..83e659742b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -487,6 +487,7 @@ AC_CHECK_HEADERS(\
port.h \
pthread.h \
pwd.h \
+ sasl/sasl.h \
sched.h \
scsi/scsi.h \
scsi/scsi_ioctl.h \
diff --git a/dlls/wldap32/bind.c b/dlls/wldap32/bind.c
index 27fb286f50..76d76323b2 100644
--- a/dlls/wldap32/bind.c
+++ b/dlls/wldap32/bind.c
@@ -25,10 +25,14 @@
#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"
@@ -156,20 +160,68 @@ ULONG CDECL ldap_bind_sA( WLDAP32_LDAP *ld, PCHAR dn, PCHAR cred, ULONG method )
if (!dnW) goto exit;
}
if (cred) {
- credW = strAtoW( cred );
- if (!credW) goto exit;
+ if (method == LDAP_AUTH_SIMPLE)
+ {
+ credW = strAtoW( cred );
+ if (!credW) goto exit;
+ }
+ else
+ credW = (WCHAR *)cred /* SEC_WINNT_AUTH_IDENTITY_A */;
}
ret = ldap_bind_sW( ld, dnW, credW, method );
exit:
strfreeW( dnW );
- strfreeW( credW );
+ if (credW != (WCHAR *)cred) strfreeW( credW );
#endif
return ret;
}
+#ifdef HAVE_SASL_SASL_H
+
+static int sasl_interact( LDAP *ld, unsigned flags, void *defaults, void *interact )
+{
+ SEC_WINNT_AUTH_IDENTITY_W *id = defaults;
+ sasl_interact_t *sasl = interact;
+
+ TRACE( "%p,%08x,%p,%p\n", ld, flags, defaults, interact );
+
+ while (sasl->id != SASL_CB_LIST_END)
+ {
+ if (sasl->id == SASL_CB_GETREALM)
+ {
+ sasl->result = id->Domain;
+ sasl->len = id->DomainLength;
+ }
+ else if (sasl->id == SASL_CB_AUTHNAME)
+ {
+ sasl->result = id->User;
+ sasl->len = id->UserLength;
+ }
+ else if (sasl->id == SASL_CB_PASS)
+ {
+ sasl->result = id->Password;
+ sasl->len = id->PasswordLength;
+ }
+
+ sasl++;
+ }
+
+ return LDAP_SUCCESS;
+}
+
+#else
+
+static int sasl_interact( LDAP *ld, unsigned flags, void *defaults, void *interact )
+{
+ FIXME( "%p,%08x,%p,%p: stub\n", ld, flags, defaults, interact );
+ return LDAP_SUCCESS;
+}
+
+#endif /* HAVE_SASL_SASL_H */
+
/***********************************************************************
* ldap_bind_sW (WLDAP32.@)
*
@@ -197,21 +249,60 @@ ULONG CDECL ldap_bind_sW( WLDAP32_LDAP *ld, PWCHAR dn, PWCHAR cred, ULONG method
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) return WLDAP32_LDAP_PARAM_ERROR;
- if (dn) {
- dnU = strWtoU( dn );
- if (!dnU) goto exit;
+ if (method == LDAP_AUTH_SIMPLE)
+ {
+ if (dn)
+ {
+ dnU = strWtoU( dn );
+ if (!dnU) goto exit;
+ }
+ if (cred)
+ {
+ credU = strWtoU( cred );
+ if (!credU) goto exit;
+
+ pwd.bv_len = strlen( credU );
+ pwd.bv_val = credU;
+ }
+
+ ret = map_error( ldap_sasl_bind_s( ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, NULL ));
}
- if (cred) {
- credU = strWtoU( cred );
- if (!credU) goto exit;
-
- pwd.bv_len = strlen( credU );
- pwd.bv_val = credU;
+ else if (method == WLDAP32_LDAP_AUTH_NEGOTIATE)
+ {
+ SEC_WINNT_AUTH_IDENTITY_A idU;
+
+ memset( &idU, 0, sizeof(idU) );
+
+ if (cred)
+ {
+ SEC_WINNT_AUTH_IDENTITY_W *id = (SEC_WINNT_AUTH_IDENTITY_W *)cred;
+
+ if (id->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI)
+ {
+ FIXME( "ANSI credentials not supported\n" );
+ return WLDAP32_LDAP_PARAM_ERROR;
+ }
+
+ 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,
+ NULL /* server will ignore DN anyway */,
+ NULL /* query supportedSASLMechanisms */,
+ NULL, NULL, LDAP_SASL_QUIET, sasl_interact, &idU ));
+
+ strfreeU( (char *)idU.Domain );
+ strfreeU( (char *)idU.User );
+ strfreeU( (char *)idU.Password );
+ }
+ else
+ {
+ FIXME( "method %#x not supported\n", method );
+ return WLDAP32_LDAP_PARAM_ERROR;
}
-
- ret = map_error( ldap_sasl_bind_s( ld, dnU, LDAP_SASL_SIMPLE, &pwd, NULL, NULL, NULL ));
exit:
strfreeU( dnU );
diff --git a/dlls/wldap32/winldap_private.h b/dlls/wldap32/winldap_private.h
index 74223029b7..df257dafec 100644
--- a/dlls/wldap32/winldap_private.h
+++ b/dlls/wldap32/winldap_private.h
@@ -101,6 +101,8 @@ typedef struct berelement
#define WLDAP32_LDAP_OPT_SECURITY_CONTEXT 0x99
#define WLDAP32_LDAP_OPT_ROOTDSE_CACHE 0x9a
+#define WLDAP32_LDAP_AUTH_NEGOTIATE 0x486
+
typedef struct ldap
{
struct
diff --git a/dlls/wldap32/wldap32.h b/dlls/wldap32/wldap32.h
index 1d4052002a..080765896c 100644
--- a/dlls/wldap32/wldap32.h
+++ b/dlls/wldap32/wldap32.h
@@ -93,6 +93,22 @@ static inline LPWSTR strUtoW( char *str )
return ret;
}
+static inline char *strnWtoU( LPCWSTR str, DWORD inlen, DWORD *outlen )
+{
+ LPSTR ret = NULL;
+ *outlen = 0;
+ if (str)
+ {
+ DWORD len = WideCharToMultiByte( CP_UTF8, 0, str, inlen, NULL, 0, NULL, NULL );
+ if ((ret = heap_alloc( len )))
+ {
+ WideCharToMultiByte( CP_UTF8, 0, str, inlen, ret, len, NULL, NULL );
+ *outlen = len;
+ }
+ }
+ return ret;
+}
+
static inline void strfreeA( LPSTR str )
{
heap_free( str );
diff --git a/include/config.h.in b/include/config.h.in
index de434d6ed2..e48e398ca8 100644
--- a/include/config.h.in
+++ b/include/config.h.in
@@ -776,6 +776,9 @@
/* Define to 1 if you have the `roundf' function. */
#undef HAVE_ROUNDF
+/* Define to 1 if you have the <sasl/sasl.h> header file. */
+#undef HAVE_SASL_SASL_H
+
/* Define to 1 if you have the <sched.h> header file. */
#undef HAVE_SCHED_H
--
2.25.1
More information about the wine-devel
mailing list