s4 torture: Add tests for dfs referrals handling in SMB/trans2 requests
authorMatthieu Patou <mat@matws.net>
Sun, 9 May 2010 21:39:27 +0000 (01:39 +0400)
committerStefan Metzmacher <metze@samba.org>
Tue, 18 May 2010 13:31:13 +0000 (15:31 +0200)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
source4/torture/config.mk
source4/torture/dfs/common.c [new file with mode: 0644]
source4/torture/dfs/domaindfs.c [new file with mode: 0644]
source4/torture/torture.c
source4/torture/wscript_build

index 50d400980f453b411c787cc1d80e39c2a0a0be16..4d65256a3d3a4d79085f7f939bf10a00551f0fcd 100644 (file)
@@ -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 (file)
index 0000000..f1cc106
--- /dev/null
@@ -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 (file)
index 0000000..18c8439
--- /dev/null
@@ -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;
+}
index a93fbe33b0570b70b69088f7aad66efb13e3d0d7..e071a21d885545e9c36191c810c6c2fd928b436a 100644 (file)
@@ -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);
index b91ba08096fb9cd78d48670e32e31079896dd007..a9183623ff633c7b9f3fa2e79616e59110725808 100644 (file)
@@ -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',