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:
Dmitry Timoshkov 2020-04-03 16:57:03 +08:00 committed by Alexandre Julliard
parent 57cb1900b6
commit 07b18a7672
5 changed files with 61 additions and 6 deletions

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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" );

View File

@ -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 {