s3: smbtorture: Add SMB2-DFS-FILENAME-LEADING-BACKSLASH test.
authorJeremy Allison <jra@samba.org>
Wed, 4 Jan 2023 01:53:17 +0000 (17:53 -0800)
committerVolker Lendecke <vl@samba.org>
Wed, 4 Jan 2023 06:50:37 +0000 (06:50 +0000)
Shows that we fail to cope with MacOSX clients that send a
(or more than one) leading '\\' character for an SMB2 DFS pathname.

I missed this in earlier tests as Windows, Linux, and
libsmbclient clients do NOT send a leading backslash
for SMB2 DFS paths. Only MacOSX (sigh:-).

Passes against Windows. Adds a knownfail for smbd.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15277

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
selftest/knownfail.d/dfs_paths
source3/selftest/tests.py
source3/torture/proto.h
source3/torture/test_smb2.c
source3/torture/torture.c

index 127c0492f51fd9c1096cef46fff42d2d9cce7a6a..51d9d6e5a43cb55125f480dade90a88da7bd1c5f 100644 (file)
@@ -1,6 +1,7 @@
 ^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.smb2.SMB2-DFS-FILENAME-LEADING-BACKSLASH.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 a40316ef53200dd9c7b6081cff5646704adcc593..8039b4a8171b9eb9277742d78d21a801fdd9f747 100755 (executable)
@@ -257,6 +257,20 @@ plantestsuite("samba3.smbtorture_s3.smb2.SMB2-DFS-PATHS",
                 smbtorture3,
                 "-mSMB2"])
 
+# BUG: https://bugzilla.samba.org/show_bug.cgi?id=15277
+# MacOSX clients send a leading '\\' character for DFS paths.
+#
+plantestsuite("samba3.smbtorture_s3.smb2.SMB2-DFS-FILENAME-LEADING-BACKSLASH",
+                "fileserver",
+                [os.path.join(samba3srcdir,
+                              "script/tests/test_smbtorture_s3.sh"),
+                'SMB2-DFS-FILENAME-LEADING-BACKSLASH',
+                '//$SERVER_IP/msdfs-pathname-share',
+                '$USERNAME',
+                '$PASSWORD',
+                smbtorture3,
+                "-mSMB2"])
+
 #
 # SMB2-NON-DFS-SHARE needs to run against a special share non-msdfs-pathname-share
 # This is an empty non-DFS share with no links, used merely to test
index 92b7dd4216c02f896f0eff7ba8346ad4deb8752e..df98a7445d7432bad4834f9f8edba8b10708a558 100644 (file)
@@ -123,6 +123,7 @@ 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_smb2_dfs_filename_leading_backslash(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 22918d39ccdc78210d3e83cfae550d4136223d15..dc249643aa651ba8974cde8928fb2253325c3ba3 100644 (file)
@@ -4946,3 +4946,193 @@ bool run_smb2_dfs_share_non_dfs_path(int dummy)
        (void)smb2_dfs_delete(cli, dfs_filename);
        return retval;
 }
+
+/*
+ * "Raw" test of an SMB2 filename with one or more leading
+ * backslash characters to a DFS share.
+ *
+ * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15277
+ *
+ * Once the server passes SMB2-DFS-PATHS we can
+ * fold this test into that one.
+ *
+ * Passes cleanly against Windows.
+ */
+
+bool run_smb2_dfs_filename_leading_backslash(int dummy)
+{
+       struct cli_state *cli = NULL;
+       NTSTATUS status;
+       bool dfs_supported = false;
+       char *dfs_filename_slash = NULL;
+       char *dfs_filename_slash_multi = NULL;
+       uint64_t file_ino = 0;
+       bool ino_matched = false;
+       uint64_t fid_persistent = 0;
+       uint64_t fid_volatile = 0;
+       bool retval = false;
+
+       printf("Starting SMB2-DFS-FILENAME-LEADING-BACKSLASH\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;
+       }
+
+       /* Ensure this is a DFS share. */
+       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;
+       }
+       dfs_supported = smbXcli_tcon_is_dfs_share(cli->smb2.tcon);
+       if (!dfs_supported) {
+               printf("Share %s does not support DFS\n",
+                       cli->share);
+               return false;
+       }
+
+       /*
+        * Create the filename with one leading backslash.
+        */
+       dfs_filename_slash = talloc_asprintf(talloc_tos(),
+                                       "\\%s\\%s\\file",
+                                       smbXcli_conn_remote_name(cli->conn),
+                                       cli->share);
+       if (dfs_filename_slash == NULL) {
+               printf("Out of memory\n");
+               return false;
+       }
+
+       /*
+        * Create the filename with many leading backslashes.
+        */
+       dfs_filename_slash_multi = talloc_asprintf(talloc_tos(),
+                                       "\\\\\\\\%s\\%s\\file",
+                                       smbXcli_conn_remote_name(cli->conn),
+                                       cli->share);
+       if (dfs_filename_slash_multi == NULL) {
+               printf("Out of memory\n");
+               return false;
+       }
+
+       /*
+        * Trying to open "\\server\\share\\file" should get
+        * NT_STATUS_OBJECT_NAME_NOT_FOUND.
+        */
+       status = get_smb2_inode(cli,
+                               dfs_filename_slash,
+                               &file_ino);
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+               printf("%s:%d Open of %s should get "
+                       "STATUS_OBJECT_NAME_NOT_FOUND, got %s\n",
+                       __FILE__,
+                       __LINE__,
+                       dfs_filename_slash,
+                       nt_errstr(status));
+               return false;
+       }
+
+       /* Now create a file called "\\server\\share\\file". */
+       status = smb2cli_create(cli->conn,
+                               cli->timeout,
+                               cli->smb2.session,
+                               cli->smb2.tcon,
+                               dfs_filename_slash,
+                               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 * */
+                               NULL); /* struct symlink_reparse_struct */
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("%s:%d smb2cli_create on %s returned %s\n",
+                       __FILE__,
+                       __LINE__,
+                       dfs_filename_slash,
+                       nt_errstr(status));
+               return false;
+       }
+
+       /*
+        * Trying to open "\\server\\share\\file" should now get
+        * a valid inode.
+        */
+       status = get_smb2_inode(cli,
+                               dfs_filename_slash,
+                               &file_ino);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("%s:%d Open of %s should succeed "
+                       "got %s\n",
+                       __FILE__,
+                       __LINE__,
+                       dfs_filename_slash,
+                       nt_errstr(status));
+               goto err;
+       }
+
+       /*
+        * Trying to open "\\\\\\server\\share\\file" should now get
+        * a valid inode that matches. MacOSX-style of DFS name test.
+        */
+       ino_matched = smb2_inode_matches(cli,
+                               dfs_filename_slash,
+                               file_ino,
+                               dfs_filename_slash_multi);
+       if (!ino_matched) {
+               printf("%s:%d Failed to match ino number for %s\n",
+                       __FILE__,
+                       __LINE__,
+                       dfs_filename_slash_multi);
+               goto err;
+       }
+
+       retval = true;
+
+  err:
+
+       if (fid_persistent != 0 || fid_volatile != 0) {
+               smb2cli_close(cli->conn,
+                             cli->timeout,
+                             cli->smb2.session,
+                             cli->smb2.tcon,
+                             0, /* flags */
+                             fid_persistent,
+                             fid_volatile);
+       }
+       /* Delete anything we made. */
+       (void)smb2_dfs_delete(cli, dfs_filename_slash);
+       return retval;
+}
index 4d22c539e5249a1cfee712ee884cd0693b10631b..acf245f3cb5bf9ab69a2590b5de692f0c33955be 100644 (file)
@@ -15369,6 +15369,10 @@ static struct {
                .name  = "SMB2-DFS-SHARE-NON-DFS-PATH",
                .fn    = run_smb2_dfs_share_non_dfs_path,
        },
+       {
+               .name  = "SMB2-DFS-FILENAME-LEADING-BACKSLASH",
+               .fn    = run_smb2_dfs_filename_leading_backslash,
+       },
        {
                .name  = "SMB1-DFS-PATHS",
                .fn    = run_smb1_dfs_paths,