From 43d30ddb1bd8b3638f48758a3d2a8eebcbef77fd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 5 Oct 2020 10:52:46 -0700 Subject: [PATCH] s3: selftest: Add new SMB1-only wildcard rename regression test. samba3.smbtorture_s3.crypt_client.SMB1-WILD-MANGLE-RENAME(nt4_dc_smb1) samba3.smbtorture_s3.plain.SMB1-WILD-MANGLE-RENAME(fileserver_smb1) knownfail for now. The recent wildcard changes broke something that used to work. Consider a directory with 2 files: dir/ foo fo* The 'fo*' file has a mangled name of FSHCRD~2. SMB1rename("dir/FSHCRD~2", "dir/ba*") will rename *both* files as the new 'rename has wildcard' check is done after the name unmangle. SMB2 doesn't allow wildcard renames so doesn't have this problem. Fix to follow. Signed-off-by: Jeremy Allison Reviewed-by: Ralph Boehme --- selftest/knownfail.d/smb1-wild-mangle-rename | 3 + selftest/skip | 1 + source3/selftest/tests.py | 3 +- source3/torture/torture.c | 175 +++++++++++++++++++ 4 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 selftest/knownfail.d/smb1-wild-mangle-rename diff --git a/selftest/knownfail.d/smb1-wild-mangle-rename b/selftest/knownfail.d/smb1-wild-mangle-rename new file mode 100644 index 00000000000..8f1c036b139 --- /dev/null +++ b/selftest/knownfail.d/smb1-wild-mangle-rename @@ -0,0 +1,3 @@ +# Check SMB1 wildcard demangle +^samba3.smbtorture_s3.plain.SMB1-WILD-MANGLE-RENAME.smbtorture\(fileserver_smb1\) +^samba3.smbtorture_s3.crypt_client.SMB1-WILD-MANGLE-RENAME.smbtorture\(nt4_dc_smb1\) diff --git a/selftest/skip b/selftest/skip index acf3765386e..5bdc10648da 100644 --- a/selftest/skip +++ b/selftest/skip @@ -62,6 +62,7 @@ ^samba3.smbtorture_s3.plain.SMB2-SESSION-REAUTH\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server ^samba3.smbtorture_s3.plain.SMB2-SESSION-RECONNECT\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server ^samba3.smbtorture_s3.plain.SMB1-WILD-MANGLE-UNLINK\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server +^samba3.smbtorture_s3.plain.SMB1-WILD-MANGLE-RENAME\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server ^samba3.*base.charset ^samba3.*raw.context ^samba3.*raw.ioctl diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 44c9fd844f4..b3b982773a6 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -108,7 +108,8 @@ fileserver_tests = [ "CLEANUP4", "DELETE-STREAM", "BAD-NBT-SESSION", - "SMB1-WILD-MANGLE-UNLINK"] + "SMB1-WILD-MANGLE-UNLINK", + "SMB1-WILD-MANGLE-RENAME"] for t in fileserver_tests: fileserver_env = "fileserver_smb1" diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 6ac812b0244..d68ee579daf 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -12825,6 +12825,177 @@ static bool run_smb1_wild_mangle_unlink_test(int dummy) return correct; } +static bool run_smb1_wild_mangle_rename_test(int dummy) +{ + static struct cli_state *cli_posix = NULL; + static struct cli_state *cli = NULL; + uint16_t fnum = (uint16_t)-1; + bool correct = false; + const char *dname = "smb1_wild_mangle_rename"; + const char *fooname = "smb1_wild_mangle_rename/foo"; + const char *foostar_name = "smb1_wild_mangle_rename/fo*"; + const char *wild_name = "smb1_wild_mangle_rename/*"; + char *windows_rename_src = NULL; + const char *windows_rename_dst = "smb1_wild_mangle_rename\\ba*"; + char *mangled_name = NULL; + NTSTATUS status; + + printf("Starting SMB1 wild mangle rename test\n"); + + if (!torture_open_connection(&cli_posix, 0)) { + return false; + } + + smbXcli_conn_set_sockopt(cli_posix->conn, sockops); + + status = torture_setup_unix_extensions(cli_posix); + if (!NT_STATUS_IS_OK(status)) { + printf("server doesn't support POSIX\n"); + return false; + } + + /* Open a Windows connection. */ + if (!torture_open_connection(&cli, 0)) { + goto out; + } + + smbXcli_conn_set_sockopt(cli->conn, sockops); + + /* Ensure we start from fresh. */ + cli_unlink(cli, + wild_name, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + cli_posix_rmdir(cli_posix, dname); + + /* + * Create two files - 'foo' and 'fo*'. + * We need POSIX extensions for this as 'fo*' + * is not a valid Windows name. + */ + + status = cli_posix_mkdir(cli_posix, dname, 0770); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_posix_mkdir of %s returned %s\n", + dname, + nt_errstr(status)); + goto out; + } + + status = cli_posix_open(cli_posix, + fooname, + O_RDWR|O_CREAT|O_EXCL, + 0660, + &fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_posix_open (create) of %s returned %s\n", + fooname, + nt_errstr(status)); + goto out; + } + status = cli_close(cli_posix, fnum); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + status = cli_posix_open(cli_posix, + foostar_name, + O_RDWR|O_CREAT|O_EXCL, + 0660, + &fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_posix_open (create) of %s returned %s\n", + foostar_name, + nt_errstr(status)); + goto out; + } + status = cli_close(cli_posix, fnum); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + /* + * Get the mangled name. We can re-use the + * previous smb1_wild_mangle_list_fn for this. + */ + + status = cli_list(cli, + wild_name, + 0, + smb1_wild_mangle_list_fn, + &mangled_name); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_list of %s returned %s\n", + wild_name, + nt_errstr(status)); + goto out; + } + + if (mangled_name == NULL) { + goto out; + } + + printf("mangled_name = %s\n", + mangled_name); + + /* + * Try a Windows rename with the mangled name. + * This should *NOT* rename the 'foo' name. + */ + + windows_rename_src = talloc_asprintf(cli_posix, + "%s\\%s", + dname, + mangled_name); + + status = cli_rename(cli, + windows_rename_src, + windows_rename_dst, + false); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_rename of %s -> %s returned %s\n", + windows_rename_src, + windows_rename_dst, + nt_errstr(status)); + goto out; + } + + /* Does 'foo' still exist ? */ + status = cli_posix_open(cli_posix, + fooname, + O_RDONLY, + 0, + &fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_posix_open O_RNONLY of %s returned %s\n", + fooname, + nt_errstr(status)); + goto out; + } + + status = cli_close(cli_posix, fnum); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + correct = true; + + out: + + TALLOC_FREE(mangled_name); + TALLOC_FREE(windows_rename_src); + + if (cli != NULL) { + cli_unlink(cli, + wild_name, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + torture_close_connection(cli); + } + + cli_posix_rmdir(cli_posix, dname); + torture_close_connection(cli_posix); + + return correct; +} + /* * Only testing minimal time strings, as the others * need (locale-dependent) guessing at what strftime does and @@ -14780,6 +14951,10 @@ static struct { .name = "SMB1-WILD-MANGLE-UNLINK", .fn = run_smb1_wild_mangle_unlink_test, }, + { + .name = "SMB1-WILD-MANGLE-RENAME", + .fn = run_smb1_wild_mangle_rename_test, + }, { .name = "CASE-INSENSITIVE-CREATE", .fn = run_case_insensitive_create, -- 2.47.3