s3: smbd: Allow fchmod from the NFS-style mode ACL in set_nt_acl() for a SMB2 POSIX...
authorJeremy Allison <jra@samba.org>
Thu, 1 Mar 2018 22:37:52 +0000 (14:37 -0800)
committerJeremy Allison <jra@samba.org>
Mon, 27 Nov 2023 19:31:01 +0000 (19:31 +0000)
To set a mode, send a one-element ACL.

Pair-Programmed-With: Ralph Boehme <slow@samba.org>

Signed-off-by: Jeremy Allison <jra@samba.org>
Signed-off-by: Ralph Boehme <slow@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Mon Nov 27 19:31:01 UTC 2023 on atb-devel-224

source3/smbd/smb2_nttrans.c

index 1312d9bfc363fec5719750d255f9b74be63532d1..bf5170f07d417bb59f490d82e283d389399655b2 100644 (file)
@@ -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;
 }
 
 /****************************************************************************