smb3: add new mount option to retrieve mode from special ACE
authorSteve French <stfrench@microsoft.com>
Mon, 24 Jun 2019 07:01:42 +0000 (02:01 -0500)
committerSteve French <stfrench@microsoft.com>
Mon, 8 Jul 2019 03:37:43 +0000 (22:37 -0500)
There is a special ACE used by some servers to allow the mode
bits to be stored.  This can be especially helpful in scenarios
in which the client is trusted, and access checking on the
client vs the POSIX mode bits is sufficient.

Add mount option to allow enabling this behavior.
Follow on patch will add support for chmod and queryinfo
(stat) by retrieving the POSIX mode bits from the special
ACE, SID: S-1-5-88-3

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 <stfrench@microsoft.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
fs/cifs/cifs_fs_sb.h
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/connect.c

index afa5623..b326d2c 100644 (file)
@@ -52,6 +52,7 @@
 #define CIFS_MOUNT_UID_FROM_ACL 0x2000000 /* try to get UID via special SID */
 #define CIFS_MOUNT_NO_HANDLE_CACHE 0x4000000 /* disable caching dir handles */
 #define CIFS_MOUNT_NO_DFS 0x8000000 /* disable DFS resolving */
+#define CIFS_MOUNT_MODE_FROM_SID 0x10000000 /* retrieve mode from special ACE */
 
 struct cifs_sb_info {
        struct rb_root tlink_tree;
index dc5fd7a..0ee63ac 100644 (file)
@@ -526,6 +526,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
                seq_puts(s, ",nobrl");
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_HANDLE_CACHE)
                seq_puts(s, ",nohandlecache");
+       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)
+               seq_puts(s, ",modefromsid");
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
                seq_puts(s, ",cifsacl");
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
index 16f2409..a4af850 100644 (file)
@@ -550,6 +550,7 @@ struct smb_vol {
        bool override_gid:1;
        bool dynperm:1;
        bool noperm:1;
+       bool mode_ace:1;
        bool no_psx_acl:1; /* set if posix acl support should be disabled */
        bool cifs_acl:1;
        bool backupuid_specified; /* mount option  backupuid  is specified */
@@ -618,7 +619,7 @@ struct smb_vol {
                         CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \
                         CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID | \
                         CIFS_MOUNT_UID_FROM_ACL | CIFS_MOUNT_NO_HANDLE_CACHE | \
-                        CIFS_MOUNT_NO_DFS)
+                        CIFS_MOUNT_NO_DFS | CIFS_MOUNT_MODE_FROM_SID)
 
 /**
  * Generic VFS superblock mount flags (s_flags) to consider when
index 1eb7314..07c9cd7 100644 (file)
@@ -96,7 +96,7 @@ enum {
        Opt_multiuser, Opt_sloppy, Opt_nosharesock,
        Opt_persistent, Opt_nopersistent,
        Opt_resilient, Opt_noresilient,
-       Opt_domainauto, Opt_rdma,
+       Opt_domainauto, Opt_rdma, Opt_modesid,
 
        /* Mount options which take numeric value */
        Opt_backupuid, Opt_backupgid, Opt_uid,
@@ -175,6 +175,7 @@ static const match_table_t cifs_mount_option_tokens = {
        { Opt_serverino, "serverino" },
        { Opt_noserverino, "noserverino" },
        { Opt_rwpidforward, "rwpidforward" },
+       { Opt_modesid, "modefromsid" },
        { Opt_cifsacl, "cifsacl" },
        { Opt_nocifsacl, "nocifsacl" },
        { Opt_acl, "acl" },
@@ -1830,6 +1831,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                case Opt_rwpidforward:
                        vol->rwpidforward = 1;
                        break;
+               case Opt_modesid:
+                       vol->mode_ace = 1;
+                       break;
                case Opt_cifsacl:
                        vol->cifs_acl = 1;
                        break;
@@ -3976,6 +3980,8 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
        if (pvolume_info->rwpidforward)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
+       if (pvolume_info->mode_ace)
+               cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MODE_FROM_SID;
        if (pvolume_info->cifs_acl)
                cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
        if (pvolume_info->backupuid_specified) {