summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorMatthieu Patou <mat@matws.net>2010-05-10 01:39:27 +0400
committerStefan Metzmacher <metze@samba.org>2010-05-18 15:31:13 +0200
commit9f01e7af6b5f0ab8022baabf097af6be82f13877 (patch)
tree355df7b9aa39d8677c034513ee4363c789053922 /source4
parent0e4e39c7f51a6fe95485710454b5ced1a6ef7a51 (diff)
downloadsamba-9f01e7af6b5f0ab8022baabf097af6be82f13877.tar.gz
samba-9f01e7af6b5f0ab8022baabf097af6be82f13877.tar.bz2
samba-9f01e7af6b5f0ab8022baabf097af6be82f13877.zip
s4 torture: Add tests for dfs referrals handling in SMB/trans2 requests
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'source4')
-rw-r--r--source4/torture/config.mk9
-rw-r--r--source4/torture/dfs/common.c71
-rw-r--r--source4/torture/dfs/domaindfs.c488
-rw-r--r--source4/torture/torture.c1
-rw-r--r--source4/torture/wscript_build11
5 files changed, 578 insertions, 2 deletions
diff --git a/source4/torture/config.mk b/source4/torture/config.mk
index 50d400980f..4d65256a3d 100644
--- a/source4/torture/config.mk
+++ b/source4/torture/config.mk
@@ -99,6 +99,13 @@ TORTURE_NDR_OBJ_FILES = $(addprefix $(torturesrcdir)/ndr/, ndr.o winreg.o atsvc.
$(eval $(call proto_header_template,$(torturesrcdir)/ndr/proto.h,$(TORTURE_NDR_OBJ_FILES:.o=.c)))
+[SUBSYSTEM::TORTURE_DFS]
+PRIVATE_DEPENDENCIES = torture LIBCLI_SMB NDR_DFSBLOBS TORTURE_UTIL
+
+TORTURE_DFS_OBJ_FILES = $(addprefix $(torturesrcdir)/dfs/, common.o domaindfs.o)
+
+$(eval $(call proto_header_template,$(torturesrcdir)/dfs/proto.h,$(TORTURE_DFS_OBJ_FILES:.o=.c)))
+
[MODULE::torture_rpc]
OUTPUT_TYPE = MERGED_OBJ
# TORTURE_NET and TORTURE_NBT use functions from torture_rpc...
@@ -112,7 +119,7 @@ PRIVATE_DEPENDENCIES = \
RPC_NDR_LSA RPC_NDR_EPMAPPER RPC_NDR_DFS RPC_NDR_FRSAPI RPC_NDR_SPOOLSS \
RPC_NDR_SRVSVC RPC_NDR_WKSSVC RPC_NDR_ROT RPC_NDR_DSSETUP \
RPC_NDR_REMACT RPC_NDR_OXIDRESOLVER RPC_NDR_NTSVCS WB_HELPER LIBSAMBA-NET \
- LIBCLI_AUTH POPT_CREDENTIALS TORTURE_LDAP TORTURE_UTIL TORTURE_RAP \
+ LIBCLI_AUTH POPT_CREDENTIALS TORTURE_LDAP TORTURE_UTIL TORTURE_RAP TORTURE_DFS \
dcerpc_server service process_model ntvfs SERVICE_SMB RPC_NDR_BROWSER LIBCLI_DRSUAPI TORTURE_LDB_MODULE
torture_rpc_OBJ_FILES = $(addprefix $(torturesrcdir)/rpc/, \
diff --git a/source4/torture/dfs/common.c b/source4/torture/dfs/common.c
new file mode 100644
index 0000000000..f1cc10663b
--- /dev/null
+++ b/source4/torture/dfs/common.c
@@ -0,0 +1,71 @@
+/*
+ Unix SMB/CIFS implementation.
+ test suite for various Domain DFS
+ Copyright (C) Matthieu Patou 2010
+
+ 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 "libcli/libcli.h"
+#include "torture/smbtorture.h"
+#include "torture/util.h"
+#include "../librpc/gen_ndr/ndr_dfsblobs.h"
+#include "librpc/ndr/libndr.h"
+#include "param/param.h"
+#include "torture/torture.h"
+#include "torture/dfs/proto.h"
+#include "libcli/raw/raw_proto.h"
+
+NTSTATUS dfs_cli_do_call(struct smbcli_tree *tree,
+ struct dfs_GetDFSReferral *ref)
+{
+ NTSTATUS result;
+ enum ndr_err_code ndr_err;
+ uint16_t setup = TRANSACT2_GET_DFS_REFERRAL;
+ struct smb_trans2 trans;
+
+ trans.in.max_param = 0;
+ trans.in.max_data = 4096;
+ trans.in.max_setup = 0;
+ trans.in.flags = 0;
+ trans.in.timeout = 0;
+ trans.in.setup_count = 1;
+ trans.in.setup = &setup;
+ trans.in.trans_name = NULL;
+ ZERO_STRUCT(trans.out);
+
+ ndr_err = ndr_push_struct_blob(&trans.in.params, tree,
+ &ref->in.req,
+ (ndr_push_flags_fn_t)ndr_push_dfs_GetDFSReferral_in);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+ trans.in.data = data_blob(NULL, 0);
+
+ result = smb_raw_trans2(tree, tree, &trans);
+
+ if (!NT_STATUS_IS_OK(result))
+ return result;
+
+ ndr_err = ndr_pull_struct_blob(&trans.out.data, tree,
+ ref->out.resp,
+ (ndr_pull_flags_fn_t)ndr_pull_dfs_referral_resp);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ return NT_STATUS_OK;
+}
+
diff --git a/source4/torture/dfs/domaindfs.c b/source4/torture/dfs/domaindfs.c
new file mode 100644
index 0000000000..18c84396d3
--- /dev/null
+++ b/source4/torture/dfs/domaindfs.c
@@ -0,0 +1,488 @@
+/*
+ Unix SMB/CIFS implementation.
+ test suite for various Domain DFS
+ Copyright (C) Matthieu Patou 2010
+
+ 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 "libcli/libcli.h"
+#include "torture/smbtorture.h"
+#include "torture/util.h"
+#include "../librpc/gen_ndr/ndr_dfsblobs.h"
+#include "librpc/ndr/libndr.h"
+#include "param/param.h"
+#include "torture/torture.h"
+#include "torture/dfs/proto.h"
+
+static bool test_getdomainreferral(struct torture_context *tctx,
+ struct smbcli_state *cli)
+{
+ struct dfs_GetDFSReferral r;
+ struct dfs_referral_resp resp;
+
+ r.in.req.max_referral_level = 3;
+ r.in.req.servername = "";
+ r.out.resp = &resp;
+
+ torture_assert_ntstatus_ok(tctx,
+ dfs_cli_do_call(cli->tree, &r),
+ "Get Domain referral failed");
+
+ torture_assert_int_equal(tctx, resp.path_consumed, 0,
+ "Path consumed not equal to 0");
+ torture_assert_int_equal(tctx, resp.nb_referrals != 0, 1,
+ "0 domains referrals returned");
+ torture_assert_int_equal(tctx, resp.header_flags, 0,
+ "Header flag different it's not a referral server");
+ torture_assert_int_equal(tctx, resp.referral_entries[0].version, 3,
+ talloc_asprintf(tctx,
+ "Not expected version for referral entry 0 got %d expected 3",
+ resp.referral_entries[0].version));
+ torture_assert_int_equal(tctx, resp.referral_entries[0].referral.v3.data.server_type,
+ DFS_SERVER_NON_ROOT,
+ talloc_asprintf(tctx,
+ "Wrong server type, expected non root server and got %d",
+ resp.referral_entries[0].referral.v3.data.server_type));
+ torture_assert_int_equal(tctx, resp.referral_entries[0].referral.v3.data.entry_flags,
+ DFS_FLAG_REFERRAL_DOMAIN_RESP,
+ talloc_asprintf(tctx,
+ "Wrong entry flag expected to have a domain response and got %d",
+ resp.referral_entries[0].referral.v3.data.entry_flags));
+ torture_assert_int_equal(tctx, strlen(
+ resp.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0,
+ 1,
+ "Length of domain is 0 or less");
+ return true;
+}
+
+static bool test_getdcreferral(struct torture_context *tctx,
+ struct smbcli_state *cli)
+{
+ struct dfs_GetDFSReferral r, r2, r3;
+ struct dfs_referral_resp resp, resp2, resp3;
+ const char* str;
+
+ r.in.req.max_referral_level = 3;
+ r.in.req.servername = "";
+ r.out.resp = &resp;
+
+ torture_assert_ntstatus_ok(tctx,
+ dfs_cli_do_call(cli->tree, &r),
+ "Get Domain referral failed");
+
+ str = resp.referral_entries[0].referral.v3.data.referrals.r2.special_name;
+ if( strchr(str, '.') == NULL ) {
+ str = resp.referral_entries[1].referral.v3.data.referrals.r2.special_name;
+ }
+
+ r2.in.req.max_referral_level = 3;
+ r2.in.req.servername = str;
+ r2.out.resp = &resp2;
+
+ torture_assert_ntstatus_ok(tctx,
+ dfs_cli_do_call(cli->tree, &r2),
+ "Get DC Domain referral failed");
+
+
+ torture_assert_int_equal(tctx, resp2.path_consumed, 0,
+ "Path consumed not equal to 0");
+ torture_assert_int_equal(tctx, resp2.nb_referrals , 1,
+ "We do not received only 1 referral");
+ torture_assert_int_equal(tctx, resp2.header_flags, 0,
+ "Header flag different it's not a referral server");
+ torture_assert_int_equal(tctx, resp2.referral_entries[0].version, 3,
+ talloc_asprintf(tctx,
+ "Not expected version for referral entry 0 got %d expected 3",
+ resp2.referral_entries[0].version));
+ torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.data.server_type,
+ DFS_SERVER_NON_ROOT,
+ talloc_asprintf(tctx,
+ "Wrong server type, expected non root server and got %d",
+ resp2.referral_entries[0].referral.v3.data.server_type));
+ torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.data.entry_flags,
+ DFS_FLAG_REFERRAL_DOMAIN_RESP,
+ talloc_asprintf(tctx,
+ "Wrong entry flag expected to have a domain response and got %d",
+ resp2.referral_entries[0].referral.v3.data.entry_flags));
+ torture_assert_int_equal(tctx, strlen(
+ resp2.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0,
+ 1,
+ "Length of domain is 0 or less");
+ torture_assert_int_equal(tctx, strlen(
+ resp2.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0]) > 0,
+ 1,
+ "Length of first dc is less than 0");
+
+ r3.in.req.max_referral_level = 3;
+ /*
+ * Windows 7 and at least windows 2008 server sends domain.fqdn instead of \domain.fqdn
+ * (as it is specified in the spec)
+ * Let's check that we are able to support it too
+ */
+ r3.in.req.servername = str;
+ r3.out.resp = &resp3;
+
+ torture_assert_ntstatus_ok(tctx,
+ dfs_cli_do_call(cli->tree, &r3),
+ "Get DC Domain referral failed");
+
+ torture_assert_int_equal(tctx, resp3.path_consumed, 0,
+ "Path consumed not equal to 0");
+ torture_assert_int_equal(tctx, resp3.nb_referrals , 1,
+ "We do not received only 1 referral");
+ torture_assert_int_equal(tctx, resp3.header_flags, 0,
+ "Header flag different it's not a referral server");
+ torture_assert_int_equal(tctx, resp3.referral_entries[0].version, 3,
+ talloc_asprintf(tctx,
+ "Not expected version for referral entry 0 got %d expected 3",
+ resp3.referral_entries[0].version));
+ torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.server_type,
+ DFS_SERVER_NON_ROOT,
+ talloc_asprintf(tctx,
+ "Wrong server type, expected non root server and got %d",
+ resp3.referral_entries[0].referral.v3.data.server_type));
+ torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.entry_flags,
+ DFS_FLAG_REFERRAL_DOMAIN_RESP,
+ talloc_asprintf(tctx,
+ "Wrong entry flag expected to have a domain response and got %d",
+ resp3.referral_entries[0].referral.v3.data.entry_flags));
+ torture_assert_int_equal(tctx, strlen(
+ resp3.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0,
+ 1,
+ "Length of domain is 0 or less");
+ torture_assert_int_equal(tctx, strlen(
+ resp3.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0]) > 0,
+ 1,
+ "Length of first dc is less than 0");
+ return true;
+}
+
+static bool test_getdcreferral_netbios(struct torture_context *tctx,
+ struct smbcli_state *cli)
+{
+ struct dfs_GetDFSReferral r, r2, r3;
+ struct dfs_referral_resp resp, resp2, resp3;
+ const char* str;
+
+ r.in.req.max_referral_level = 3;
+ r.in.req.servername = "";
+ r.out.resp = &resp;
+
+ torture_assert_ntstatus_ok(tctx,
+ dfs_cli_do_call(cli->tree, &r),
+ "Get Domain referral failed");
+
+ r2.in.req.max_referral_level = 3;
+
+ str = resp.referral_entries[0].referral.v3.data.referrals.r2.special_name;
+ if( strchr(str, '.') != NULL ) {
+ str = resp.referral_entries[1].referral.v3.data.referrals.r2.special_name;
+ }
+
+ r2.in.req.servername = str;
+ r2.out.resp = &resp2;
+
+ torture_assert_ntstatus_ok(tctx,
+ dfs_cli_do_call(cli->tree, &r2),
+ "Get DC Domain referral failed");
+
+ torture_assert_int_equal(tctx, resp2.path_consumed, 0,
+ "Path consumed not equal to 0");
+ torture_assert_int_equal(tctx, resp2.nb_referrals , 1,
+ "We do not received only 1 referral");
+ torture_assert_int_equal(tctx, resp2.header_flags, 0,
+ "Header flag different it's not a referral server");
+ torture_assert_int_equal(tctx, resp2.referral_entries[0].version, 3,
+ talloc_asprintf(tctx,
+ "Not expected version for referral entry 0 got %d expected 3",
+ resp2.referral_entries[0].version));
+ torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.data.server_type,
+ DFS_SERVER_NON_ROOT,
+ talloc_asprintf(tctx,
+ "Wrong server type, expected non root server and got %d",
+ resp2.referral_entries[0].referral.v3.data.server_type));
+ torture_assert_int_equal(tctx, resp2.referral_entries[0].referral.v3.data.entry_flags,
+ DFS_FLAG_REFERRAL_DOMAIN_RESP,
+ talloc_asprintf(tctx,
+ "Wrong entry flag expected to have a domain response and got %d",
+ resp2.referral_entries[0].referral.v3.data.entry_flags));
+ torture_assert_int_equal(tctx, strlen(
+ resp2.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0,
+ 1,
+ "Length of domain is 0 or less");
+ torture_assert_int_equal(tctx, strlen(
+ resp2.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0]) > 0,
+ 1,
+ "Length of first dc is less than 0");
+ torture_assert(tctx, strchr(
+ resp2.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0],'.') == NULL,
+ "referral contains dots it's not a netbios name");
+
+ r3.in.req.max_referral_level = 3;
+ /*
+ * Windows 7 and at least windows 2008 server sends domain.fqdn instead of \domain.fqdn
+ * (as it is specified in the spec)
+ * Let's check that we are able to support it too
+ */
+ r3.in.req.servername = str + 1;
+ r3.out.resp = &resp3;
+
+ torture_assert_ntstatus_ok(tctx,
+ dfs_cli_do_call(cli->tree, &r3),
+ "Get DC Domain referral failed");
+
+ torture_assert_int_equal(tctx, resp3.path_consumed, 0,
+ "Path consumed not equal to 0");
+ torture_assert_int_equal(tctx, resp3.nb_referrals , 1,
+ "We do not received only 1 referral");
+ torture_assert_int_equal(tctx, resp3.header_flags, 0,
+ "Header flag different it's not a referral server");
+ torture_assert_int_equal(tctx, resp3.referral_entries[0].version, 3,
+ talloc_asprintf(tctx,
+ "Not expected version for referral entry 0 got %d expected 3",
+ resp3.referral_entries[0].version));
+ torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.server_type,
+ DFS_SERVER_NON_ROOT,
+ talloc_asprintf(tctx,
+ "Wrong server type, expected non root server and got %d",
+ resp3.referral_entries[0].referral.v3.data.server_type));
+ torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.entry_flags,
+ DFS_FLAG_REFERRAL_DOMAIN_RESP,
+ talloc_asprintf(tctx,
+ "Wrong entry flag expected to have a domain response and got %d",
+ resp3.referral_entries[0].referral.v3.data.entry_flags));
+ torture_assert_int_equal(tctx, strlen(
+ resp3.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0,
+ 1,
+ "Length of domain is 0 or less");
+ torture_assert_int_equal(tctx, strlen(
+ resp3.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0]) > 0,
+ 1,
+ "Length of first dc is less than 0");
+ torture_assert(tctx, strchr(
+ resp3.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0],'.') == NULL,
+ "referral contains dots it's not a netbios name");
+ return true;
+}
+
+static bool test_getsysvolreferral(struct torture_context *tctx,
+ struct smbcli_state *cli)
+{
+ const char* str;
+ struct dfs_GetDFSReferral r, r2, r3;
+ struct dfs_referral_resp resp, resp2, resp3;
+
+ r.in.req.max_referral_level = 3;
+ r.in.req.servername = "";
+ r.out.resp = &resp;
+
+ torture_assert_ntstatus_ok(tctx,
+ dfs_cli_do_call(cli->tree, &r),
+ "Get Domain referral failed");
+
+ str = resp.referral_entries[0].referral.v3.data.referrals.r2.special_name;
+ if( strchr(str, '.') == NULL ) {
+ str = resp.referral_entries[1].referral.v3.data.referrals.r2.special_name;
+ }
+
+ r2.in.req.max_referral_level = 3;
+ r2.in.req.servername = str;
+ r2.out.resp = &resp2;
+
+ torture_assert_ntstatus_ok(tctx,
+ dfs_cli_do_call(cli->tree, &r2),
+ "Get DC Domain referral failed");
+
+ r3.in.req.max_referral_level = 3;
+ r3.in.req.servername = talloc_asprintf(tctx, "%s\\sysvol", str);
+ r3.out.resp = &resp3;
+
+ torture_assert_ntstatus_ok(tctx,
+ dfs_cli_do_call(cli->tree, &r3),
+ "Get sysvol Domain referral failed");
+
+ torture_assert_int_equal(tctx, resp3.path_consumed, 2*strlen(r3.in.req.servername),
+ "Path consumed not equal to length of the request");
+ torture_assert_int_equal(tctx, resp3.nb_referrals != 0, 1,
+ "We do not receive at least 1 referral");
+ torture_assert_int_equal(tctx, resp3.header_flags, DFS_HEADER_FLAG_STORAGE_SVR,
+ "Header flag different it's not a referral for a storage");
+ torture_assert_int_equal(tctx, resp3.referral_entries[0].version, 3,
+ talloc_asprintf(tctx,
+ "Not expected version for referral entry 0 got %d expected 3",
+ resp3.referral_entries[0].version));
+ torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.server_type,
+ DFS_SERVER_NON_ROOT,
+ talloc_asprintf(tctx,
+ "Wrong server type, expected non root server and got %d",
+ resp3.referral_entries[0].referral.v3.data.server_type));
+ torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v3.data.entry_flags,
+ 0,
+ talloc_asprintf(tctx,
+ "Wrong entry flag expected to have a non domain response and got %d",
+ resp3.referral_entries[0].referral.v3.data.entry_flags));
+ torture_assert_int_equal(tctx, strlen(
+ resp3.referral_entries[0].referral.v3.data.referrals.r2.special_name) > 0,
+ 1,
+ "Length of domain is 0 or less");
+ torture_assert_int_equal(tctx, strlen(
+ resp2.referral_entries[0].referral.v3.data.referrals.r2.expanded_names[0]) > 0,
+ 1,
+ "Length of first referral is less than 0");
+
+ r3.in.req.max_referral_level = 4;
+
+ torture_assert_ntstatus_ok(tctx,
+ dfs_cli_do_call(cli->tree, &r3),
+ "Get sysvol Domain referral failed");
+
+ torture_assert_int_equal(tctx, resp3.referral_entries[0].version, 4,
+ talloc_asprintf(tctx,
+ "Not expected version for referral entry 0 got %d expected 4",
+ resp3.referral_entries[0].version));
+#if 0
+ /*
+ * We do not support fallback indication for the moment
+ */
+ torture_assert_int_equal(tctx, resp3.header_flags,
+ DFS_HEADER_FLAG_STORAGE_SVR | DFS_HEADER_FLAG_TARGET_BCK,
+ "Header flag different it's not a referral for a storage with fallback");
+#endif
+ torture_assert_int_equal(tctx, resp3.referral_entries[0].referral.v4.entry_flags,
+ DFS_FLAG_REFERRAL_FIRST_TARGET_SET,
+ talloc_asprintf(tctx,
+ "Wrong entry flag expected to have a non domain response and got %d",
+ resp3.referral_entries[0].referral.v4.entry_flags));
+ return true;
+}
+
+static bool test_unknowndomain(struct torture_context *tctx,
+ struct smbcli_state *cli)
+{
+ struct dfs_GetDFSReferral r, r2;
+ struct dfs_referral_resp resp, resp2;
+
+ r.in.req.max_referral_level = 3;
+ r.in.req.servername = "";
+ r.out.resp = &resp;
+
+ torture_assert_ntstatus_ok(tctx,
+ dfs_cli_do_call(cli->tree, &r),
+ "Get Domain referral failed");
+
+ r2.in.req.max_referral_level = 3;
+ r2.in.req.servername = "foobar.none.net";
+ r2.out.resp = &resp2;
+
+ torture_assert_ntstatus_equal(tctx,
+ dfs_cli_do_call(cli->tree, &r2),
+ NT_STATUS_INVALID_PARAMETER,
+ "Get DC Domain didn't return exptected error code");
+
+ return true;
+}
+
+static bool test_getsysvolplusreferral(struct torture_context *tctx,
+ struct smbcli_state *cli)
+{
+ const char* str;
+ struct dfs_GetDFSReferral r, r2, r3;
+ struct dfs_referral_resp resp, resp2, resp3;
+
+ r.in.req.max_referral_level = 3;
+ r.in.req.servername = "";
+ r.out.resp = &resp;
+
+ torture_assert_ntstatus_ok(tctx,
+ dfs_cli_do_call(cli->tree, &r),
+ "Get Domain referral failed");
+
+ r2.in.req.max_referral_level = 3;
+ r2.in.req.servername = resp.referral_entries[0].referral.v3.data.referrals.r2.special_name;
+ r2.out.resp = &resp2;
+
+ torture_assert_ntstatus_ok(tctx,
+ dfs_cli_do_call(cli->tree, &r2),
+ "Get DC Domain referral failed");
+
+ str = resp2.referral_entries[0].referral.v3.data.referrals.r2.special_name;
+ r3.in.req.max_referral_level = 3;
+ r3.in.req.servername = talloc_asprintf(tctx, "%s\\sysvol\\foo", str);
+ r3.out.resp = &resp3;
+
+ torture_assert_ntstatus_equal(tctx,
+ dfs_cli_do_call(cli->tree, &r3),
+ NT_STATUS_NOT_FOUND,
+ "Bad behavior with subtree sysvol referral");
+
+ return true;
+}
+
+static bool test_low_referral_level(struct torture_context *tctx,
+ struct smbcli_state *cli)
+{
+ struct dfs_GetDFSReferral r;
+ struct dfs_referral_resp resp;
+
+ r.in.req.max_referral_level = 2;
+ r.in.req.servername = "";
+ r.out.resp = &resp;
+
+ torture_assert_ntstatus_equal(tctx,
+ dfs_cli_do_call(cli->tree, &r),
+ NT_STATUS_UNSUCCESSFUL,
+ "Unexpected STATUS for invalid deferral retquest");
+
+ return true;
+}
+
+NTSTATUS torture_dfs_init(void)
+{
+ struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "DFS");
+ struct torture_suite *suite_basic = torture_suite_create(suite, "DOMAIN");
+
+ torture_suite_add_suite(suite, suite_basic);
+
+ torture_suite_add_1smb_test(suite_basic, "domain referral",
+ test_getdomainreferral);
+ torture_suite_add_1smb_test(suite_basic, "dc referral",
+ test_getdcreferral);
+ torture_suite_add_1smb_test(suite_basic, "dc referral netbios",
+ test_getdcreferral_netbios);
+
+ torture_suite_add_1smb_test(suite_basic, "sysvol referral",
+ test_getsysvolreferral);
+
+ /* Non standard case */
+
+ torture_suite_add_1smb_test(suite_basic, "dc referral on unknown domain",
+ test_unknowndomain);
+ torture_suite_add_1smb_test(suite_basic, "sysvol with subtree referral",
+ test_getsysvolplusreferral);
+ torture_suite_add_1smb_test(suite_basic, "referral with a level 2",
+ test_low_referral_level);
+
+ /*
+ * test with invalid level
+ * test with netbios
+ */
+
+ suite->description = talloc_strdup(suite, "DFS referrals calls");
+
+ torture_register_suite(suite);
+
+ return NT_STATUS_OK;
+}
diff --git a/source4/torture/torture.c b/source4/torture/torture.c
index a93fbe33b0..e071a21d88 100644
--- a/source4/torture/torture.c
+++ b/source4/torture/torture.c
@@ -65,6 +65,7 @@ _PUBLIC_ int torture_init(void)
extern NTSTATUS torture_nbt_init(void);
extern NTSTATUS torture_nbench_init(void);
extern NTSTATUS torture_rap_init(void);
+ extern NTSTATUS torture_dfs_init(void);
extern NTSTATUS torture_rpc_init(void);
extern NTSTATUS torture_ntp_init(void);
extern NTSTATUS torture_smb2_init(void);
diff --git a/source4/torture/wscript_build b/source4/torture/wscript_build
index b91ba08096..a9183623ff 100644
--- a/source4/torture/wscript_build
+++ b/source4/torture/wscript_build
@@ -44,7 +44,7 @@ bld.SAMBA_MODULE('torture_rpc',
autoproto='rpc/proto.h',
subsystem='smbtorture',
init_function='torture_rpc_init',
- deps='NDR_TABLE RPC_NDR_UNIXINFO dcerpc_samr RPC_NDR_WINREG RPC_NDR_INITSHUTDOWN RPC_NDR_OXIDRESOLVER RPC_NDR_EVENTLOG RPC_NDR_ECHO RPC_NDR_SVCCTL RPC_NDR_NETLOGON dcerpc_atsvc dcerpc_mgmt RPC_NDR_DRSUAPI RPC_NDR_LSA RPC_NDR_EPMAPPER RPC_NDR_DFS RPC_NDR_FRSAPI RPC_NDR_SPOOLSS RPC_NDR_SRVSVC RPC_NDR_WKSSVC RPC_NDR_ROT RPC_NDR_DSSETUP RPC_NDR_REMACT RPC_NDR_OXIDRESOLVER RPC_NDR_NTSVCS WB_HELPER LIBSAMBA-NET LIBCLI_AUTH POPT_CREDENTIALS TORTURE_LDAP TORTURE_UTIL TORTURE_RAP dcerpc_server service process_model ntvfs SERVICE_SMB RPC_NDR_BROWSER LIBCLI_DRSUAPI TORTURE_LDB_MODULE',
+ deps='NDR_TABLE RPC_NDR_UNIXINFO dcerpc_samr RPC_NDR_WINREG RPC_NDR_INITSHUTDOWN RPC_NDR_OXIDRESOLVER RPC_NDR_EVENTLOG RPC_NDR_ECHO RPC_NDR_SVCCTL RPC_NDR_NETLOGON dcerpc_atsvc dcerpc_mgmt RPC_NDR_DRSUAPI RPC_NDR_LSA RPC_NDR_EPMAPPER RPC_NDR_DFS RPC_NDR_FRSAPI RPC_NDR_SPOOLSS RPC_NDR_SRVSVC RPC_NDR_WKSSVC RPC_NDR_ROT RPC_NDR_DSSETUP RPC_NDR_REMACT RPC_NDR_OXIDRESOLVER RPC_NDR_NTSVCS WB_HELPER LIBSAMBA-NET LIBCLI_AUTH POPT_CREDENTIALS TORTURE_LDAP TORTURE_UTIL TORTURE_RAP dcerpc_server service process_model ntvfs SERVICE_SMB RPC_NDR_BROWSER LIBCLI_DRSUAPI TORTURE_LDB_MODULE TORTURE_DFS',
internal_module=True
)
@@ -59,6 +59,15 @@ bld.SAMBA_MODULE('TORTURE_RAP',
internal_module=True
)
+bld.SAMBA_MODULE('TORTURE_DFS',
+ source='dfs/domaindfs.c dfs/common.c',
+ autoproto='dfs/proto.h',
+ subsystem='smbtorture',
+ init_function='torture_dfs_init',
+ deps='TORTURE_UTIL LIBCLI_SMB',
+ internal_module=True
+ )
+
bld.SAMBA_MODULE('TORTURE_AUTH',
source='auth/ntlmssp.c auth/pac.c',