summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2022-09-08 14:24:38 -0700
committerJeremy Allison <jra@samba.org>2022-09-14 17:33:37 +0000
commit85dc30f95982cbb24620c11bf78c96417c70ca7a (patch)
tree5f28c8b5568d5f14c145f75b564306c3044e12e8
parent7b5955dcd5a8452fc6be8b251f44d9f236bb3eff (diff)
downloadsamba-85dc30f95982cbb24620c11bf78c96417c70ca7a.tar.gz
s3: smbtorture3: Add test_smb1_ctemp() DFS test to run_smb1_dfs_operations().
NB. This passes against Windows, but SMBctemp is broken on a Windows DFS share and always returns NT_STATUS_FILE_IS_A_DIRECTORY. When we fix the Samba server to correctly process DFS pathnames we'll have to change this test to understand it's running against smbd and modify the expected behavior to match a working server. Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Noel Power <npower@samba.org>
-rw-r--r--source3/torture/test_smb1_dfs.c158
1 files changed, 158 insertions, 0 deletions
diff --git a/source3/torture/test_smb1_dfs.c b/source3/torture/test_smb1_dfs.c
index bbaf7a5524e..e53d9e55b59 100644
--- a/source3/torture/test_smb1_dfs.c
+++ b/source3/torture/test_smb1_dfs.c
@@ -3814,6 +3814,159 @@ static bool test_smb1_chkpath(struct cli_state *cli)
return retval;
}
+static NTSTATUS smb1_ctemp(struct cli_state *cli,
+ const char *path,
+ char **tmp_path)
+{
+ uint16_t vwv[3] = { 0 };
+ uint8_t *bytes = NULL;
+ NTSTATUS status;
+ uint16_t *return_words = NULL;
+ uint8_t return_wcount = 0;
+ uint32_t return_bytecount = 0;
+ uint8_t *return_bytes = NULL;
+ size_t sret = 0;
+ uint16_t fnum = (uint16_t)-1;
+
+ 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;
+ }
+ status = cli_smb(talloc_tos(),
+ cli,
+ SMBctemp, /* command. */
+ 0, /* additional_flags. */
+ 3, /* wct. */
+ vwv, /* vwv. */
+ talloc_get_size(bytes), /* num_bytes. */
+ bytes, /* bytes. */
+ NULL, /* result parent. */
+ 1, /* min_wct. */
+ &return_wcount, /* return wcount. */
+ &return_words, /* return wvw. */
+ &return_bytecount, /* return byte count. */
+ &return_bytes); /* return bytes. */
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (return_wcount != 1) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ fnum = PULL_LE_U16(return_words, 0);
+
+ /* Delete the file by fnum. */
+ status = cli_nt_delete_on_close(cli, fnum, 1);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ (void)smb1cli_close(cli->conn,
+ cli->timeout,
+ cli->smb1.pid,
+ cli->smb1.tcon,
+ cli->smb1.session,
+ fnum,
+ 0); /* last_modified */
+ fnum = (uint16_t)-1;
+
+ if (return_bytecount < 2) {
+ return NT_STATUS_DATA_ERROR;
+ }
+
+ sret = pull_string_talloc(talloc_tos(),
+ NULL,
+ 0,
+ tmp_path,
+ return_bytes,
+ return_bytecount,
+ STR_ASCII);
+ if (sret == 0) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return status;
+}
+
+static bool test_smb1_ctemp(struct cli_state *cli)
+{
+ NTSTATUS status;
+ bool retval = false;
+ char *retpath = NULL;
+
+ /* Start clean. */
+ (void)smb1_dfs_delete(cli, "\\BAD\\BAD\\ctemp_dir");
+
+ status = smb1_mkdir(cli, "\\BAD\\BAD\\ctemp_dir");
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("%s:%d Failed to create %s (%s)\n",
+ __FILE__,
+ __LINE__,
+ "\\BAD\\BAD\\ctemp_dir",
+ nt_errstr(status));
+ goto err;
+ }
+
+ /*
+ * Windows returns NT_STATUS_FILE_IS_A_DIRECTORY
+ * for all SMBctemp calls on a DFS share, no
+ * matter what we put in the pathname.
+ */
+
+ /*
+ * When we fix smbd we'll need to detect running
+ * in smbtorture3 against smbd here and modify
+ * the expected behavior. Windows is simply
+ * broken here.
+ */
+ status = smb1_ctemp(cli, "ctemp_dir", &retpath);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
+ printf("%s:%d SMB1ctemp of %s should get "
+ "NT_STATUS_FILE_IS_A_DIRECTORY, got %s\n",
+ __FILE__,
+ __LINE__,
+ "ctemp_dir",
+ nt_errstr(status));
+ goto err;
+ }
+ status = smb1_ctemp(cli, "\\BAD\\ctemp_dir", &retpath);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
+ printf("%s:%d SMB1ctemp of %s should get "
+ "NT_STATUS_FILE_IS_A_DIRECTORY, got %s\n",
+ __FILE__,
+ __LINE__,
+ "\\BAD\\ctemp_dir",
+ nt_errstr(status));
+ goto err;
+ }
+ status = smb1_ctemp(cli, "\\BAD\\BAD\\ctemp_dir", &retpath);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
+ printf("%s:%d SMB1ctemp of %s should get "
+ "NT_STATUS_FILE_IS_A_DIRECTORY, got %s\n",
+ __FILE__,
+ __LINE__,
+ "\\BAD\\BAD\\ctemp_dir",
+ nt_errstr(status));
+ goto err;
+ }
+
+ retval = true;
+
+ err:
+
+ (void)smb1_dfs_delete(cli, "\\BAD\\BAD\\ctemp_dir");
+ return retval;
+}
+
/*
* "Raw" test of different SMB1 operations to a DFS share.
* We must (mostly) use the lower level smb1cli_XXXX() interfaces,
@@ -3911,6 +4064,11 @@ bool run_smb1_dfs_operations(int dummy)
goto err;
}
+ ok = test_smb1_ctemp(cli);
+ if (!ok) {
+ goto err;
+ }
+
retval = true;
err: