From 824f5b47818fd4cc7fe0084bf454bb31930c4f38 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 6 Jul 2005 14:56:45 +0000 Subject: r8185: Delete on close on directories: Creating a file in a directory with delete-on-close set returns DELETE_PENDING, and trying to set the flag on a non-empty directory returns DIRECTORY_NOT_EMPTY. Volker (This used to be commit 5680f34778b2f5291936f4d4fb937a7713696c52) --- source4/torture/basic/delete.c | 137 +++++++++++++++++++++++++++++++++++++++++ source4/torture/raw/search.c | 9 +-- 2 files changed, 142 insertions(+), 4 deletions(-) (limited to 'source4/torture') diff --git a/source4/torture/basic/delete.c b/source4/torture/basic/delete.c index d4d196968a..e28561db37 100644 --- a/source4/torture/basic/delete.c +++ b/source4/torture/basic/delete.c @@ -39,6 +39,7 @@ static BOOL check_delete_on_close(struct smbcli_state *cli, int fnum, status = torture_single_search(cli, mem_ctx, fname, RAW_SEARCH_FULL_DIRECTORY_INFO, + FILE_ATTRIBUTE_DIRECTORY, &data); if (!NT_STATUS_IS_OK(status)) { printf("(%s) single_search failed (%s)\n", @@ -138,8 +139,10 @@ BOOL torture_test_delete(void) struct smbcli_state *cli1; struct smbcli_state *cli2 = NULL; const char *fname = "\\delete.file"; + const char *dirname = "\\delete.dir"; int fnum1 = -1; int fnum2 = -1; + int dnum1 = -1; BOOL correct = True; NTSTATUS status; @@ -149,6 +152,8 @@ BOOL torture_test_delete(void) return False; } + smbcli_deltree(cli1->tree, dirname); + /* Test 1 - this should delete the file on close. */ smbcli_setatr(cli1->tree, fname, 0, 0); @@ -793,9 +798,141 @@ BOOL torture_test_delete(void) } smbcli_close(cli1->tree, fnum1); + smbcli_unlink(cli1->tree, fname); printf("thirteenth delete on close test succeeded.\n"); + /* Test 14 -- directory */ + + dnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0, + SEC_FILE_READ_DATA| + SEC_FILE_WRITE_DATA| + SEC_STD_DELETE, + FILE_ATTRIBUTE_DIRECTORY, + NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE| + NTCREATEX_SHARE_ACCESS_DELETE, + NTCREATEX_DISP_CREATE, 0, 0); + if (dnum1 == -1) { + printf("(%s) open of %s failed: %s!\n", + __location__, dirname, smbcli_errstr(cli1->tree)); + correct = False; + goto fail; + } + + check_delete_on_close(cli1, dnum1, dirname, False); + if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, dnum1, True))) { + printf("(%s) setting delete_on_close on file failed !\n", + __location__); + correct = False; + goto fail; + } + check_delete_on_close(cli1, dnum1, dirname, True); + smbcli_close(cli1->tree, dnum1); + + /* Now it should be gone... */ + + dnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0, + SEC_FILE_READ_DATA| + SEC_FILE_WRITE_DATA| + SEC_STD_DELETE, + FILE_ATTRIBUTE_DIRECTORY, + NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE| + NTCREATEX_SHARE_ACCESS_DELETE, + NTCREATEX_DISP_OPEN, 0, 0); + if (dnum1 != -1) { + printf("(%s) setting delete_on_close on file succeeded !\n", + __location__); + correct = False; + goto fail; + } + + printf("fourteenth delete on close test succeeded.\n"); + + /* Test 15 -- non-empty directory */ + + dnum1 = smbcli_nt_create_full(cli1->tree, dirname, 0, + SEC_FILE_READ_DATA| + SEC_FILE_WRITE_DATA| + SEC_STD_DELETE, + FILE_ATTRIBUTE_DIRECTORY, + NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE| + NTCREATEX_SHARE_ACCESS_DELETE, + NTCREATEX_DISP_CREATE, + NTCREATEX_OPTIONS_DIRECTORY, 0); + if (dnum1 == -1) { + printf("(%s) open of %s failed: %s!\n", + __location__, dirname, smbcli_errstr(cli1->tree)); + correct = False; + goto fail; + } + + check_delete_on_close(cli1, dnum1, dirname, False); + status = smbcli_nt_delete_on_close(cli1->tree, dnum1, True); + + { + char *fullname; + asprintf(&fullname, "\\%s%s", dirname, fname); + fnum1 = smbcli_open(cli1->tree, fullname, O_CREAT|O_RDWR, + DENY_NONE); + if (fnum1 != -1) { + printf("(%s) smbcli_open succeeded, should have " + "failed: %s\n", + __location__, smbcli_errstr(cli1->tree)); + correct = False; + goto fail; + } + + if (!NT_STATUS_EQUAL(smbcli_nt_error(cli1->tree), + NT_STATUS_DELETE_PENDING)) { + printf("(%s) smbcli_open returned %s, expected " + "NT_STATUS_DELETE_PENDING\n", + __location__, smbcli_errstr(cli1->tree)); + correct = False; + goto fail; + } + } + + status = smbcli_nt_delete_on_close(cli1->tree, dnum1, False); + if (!NT_STATUS_IS_OK(status)) { + printf("(%s) setting delete_on_close on file failed !\n", + __location__); + correct = False; + goto fail; + } + + { + char *fullname; + asprintf(&fullname, "\\%s%s", dirname, fname); + fnum1 = smbcli_open(cli1->tree, fullname, O_CREAT|O_RDWR, + DENY_NONE); + if (fnum1 == -1) { + printf("(%s) smbcli_open failed: %s\n", + __location__, smbcli_errstr(cli1->tree)); + correct = False; + goto fail; + } + smbcli_close(cli1->tree, fnum1); + } + + status = smbcli_nt_delete_on_close(cli1->tree, dnum1, True); + + if (!NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) { + printf("(%s) setting delete_on_close returned %s, expected " + "NT_STATUS_DIRECTORY_NOT_EMPTY\n", __location__, + smbcli_errstr(cli1->tree)); + correct = False; + goto fail; + } + + smbcli_close(cli1->tree, dnum1); + + /* Now it should be gone... */ + + printf("fifteenth delete on close test succeeded.\n"); + printf("finished delete test\n"); fail: diff --git a/source4/torture/raw/search.c b/source4/torture/raw/search.c index 05fa24c6a2..c3cb76d552 100644 --- a/source4/torture/raw/search.c +++ b/source4/torture/raw/search.c @@ -44,6 +44,7 @@ NTSTATUS torture_single_search(struct smbcli_state *cli, TALLOC_CTX *mem_ctx, const char *pattern, enum smb_search_level level, + uint16_t attrib, union smb_search_data *data) { union smb_search_first io; @@ -55,10 +56,10 @@ NTSTATUS torture_single_search(struct smbcli_state *cli, level == RAW_SEARCH_FFIRST || level == RAW_SEARCH_FUNIQUE) { io.search_first.in.max_count = 1; - io.search_first.in.search_attrib = 0; + io.search_first.in.search_attrib = attrib; io.search_first.in.pattern = pattern; } else { - io.t2ffirst.in.search_attrib = 0; + io.t2ffirst.in.search_attrib = attrib; io.t2ffirst.in.max_count = 1; io.t2ffirst.in.flags = FLAG_TRANS2_FIND_CLOSE; io.t2ffirst.in.storage_type = 0; @@ -145,7 +146,7 @@ static BOOL test_one_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) printf("testing %s\n", levels[i].name); levels[i].status = torture_single_search(cli, mem_ctx, fname, - levels[i].level, + levels[i].level, 0, &levels[i].data); /* see if this server claims to support this level */ @@ -164,7 +165,7 @@ static BOOL test_one_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) } status = torture_single_search(cli, mem_ctx, fname2, - levels[i].level, + levels[i].level, 0, &levels[i].data); expected_status = NT_STATUS_NO_SUCH_FILE; -- cgit