From d428255bcb0c40ad35388817bfb6cd2434ab703b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 28 Dec 2010 18:11:33 -0800 Subject: [PATCH] Fix bug #7892 - open_file_fchmod() leaves a stale lock. --- source3/include/proto.h | 3 +-- source3/smbd/dosmode.c | 11 ++++------- source3/smbd/open.c | 40 ++++------------------------------------ source3/smbd/posix_acls.c | 4 ++-- 4 files changed, 11 insertions(+), 47 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index f87d91a..7c2893b 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6637,10 +6637,9 @@ bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func uint32 *pshare_mode, uint32 *pcreate_disposition, uint32 *pcreate_options); -NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn, +NTSTATUS open_file_fchmod(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf, files_struct **result); -NTSTATUS close_file_fchmod(struct smb_request *req, files_struct *fsp); NTSTATUS create_directory(connection_struct *conn, struct smb_request *req, const char *directory); void msg_file_was_renamed(struct messaging_context *msg, void *private_data, diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 7b47fe6..2092712 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -301,7 +301,7 @@ static bool set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_ * are not violating security in doing the setxattr. */ - if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, path, sbuf, + if (!NT_STATUS_IS_OK(open_file_fchmod(conn, path, sbuf, &fsp))) return ret; become_root(); @@ -309,7 +309,7 @@ static bool set_ea_dos_attribute(connection_struct *conn, const char *path, SMB_ ret = True; } unbecome_root(); - close_file_fchmod(NULL, fsp); + close_file(NULL, fsp, NORMAL_CLOSE); return ret; } DEBUG(10,("set_ea_dos_attribute: set EA %s on file %s\n", attrstr, path)); @@ -705,18 +705,15 @@ int file_set_dosmode(connection_struct *conn, const char *fname, * We need to open the file with write access whilst * still in our current user context. This ensures we * are not violating security in doing the fchmod. - * This file open does *not* break any oplocks we are - * holding. We need to review this.... may need to - * break batch oplocks open by others. JRA. */ files_struct *fsp; - if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, fname, st, + if (!NT_STATUS_IS_OK(open_file_fchmod(conn, fname, st, &fsp))) return -1; become_root(); ret = SMB_VFS_FCHMOD(fsp, unixmode); unbecome_root(); - close_file_fchmod(NULL, fsp); + close_file(NULL, fsp, NORMAL_CLOSE); if (!newfile) { notify_fname(conn, NOTIFY_ACTION_MODIFIED, FILE_NOTIFY_CHANGE_ATTRIBUTES, fname); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index ab3bf1e..1722895 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -2207,23 +2207,15 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, Open a file for for write to ensure that we can fchmod it. ****************************************************************************/ -NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn, +NTSTATUS open_file_fchmod(connection_struct *conn, const char *fname, SMB_STRUCT_STAT *psbuf, files_struct **result) { - files_struct *fsp = NULL; - NTSTATUS status; - if (!VALID_STAT(*psbuf)) { return NT_STATUS_INVALID_PARAMETER; } - status = file_new(req, conn, &fsp); - if(!NT_STATUS_IS_OK(status)) { - return status; - } - - status = SMB_VFS_CREATE_FILE( + return SMB_VFS_CREATE_FILE( conn, /* conn */ NULL, /* req */ 0, /* root_dir_fid */ @@ -2235,37 +2227,13 @@ NTSTATUS open_file_fchmod(struct smb_request *req, connection_struct *conn, FILE_OPEN, /* create_disposition*/ 0, /* create_options */ 0, /* file_attributes */ - 0, /* oplock_request */ + INTERNAL_OPEN_ONLY, /* oplock_request */ 0, /* allocation_size */ NULL, /* sd */ NULL, /* ea_list */ - &fsp, /* result */ + result, /* result */ NULL, /* pinfo */ psbuf); /* psbuf */ - - /* - * This is not a user visible file open. - * Don't set a share mode. - */ - - if (!NT_STATUS_IS_OK(status)) { - file_free(req, fsp); - return status; - } - - *result = fsp; - return NT_STATUS_OK; -} - -/**************************************************************************** - Close the fchmod file fd - ensure no locks are lost. -****************************************************************************/ - -NTSTATUS close_file_fchmod(struct smb_request *req, files_struct *fsp) -{ - NTSTATUS status = fd_close(fsp); - file_free(req, fsp); - return status; } static NTSTATUS mkdir_internal(connection_struct *conn, diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 43edf21..6474977 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3472,7 +3472,7 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) return -1; } - if (!NT_STATUS_IS_OK(open_file_fchmod(NULL, conn, fname, &st, &fsp))) { + if (!NT_STATUS_IS_OK(open_file_fchmod(conn, fname, &st, &fsp))) { return -1; } @@ -3481,7 +3481,7 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) ret = SMB_VFS_FCHOWN(fsp, uid, (gid_t)-1); unbecome_root(); - close_file_fchmod(NULL, fsp); + close_file(NULL, fsp, NORMAL_CLOSE); return ret; } -- 1.7.0.4