diff options
Diffstat (limited to 'source4/torture')
-rw-r--r-- | source4/torture/raw/write.c | 103 |
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; } |