From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/wldap32/Makefile.in | 1 + dlls/wldap32/bind.c | 3 ++- dlls/wldap32/init.c | 18 ++++++++++++++++++ dlls/wldap32/winldap_private.h | 2 +- 4 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/dlls/wldap32/Makefile.in b/dlls/wldap32/Makefile.in index 30b1c389b60..a23dbadb3f4 100644 --- a/dlls/wldap32/Makefile.in +++ b/dlls/wldap32/Makefile.in @@ -1,6 +1,7 @@ MODULE = wldap32.dll IMPORTLIB = wldap32 IMPORTS = $(LDAP_PE_LIBS) crypt32 secur32 ws2_32 user32 +DELAYIMPORTS = netapi32 EXTRAINCL = $(LDAP_PE_CFLAGS)
SOURCES = \ diff --git a/dlls/wldap32/bind.c b/dlls/wldap32/bind.c index f150a4f0c02..c297c234ad6 100644 --- a/dlls/wldap32/bind.c +++ b/dlls/wldap32/bind.c @@ -140,7 +140,7 @@ static int interact_callback( LDAP *ld, unsigned flags, void *defaults, void *sa SEC_WINNT_AUTH_IDENTITY_W *id = defaults; struct sasl_interact *ptr = sasl_interact;
- TRACE( "%p, %08xlx, %p, %p\n", ld, flags, defaults, sasl_interact ); + TRACE( "%p, %08x, %p, %p\n", ld, flags, defaults, sasl_interact );
if (!defaults) return 0;
@@ -495,6 +495,7 @@ ULONG CDECL WLDAP32_ldap_unbind( LDAP *ld )
if (SERVER_CTRLS(ld)) ldap_value_free_len( SERVER_CTRLS(ld) );
+ free( ld->ld_host ); free( ld ); return ret; } diff --git a/dlls/wldap32/init.c b/dlls/wldap32/init.c index 44fc44ee485..28792cb1513 100644 --- a/dlls/wldap32/init.c +++ b/dlls/wldap32/init.c @@ -26,6 +26,9 @@ #include "winternl.h" #include "schannel.h" #include "sspi.h" +#include "dsgetdc.h" +#include "lmcons.h" +#include "lmapibuf.h"
#include "wine/debug.h" #include "winldap_private.h" @@ -238,6 +241,7 @@ LDAP * CDECL cldap_openW( WCHAR *hostname, ULONG portnumber ) if (!(url = urlify_hostnames( "cldap://", hostnameU, portnumber ))) goto exit;
ld = create_context( url ); + if (ld) ld->ld_host = strUtoW( hostnameU );
exit: free( hostnameU ); @@ -252,6 +256,7 @@ ULONG CDECL WLDAP32_ldap_connect( LDAP *ld, struct l_timeval *timeout ) { QUERYCLIENTCERT *client_cert_callback = CLIENT_CERT_CALLBACK(ld); VERIFYSERVERCERT *server_cert_callback = SERVER_CERT_CALLBACK(ld); + DOMAIN_CONTROLLER_INFOW *dcinfo; int ret;
TRACE( "(%p, %p)\n", ld, timeout ); @@ -263,6 +268,16 @@ ULONG CDECL WLDAP32_ldap_connect( LDAP *ld, struct l_timeval *timeout ) FIXME( "mTLS is not implemented\n" );
if (timeout && (timeout->tv_sec || timeout->tv_usec)) FIXME( "ignoring timeout\n" ); + + if (DsGetDcNameW( NULL, ld->ld_host, NULL, NULL, DS_RETURN_DNS_NAME, &dcinfo ) == ERROR_SUCCESS) + { + WCHAR *dc_name; + TRACE( "ld_host %s resolved to DC %s\n", debugstr_w( ld->ld_host ), debugstr_w( dcinfo->DomainControllerName ) ); + dc_name = dcinfo->DomainControllerName + 2; + ldap_set_optionW( ld, WLDAP32_LDAP_OPT_HOST_NAME, &dc_name ); + NetApiBufferFree( dcinfo ); + } + if ((ret = ldap_connect( CTX(ld) ))) return map_error( ret );
if (server_cert_callback) @@ -323,6 +338,7 @@ LDAP * CDECL ldap_initW( const PWCHAR hostname, ULONG portnumber ) if (!(url = urlify_hostnames( "ldap://", hostnameU, portnumber ))) goto exit;
ld = create_context( url ); + if (ld) ld->ld_host = strUtoW( hostnameU );
exit: free( hostnameU ); @@ -362,6 +378,7 @@ LDAP * CDECL ldap_openW( WCHAR *hostname, ULONG portnumber ) if (!(url = urlify_hostnames( "ldap://", hostnameU, portnumber ))) goto exit;
ld = create_context( url ); + if (ld) ld->ld_host = strUtoW( hostnameU );
exit: free( hostnameU ); @@ -406,6 +423,7 @@ LDAP * CDECL ldap_sslinitW( WCHAR *hostname, ULONG portnumber, int secure ) if (!url) goto exit;
ld = create_context( url ); + if (ld) ld->ld_host = strUtoW( hostnameU );
exit: free( hostnameU ); diff --git a/dlls/wldap32/winldap_private.h b/dlls/wldap32/winldap_private.h index d75ba425774..da1824f3749 100644 --- a/dlls/wldap32/winldap_private.h +++ b/dlls/wldap32/winldap_private.h @@ -206,7 +206,7 @@ struct ld_sb typedef struct ldap { struct ld_sb ld_sb; - char *ld_host; + WCHAR *ld_host; ULONG ld_version; UCHAR ld_lberoptions; ULONG ld_deref;
From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/wldap32/init.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-)
diff --git a/dlls/wldap32/init.c b/dlls/wldap32/init.c index 28792cb1513..fe83f3b511c 100644 --- a/dlls/wldap32/init.c +++ b/dlls/wldap32/init.c @@ -330,12 +330,15 @@ LDAP * CDECL ldap_initA( const PCHAR hostname, ULONG portnumber ) LDAP * CDECL ldap_initW( const PWCHAR hostname, ULONG portnumber ) { LDAP *ld = NULL; - char *hostnameU, *url = NULL; + char *hostnameU = NULL, *url = NULL;
TRACE( "(%s, %lu)\n", debugstr_w(hostname), portnumber );
- if (!(hostnameU = strWtoU( hostname ? hostname : L"localhost" ))) return NULL; - if (!(url = urlify_hostnames( "ldap://", hostnameU, portnumber ))) goto exit; + if (hostname) + { + if (!(hostnameU = strWtoU( hostname ))) return NULL; + if (!(url = urlify_hostnames( "ldap://", hostnameU, portnumber ))) goto exit; + }
ld = create_context( url ); if (ld) ld->ld_host = strUtoW( hostnameU ); @@ -370,12 +373,15 @@ LDAP * CDECL ldap_openA( char *hostname, ULONG portnumber ) LDAP * CDECL ldap_openW( WCHAR *hostname, ULONG portnumber ) { LDAP *ld = NULL; - char *hostnameU, *url = NULL; + char *hostnameU = NULL, *url = NULL;
TRACE( "(%s, %lu)\n", debugstr_w(hostname), portnumber );
- if (!(hostnameU = strWtoU( hostname ? hostname : L"localhost" ))) return NULL; - if (!(url = urlify_hostnames( "ldap://", hostnameU, portnumber ))) goto exit; + if (hostname) + { + if (!(hostnameU = strWtoU( hostname ))) return NULL; + if (!(url = urlify_hostnames( "ldap://", hostnameU, portnumber ))) goto exit; + }
ld = create_context( url ); if (ld) ld->ld_host = strUtoW( hostnameU ); @@ -410,17 +416,20 @@ LDAP * CDECL ldap_sslinitA( char *hostname, ULONG portnumber, int secure ) LDAP * CDECL ldap_sslinitW( WCHAR *hostname, ULONG portnumber, int secure ) { LDAP *ld = NULL; - char *hostnameU, *url = NULL; + char *hostnameU = NULL, *url = NULL;
TRACE( "(%s, %lu, %d)\n", debugstr_w(hostname), portnumber, secure );
- if (!(hostnameU = strWtoU( hostname ? hostname : L"localhost" ))) return NULL; + if (hostname) + { + if (!(hostnameU = strWtoU( hostname ))) return NULL;
- if (secure) - url = urlify_hostnames( "ldaps://", hostnameU, portnumber ); - else - url = urlify_hostnames( "ldap://", hostnameU, portnumber ); - if (!url) goto exit; + if (secure) + url = urlify_hostnames( "ldaps://", hostnameU, portnumber ); + else + url = urlify_hostnames( "ldap://", hostnameU, portnumber ); + if (!url) goto exit; + }
ld = create_context( url ); if (ld) ld->ld_host = strUtoW( hostnameU );
From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/wldap32/tests/Makefile.in | 2 +- dlls/wldap32/tests/parse.c | 56 ++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/dlls/wldap32/tests/Makefile.in b/dlls/wldap32/tests/Makefile.in index b387ec95a71..10488eedbe3 100644 --- a/dlls/wldap32/tests/Makefile.in +++ b/dlls/wldap32/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = wldap32.dll -IMPORTS = crypt32 wldap32 +IMPORTS = crypt32 wldap32 netapi32
SOURCES = \ ber.c \ diff --git a/dlls/wldap32/tests/parse.c b/dlls/wldap32/tests/parse.c index faf49622586..760bf0ce703 100644 --- a/dlls/wldap32/tests/parse.c +++ b/dlls/wldap32/tests/parse.c @@ -25,6 +25,9 @@ #include <winbase.h> #include <winldap.h> #include <winber.h> +#include <dsgetdc.h> +#include <lmcons.h> +#include <lmapibuf.h>
#include "wine/test.h"
@@ -671,10 +674,63 @@ static void test_ldap_host_name(void) ldap_unbind( ld ); }
+static void test_ldap_search_dc(void) +{ + DOMAIN_CONTROLLER_INFOW *info; + char *attrs[] = { (char *)"defaultNamingContext", NULL }; + LDAP *ld; + int version; + LDAPMessage *res, *entry; + char **values; + ULONG ret; + + ret = DsGetDcNameW( NULL, NULL, NULL, NULL, DS_RETURN_DNS_NAME, &info ); + if (ret != ERROR_SUCCESS) + { + skip( "Computer is not part of an Active Directory Domain\n" ); + return; + } + trace( "Computer is part of domain %s\n", wine_dbgstr_w(info->DomainName) ); + NetApiBufferFree( info ); + + ld = ldap_initA( NULL, 389 ); + ok( ld != NULL, "ldap_init failed\n" ); + + version = LDAP_VERSION3; + ret = ldap_set_optionW( ld, LDAP_OPT_PROTOCOL_VERSION, &version ); + if (ret == LDAP_SERVER_DOWN || ret == LDAP_UNAVAILABLE) + { + skip( "test server can't be reached\n" ); + ldap_unbind( ld ); + return; + } + + ret = ldap_search_sA( ld, NULL, LDAP_SCOPE_BASE, (char *)"(objectclass=*)", attrs, FALSE, &res ); + ok( !ret, "ldap_search_s error %#lx\n", ret ); + if (ret) + { + ldap_unbind( ld ); + return; + } + + entry = ldap_first_entry( ld, res ); + ok( entry != NULL, "expected entry != NULL\n" ); + + values = ldap_get_valuesA( ld, entry, attrs[0] ); + ok( entry != NULL, "expected values != NULL\n" ); + trace( "%s[0]: %s\n", attrs[0], values[0] ); + + ldap_value_freeA( values ); + ldap_msgfree( res ); + + ldap_unbind( ld ); +} + START_TEST (parse) { LDAP *ld;
+ test_ldap_search_dc(); test_ldap_host_name(); test_ldap_paged_search(); test_ldap_server_control();
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=151170
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: input.c:4306: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 00000000006C00DE, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
Hans Leidekker (@hans) commented about dlls/wldap32/Makefile.in:
MODULE = wldap32.dll IMPORTLIB = wldap32 IMPORTS = $(LDAP_PE_LIBS) crypt32 secur32 ws2_32 user32 +DELAYIMPORTS = netapi32
It's very likely that ldap_connect() will be called so it would be better to make this a regular import.
Hans Leidekker (@hans) commented about dlls/wldap32/init.c:
if (!(url = urlify_hostnames( "cldap://", hostnameU, portnumber ))) goto exit; ld = create_context( url );
- if (ld) ld->ld_host = strUtoW( hostnameU );
Checking for allocation failure would be nice.