From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/wldap32/Makefile.in | 2 +- dlls/wldap32/bind.c | 3 +- dlls/wldap32/init.c | 50 ++++++++++++++++++++++++++++------ dlls/wldap32/winldap_private.h | 2 +- 4 files changed, 46 insertions(+), 11 deletions(-)
diff --git a/dlls/wldap32/Makefile.in b/dlls/wldap32/Makefile.in index 30b1c389b60..10f96c9e8ff 100644 --- a/dlls/wldap32/Makefile.in +++ b/dlls/wldap32/Makefile.in @@ -1,6 +1,6 @@ MODULE = wldap32.dll IMPORTLIB = wldap32 -IMPORTS = $(LDAP_PE_LIBS) crypt32 secur32 ws2_32 user32 +IMPORTS = $(LDAP_PE_LIBS) crypt32 secur32 ws2_32 user32 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..dcd20fea999 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" @@ -231,15 +234,20 @@ LDAP * CDECL cldap_openW( WCHAR *hostname, ULONG portnumber ) { LDAP *ld = NULL; char *hostnameU, *url = NULL; + WCHAR *hostnameW;
TRACE( "(%s, %lu)\n", debugstr_w(hostname), portnumber );
- if (!(hostnameU = strWtoU( hostname ? hostname : L"localhost" ))) return NULL; + if (!(hostnameW = wcsdup( hostname ? hostname : L"localhost" ))) return NULL; + if (!(hostnameU = strWtoU( hostnameW ))) goto exit; if (!(url = urlify_hostnames( "cldap://", hostnameU, portnumber ))) goto exit;
ld = create_context( url ); - exit: + if (ld) + ld->ld_host = hostnameW; + else + free( hostnameW ); free( hostnameU ); free( url ); return ld; @@ -252,6 +260,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 +272,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) @@ -316,15 +335,20 @@ LDAP * CDECL ldap_initW( const PWCHAR hostname, ULONG portnumber ) { LDAP *ld = NULL; char *hostnameU, *url = NULL; + WCHAR *hostnameW;
TRACE( "(%s, %lu)\n", debugstr_w(hostname), portnumber );
- if (!(hostnameU = strWtoU( hostname ? hostname : L"localhost" ))) return NULL; + if (!(hostnameW = wcsdup( hostname ? hostname : L"localhost" ))) return NULL; + if (!(hostnameU = strWtoU( hostnameW ))) goto exit; if (!(url = urlify_hostnames( "ldap://", hostnameU, portnumber ))) goto exit;
ld = create_context( url ); - exit: + if (ld) + ld->ld_host = hostnameW; + else + free( hostnameW ); free( hostnameU ); free( url ); return ld; @@ -355,15 +379,20 @@ LDAP * CDECL ldap_openW( WCHAR *hostname, ULONG portnumber ) { LDAP *ld = NULL; char *hostnameU, *url = NULL; + WCHAR *hostnameW;
TRACE( "(%s, %lu)\n", debugstr_w(hostname), portnumber );
- if (!(hostnameU = strWtoU( hostname ? hostname : L"localhost" ))) return NULL; + if (!(hostnameW = wcsdup( hostname ? hostname : L"localhost" ))) return NULL; + if (!(hostnameU = strWtoU( hostnameW ))) goto exit; if (!(url = urlify_hostnames( "ldap://", hostnameU, portnumber ))) goto exit;
ld = create_context( url ); - exit: + if (ld) + ld->ld_host = hostnameW; + else + free( hostnameW ); free( hostnameU ); free( url ); return ld; @@ -394,10 +423,12 @@ LDAP * CDECL ldap_sslinitW( WCHAR *hostname, ULONG portnumber, int secure ) { LDAP *ld = NULL; char *hostnameU, *url = NULL; + WCHAR *hostnameW;
TRACE( "(%s, %lu, %d)\n", debugstr_w(hostname), portnumber, secure );
- if (!(hostnameU = strWtoU( hostname ? hostname : L"localhost" ))) return NULL; + if (!(hostnameW = wcsdup( hostname ? hostname : L"localhost" ))) return NULL; + if (!(hostnameU = strWtoU( hostnameW ))) goto exit;
if (secure) url = urlify_hostnames( "ldaps://", hostnameU, portnumber ); @@ -406,8 +437,11 @@ LDAP * CDECL ldap_sslinitW( WCHAR *hostname, ULONG portnumber, int secure ) if (!url) goto exit;
ld = create_context( url ); - exit: + if (ld) + ld->ld_host = hostnameW; + else + free( hostnameW ); free( hostnameU ); free( url ); return ld; 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;