From f0df11ce9dd9bbbc8cee9122e06e2b3c1954b7e7 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 14 May 2020 14:22:16 +0200 Subject: [PATCH] s4/torture: add a *real* root_dir_fid test raw.samba3rootdirfid tests with the share root directory as root_dir_fid handle, that doesn't cover the case where the relative name has more then one path component. It only works because in unix_convert() we run into the creating file optimasation. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14380 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison --- .../knownfail.d/samba3.raw.samba3rootdirfid2 | 1 + source3/selftest/tests.py | 3 +- source4/torture/raw/raw.c | 2 + source4/torture/raw/samba3misc.c | 74 +++++++++++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 selftest/knownfail.d/samba3.raw.samba3rootdirfid2 diff --git a/selftest/knownfail.d/samba3.raw.samba3rootdirfid2 b/selftest/knownfail.d/samba3.raw.samba3rootdirfid2 new file mode 100644 index 00000000000..745c841e0e0 --- /dev/null +++ b/selftest/knownfail.d/samba3.raw.samba3rootdirfid2 @@ -0,0 +1 @@ +^samba3.raw.samba3rootdirfid2 diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index b5d7c367883..7309c05a7a5 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -553,7 +553,7 @@ raw = ["raw.acls", "raw.chkpath", "raw.close", "raw.composite", "raw.context", " "raw.sfileinfo.base", "raw.sfileinfo.bug", "raw.streams", "raw.unlink", "raw.write", "raw.samba3hide", "raw.samba3badpath", "raw.sfileinfo.rename", "raw.session", "raw.samba3caseinsensitive", "raw.samba3posixtimedlock", - "raw.samba3rootdirfid", "raw.sfileinfo.end-of-file", + "raw.samba3rootdirfid", "raw.samba3rootdirfid2", "raw.sfileinfo.end-of-file", "raw.bench-oplock", "raw.bench-lock", "raw.bench-open", "raw.bench-tcon", "raw.samba3checkfsp", "raw.samba3closeerr", "raw.samba3oplocklogoff", "raw.samba3badnameblob"] @@ -832,6 +832,7 @@ for t in tests: "raw.samba3oplocklogoff", "raw.samba3posixtimedlock", "raw.samba3rootdirfid", + "raw.samba3rootdirfid2", "raw.seek", "raw.sfileinfo.bug", "raw.sfileinfo.end-of-file", diff --git a/source4/torture/raw/raw.c b/source4/torture/raw/raw.c index a225efe0b5d..b3716b6d0af 100644 --- a/source4/torture/raw/raw.c +++ b/source4/torture/raw/raw.c @@ -67,6 +67,8 @@ NTSTATUS torture_raw_init(TALLOC_CTX *ctx) torture_suite_add_1smb_test(suite, "samba3closeerr", torture_samba3_closeerr); torture_suite_add_1smb_test(suite, "samba3rootdirfid", torture_samba3_rootdirfid); + torture_suite_add_1smb_test(suite, "samba3rootdirfid2", + torture_samba3_rootdirfid2); torture_suite_add_1smb_test(suite, "samba3checkfsp", torture_samba3_checkfsp); torture_suite_add_1smb_test(suite, "samba3oplocklogoff", torture_samba3_oplock_logoff); torture_suite_add_1smb_test(suite, "samba3badnameblob", torture_samba3_check_openX_badname); diff --git a/source4/torture/raw/samba3misc.c b/source4/torture/raw/samba3misc.c index 2f484023bea..dda1fdd9eeb 100644 --- a/source4/torture/raw/samba3misc.c +++ b/source4/torture/raw/samba3misc.c @@ -986,6 +986,80 @@ bool torture_samba3_rootdirfid(struct torture_context *tctx, struct smbcli_state return ret; } +bool torture_samba3_rootdirfid2(struct torture_context *tctx, struct smbcli_state *cli) +{ + int fnum; + uint16_t dnum; + union smb_open io; + const char *dirname1 = "dir1"; + const char *dirname2 = "dir1/dir2"; + const char *path = "dir1/dir2/testfile"; + const char *relname = "dir2/testfile"; + bool ret = false; + + smbcli_deltree(cli->tree, dirname1); + + torture_assert(tctx, torture_setup_dir(cli, dirname1), "creating test directory"); + torture_assert(tctx, torture_setup_dir(cli, dirname2), "creating test directory"); + + fnum = smbcli_open(cli->tree, path, O_RDWR | O_CREAT, DENY_NONE); + if (fnum == -1) { + torture_result(tctx, TORTURE_FAIL, + "Could not create file: %s", + smbcli_errstr(cli->tree)); + goto done; + } + smbcli_close(cli->tree, fnum); + + ZERO_STRUCT(io); + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; + io.ntcreatex.in.root_fid.fnum = 0; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.access_mask = + SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_DIRECTORY; + io.ntcreatex.in.share_access = + NTCREATEX_SHARE_ACCESS_READ + | NTCREATEX_SHARE_ACCESS_READ; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.fname = dirname1; + torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io), + NT_STATUS_OK, + ret, done, "smb_open on the directory failed: %s\n"); + + dnum = io.ntcreatex.out.file.fnum; + + io.ntcreatex.in.flags = + NTCREATEX_FLAGS_REQUEST_OPLOCK + | NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK; + io.ntcreatex.in.root_fid.fnum = dnum; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN; + io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; + io.ntcreatex.in.fname = relname; + + torture_assert_ntstatus_equal_goto(tctx, smb_raw_open(cli->tree, tctx, &io), + NT_STATUS_OK, + ret, done, "smb_open on the file failed"); + + smbcli_close(cli->tree, io.ntcreatex.out.file.fnum); + smbcli_close(cli->tree, dnum); + + ret = true; +done: + smbcli_deltree(cli->tree, dirname1); + return ret; +} + bool torture_samba3_oplock_logoff(struct torture_context *tctx, struct smbcli_state *cli) { union smb_open io;