]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: smbtorture3: Add new SMB2-DFS-SHARE-NON-DFS-PATH test.
authorJeremy Allison <jra@samba.org>
Tue, 27 Sep 2022 17:37:41 +0000 (10:37 -0700)
committerNoel Power <npower@samba.org>
Wed, 28 Sep 2022 19:34:29 +0000 (19:34 +0000)
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

selftest/knownfail.d/dfs_paths
source3/selftest/tests.py
source3/torture/proto.h
source3/torture/test_smb2.c
source3/torture/torture.c

index 64ddfc9160afb1b85b0f91fb8f8f4597ccbf3460..127c0492f51fd9c1096cef46fff42d2d9cce7a6a 100644 (file)
@@ -1,5 +1,6 @@
 ^samba3.smbtorture_s3.smb2.SMB2-DFS-PATHS.smbtorture\(fileserver\)
 ^samba3.smbtorture_s3.smb2.SMB2-NON-DFS-SHARE.smbtorture\(fileserver\)
+^samba3.smbtorture_s3.smb2.SMB2-DFS-SHARE-NON-DFS-PATH.smbtorture\(fileserver\)
 ^samba3.smbtorture_s3.smb1.SMB1-DFS-PATHS.smbtorture\(fileserver\)
 ^samba3.smbtorture_s3.smb1.SMB1-DFS-SEARCH-PATHS.smbtorture\(fileserver\)
 ^samba3.smbtorture_s3.smb1.SMB1-DFS-OPERATIONS.smbtorture\(fileserver\)
index 68959ba0b900cb340caa45ec55a3bf8d97dc459d..04e47fa962f1dc4aa326123ed4f9a5dff20d4c86 100755 (executable)
@@ -264,6 +264,22 @@ plantestsuite("samba3.smbtorture_s3.smb2.SMB2-NON-DFS-SHARE",
                 smbtorture3,
                 "-mSMB2"])
 
+#
+# SMB2-DFS-SHARE-NON-DFS-PATH needs to run against a special share msdfs-pathname-share
+# This is an empty DFS share with no links, used merely to test
+# incoming non-DFS pathnames and how they map to local paths.
+#
+plantestsuite("samba3.smbtorture_s3.smb2.SMB2-DFS-SHARE-NON-DFS-PATH",
+                "fileserver",
+                [os.path.join(samba3srcdir,
+                              "script/tests/test_smbtorture_s3.sh"),
+                'SMB2-DFS-SHARE-NON-DFS-PATH',
+                '//$SERVER_IP/msdfs-pathname-share',
+                '$USERNAME',
+                '$PASSWORD',
+                smbtorture3,
+                "-mSMB2"])
+
 #
 # SMB1-DFS-PATHS needs to run against a special share msdfs-pathname-share
 # This is an empty DFS share with no links, used merely to test
index 7093e8a7665cfecaf020d4bae906ea687285b8ee..7b00da26181c058ea800dedd4ed9c9c75c669980 100644 (file)
@@ -122,6 +122,7 @@ bool run_smb2_quota1(int dummy);
 bool run_smb2_stream_acl(int dummy);
 bool run_smb2_dfs_paths(int dummy);
 bool run_smb2_non_dfs_share(int dummy);
+bool run_smb2_dfs_share_non_dfs_path(int dummy);
 bool run_smb1_dfs_paths(int dummy);
 bool run_smb1_dfs_search_paths(int dummy);
 bool run_smb1_dfs_operations(int dummy);
index d3e9b4a6ad15a17fa1945c9a6bc2e3d31865aa4f..01664b143902068e0ecfea5682dbf6f3a4390233 100644 (file)
@@ -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;
+}
index ee50fd8ee099b00d3fce49e24e0f912b072bea3f..65fbd4b5aa0a465c2ff61b60ab0c7e7ed6332866 100644 (file)
@@ -15365,6 +15365,10 @@ static struct {
                .name  = "SMB2-NON-DFS-SHARE",
                .fn    = run_smb2_non_dfs_share,
        },
+       {
+               .name  = "SMB2-DFS-SHARE-NON-DFS-PATH",
+               .fn    = run_smb2_dfs_share_non_dfs_path,
+       },
        {
                .name  = "SMB1-DFS-PATHS",
                .fn    = run_smb1_dfs_paths,