From patchwork Fri Jul 19 08:31:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 11049857 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D397714F6 for ; Fri, 19 Jul 2019 08:31:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BE023287FA for ; Fri, 19 Jul 2019 08:31:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AE0982886E; Fri, 19 Jul 2019 08:31:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7FF18287FA for ; Fri, 19 Jul 2019 08:31:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726112AbfGSIbr (ORCPT ); Fri, 19 Jul 2019 04:31:47 -0400 Received: from mail-pg1-f179.google.com ([209.85.215.179]:37499 "EHLO mail-pg1-f179.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726036AbfGSIbr (ORCPT ); Fri, 19 Jul 2019 04:31:47 -0400 Received: by mail-pg1-f179.google.com with SMTP id i70so3396418pgd.4 for ; Fri, 19 Jul 2019 01:31:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=qr+vzmrxKDJE3gBHNNljtkicer3EU9BSwZ8D3VJsD4U=; b=VQ8MQ7daYgPvOsz2V9bOKgxoKHQCjyLZxI8clEbPpecMTLGyT10hYwSAaAu0KZ5J/0 MIe+rxxQo0k502AXofDlQI7w/9Do3Ooq6OMd3JQBNVVD8jctU96JQMd/OjRyYEqEdwoE HEwQsGeInQ6oiw5wjGSylWk9Ky3f8QKXf8sMUJ5B8FYZgH2z5uL1YKeOVUALBc6tjcNq 9OsEj7Mvz4JipMQtQgCMdpcba9+hmKOJ4iDNTiQWpU/KfRs2aItdBZvoc6RUcNTh/emJ HxqFxivmUotgXFIiipMk7y3A6GcNqwK1QFiy+2AyOKkSVfNmPrntQrKOiIUzO8SwTwdd j5Zw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=qr+vzmrxKDJE3gBHNNljtkicer3EU9BSwZ8D3VJsD4U=; b=UA3VdsLJcq76unGpVDAHby7Kx/vqY9l+0seco5S59FOVtRRneWKp4BftrotbKtuaHB x8Nu/L8BGD7g+7J594ToITTr9WOrYtxQ+eMIcnPcNevU0qpgkNEf5ZCZzSBrITuTuS3Z vec79LTKhTIhbPgZim0cnXDTOdmmSHYBDpucE+XEp+UitizmNPFu5OPrfvCQ0Wh+RsX6 F1es/YFcmryOAmIvCwD8jpToKxpxyr3ElYQNQ/y8jBXDg8ghYbeOwEZ5sBmOqVYSVpWo sMg/4+5j4YefLrjAxFZGUrws0NTgdO7esHLU8X5qH5PaJ24+tfoDQ8w1OQGX0xQFLtXe btDA== X-Gm-Message-State: APjAAAWTdMCimwmNHT/OG4L2ONixtd8fTdNYIsT5oVDLgUuVmhjdfiR+ KmOftbmuvKJEsodlAMOOjvC5UVCIWpx08T0qeCQUEkIafX4= X-Google-Smtp-Source: APXvYqwUaTWp6cTkmWccO0tBAODdqHs6PFQvHj5hlaQqSrk06JBC9zzxcp7SsznCmsDKOYuh17pbrIKS/Wvpx/LsKT4= X-Received: by 2002:a65:6454:: with SMTP id s20mr52852475pgv.15.1563525105313; Fri, 19 Jul 2019 01:31:45 -0700 (PDT) MIME-Version: 1.0 From: Steve French Date: Fri, 19 Jul 2019 03:31:33 -0500 Message-ID: Subject: [PATCH][CIFS] Allow chmod to set mode using special SID To: CIFS Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When mounting with "modefromsid" set mode bits (chmod) by adding ACE with special SID (S-1-5-88-3-) to the ACL. Subsequent patch will fix setting default mode on file create and mkdir. See See e.g. https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/hh509017(v=ws.10) An example: # touch /mnt-to-windows/newfile0754 # chmod 0754 /mnt-to-windows/newfile0754 # stat /mnt-to-windows/newfile0754 File: /mnt-to-windows/newfile0754 Size: 0 Blocks: 0 IO Block: 1048576 regular empty file Device: 33h/51d Inode: 3659174697263184 Links: 1 Access: (0754/-rwxr-xr--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2019-07-19 08:21:14.970287500 +0000 Modify: 2019-07-19 08:21:14.970287500 +0000 Change: 2019-07-19 08:21:25.665086200 +0000 (Notice the last ACE which has the mode bits embedded, 492 decimal is 0754 octal) # getcifsacl /mnt-to-windows/newfile0754 REVISION:0x1 CONTROL:0x8004 OWNER:S-1-5-32-544 GROUP:S-1-5-21-3447553893-1265514152-1435875098-513 ACL:S-1-5-32-544:ALLOWED/0x0/FULL ACL:S-1-5-21-3447553893-1265514152-1435875098-513:ALLOWED/0x0/0x1f01b9 ACL:S-1-1-0:ALLOWED/0x0/0x1f0199 ACL:S-1-5-88-3-492:DENIED/0x0/ From ee2cea10a32827be97d0f7504ac5a835a35bd1a6 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 19 Jul 2019 08:15:55 +0000 Subject: [PATCH] cifs: allow chmod to set mode bits using special sid When mounting with "modefromsid" set mode bits (chmod) by adding ACE with special SID (S-1-5-88-3-) to the ACL. Subsequent patch will fix setting default mode on file create and mkdir. See See e.g. https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/hh509017(v=ws.10) Signed-off-by: Steve French --- fs/cifs/cifsacl.c | 42 +++++++++++++++++++++++++++++++++++++----- fs/cifs/inode.c | 6 ++++-- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 2a14748b8e09..a31bee51b1b4 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -806,7 +806,7 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, - struct cifs_sid *pgrpsid, __u64 nmode) + struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid) { u16 size = 0; struct cifs_acl *pnndacl; @@ -820,8 +820,33 @@ static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size), &sid_everyone, nmode, S_IRWXO); + /* TBD: Move this ACE to the top of ACE list instead of bottom */ + if (modefromsid) { + struct cifs_ace *pntace = + (struct cifs_ace *)((char *)pnndacl + size); + int i; + + pntace->type = ACCESS_DENIED; + pntace->flags = 0x0; + pntace->sid.num_subauth = 3; + pntace->sid.revision = 1; + /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4) */ + pntace->size = cpu_to_le16(28); + size += 28; + for (i = 0; i < NUM_AUTHS; i++) + pntace->sid.authority[i] = + sid_unix_NFS_mode.authority[i]; + pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0]; + pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1]; + pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777); + + pndacl->num_aces = cpu_to_le32(4); + size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size), + &sid_unix_NFS_mode, nmode, S_IRWXO); + } else + pndacl->num_aces = cpu_to_le32(3); + pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl)); - pndacl->num_aces = cpu_to_le32(3); return 0; } @@ -921,7 +946,8 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, /* Convert permission bits from mode to equivalent CIFS ACL */ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, - __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, int *aclflag) + __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, + bool mode_from_sid, int *aclflag) { int rc = 0; __u32 dacloffset; @@ -946,7 +972,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, ndacl_ptr->num_aces = 0; rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr, - nmode); + nmode, mode_from_sid); sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size); /* copy sec desc control portion & owner and group sids */ copy_sec_desc(pntsd, pnntsd, sidsoffset); @@ -1196,6 +1222,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); struct smb_version_operations *ops; + bool mode_from_sid; if (IS_ERR(tlink)) return PTR_ERR(tlink); @@ -1233,8 +1260,13 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, return -ENOMEM; } + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) + mode_from_sid = true; + else + mode_from_sid = false; + rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid, - &aclflag); + mode_from_sid, &aclflag); cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index c1e620ebcf7c..83664735efa5 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -2489,7 +2489,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) if (attrs->ia_valid & ATTR_GID) gid = attrs->ia_gid; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) || + (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) { if (uid_valid(uid) || gid_valid(gid)) { rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64, uid, gid); @@ -2510,7 +2511,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) if (attrs->ia_valid & ATTR_MODE) { mode = attrs->ia_mode; rc = 0; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) || + (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) { rc = id_mode_to_cifs_acl(inode, full_path, mode, INVALID_UID, INVALID_GID); if (rc) { -- 2.20.1