r8185: Delete on close on directories:
authorVolker Lendecke <vlendec@samba.org>
Wed, 6 Jul 2005 14:56:45 +0000 (14:56 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:19:18 +0000 (13:19 -0500)
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
source4/torture/raw/search.c

index d4d196968a739f96e8621e6333e6e8a7252c54ee..e28561db37937afa5571a94d6b44e3bd042d7f10 100644 (file)
@@ -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:
index 05fa24c6a2ad05e0336b5487b8f70d86fdc69c76..c3cb76d552058811aece13ecefca16b0a7874063 100644 (file)
@@ -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;