1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

drsuapi tests for DsBind with w2k8

These are marked as known_fail pending the next patch ("Extend DsBind
and DsGetDomainControllerInfo to work with w2k8").

Signed-off-by: Dirk Godau <voidswitch@gmail.com>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
This commit is contained in:
Dirk Godau 2016-05-25 11:50:09 +12:00 committed by Douglas Bagnall
parent bc3fcb23fa
commit 6ded4f5230
6 changed files with 356 additions and 1 deletions

View File

@ -330,3 +330,4 @@
# ad_dc requires signing
#
^samba4.smb.signing.*disabled.*signing=off.*\(ad_dc\)
^samba4.rpc.drsuapi_w2k8.*DsGetDomainControllerInfo_W2K8

View File

@ -147,7 +147,7 @@ else:
ncacn_np_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.netlogon.admin", "rpc.handles", "rpc.samsync", "rpc.samba3-sessionkey", "rpc.samba3-getusername", "rpc.samba3-lsa", "rpc.samba3-bind", "rpc.samba3-netlogon", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"]
ncalrpc_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.altercontext", "rpc.netlogon", "rpc.netlogon.admin", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext"]
drs_rpc_tests = smbtorture4_testsuites("drs.rpc")
ncacn_ip_tcp_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.drsuapi", "rpc.netlogon", "rpc.netlogon.admin", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext", "rpc.samr.passwords.validate"] + drs_rpc_tests
ncacn_ip_tcp_tests = ["rpc.schannel", "rpc.join", "rpc.lsa", "rpc.dssetup", "rpc.drsuapi", "rpc.drsuapi_w2k8", "rpc.netlogon", "rpc.netlogon.admin", "rpc.asyncbind", "rpc.lsalookup", "rpc.lsa-getuser", "rpc.schannel2", "rpc.authcontext", "rpc.samr.passwords.validate"] + drs_rpc_tests
slow_ncacn_np_tests = ["rpc.samlogon", "rpc.samr", "rpc.samr.users", "rpc.samr.large-dc", "rpc.samr.users.privileges", "rpc.samr.passwords", "rpc.samr.passwords.pwdlastset", "rpc.samr.passwords.lockout", "rpc.samr.passwords.badpwdcount"]
slow_ncacn_ip_tcp_tests = ["rpc.cracknames"]

View File

@ -40,6 +40,24 @@ struct DsPrivate {
struct test_join *join;
};
/**
* Data structure of DRSUAPI W2K8 tests
* W2K8 Clients use different versions of structs
*/
struct DsPrivate_w2k8 {
struct dcerpc_pipe *drs_pipe;
struct policy_handle bind_handle;
struct GUID bind_guid;
struct drsuapi_DsBindInfoCtr srv_bind_info;
const char *domain_obj_dn;
const char *domain_guid_str;
const char *domain_dns_name;
struct GUID domain_guid;
struct drsuapi_DsGetDCInfo3 dcinfo;
struct test_join *join;
};
/**
* Custom torture macro to check dcerpc_drsuapi_ call

View File

@ -0,0 +1,334 @@
/*
Unix SMB/CIFS implementation.
DRSUapi tests
Copyright (C) Andrew Tridgell 2003
Copyright (C) Stefan (metze) Metzmacher 2004
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2006
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "librpc/gen_ndr/ndr_drsuapi_c.h"
#include "torture/rpc/torture_rpc.h"
#include "param/param.h"
#define TEST_MACHINE_NAME "torturetest"
/*
* DsBind as sent from W2K8 Client.
* This should work regardless of functional level, and accept
* any info <=48
*/
bool test_DsBind_w2k8(struct torture_context *tctx,
struct DsPrivate_w2k8 *priv)
{
NTSTATUS status;
struct dcerpc_pipe *p = priv->drs_pipe;
struct drsuapi_DsBind r;
struct drsuapi_DsBindInfo48 *bind_info48;
struct drsuapi_DsBindInfoCtr bind_info_ctr;
/* We send info48 */
ZERO_STRUCT(bind_info_ctr);
bind_info_ctr.length = 48;
bind_info48 = &bind_info_ctr.info.info48;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_BASE;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7;
bind_info48->supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT;
/*
* We wish for DRSUAPI_SUPPORTED_EXTENSION_LH_BETA2,
* needed for DsGetDomainControllerInfo level 3
*/
bind_info48->supported_extensions_ext |= DRSUAPI_SUPPORTED_EXTENSION_LH_BETA2;
GUID_from_string(DRSUAPI_DS_BIND_GUID, &priv->bind_guid);
r.in.bind_guid = &priv->bind_guid;
r.in.bind_info = &bind_info_ctr;
r.out.bind_handle = &priv->bind_handle;
torture_comment(tctx, "Testing DsBind W2K8\n");
status = dcerpc_drsuapi_DsBind_r(p->binding_handle, tctx, &r);
torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsBind");
torture_assert_not_null(tctx, r.out.bind_info,
"DsBind with info48 results in NULL");
/* cache server supported extensions, i.e. bind_info */
priv->srv_bind_info = *r.out.bind_info;
/*
* We do not check for length here, because it should be valid to return
* any valid info
*/
return true;
}
static bool test_DsGetDomainControllerInfo_w2k8(struct torture_context *tctx,
struct DsPrivate_w2k8 *priv)
{
NTSTATUS status;
struct dcerpc_pipe *p = priv->drs_pipe;
struct drsuapi_DsGetDomainControllerInfo r;
union drsuapi_DsGetDCInfoCtr ctr;
int32_t level_out = 0;
uint32_t supported_extensions_ext = 0;
bool found = false;
int j, k;
struct {
const char *name;
WERROR expected;
} names[] = {
{
.name = torture_join_dom_netbios_name(priv->join),
.expected = WERR_OK
},
{
.name = torture_join_dom_dns_name(priv->join),
.expected = WERR_OK
},
{
.name = "__UNKNOWN_DOMAIN__",
.expected = WERR_DS_OBJ_NOT_FOUND
},
{
.name = "unknown.domain.samba.example.com",
.expected = WERR_DS_OBJ_NOT_FOUND
},
};
/* Levels 1 and 2 are tested in standard drsuapi tests */
int level = 3;
/* Do Bind first. */
if (!test_DsBind_w2k8(tctx, priv)) {
return false;
}
/*
* We used DsBind_w2k8, so DRSUAPI_SUPPORTED_EXTENSION_LH_BETA2
* should mean support for level 3
*/
/*
* We are looking for an extension found in info32 and later
*/
switch (priv->srv_bind_info.length) {
case 32:
supported_extensions_ext = priv->srv_bind_info.info.info32.supported_extensions_ext;
break;
case 48:
supported_extensions_ext = priv->srv_bind_info.info.info48.supported_extensions_ext;
break;
default:
supported_extensions_ext = 0;
break;
}
supported_extensions_ext &= DRSUAPI_SUPPORTED_EXTENSION_LH_BETA2;
torture_assert(tctx, (supported_extensions_ext > 0),
"Server does not support DRSUAPI_SUPPORTED_EXTENSION_LH_BETA2");
for (j=0; j < ARRAY_SIZE(names); j++) {
union drsuapi_DsGetDCInfoRequest req;
r.in.bind_handle = &priv->bind_handle;
r.in.level = 1;
r.in.req = &req;
r.in.req->req1.domain_name = names[j].name;
r.in.req->req1.level = level;
r.out.ctr = &ctr;
r.out.level_out = &level_out;
torture_comment(tctx,
"Testing DsGetDomainControllerInfo level %d on domainname '%s'\n",
r.in.req->req1.level, r.in.req->req1.domain_name);
status = dcerpc_drsuapi_DsGetDomainControllerInfo_r(p->binding_handle, tctx, &r);
torture_assert_ntstatus_ok(tctx, status,
"dcerpc_drsuapi_DsGetDomainControllerInfo with dns domain failed");
torture_assert_werr_equal(tctx, r.out.result, names[j].expected,
"DsGetDomainControllerInfo level with dns domain failed");
if (!W_ERROR_IS_OK(r.out.result)) {
/* If this was an error, we can't read the result structure */
continue;
}
torture_assert_int_equal(tctx, r.in.req->req1.level, *r.out.level_out,
"dcerpc_drsuapi_DsGetDomainControllerInfo in/out level differs");
for (k=0; k < r.out.ctr->ctr3.count; k++) {
if (strcasecmp_m(r.out.ctr->ctr3.array[k].netbios_name,
torture_join_netbios_name(priv->join)) == 0) {
found = true;
priv->dcinfo = r.out.ctr->ctr3.array[k];
break;
}
}
break;
torture_assert(tctx, found,
"dcerpc_drsuapi_DsGetDomainControllerInfo: Failed to find the domain controller we just created during the join");
}
return true;
}
bool test_DsUnbind_w2k8(struct torture_context *tctx,
struct DsPrivate_w2k8 *priv)
{
NTSTATUS status;
struct dcerpc_pipe *p = priv->drs_pipe;
struct drsuapi_DsUnbind r;
r.in.bind_handle = &priv->bind_handle;
r.out.bind_handle = &priv->bind_handle;
torture_comment(tctx, "Testing DsUnbind W2K8\n");
status = dcerpc_drsuapi_DsUnbind_r(p->binding_handle, tctx, &r);
torture_drsuapi_assert_call(tctx, p, status, &r, "dcerpc_drsuapi_DsUnbind");
return true;
}
/**
* Common test case setup function to be used
* in DRS suit of test when appropriate
*/
bool torture_drsuapi_w2k8_tcase_setup_common(struct torture_context *tctx,
struct DsPrivate_w2k8 *priv)
{
NTSTATUS status;
int rnd = rand() % 1000;
char *name = talloc_asprintf(tctx, "%s%d", TEST_MACHINE_NAME, rnd);
struct cli_credentials *machine_credentials;
torture_assert(tctx, priv, "Invalid argument");
torture_comment(tctx, "Create DRSUAPI pipe\n");
status = torture_rpc_connection(tctx,
&priv->drs_pipe,
&ndr_table_drsuapi);
torture_assert(tctx, NT_STATUS_IS_OK(status), "Unable to connect to DRSUAPI pipe");
torture_comment(tctx, "About to join domain with name %s\n", name);
priv->join = torture_join_domain(tctx, name, ACB_SVRTRUST,
&machine_credentials);
torture_assert(tctx, priv->join, "Failed to join as BDC");
/*
* After that every test should use DsBind and DsGetDomainControllerInfo
*/
if (!test_DsBind_w2k8(tctx, priv)) {
/* clean up */
torture_drsuapi_w2k8_tcase_teardown_common(tctx, priv);
torture_fail(tctx, "Failed execute test_DsBind_w2k8()");
}
return true;
}
/**
* Common test case teardown function to be used
* in DRS suit of test when appropriate
*/
bool torture_drsuapi_w2k8_tcase_teardown_common(struct torture_context *tctx,
struct DsPrivate_w2k8 *priv)
{
if (priv->join) {
torture_leave_domain(tctx, priv->join);
}
return true;
}
/**
* Test case setup for DRSUAPI test case
*/
static bool torture_drsuapi_w2k8_tcase_setup(struct torture_context *tctx, void **data)
{
struct DsPrivate_w2k8 *priv;
*data = priv = talloc_zero(tctx, struct DsPrivate_w2k8);
return torture_drsuapi_w2k8_tcase_setup_common(tctx, priv);
}
/**
* Test case tear-down for DRSUAPI test case
*/
static bool torture_drsuapi_w2k8_tcase_teardown(struct torture_context *tctx, void *data)
{
bool ret;
struct DsPrivate_w2k8 *priv = talloc_get_type(data, struct DsPrivate_w2k8);
ret = torture_drsuapi_w2k8_tcase_teardown_common(tctx, priv);
talloc_free(priv);
return ret;
}
/**
* DRSUAPI test case implementation
*/
void torture_rpc_drsuapi_w2k8_tcase(struct torture_suite *suite)
{
typedef bool (*run_func) (struct torture_context *test, void *tcase_data);
struct torture_tcase *tcase = torture_suite_add_tcase(suite, "drsuapi_w2k8");
torture_tcase_set_fixture(tcase, torture_drsuapi_w2k8_tcase_setup,
torture_drsuapi_w2k8_tcase_teardown);
torture_tcase_add_simple_test(tcase, "DsBind_W2K8", (run_func)test_DsBind_w2k8);
torture_tcase_add_simple_test(tcase, "DsGetDomainControllerInfo_W2K8", (run_func)test_DsGetDomainControllerInfo_w2k8);
}

View File

@ -530,6 +530,7 @@ NTSTATUS torture_rpc_init(void)
torture_suite_add_simple_test(suite, "authcontext", torture_bind_authcontext);
torture_suite_add_suite(suite, torture_rpc_samba3(suite));
torture_rpc_drsuapi_tcase(suite);
torture_rpc_drsuapi_w2k8_tcase(suite);
torture_rpc_drsuapi_cracknames_tcase(suite);
torture_suite_add_suite(suite, torture_rpc_dssetup(suite));
torture_suite_add_suite(suite, torture_rpc_browser(suite));

View File

@ -83,6 +83,7 @@ bld.SAMBA_MODULE('torture_rpc',
rpc/echo.c
rpc/dfs.c
rpc/drsuapi.c
rpc/drsuapi_w2k8.c
rpc/drsuapi_cracknames.c
rpc/dsgetinfo.c
rpc/spoolss.c