From: Jeremy Allison Date: Mon, 5 Oct 2020 17:29:16 +0000 (-0700) Subject: s3: selftest: Add new SMB1-only wildcard unlink regression test. X-Git-Tag: talloc-2.3.2~296 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f3281e0befb43224010f2940230a5a2b54fea4c4;p=thirdparty%2Fsamba.git s3: selftest: Add new SMB1-only wildcard unlink regression test. samba3.smbtorture_s3.crypt_client.SMB1-WILD-MANGLE-UNLINK(nt4_dc_smb1) samba3.smbtorture_s3.plain.SMB1-WILD-MANGLE-UNLINK(fileserver_smb1) knownfail for now. The recent wildcard changes broke something that used to work. Consider a directory with 2 files: dir/ a * The '*' file has a mangled name of _2X68P~X. SMB1unlink("_2X68P~X") will delete *both* files as the new 'unlink has wildcard' check is done after the name unmangle. SMB2 doesn't suffer from this problem, as it doesn't allow wildcard unlinks. Fix to follow. Signed-off-by: Jeremy Allison Reviewed-by: Ralph Boehme --- diff --git a/selftest/knownfail.d/smb1-wild-mangle-unlink b/selftest/knownfail.d/smb1-wild-mangle-unlink new file mode 100644 index 00000000000..a8cdf25a070 --- /dev/null +++ b/selftest/knownfail.d/smb1-wild-mangle-unlink @@ -0,0 +1,3 @@ +# Check SMB1 wildcard demangle +^samba3.smbtorture_s3.plain.SMB1-WILD-MANGLE-UNLINK.smbtorture\(fileserver_smb1\) +^samba3.smbtorture_s3.crypt_client.SMB1-WILD-MANGLE-UNLINK.smbtorture\(nt4_dc_smb1\) diff --git a/selftest/skip b/selftest/skip index d13cf7cd18b..acf3765386e 100644 --- a/selftest/skip +++ b/selftest/skip @@ -61,6 +61,7 @@ ^samba3.smbtorture_s3.plain.BAD-NBT-SESSION\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server ^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.*base.charset ^samba3.*raw.context ^samba3.*raw.ioctl diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index c307e9c16e9..44c9fd844f4 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -107,7 +107,8 @@ fileserver_tests = [ "CLEANUP2", "CLEANUP4", "DELETE-STREAM", - "BAD-NBT-SESSION"] + "BAD-NBT-SESSION", + "SMB1-WILD-MANGLE-UNLINK"] for t in fileserver_tests: fileserver_env = "fileserver_smb1" diff --git a/source3/torture/torture.c b/source3/torture/torture.c index bdb38a10de1..6ac812b0244 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -12645,6 +12645,186 @@ static bool run_symlink_open_test(int dummy) return correct; } +static NTSTATUS smb1_wild_mangle_list_fn(const char *mnt, + struct file_info *finfo, + const char *name, + void *state) +{ + char **mangled_name_return = (char **)state; + bool is_mangled = strchr(finfo->name, '~'); + + if (is_mangled) { + *mangled_name_return = talloc_strdup(NULL, finfo->name); + if (*mangled_name_return == NULL) { + return NT_STATUS_NO_MEMORY; + } + } + return NT_STATUS_OK; +} + +static bool run_smb1_wild_mangle_unlink_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_unlink"; + const char *aname = "smb1_wild_mangle_unlink/a"; + const char *star_name = "smb1_wild_mangle_unlink/*"; + char *windows_unlink_name = NULL; + char *mangled_name = NULL; + NTSTATUS status; + + printf("Starting SMB1 wild mangle unlink test\n"); + + /* Open a Windows connection. */ + if (!torture_open_connection(&cli, 0)) { + return false; + } + + smbXcli_conn_set_sockopt(cli->conn, sockops); + + /* Open a POSIX connection. */ + if (!torture_open_connection(&cli_posix, 0)) { + goto out; + } + + 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"); + goto out; + } + + /* Start fresh. */ + cli_unlink(cli, + star_name, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + cli_rmdir(cli, dname); + + /* + * Create two files - 'a' and '*'. + * We need POSIX extensions for this as '*' + * is not a valid Windows name. + */ + + status = cli_mkdir(cli, dname); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_mkdir of %s returned %s\n", + dname, + nt_errstr(status)); + goto out; + } + + status = cli_posix_open(cli_posix, + aname, + O_RDWR|O_CREAT|O_EXCL, + 0660, + &fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_posix_open (create) of %s returned %s\n", + aname, + 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, + star_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", + star_name, + nt_errstr(status)); + goto out; + } + status = cli_close(cli_posix, fnum); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + status = cli_list(cli, + star_name, + 0, + smb1_wild_mangle_list_fn, + &mangled_name); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_list of %s returned %s\n", + star_name, + nt_errstr(status)); + goto out; + } + + if (mangled_name == NULL) { + goto out; + } + + printf("mangled_name = %s\n", + mangled_name); + + /* + * Try a Windows unlink with the mangled name. + * This should *NOT* unlink the 'a' name. + */ + + windows_unlink_name = talloc_asprintf(cli_posix, + "%s\\%s", + dname, + mangled_name); + + status = cli_unlink(cli, windows_unlink_name, 0); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_unlink of %s returned %s\n", + windows_unlink_name, + nt_errstr(status)); + goto out; + } + + /* Does 'a' still exist ? */ + status = cli_posix_open(cli_posix, + aname, + O_RDONLY, + 0, + &fnum); + if (!NT_STATUS_IS_OK(status)) { + printf("cli_posix_open O_RNONLY of %s returned %s\n", + aname, + nt_errstr(status)); + goto out; + } + + status = cli_close(cli_posix, fnum); + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + correct = true; + + out: + + TALLOC_FREE(windows_unlink_name); + TALLOC_FREE(mangled_name); + + if (cli != NULL) { + cli_unlink(cli, + star_name, + FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN); + cli_rmdir(cli, dname); + torture_close_connection(cli); + } + + if (cli_posix != NULL) { + torture_close_connection(cli_posix); + } + + return correct; +} + /* * Only testing minimal time strings, as the others * need (locale-dependent) guessing at what strftime does and @@ -14596,6 +14776,10 @@ static struct { .name = "WINDOWS-BAD-SYMLINK", .fn = run_symlink_open_test, }, + { + .name = "SMB1-WILD-MANGLE-UNLINK", + .fn = run_smb1_wild_mangle_unlink_test, + }, { .name = "CASE-INSENSITIVE-CREATE", .fn = run_case_insensitive_create,