From: Jeremy Allison Date: Thu, 1 Mar 2018 22:37:52 +0000 (-0800) Subject: s3: smbd: Allow fchmod from the NFS-style mode ACL in set_nt_acl() for a SMB2 POSIX... X-Git-Tag: talloc-2.4.2~531 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8f42b8431efcdeee9e270423bab9e111775430c9;p=thirdparty%2Fsamba.git s3: smbd: Allow fchmod from the NFS-style mode ACL in set_nt_acl() for a SMB2 POSIX handle. To set a mode, send a one-element ACL. Pair-Programmed-With: Ralph Boehme Signed-off-by: Jeremy Allison Signed-off-by: Ralph Boehme Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Mon Nov 27 19:31:01 UTC 2023 on atb-devel-224 --- diff --git a/source3/smbd/smb2_nttrans.c b/source3/smbd/smb2_nttrans.c index 1312d9bfc36..bf5170f07d4 100644 --- a/source3/smbd/smb2_nttrans.c +++ b/source3/smbd/smb2_nttrans.c @@ -167,6 +167,50 @@ NTSTATUS set_sd(files_struct *fsp, struct security_descriptor *psd, return status; } +static bool check_smb2_posix_chmod_ace(const struct files_struct *fsp, + uint32_t security_info_sent, + struct security_descriptor *psd, + mode_t *pmode) +{ + int cmp; + + /* + * This must be an ACL with one ACE containing an + * MS NFS style mode entry coming in on a POSIX + * handle over SMB2+. + */ + if (!fsp->conn->sconn->using_smb2) { + return false; + } + + if (!(fsp->posix_flags & FSP_POSIX_FLAGS_OPEN)) { + return false; + } + + if (!(security_info_sent & SECINFO_DACL)) { + return false; + } + + if (psd->dacl == NULL) { + return false; + } + + if (psd->dacl->num_aces != 1) { + return false; + } + + cmp = dom_sid_compare_domain(&global_sid_Unix_NFS_Mode, + &psd->dacl->aces[0].trustee); + if (cmp != 0) { + return false; + } + + *pmode = (mode_t)psd->dacl->aces[0].trustee.sub_auths[2]; + *pmode &= (S_IRWXU | S_IRWXG | S_IRWXO); + + return true; +} + /**************************************************************************** Internal fn to set security descriptors from a data blob. ****************************************************************************/ @@ -176,6 +220,9 @@ NTSTATUS set_sd_blob(files_struct *fsp, uint8_t *data, uint32_t sd_len, { struct security_descriptor *psd = NULL; NTSTATUS status; + bool do_chmod = false; + mode_t smb2_posix_mode = 0; + int ret; if (sd_len == 0) { return NT_STATUS_INVALID_PARAMETER; @@ -187,7 +234,27 @@ NTSTATUS set_sd_blob(files_struct *fsp, uint8_t *data, uint32_t sd_len, return status; } - return set_sd(fsp, psd, security_info_sent); + do_chmod = check_smb2_posix_chmod_ace(fsp, + security_info_sent, + psd, + &smb2_posix_mode); + if (!do_chmod) { + return set_sd(fsp, psd, security_info_sent); + } + + TALLOC_FREE(psd); + + ret = SMB_VFS_FCHMOD(fsp, smb2_posix_mode); + if (ret != 0) { + status = map_nt_error_from_unix(errno); + DBG_ERR("smb2_posix_chmod [%s] [%04o] failed: %s\n", + fsp_str_dbg(fsp), + (unsigned)smb2_posix_mode, + nt_errstr(status)); + return status; + } + + return NT_STATUS_OK; } /****************************************************************************