source4/torture/raw: Fix prototypes for all functions.
[gd/samba-autobuild/.git] / source4 / torture / raw / rename.c
index e91c3b2319adcb5439f0447390863bc1e538881f..b9f2039ff2a3a45a9a79c1cc0992a2197b83c199 100644 (file)
 */
 
 #include "includes.h"
-#include "torture/torture.h"
-#include "libcli/raw/libcliraw.h"
 #include "libcli/libcli.h"
 #include "torture/util.h"
+#include "torture/raw/proto.h"
 
 #define CHECK_STATUS(status, correct) do { \
        if (!NT_STATUS_EQUAL(status, correct)) { \
@@ -67,7 +66,7 @@ static bool test_mv(struct torture_context *tctx,
        torture_comment(tctx, "Trying simple rename\n");
 
        op.generic.level = RAW_OPEN_NTCREATEX;
-       op.ntcreatex.in.root_fid = 0;
+       op.ntcreatex.in.root_fid.fnum = 0;
        op.ntcreatex.in.flags = 0;
        op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        op.ntcreatex.in.create_options = 0;
@@ -208,7 +207,7 @@ static bool test_osxrename(struct torture_context *tctx,
                return false;
        }
        op.generic.level = RAW_OPEN_NTCREATEX;
-       op.ntcreatex.in.root_fid = 0;
+       op.ntcreatex.in.root_fid.fnum = 0;
        op.ntcreatex.in.flags = 0;
        op.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
        op.ntcreatex.in.create_options = 0;
@@ -307,7 +306,7 @@ static bool test_ntrename(struct torture_context *tctx,
        status = smb_raw_rename(cli->tree, &io);
        CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
        
-       smb_raw_exit(cli->session);
+       smbcli_close(cli->tree, fnum);
        status = smb_raw_rename(cli->tree, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
 
@@ -428,15 +427,27 @@ static bool test_ntrename(struct torture_context *tctx,
        io.ntrename.in.attrib = 0;
        io.ntrename.in.flags = 0;
        status = smb_raw_rename(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
+       if (TARGET_IS_WIN7(tctx)) {
+               CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+       } else {
+               CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
+       }
 
        io.ntrename.in.flags = 300;
        status = smb_raw_rename(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
+       if (TARGET_IS_WIN7(tctx)) {
+               CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+       } else {
+               CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
+       }
 
        io.ntrename.in.flags = 0x106;
        status = smb_raw_rename(cli->tree, &io);
-       CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
+       if (TARGET_IS_WIN7(tctx)) {
+               CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+       } else {
+               CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
+       }
 
        torture_comment(tctx, "Checking unknown field\n");
        io.ntrename.in.old_name = fname1;
@@ -507,8 +518,18 @@ static bool test_ntrename(struct torture_context *tctx,
                io.ntrename.in.attrib = 0;
                io.ntrename.in.cluster_size = 0;
                status = smb_raw_rename(cli->tree, &io);
-               if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
-                       torture_warning(tctx, "flags=0x%x status=%s\n", i, nt_errstr(status));
+               if (TARGET_IS_WIN7(tctx)){
+                       if (!NT_STATUS_EQUAL(status,
+                                            NT_STATUS_INVALID_PARAMETER)) {
+                               torture_warning(tctx, "flags=0x%x status=%s\n",
+                                               i, nt_errstr(status));
+                       }
+               } else {
+                       if (!NT_STATUS_EQUAL(status,
+                                            NT_STATUS_ACCESS_DENIED)) {
+                               torture_warning(tctx, "flags=0x%x status=%s\n",
+                                               i, nt_errstr(status));
+                       }
                }
        }
        
@@ -528,7 +549,9 @@ static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *c
        NTSTATUS status;
         const char *dname1 = BASEDIR "\\dir_for_rename";
         const char *dname2 = BASEDIR "\\renamed_dir";
+        const char *dname1_long = BASEDIR "\\dir_for_rename_long";
         const char *fname = BASEDIR "\\dir_for_rename\\file.txt";
+       const char *sname = BASEDIR "\\renamed_dir:a stream:$DATA";
        bool ret = true;
        int fnum = -1;
 
@@ -541,8 +564,10 @@ static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *c
         /* create a directory */
         smbcli_rmdir(cli->tree, dname1);
         smbcli_rmdir(cli->tree, dname2);
+        smbcli_rmdir(cli->tree, dname1_long);
         smbcli_unlink(cli->tree, dname1);
         smbcli_unlink(cli->tree, dname2);
+        smbcli_unlink(cli->tree, dname1_long);
 
         ZERO_STRUCT(io);
         io.generic.level = RAW_OPEN_NTCREATEX;
@@ -560,12 +585,20 @@ static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *c
         fnum = io.ntcreatex.out.file.fnum;
        smbcli_close(cli->tree, fnum);
 
+        /* create the longname directory */
+        io.ntcreatex.in.fname = dname1_long;
+        status = smb_raw_open(cli->tree, tctx, &io);
+        CHECK_STATUS(status, NT_STATUS_OK);
+
+        fnum = io.ntcreatex.out.file.fnum;
+       smbcli_close(cli->tree, fnum);
+
         /* Now create and hold open a file. */
         ZERO_STRUCT(io);
 
         io.generic.level = RAW_OPEN_NTCREATEX;
         io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
-        io.ntcreatex.in.root_fid = 0;
+        io.ntcreatex.in.root_fid.fnum = 0;
         io.ntcreatex.in.alloc_size = 0;
         io.ntcreatex.in.access_mask = SEC_RIGHTS_FILE_ALL;
         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
@@ -593,8 +626,82 @@ 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);
+
+       /* Open a handle on the long name, and then
+        * try a rename. This would catch a regression
+        * in bug #6781.
+        */
+       io.ntcreatex.in.fname = dname1_long;
+       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 = 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);
+
+       /* close our handle to the longname 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 = 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);
+
 done:
-       
+
        if (fnum != -1) {
                smbcli_close(cli->tree, fnum);
        }
@@ -611,7 +718,7 @@ extern bool test_nttransrename(struct torture_context *tctx, struct smbcli_state
 */
 struct torture_suite *torture_raw_rename(TALLOC_CTX *mem_ctx)
 {
-       struct torture_suite *suite = torture_suite_create(mem_ctx, "RENAME");
+       struct torture_suite *suite = torture_suite_create(mem_ctx, "rename");
 
        torture_suite_add_1smb_test(suite, "mv", test_mv);
        /* test_trans2rename and test_nttransrename are actually in torture/raw/oplock.c to