s4 torture: Extend the RAW-RENAME test to more fully test directory renames.
authorTim Prouty <tprouty@samba.org>
Thu, 6 Aug 2009 18:23:23 +0000 (11:23 -0700)
committerTim Prouty <tprouty@samba.org>
Fri, 7 Aug 2009 00:07:49 +0000 (17:07 -0700)
The existing test was only covering files opened underneath the
directory that was being renamed.  It is not uncommon for windows
clients to actually hold a read-only handle to a directory open across
the rename, which it turns out doesn't return NT_STATUS_ACCESS_DENIED.
Additionally, holding a handle open to a stream on the directory is
also allowed.

source4/torture/raw/rename.c

index e91c3b2319adcb5439f0447390863bc1e538881f..15fed0e3d8f6b6ddbf50c753d196fb8940fbaff3 100644 (file)
@@ -529,6 +529,7 @@ static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *c
         const char *dname1 = BASEDIR "\\dir_for_rename";
         const char *dname2 = BASEDIR "\\renamed_dir";
         const char *fname = BASEDIR "\\dir_for_rename\\file.txt";
+       const char *sname = BASEDIR "\\dir_for_rename:a stream:$DATA";
        bool ret = true;
        int fnum = -1;
 
@@ -593,6 +594,55 @@ static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *c
        status = smb_raw_rename(cli->tree, &ren_io);
        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
 
+       /* Close the file and try the rename. */
+       smbcli_close(cli->tree, fnum);
+
+       status = smb_raw_rename(cli->tree, &ren_io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       /*
+        * Now try just holding a second handle on the directory and holding
+        * it open across a rename.  This should be allowed.
+        */
+       io.ntcreatex.in.fname = dname2;
+       io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
+
+       io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL |
+           SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA;
+
+       status = smb_raw_open(cli->tree, tctx, &io);
+        CHECK_STATUS(status, NT_STATUS_OK);
+        fnum = io.ntcreatex.out.file.fnum;
+
+       ren_io.generic.level = RAW_RENAME_RENAME;
+       ren_io.rename.in.pattern1 = dname2;
+       ren_io.rename.in.pattern2 = dname1;
+       ren_io.rename.in.attrib = 0;
+
+       status = smb_raw_rename(cli->tree, &ren_io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
+       /* close our handle to the directory. */
+       smbcli_close(cli->tree, fnum);
+
+       /*
+        * Now try opening a stream on the directory and holding it open
+        * across a rename.  This should be allowed.
+        */
+       io.ntcreatex.in.fname = sname;
+
+       status = smb_raw_open(cli->tree, tctx, &io);
+        CHECK_STATUS(status, NT_STATUS_OK);
+        fnum = io.ntcreatex.out.file.fnum;
+
+       ren_io.generic.level = RAW_RENAME_RENAME;
+       ren_io.rename.in.pattern1 = dname1;
+       ren_io.rename.in.pattern2 = dname2;
+       ren_io.rename.in.attrib = 0;
+
+       status = smb_raw_rename(cli->tree, &ren_io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+
 done:
        
        if (fnum != -1) {