From 03fe0d631dcda88d0268941b6406240bdc91bc0e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 20 Sep 2024 21:49:23 +0200 Subject: [PATCH] smbd: Simplify unix_perms_from_wire() Remove enum perm_type: Only the _NEW_ defines were actually used, and this made the logic harder for me to understand than necessary. On the other hand, it forced you to think about what this is. Now you could theoretically miss applying masks. Still, I like it better with this patch. Signed-off-by: Volker Lendecke Reviewed-by: Ralph Boehme --- source3/smbd/open.c | 14 ++++++++----- source3/smbd/proto.h | 8 ------- source3/smbd/smb1_trans2.c | 43 ++++++++++++++++++++------------------ source3/smbd/smb2_trans2.c | 15 ------------- 4 files changed, 32 insertions(+), 48 deletions(-) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 6b6c8b8abdc..4f69a7749d8 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -7031,9 +7031,6 @@ NTSTATUS create_file_default(connection_struct *conn, uint32_t wire_mode_bits = 0; mode_t mode_bits = 0; SMB_STRUCT_STAT sbuf = { 0 }; - enum perm_type ptype = - (create_options & FILE_DIRECTORY_FILE) ? - PERM_NEW_DIR : PERM_NEW_FILE; if (posx->data.length != 4) { status = NT_STATUS_INVALID_PARAMETER; @@ -7041,11 +7038,18 @@ NTSTATUS create_file_default(connection_struct *conn, } wire_mode_bits = IVAL(posx->data.data, 0); - status = unix_perms_from_wire( - conn, &sbuf, wire_mode_bits, ptype, &mode_bits); + status = unix_perms_from_wire(conn, + &sbuf, + wire_mode_bits, + &mode_bits); if (!NT_STATUS_IS_OK(status)) { goto fail; } + if (create_options & FILE_DIRECTORY_FILE) { + mode_bits = apply_conf_dir_mask(conn, mode_bits); + } else { + mode_bits = apply_conf_file_mask(conn, mode_bits); + } /* * Remove type info from mode, leaving only the * permissions and setuid/gid bits. diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 9265962a2d2..0661afea1c2 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -1088,17 +1088,9 @@ bool map_info2_flags_to_sbuf(const SMB_STRUCT_STAT *psbuf, const uint32_t smb_fmask, int *stat_fflags); -enum perm_type { - PERM_NEW_FILE, - PERM_NEW_DIR, - PERM_EXISTING_FILE, - PERM_EXISTING_DIR -}; - NTSTATUS unix_perms_from_wire(connection_struct *conn, const SMB_STRUCT_STAT *psbuf, uint32_t perms, - enum perm_type ptype, mode_t *ret_perms); struct ea_list *read_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size); diff --git a/source3/smbd/smb1_trans2.c b/source3/smbd/smb1_trans2.c index e41be9f4d71..666a8ebb2a6 100644 --- a/source3/smbd/smb1_trans2.c +++ b/source3/smbd/smb1_trans2.c @@ -3170,11 +3170,14 @@ static NTSTATUS smb_posix_mkdir(connection_struct *conn, raw_unixmode = IVAL(pdata,8); /* Next 4 bytes are not yet defined. */ - status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode, - PERM_NEW_DIR, &unixmode); + status = unix_perms_from_wire(conn, + &smb_fname->st, + raw_unixmode, + &unixmode); if (!NT_STATUS_IS_OK(status)) { return status; } + unixmode = apply_conf_dir_mask(conn, unixmode); status = make_smb2_posix_create_ctx(talloc_tos(), &posx, unixmode); if (!NT_STATUS_IS_OK(status)) { @@ -3389,14 +3392,17 @@ static NTSTATUS smb_posix_open(connection_struct *conn, raw_unixmode = IVAL(pdata,8); /* Next 4 bytes are not yet defined. */ - status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode, - (VALID_STAT(smb_fname->st) ? - PERM_EXISTING_FILE : PERM_NEW_FILE), + status = unix_perms_from_wire(conn, + &smb_fname->st, + raw_unixmode, &unixmode); if (!NT_STATUS_IS_OK(status)) { return status; } + if (!VALID_STAT(smb_fname->st)) { + unixmode = apply_conf_dir_mask(conn, unixmode); + } status = make_smb2_posix_create_ctx(talloc_tos(), &posx, unixmode); if (!NT_STATUS_IS_OK(status)) { @@ -3843,11 +3849,14 @@ static NTSTATUS smb_unix_mknod(connection_struct *conn, return NT_STATUS_INVALID_PARAMETER; } - status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode, - PERM_NEW_FILE, &unixmode); + status = unix_perms_from_wire(conn, + &smb_fname->st, + raw_unixmode, + &unixmode); if (!NT_STATUS_IS_OK(status)) { return status; } + unixmode = apply_conf_file_mask(conn, unixmode); #if defined(HAVE_MAKEDEV) dev = makedev(dev_major, dev_minor); @@ -3951,7 +3960,6 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn, uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE; gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE; NTSTATUS status = NT_STATUS_OK; - enum perm_type ptype; files_struct *all_fsps = NULL; bool modify_mtime = true; struct file_id id; @@ -3979,21 +3987,16 @@ static NTSTATUS smb_set_file_unix_basic(connection_struct *conn, set_grp = (gid_t)IVAL(pdata,48); raw_unixmode = IVAL(pdata,84); - if (VALID_STAT(smb_fname->st)) { - if (S_ISDIR(smb_fname->st.st_ex_mode)) { - ptype = PERM_EXISTING_DIR; - } else { - ptype = PERM_EXISTING_FILE; - } - } else { - ptype = PERM_NEW_FILE; - } - - status = unix_perms_from_wire(conn, &smb_fname->st, raw_unixmode, - ptype, &unixmode); + status = unix_perms_from_wire(conn, + &smb_fname->st, + raw_unixmode, + &unixmode); if (!NT_STATUS_IS_OK(status)) { return status; } + if (!VALID_STAT(smb_fname->st)) { + unixmode = apply_conf_file_mask(conn, unixmode); + } DBG_DEBUG("SMB_SET_FILE_UNIX_BASIC: name = " "%s size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", diff --git a/source3/smbd/smb2_trans2.c b/source3/smbd/smb2_trans2.c index ad0b85b77c5..fe19c391e0e 100644 --- a/source3/smbd/smb2_trans2.c +++ b/source3/smbd/smb2_trans2.c @@ -894,7 +894,6 @@ static struct ea_list *ea_list_union(struct ea_list *name_list, struct ea_list * NTSTATUS unix_perms_from_wire(connection_struct *conn, const SMB_STRUCT_STAT *psbuf, uint32_t perms, - enum perm_type ptype, mode_t *ret_perms) { mode_t ret = 0; @@ -909,20 +908,6 @@ NTSTATUS unix_perms_from_wire(connection_struct *conn, ret = wire_perms_to_unix(perms); - if (ptype == PERM_NEW_FILE) { - /* - * "create mask"/"force create mode" are - * only applied to new files, not existing ones. - */ - ret = apply_conf_file_mask(conn, ret); - } else if (ptype == PERM_NEW_DIR) { - /* - * "directory mask"/"force directory mode" are - * only applied to new directories, not existing ones. - */ - ret = apply_conf_dir_mask(conn, ret); - } - *ret_perms = ret; return NT_STATUS_OK; }