mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-15 06:31:03 +00:00
wldap32: Locally cache "supportedControl" rootDSE attribute, and check it in ldap_set_option(LDAP_OPT_SERVER_CONTROLS).
Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
57cb1900b6
commit
07b18a7672
|
@ -498,15 +498,12 @@ todo_wine
|
|||
pref[1].vValue.Integer = ADS_SECURITY_INFO_OWNER | ADS_SECURITY_INFO_GROUP | ADS_SECURITY_INFO_DACL;
|
||||
pref[1].dwStatus = 0xdeadbeef;
|
||||
hr = IDirectorySearch_SetSearchPreference(ds, pref, ARRAY_SIZE(pref));
|
||||
todo_wine
|
||||
ok(hr == S_ADS_ERRORSOCCURRED, "got %#x\n", hr);
|
||||
ok(pref[0].dwStatus == ADS_STATUS_S_OK, "got %d\n", pref[0].dwStatus);
|
||||
/* ldap.forumsys.com doesn't support NT security, real ADs DC - does */
|
||||
todo_wine
|
||||
ok(pref[1].dwStatus == ADS_STATUS_INVALID_SEARCHPREF, "got %d\n", pref[1].dwStatus);
|
||||
|
||||
hr = IDirectorySearch_ExecuteSearch(ds, (WCHAR *)L"(objectClass=*)", NULL, ~0, &sh);
|
||||
todo_wine
|
||||
ok(hr == S_OK, "got %#x\n", hr);
|
||||
if (hr != S_OK) goto fail;
|
||||
|
||||
|
|
|
@ -766,6 +766,8 @@ ULONG CDECL WLDAP32_ldap_unbind( WLDAP32_LDAP *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
|
||||
|
@ -797,6 +799,8 @@ ULONG CDECL WLDAP32_ldap_unbind_s( WLDAP32_LDAP *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
|
||||
|
|
|
@ -398,6 +398,58 @@ ULONG CDECL ldap_set_optionA( WLDAP32_LDAP *ld, int option, void *value )
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LDAP
|
||||
|
||||
static BOOL query_supported_server_ctrls( WLDAP32_LDAP *ld )
|
||||
{
|
||||
char *attrs[] = { (char *)"supportedControl", NULL };
|
||||
LDAPMessage *res, *entry;
|
||||
|
||||
if ( ld->ld_server_ctrls ) return TRUE;
|
||||
|
||||
if (ldap_search_ext_s( ld->ld, (char *)"", LDAP_SCOPE_BASE, (char *)"(objectClass=*)", attrs, FALSE,
|
||||
NULL, NULL, NULL, 0, &res ) != LDAP_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
entry = ldap_first_entry( ld->ld, res );
|
||||
if (entry)
|
||||
{
|
||||
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 );
|
||||
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 ));
|
||||
}
|
||||
|
||||
ldap_msgfree( res );
|
||||
|
||||
return ld->ld_server_ctrls != NULL;
|
||||
}
|
||||
|
||||
static BOOL is_supported_server_ctrls( WLDAP32_LDAP *ld, LDAPControl **ctrls )
|
||||
{
|
||||
ULONG user_count, server_count, i, n, supported = 0;
|
||||
|
||||
if (!query_supported_server_ctrls( ld ))
|
||||
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 );
|
||||
|
||||
for (n = 0; n < user_count; n++)
|
||||
{
|
||||
for (i = 0; i < server_count; i++)
|
||||
{
|
||||
if (!strncmp( ctrls[n]->ldctl_oid, ld->ld_server_ctrls[i]->bv_val, ld->ld_server_ctrls[i]->bv_len))
|
||||
supported++;
|
||||
}
|
||||
}
|
||||
|
||||
return supported == user_count;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* ldap_set_optionW (WLDAP32.@)
|
||||
*
|
||||
|
@ -433,7 +485,10 @@ ULONG CDECL ldap_set_optionW( WLDAP32_LDAP *ld, int option, void *value )
|
|||
ctrlsU = controlarrayWtoU( value );
|
||||
if (!ctrlsU) return WLDAP32_LDAP_NO_MEMORY;
|
||||
|
||||
ret = map_error( ldap_set_option( ld->ld, option, ctrlsU ));
|
||||
if (!is_supported_server_ctrls( ld, ctrlsU ))
|
||||
ret = WLDAP32_LDAP_PARAM_ERROR;
|
||||
else
|
||||
ret = map_error( ldap_set_option( ld->ld, option, ctrlsU ));
|
||||
controlarrayfreeU( ctrlsU );
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -201,12 +201,10 @@ static void test_ldap_server_control( void )
|
|||
ctrls[0] = &mask;
|
||||
ctrls[1] = NULL;
|
||||
ret = ldap_set_optionW(ld, LDAP_OPT_SERVER_CONTROLS, ctrls);
|
||||
todo_wine
|
||||
ok( ret == LDAP_PARAM_ERROR, "ldap_set_optionW should fail: 0x%x\n", ret );
|
||||
|
||||
res = NULL;
|
||||
ret = ldap_search_sA( ld, (char *)"OU=scientists,DC=example,DC=com", LDAP_SCOPE_BASE, (char *)"(objectclass=*)", NULL, FALSE, &res );
|
||||
todo_wine
|
||||
ok( !ret, "ldap_search_sA failed 0x%x\n", ret );
|
||||
ok( res != NULL, "expected res != NULL\n" );
|
||||
|
||||
|
|
|
@ -131,6 +131,7 @@ typedef struct wldap32
|
|||
ULONG ld_cldaptimeout;
|
||||
ULONG ld_refhoplimit;
|
||||
ULONG ld_options;
|
||||
struct berval **ld_server_ctrls;
|
||||
} WLDAP32_LDAP, *WLDAP32_PLDAP;
|
||||
|
||||
typedef struct ldapmodA {
|
||||
|
|
Loading…
Reference in a new issue