summaryrefslogtreecommitdiff
path: root/source4/torture
diff options
context:
space:
mode:
Diffstat (limited to 'source4/torture')
-rw-r--r--source4/torture/raw/write.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/source4/torture/raw/write.c b/source4/torture/raw/write.c
index 77c73a42b4..7aff22129b 100644
--- a/source4/torture/raw/write.c
+++ b/source4/torture/raw/write.c
@@ -670,6 +670,105 @@ done:
return ret;
}
+/* Windows does obviously not update the stat info during a write call. I
+ * *think* this is the problem causing a spurious Excel 2003 on XP error
+ * message when saving a file. Excel does a setfileinfo, writes, and then does
+ * a getpath(!)info. Or so... For Samba sometimes it displays an error message
+ * that the file might have been changed in between. What i've been able to
+ * trace down is that this happens if the getpathinfo after the write shows a
+ * different last write time than the setfileinfo showed. This is really
+ * nasty....
+ */
+
+static BOOL test_finfo_after_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+{
+ union smb_open io1;
+ union smb_fileinfo finfo1, finfo2;
+ union smb_write io3;
+ const char *fname = BASEDIR "\\torture_file.txt";
+ NTSTATUS status;
+ int fnum = -1;
+ BOOL ret = True;
+
+ io1.generic.level = RAW_OPEN_NTCREATEX;
+ io1.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED;
+ io1.ntcreatex.in.root_fid = 0;
+ io1.ntcreatex.in.access_mask = GENERIC_RIGHTS_FILE_WRITE|GENERIC_RIGHTS_FILE_READ;
+ io1.ntcreatex.in.alloc_size = 1024*1024;
+ io1.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+ io1.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+ io1.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+ io1.ntcreatex.in.create_options = 0;
+ io1.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+ io1.ntcreatex.in.security_flags = 0;
+ io1.ntcreatex.in.fname = fname;
+
+ status = smb_raw_open(cli->tree, mem_ctx, &io1);
+
+ if (!NT_STATUS_IS_OK(status))
+ return False;
+
+ fnum = io1.ntcreatex.out.fnum;
+
+ finfo1.basic_info.level = RAW_FILEINFO_BASIC_INFO;
+ finfo1.basic_info.in.fnum = fnum;
+
+ status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo1);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
+ return False;
+ }
+
+ io3.generic.level = RAW_WRITE_WRITE;
+ io3.write.in.fnum = fnum;
+ io3.write.in.count = 1;
+ io3.write.in.offset = 0;
+ io3.write.in.remaining = 0;
+ io3.write.in.data = "x";
+
+ msleep(1000);
+
+ status = smb_raw_write(cli->tree, &io3);
+
+ if (!NT_STATUS_IS_OK(status))
+ return False;
+
+ finfo2.basic_info.level = RAW_FILEINFO_BASIC_INFO;
+ finfo2.basic_info.in.fname = fname;
+
+ status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo2);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("fileinfo failed: %s\n", nt_errstr(status)));
+ return False;
+ }
+
+ if (finfo1.basic_info.out.create_time !=
+ finfo2.basic_info.out.create_time) {
+ ret = False;
+ }
+
+ if (finfo1.basic_info.out.access_time !=
+ finfo2.basic_info.out.access_time) {
+ ret = False;
+ }
+
+ if (finfo1.basic_info.out.write_time !=
+ finfo2.basic_info.out.write_time) {
+ ret = False;
+ }
+
+ if (finfo1.basic_info.out.change_time !=
+ finfo2.basic_info.out.change_time) {
+ ret = False;
+ }
+
+ smbcli_close(cli->tree, fnum);
+ smbcli_unlink(cli->tree, fname);
+
+ return ret;
+}
/*
basic testing of write calls
@@ -686,6 +785,10 @@ BOOL torture_raw_write(int dummy)
mem_ctx = talloc_init("torture_raw_write");
+ if (!test_finfo_after_write(cli, mem_ctx)) {
+ ret = False;
+ }
+
if (!test_write(cli, mem_ctx)) {
ret = False;
}