]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: smbtorture3: Add an SMB1 operations torture tester.
authorJeremy Allison <jra@samba.org>
Wed, 7 Sep 2022 00:25:18 +0000 (17:25 -0700)
committerJeremy Allison <jra@samba.org>
Wed, 14 Sep 2022 17:33:37 +0000 (17:33 +0000)
Only tests SMB1unlink for now, but I will add other operations
later.

smbtorture3 test is: SMB1-DFS-OPERATIONS.

Passes fully against Windows. Adds knownfail for smbd.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Noel Power <npower@samba.org>
selftest/knownfail.d/dfs_paths
source3/selftest/tests.py
source3/torture/proto.h
source3/torture/test_smb1_dfs.c
source3/torture/torture.c

index 330c17d02a0f63dfd711d10ceac1a1389b863776..64ddfc9160afb1b85b0f91fb8f8f4597ccbf3460 100644 (file)
@@ -2,3 +2,4 @@
 ^samba3.smbtorture_s3.smb2.SMB2-NON-DFS-SHARE.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 b11fedd6c4fa184ddb0538cf373107c790438fee..68959ba0b900cb340caa45ec55a3bf8d97dc459d 100755 (executable)
@@ -296,6 +296,22 @@ plantestsuite("samba3.smbtorture_s3.smb1.SMB1-DFS-SEARCH-PATHS",
                 smbtorture3,
                 "-mNT1"])
 
+#
+# SMB1-DFS-OPERATIONS needs to run against a special share msdfs-pathname-share
+# This is an empty DFS share with no links, used merely to test
+# incoming DFS pathnames and how they map to local paths.
+#
+plantestsuite("samba3.smbtorture_s3.smb1.SMB1-DFS-OPERATIONS",
+                "fileserver",
+                [os.path.join(samba3srcdir,
+                              "script/tests/test_smbtorture_s3.sh"),
+                'SMB1-DFS-OPERATIONS',
+                '//$SERVER_IP/msdfs-pathname-share',
+                '$USERNAME',
+                '$PASSWORD',
+                smbtorture3,
+                "-mNT1"])
+
 #
 # SMB2-STREAM-ACL needs to run against a special share - vfs_wo_fruit
 #
index d5e404eaefa833c654691f46ba9a1ccb954376e8..7093e8a7665cfecaf020d4bae906ea687285b8ee 100644 (file)
@@ -124,6 +124,7 @@ bool run_smb2_dfs_paths(int dummy);
 bool run_smb2_non_dfs_share(int dummy);
 bool run_smb1_dfs_paths(int dummy);
 bool run_smb1_dfs_search_paths(int dummy);
+bool run_smb1_dfs_operations(int dummy);
 bool run_list_dir_async_test(int dummy);
 bool run_delete_on_close_non_empty(int dummy);
 bool run_delete_on_close_nonwrite_delete_yes_test(int dummy);
index 1acea318e37561a9c25ee239655efd1d45f5c602..211be4e1aba0d8d411aea2df341c774405d3ec66 100644 (file)
@@ -2361,3 +2361,202 @@ bool run_smb1_dfs_search_paths(int dummy)
        (void)smb1_dfs_delete(cli, "BAD\\BAD\\file");
        return retval;
 }
+
+static bool smb1_create_testfile(struct cli_state *cli,
+                                const char *path)
+{
+       NTSTATUS status;
+       uint16_t fnum = (uint16_t)-1;
+
+       /* Create a test file. */
+       status = smb1cli_ntcreatex(cli->conn,
+                                  cli->timeout,
+                                  cli->smb1.pid,
+                                  cli->smb1.tcon,
+                                  cli->smb1.session,
+                                  path,
+                                  OPLOCK_NONE, /* CreatFlags */
+                                  0, /* RootDirectoryFid */
+                                  SEC_STD_SYNCHRONIZE|
+                                       SEC_STD_DELETE |
+                                       SEC_FILE_READ_DATA|
+                                       SEC_FILE_READ_ATTRIBUTE, /* DesiredAccess */
+                                  0, /* AllocationSize */
+                                  FILE_ATTRIBUTE_NORMAL, /* FileAttributes */
+                                  FILE_SHARE_READ|
+                                       FILE_SHARE_WRITE|
+                                       FILE_SHARE_DELETE, /* ShareAccess */
+                                  FILE_CREATE, /* CreateDisposition */
+                                  0, /* CreateOptions */
+                                  2, /* ImpersonationLevel */
+                                  0, /* SecurityFlags */
+                                  &fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("%s:%d smb1cli_ntcreatex on %s returned %s\n",
+                       __FILE__,
+                       __LINE__,
+                       path,
+                       nt_errstr(status));
+               return false;
+       }
+
+       /* Close "file" handle. */
+       (void)smb1cli_close(cli->conn,
+                           cli->timeout,
+                           cli->smb1.pid,
+                           cli->smb1.tcon,
+                           cli->smb1.session,
+                           fnum,
+                           0); /* last_modified */
+       return true;
+}
+
+static NTSTATUS smb1_unlink(struct cli_state *cli,
+                           const char *path)
+{
+       uint16_t vwv[1];
+       uint8_t *bytes = NULL;
+
+       PUSH_LE_U16(vwv, 0, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
+       bytes = talloc_array(talloc_tos(), uint8_t, 1);
+       if (bytes == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       bytes[0] = 4;
+       bytes = smb_bytes_push_str(bytes,
+                                  smbXcli_conn_use_unicode(cli->conn),
+                                  path,
+                                  strlen(path)+1,
+                                  NULL);
+       if (bytes == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       return cli_smb(talloc_tos(),
+                      cli,
+                      SMBunlink, /* command. */
+                      0, /* additional_flags. */
+                      1, /* wct. */
+                      vwv, /* vwv. */
+                      talloc_get_size(bytes), /* num_bytes. */
+                      bytes, /* bytes. */
+                      NULL, /* result parent. */
+                      0, /* min_wct. */
+                      NULL, /* return wcount. */
+                      NULL, /* return wvw. */
+                      NULL, /* return byte count. */
+                      NULL); /* return bytes. */
+}
+
+static bool test_smb1_unlink(struct cli_state *cli)
+{
+       NTSTATUS status;
+       bool retval = false;
+       bool ok = false;
+
+       /* Start clean. */
+       (void)smb1_dfs_delete(cli, "\\BAD\\BAD\\file");
+
+       /* Create a test file. */
+       ok = smb1_create_testfile(cli, "\\BAD\\BAD\\file");
+       if (!ok) {
+               printf("%s:%d failed to create test file %s\n",
+                       __FILE__,
+                       __LINE__,
+                       "\\BAD\\BAD\\file");
+               goto err;
+       }
+
+       status = smb1_unlink(cli, "file");
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
+               printf("%s:%d SMB1unlink of %s should get "
+                       "NT_STATUS_FILE_IS_A_DIRECTORY, got %s\n",
+                       __FILE__,
+                       __LINE__,
+                       "file",
+                       nt_errstr(status));
+               goto err;
+       }
+       status = smb1_unlink(cli, "\\BAD\\file");
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
+               printf("%s:%d SMB1unlink of %s should get "
+                       "NT_STATUS_FILE_IS_A_DIRECTORY, got %s\n",
+                       __FILE__,
+                       __LINE__,
+                       "\\BAD\\file",
+                       nt_errstr(status));
+               goto err;
+       }
+       status = smb1_unlink(cli, "\\BAD\\BAD\\file");
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("%s:%d SMB1unlink on %s returned %s\n",
+                       __FILE__,
+                       __LINE__,
+                       "\\BAD\\BAD\\file",
+                       nt_errstr(status));
+               goto err;
+       }
+
+       retval = true;
+
+  err:
+
+       (void)smb1_dfs_delete(cli, "\\BAD\\BAD\\file");
+       return retval;
+}
+
+/*
+ * "Raw" test of different SMB1 operations to a DFS share.
+ * We must (mostly) use the lower level smb1cli_XXXX() interfaces,
+ * not the cli_XXX() ones here as the ultimate goal is to fix our
+ * cli_XXX() interfaces to work transparently over DFS.
+ *
+ * So here, we're testing the server code, not the client code.
+ *
+ * Passes cleanly against Windows.
+ */
+
+bool run_smb1_dfs_operations(int dummy)
+{
+       struct cli_state *cli = NULL;
+       bool dfs_supported = false;
+       bool retval = false;
+       bool ok = false;
+
+       printf("Starting SMB1-DFS-OPS\n");
+
+       if (!torture_init_connection(&cli)) {
+               return false;
+       }
+
+       if (!torture_open_connection(&cli, 0)) {
+               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->smb1.tcon);
+       if (!dfs_supported) {
+               printf("Share %s does not support DFS\n",
+                       cli->share);
+               return false;
+       }
+
+       ok = test_smb1_unlink(cli);
+       if (!ok) {
+               goto err;
+       }
+
+       retval = true;
+
+  err:
+
+       /* Delete anything we made. */
+       (void)smb1_dfs_delete(cli, "\\BAD\\BAD\\file");
+       return retval;
+}
index 75d0248d773431e56ba4b08ad7669265e230f154..2bd15fcec009fb8bcde35bd74b98b909a89a384a 100644 (file)
@@ -15375,6 +15375,10 @@ static struct {
                .name  = "SMB1-DFS-SEARCH-PATHS",
                .fn    = run_smb1_dfs_search_paths,
        },
+       {
+               .name  = "SMB1-DFS-OPERATIONS",
+               .fn    = run_smb1_dfs_operations,
+       },
        {
                .name  = "CLEANUP1",
                .fn    = run_cleanup1,