From d698cec1c7e700e57cab46d33df0dde13303b318 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 27 Nov 2015 18:29:55 +0100 Subject: [PATCH] s3:smbd: convert file_struct.posix_open to a bitmap with flags This is in preperation of a more fine grained control of POSIX behaviour in the SMB and VFS layers. Inititally we use an uint8_t for the flags bitmap and add a define posix_flags as posix_open in order to avoid breaking the VFS ABI. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11065 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison --- source3/include/vfs.h | 10 +++++++++- source3/locking/locking.c | 3 ++- source3/modules/vfs_acl_common.c | 4 ++-- source3/param/loadparm.c | 3 ++- source3/smbd/close.c | 6 ++++-- source3/smbd/fileio.c | 8 ++++---- source3/smbd/open.c | 10 ++++++---- source3/smbd/reply.c | 2 +- source3/smbd/smb2_close.c | 2 +- source3/smbd/vfs.c | 4 ++-- 10 files changed, 33 insertions(+), 19 deletions(-) diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 99453759242..56a90493c2f 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -218,6 +218,9 @@ struct fsp_lease { struct smb2_lease lease; }; +/* VFS ABI stability hack */ +#define posix_flags posix_open + typedef struct files_struct { struct files_struct *next, *prev; uint64_t fnum; @@ -255,7 +258,7 @@ typedef struct files_struct { bool aio_write_behind; bool initial_delete_on_close; /* Only set at NTCreateX if file was created. */ bool delete_on_close; - bool posix_open; + uint8_t posix_flags; bool is_sparse; bool backup_intent; /* Handle was successfully opened with backup intent and opener has privilege to do so. */ @@ -297,6 +300,11 @@ typedef struct files_struct { struct tevent_req *deferred_close; } files_struct; +#define FSP_POSIX_FLAGS_OPEN 0x01 + +#define FSP_POSIX_FLAGS_ALL \ + (FSP_POSIX_FLAGS_OPEN) + struct vuid_cache_entry { struct auth_session_info *session_info; uint64_t vuid; /* SMB2 compat */ diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 7b8bc8425fa..5a9746094ba 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -847,7 +847,8 @@ bool set_share_mode(struct share_mode_lock *lck, struct files_struct *fsp, e->id = fsp->file_id; e->share_file_id = fsp->fh->gen_id; e->uid = (uint32_t)uid; - e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0; + e->flags = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ? + SHARE_MODE_FLAG_POSIX_OPEN : 0; e->name_hash = fsp->name_hash; return true; diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c index 625e7cb672e..f73e80c5ada 100644 --- a/source3/modules/vfs_acl_common.c +++ b/source3/modules/vfs_acl_common.c @@ -1089,7 +1089,7 @@ static int chmod_acl_module_common(struct vfs_handle_struct *handle, static int fchmod_acl_module_common(struct vfs_handle_struct *handle, struct files_struct *fsp, mode_t mode) { - if (fsp->posix_open) { + if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { /* Only allow this on POSIX opens. */ return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode); } @@ -1109,7 +1109,7 @@ static int chmod_acl_acl_module_common(struct vfs_handle_struct *handle, static int fchmod_acl_acl_module_common(struct vfs_handle_struct *handle, struct files_struct *fsp, mode_t mode) { - if (fsp->posix_open) { + if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { /* Only allow this on POSIX opens. */ return SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode); } diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index e32cf73c72e..348298d4aba 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4311,7 +4311,8 @@ enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp) if (posix_default_lock_was_set) { return posix_cifsx_locktype; } else { - return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK; + return (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ? + POSIX_LOCK : WINDOWS_LOCK; } } diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 0e75bf05c91..1cb546055d0 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -327,7 +327,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, if (e->name_hash != fsp->name_hash) { continue; } - if (fsp->posix_open + if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) { continue; } @@ -1103,7 +1103,9 @@ static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp, struct share_mode_entry *e = &lck->data->share_modes[i]; if (is_valid_share_mode_entry(e) && e->name_hash == fsp->name_hash) { - if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) { + if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) && + (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) + { continue; } if (serverid_equal(&self, &e->pid) && diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c index 2fe04324ee1..156c139effa 100644 --- a/source3/smbd/fileio.c +++ b/source3/smbd/fileio.c @@ -193,7 +193,7 @@ void trigger_write_time_update(struct files_struct *fsp) { int delay; - if (fsp->posix_open) { + if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { /* Don't use delayed writes on POSIX files. */ return; } @@ -238,7 +238,7 @@ void trigger_write_time_update_immediate(struct files_struct *fsp) { struct smb_file_time ft; - if (fsp->posix_open) { + if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { /* Don't use delayed writes on POSIX files. */ return; } @@ -284,7 +284,7 @@ void mark_file_modified(files_struct *fsp) } trigger_write_time_update(fsp); - if (fsp->posix_open) { + if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { return; } if (!(lp_store_dos_attributes(SNUM(fsp->conn)) || @@ -1047,7 +1047,7 @@ NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, bool write_throug int fsp_stat(files_struct *fsp) { if (fsp->fh->fd == -1) { - if (fsp->posix_open) { + if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { return SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name); } else { return SMB_VFS_STAT(fsp->conn, fsp->fsp_name); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index c34742e1330..9cd415b57b7 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -362,7 +362,7 @@ NTSTATUS fd_open(struct connection_struct *conn, * client should be doing this. */ - if (fsp->posix_open || !lp_follow_symlinks(SNUM(conn))) { + if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) { flags |= O_NOFOLLOW; } #endif @@ -945,7 +945,7 @@ static NTSTATUS open_file(files_struct *fsp, access_mask); if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) && - fsp->posix_open && + (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) && S_ISLNK(smb_fname->st.st_ex_mode)) { /* This is a POSIX stat open for delete * or rename on a symlink that points @@ -2703,7 +2703,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, fsp->access_mask = open_access_mask; /* We change this to the * requested access_mask after * the open is done. */ - fsp->posix_open = posix_open; + fsp->posix_flags |= posix_open ? FSP_POSIX_FLAGS_OPEN : 0; if (timeval_is_zero(&request_time)) { request_time = fsp->open_time; @@ -3569,7 +3569,9 @@ static NTSTATUS open_directory(connection_struct *conn, fsp->oplock_type = NO_OPLOCK; fsp->sent_oplock_break = NO_BREAK_SENT; fsp->is_directory = True; - fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False; + if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) { + fsp->posix_flags |= FSP_POSIX_FLAGS_ALL; + } status = fsp_set_smb_fname(fsp, smb_dname); if (!NT_STATUS_IS_OK(status)) { file_free(req, fsp); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 572ca92a290..2e5e521d1be 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2669,7 +2669,7 @@ static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp, } if (S_ISDIR(fsp->fsp_name->st.st_ex_mode)) { - if (fsp->posix_open) { + if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { return NT_STATUS_OK; } diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c index ed53e1be0a7..367c9fa125e 100644 --- a/source3/smbd/smb2_close.c +++ b/source3/smbd/smb2_close.c @@ -231,7 +231,7 @@ static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req, return NT_STATUS_NO_MEMORY; } - posix_open = fsp->posix_open; + posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN); smb_fname = cp_smb_filename(talloc_tos(), fsp->fsp_name); if (smb_fname == NULL) { return NT_STATUS_NO_MEMORY; diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 9f3ba6dd905..0c272a7967b 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -1309,7 +1309,7 @@ NTSTATUS vfs_stat_fsp(files_struct *fsp) int ret; if(fsp->fh->fd == -1) { - if (fsp->posix_open) { + if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name); } else { ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name); @@ -1939,7 +1939,7 @@ NTSTATUS vfs_chown_fsp(files_struct *fsp, uid_t uid, gid_t gid) path = fsp->fsp_name->base_name; } - if (fsp->posix_open || as_root) { + if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || as_root) { ret = SMB_VFS_LCHOWN(fsp->conn, path, uid, gid); -- 2.34.1