summaryrefslogtreecommitdiff
path: root/source3/torture/test_smb2.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2022-09-27 10:37:41 -0700
committerNoel Power <npower@samba.org>2022-09-28 19:34:29 +0000
commit318da783e9df83550d86fcefcf89f55a77addcbe (patch)
tree3278f415d23c762d6a025f2f197a4a3489945f8b /source3/torture/test_smb2.c
parentf3dc1a42f578bec784d01b8caf6ff13e230116a2 (diff)
downloadsamba-318da783e9df83550d86fcefcf89f55a77addcbe.tar.gz
s3: smbtorture3: Add new SMB2-DFS-SHARE-NON-DFS-PATH test.
Uses non-DFS names and DFS-names against a DFS share, shows that Windows looks correctly at the DFS flag when SMB2 requests are made on a DFS share. Passes against Windows 2022. Mark as knownfail for smbd. Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Noel Power <npower@samba.org> Autobuild-User(master): Noel Power <npower@samba.org> Autobuild-Date(master): Wed Sep 28 19:34:29 UTC 2022 on sn-devel-184
Diffstat (limited to 'source3/torture/test_smb2.c')
-rw-r--r--source3/torture/test_smb2.c207
1 files changed, 207 insertions, 0 deletions
diff --git a/source3/torture/test_smb2.c b/source3/torture/test_smb2.c
index d3e9b4a6ad1..01664b14390 100644
--- a/source3/torture/test_smb2.c
+++ b/source3/torture/test_smb2.c
@@ -4521,3 +4521,210 @@ bool run_smb2_non_dfs_share(int dummy)
(void)smb2_dfs_delete(cli, "file");
return retval;
}
+
+/*
+ * Add a test that sends a non-DFS path and does not set the
+ * SMB2 flag FLAGS2_DFS_PATHNAMES to a DFS
+ * share. Windows passes this (it just treats the
+ * pathnames as non-DFS).
+ */
+
+bool run_smb2_dfs_share_non_dfs_path(int dummy)
+{
+ struct cli_state *cli = NULL;
+ NTSTATUS status;
+ bool dfs_supported = false;
+ uint64_t fid_persistent = 0;
+ uint64_t fid_volatile = 0;
+ bool retval = false;
+ char *dfs_filename = NULL;
+ uint64_t root_ino = (uint64_t)-1;
+ bool ino_matched = false;
+
+ printf("Starting SMB2-DFS-SHARE-NON-DFS-PATH\n");
+
+ if (!torture_init_connection(&cli)) {
+ return false;
+ }
+
+ status = smbXcli_negprot(cli->conn,
+ cli->timeout,
+ PROTOCOL_SMB2_02,
+ PROTOCOL_SMB3_11);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("smbXcli_negprot returned %s\n", nt_errstr(status));
+ return false;
+ }
+
+ status = cli_session_setup_creds(cli, torture_creds);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_session_setup returned %s\n", nt_errstr(status));
+ return false;
+ }
+
+ status = cli_tree_connect(cli, share, "?????", NULL);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("cli_tree_connect returned %s\n", nt_errstr(status));
+ return false;
+ }
+
+ dfs_supported = smbXcli_conn_dfs_supported(cli->conn);
+ if (!dfs_supported) {
+ printf("Server %s does not support DFS\n",
+ smbXcli_conn_remote_name(cli->conn));
+ return false;
+ }
+ /* Ensure this is a DFS share. */
+ dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
+ if (!dfs_supported) {
+ printf("Share %s is not a DFS share.\n",
+ cli->share);
+ return false;
+ }
+ /* Come up with a "valid" SMB2 DFS name. */
+ dfs_filename = talloc_asprintf(talloc_tos(),
+ "%s\\%s\\file",
+ smbXcli_conn_remote_name(cli->conn),
+ cli->share);
+ if (dfs_filename == NULL) {
+ printf("Out of memory\n");
+ return false;
+ }
+
+ /* Get the root of the share ino. */
+ status = get_smb2_inode(cli,
+ "SERVER\\SHARE",
+ &root_ino);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("%s:%d get_smb2_inode on %s returned %s\n",
+ __FILE__,
+ __LINE__,
+ "SERVER\\SHARE",
+ nt_errstr(status));
+ goto err;
+ }
+
+ /* Create a dfs_filename. */
+ status = smb2cli_create(cli->conn,
+ cli->timeout,
+ cli->smb2.session,
+ cli->smb2.tcon,
+ dfs_filename,
+ SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
+ SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
+ SEC_STD_SYNCHRONIZE|
+ SEC_STD_DELETE |
+ SEC_FILE_READ_DATA|
+ SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
+ FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
+ FILE_CREATE, /* create_disposition, */
+ 0, /* create_options, */
+ NULL, /* smb2_create_blobs *blobs */
+ &fid_persistent,
+ &fid_volatile,
+ NULL, /* struct smb_create_returns * */
+ talloc_tos(), /* mem_ctx. */
+ NULL); /* struct smb2_create_blobs * */
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("%s:%d smb2cli_create on %s returned %s\n",
+ __FILE__,
+ __LINE__,
+ dfs_filename,
+ nt_errstr(status));
+ goto err;
+ }
+
+ /* Close the handle we just opened. */
+ smb2cli_close(cli->conn,
+ cli->timeout,
+ cli->smb2.session,
+ cli->smb2.tcon,
+ 0, /* flags */
+ fid_persistent,
+ fid_volatile);
+
+ fid_persistent = 0;
+ fid_volatile = 0;
+
+ /*
+ * Force the share to be non-DFS, as far as the client
+ * is concerned.
+ */
+ smb2cli_tcon_set_values(cli->smb2.tcon,
+ cli->smb2.session,
+ smb2cli_tcon_current_id(cli->smb2.tcon),
+ 0,
+ smb2cli_tcon_flags(cli->smb2.tcon),
+ smb2cli_tcon_capabilities(cli->smb2.tcon) &
+ ~SMB2_SHARE_CAP_DFS,
+ 0);
+
+ /*
+ * Prove we can still use non-DFS pathnames on a DFS
+ * share so long as we don't set the FLAGS2_DFS_PATHNAMES
+ * in the SMB2 request.
+ */
+ status = smb2cli_create(cli->conn,
+ cli->timeout,
+ cli->smb2.session,
+ cli->smb2.tcon,
+ "file",
+ SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */
+ SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */
+ SEC_STD_SYNCHRONIZE|
+ SEC_STD_DELETE |
+ SEC_FILE_READ_DATA|
+ SEC_FILE_READ_ATTRIBUTE, /* desired_access, */
+ FILE_ATTRIBUTE_NORMAL, /* file_attributes, */
+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */
+ FILE_OPEN, /* create_disposition, */
+ 0, /* create_options, */
+ NULL, /* smb2_create_blobs *blobs */
+ &fid_persistent,
+ &fid_volatile,
+ NULL, /* struct smb_create_returns * */
+ talloc_tos(), /* mem_ctx. */
+ NULL); /* struct smb2_create_blobs * */
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("%s:%d smb2cli_create on %s returned %s\n",
+ __FILE__,
+ __LINE__,
+ "file",
+ nt_errstr(status));
+ goto err;
+ }
+
+ /*
+ * Show that now we're using non-DFS pathnames
+ * on a DFS share, "" opens the root of the share.
+ */
+ ino_matched = smb2_inode_matches(cli,
+ "SERVER\\SHARE",
+ root_ino,
+ "");
+ if (!ino_matched) {
+ printf("%s:%d Failed to match ino number for %s\n",
+ __FILE__,
+ __LINE__,
+ "");
+ goto err;
+ }
+
+ retval = true;
+
+ err:
+
+ if (fid_volatile != 0) {
+ smb2cli_close(cli->conn,
+ cli->timeout,
+ cli->smb2.session,
+ cli->smb2.tcon,
+ 0, /* flags */
+ fid_persistent,
+ fid_volatile);
+ }
+ (void)smb2_dfs_delete(cli, "file");
+ (void)smb2_dfs_delete(cli, dfs_filename);
+ return retval;
+}