summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2009-02-25 14:55:19 -0800
committerKarolin Seeger <kseeger@samba.org>2009-03-27 13:06:51 +0100
commit55af8687bcdddfb7295268f3c988a0b05ad8bf68 (patch)
treea4d475f75e3ae078904cf852b29f6122d106d649
parentaaf6251e21b2c01ee1fb19bde52f4a2d88d9ad65 (diff)
downloadsamba-55af8687bcdddfb7295268f3c988a0b05ad8bf68.tar.gz
samba-55af8687bcdddfb7295268f3c988a0b05ad8bf68.tar.xz
samba-55af8687bcdddfb7295268f3c988a0b05ad8bf68.zip
Fix more POSIX path lstat calls. Fix bug where close can return
failure if we have a pending modtime and the containing directory of the file has been renamed (there is no POSIX "update time by fd" call). This can't happen on Windows as the rename will fail if there are open files beneath it. Will add a torture test for this. Jeremy. (cherry picked from commit 5fb3b5e903c08013074ba473399ddee30f6c328f)
-rw-r--r--source/smbd/close.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/source/smbd/close.c b/source/smbd/close.c
index 9fd5693068a..81d25efa51e 100644
--- a/source/smbd/close.c
+++ b/source/smbd/close.c
@@ -467,6 +467,7 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
SMB_STRUCT_STAT sbuf;
struct timespec ts[2];
NTSTATUS status;
+ int ret = -1;
ZERO_STRUCT(sbuf);
ZERO_STRUCT(ts);
@@ -481,15 +482,19 @@ static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
/* Ensure we have a valid stat struct for the source. */
if (fsp->fh->fd != -1) {
- if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
- return map_nt_error_from_unix(errno);
- }
+ ret = SMB_VFS_FSTAT(fsp, &sbuf);
} else {
- if (SMB_VFS_STAT(fsp->conn,fsp->fsp_name,&sbuf) == -1) {
- return map_nt_error_from_unix(errno);
+ if (fsp->posix_open) {
+ ret = SMB_VFS_LSTAT(fsp->conn,fsp->fsp_name,&sbuf);
+ } else {
+ ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name,&sbuf);
}
}
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+
if (!VALID_STAT(sbuf)) {
/* if it doesn't seem to be a real file */
return NT_STATUS_OK;
@@ -575,6 +580,13 @@ static NTSTATUS close_normal_file(files_struct *fsp, enum file_close_type close_
*/
saved_status4 = update_write_time_on_close(fsp);
+ if (NT_STATUS_EQUAL(saved_status4, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+ /* Someone renamed the file or a parent directory containing
+ * this file. We can't do anything about this, we don't have
+ * an "update timestamp by fd" call in POSIX. Eat the error. */
+
+ saved_status4 = NT_STATUS_OK;
+ }
if (NT_STATUS_IS_OK(status)) {
if (!NT_STATUS_IS_OK(saved_status1)) {