smb3: pass mode bits into create calls
authorSteve French <stfrench@microsoft.com>
Wed, 25 Sep 2019 05:32:13 +0000 (00:32 -0500)
committerSteve French <stfrench@microsoft.com>
Thu, 26 Sep 2019 07:06:42 +0000 (02:06 -0500)
We need to populate an ACL (security descriptor open context)
on file and directory correct.  This patch passes in the
mode.  Followon patch will build the open context and the
security descriptor (from the mode) that goes in the open
context.

Signed-off-by: Steve French <stfrench@microsoft.com>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>
fs/cifs/cifsglob.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/inode.c
fs/cifs/smb2inode.c
fs/cifs/smb2pdu.c
fs/cifs/smb2proto.h

index 54e204589cb98be350bf9012b833987cca590774..2e960e1049db565d4f8a64a731329f74f8cc5404 100644 (file)
@@ -331,8 +331,9 @@ struct smb_version_operations {
                        umode_t mode, struct cifs_tcon *tcon,
                        const char *full_path,
                        struct cifs_sb_info *cifs_sb);
-       int (*mkdir)(const unsigned int, struct cifs_tcon *, const char *,
-                    struct cifs_sb_info *);
+       int (*mkdir)(const unsigned int xid, struct inode *inode, umode_t mode,
+                    struct cifs_tcon *tcon, const char *name,
+                    struct cifs_sb_info *sb);
        /* set info on created directory */
        void (*mkdir_setinfo)(struct inode *, const char *,
                              struct cifs_sb_info *, struct cifs_tcon *,
@@ -1209,6 +1210,7 @@ struct cifs_search_info {
        bool smallBuf:1; /* so we know which buf_release function to call */
 };
 
+#define ACL_NO_MODE    -1
 struct cifs_open_parms {
        struct cifs_tcon *tcon;
        struct cifs_sb_info *cifs_sb;
index 99b1b1ef558ce7cdc49b6897090468f472792dcd..e53e9f62b87b7b043f11010877ab59c5937c7014 100644 (file)
@@ -372,7 +372,8 @@ extern int CIFSSMBUnixSetPathInfo(const unsigned int xid,
                                  const struct nls_table *nls_codepage,
                                  int remap);
 
-extern int CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon,
+extern int CIFSSMBMkDir(const unsigned int xid, struct inode *inode,
+                       umode_t mode, struct cifs_tcon *tcon,
                        const char *name, struct cifs_sb_info *cifs_sb);
 extern int CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon,
                        const char *name, struct cifs_sb_info *cifs_sb);
index dbee2132e419d03147fc2b3de8f864aca06a293f..4f554f019a98984fe3a2914d2f1365da6e82a6d6 100644 (file)
@@ -1078,7 +1078,8 @@ RmDirRetry:
 }
 
 int
-CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
+CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
+            struct cifs_tcon *tcon, const char *name,
             struct cifs_sb_info *cifs_sb)
 {
        int rc = 0;
index 26cdfbf1e16475246f29ee222ea548d04fe17def..3bae2e53f0b85fe3b78885d34e12070ce57cfb53 100644 (file)
@@ -1622,13 +1622,14 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
        }
 
        /* BB add setting the equivalent of mode via CreateX w/ACLs */
-       rc = server->ops->mkdir(xid, tcon, full_path, cifs_sb);
+       rc = server->ops->mkdir(xid, inode, mode, tcon, full_path, cifs_sb);
        if (rc) {
                cifs_dbg(FYI, "cifs_mkdir returned 0x%x\n", rc);
                d_drop(direntry);
                goto mkdir_out;
        }
 
+       /* TODO: skip this for smb2/smb3 */
        rc = cifs_mkdir_qinfo(inode, direntry, mode, full_path, cifs_sb, tcon,
                              xid);
 mkdir_out:
index d2a3fb7e5c8dcc7260b7fa3672495f8ea9d5e70d..4121ac1163cabda6260adcf53f1814bc8112ba67 100644 (file)
@@ -51,7 +51,7 @@ static int
 smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
                 struct cifs_sb_info *cifs_sb, const char *full_path,
                 __u32 desired_access, __u32 create_disposition,
-                __u32 create_options, void *ptr, int command,
+                __u32 create_options, umode_t mode, void *ptr, int command,
                 struct cifsFileInfo *cfile)
 {
        int rc;
@@ -103,6 +103,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
                oparms.create_options |= CREATE_OPEN_BACKUP_INTENT;
        oparms.fid = &fid;
        oparms.reconnect = false;
+       oparms.mode = mode;
 
        memset(&open_iov, 0, sizeof(open_iov));
        rqst[num_rqst].rq_iov = open_iov;
@@ -478,7 +479,7 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
        cifs_get_readable_path(tcon, full_path, &cfile);
        rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
                              FILE_READ_ATTRIBUTES, FILE_OPEN, create_options,
-                             smb2_data, SMB2_OP_QUERY_INFO, cfile);
+                             ACL_NO_MODE, smb2_data, SMB2_OP_QUERY_INFO, cfile);
        if (rc == -EOPNOTSUPP) {
                *symlink = true;
                create_options |= OPEN_REPARSE_POINT;
@@ -486,8 +487,8 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
                /* Failed on a symbolic link - query a reparse point info */
                rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
                                      FILE_READ_ATTRIBUTES, FILE_OPEN,
-                                     create_options, smb2_data,
-                                     SMB2_OP_QUERY_INFO, NULL);
+                                     create_options, ACL_NO_MODE,
+                                     smb2_data, SMB2_OP_QUERY_INFO, NULL);
        }
        if (rc)
                goto out;
@@ -499,12 +500,14 @@ out:
 }
 
 int
-smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
+smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode,
+          struct cifs_tcon *tcon, const char *name,
           struct cifs_sb_info *cifs_sb)
 {
        return smb2_compound_op(xid, tcon, cifs_sb, name,
                                FILE_WRITE_ATTRIBUTES, FILE_CREATE,
-                               CREATE_NOT_FILE, NULL, SMB2_OP_MKDIR, NULL);
+                               CREATE_NOT_FILE, mode, NULL, SMB2_OP_MKDIR,
+                               NULL);
 }
 
 void
@@ -525,8 +528,8 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name,
        cifs_get_writable_path(tcon, name, &cfile);
        tmprc = smb2_compound_op(xid, tcon, cifs_sb, name,
                                 FILE_WRITE_ATTRIBUTES, FILE_CREATE,
-                                CREATE_NOT_FILE, &data, SMB2_OP_SET_INFO,
-                                cfile);
+                                CREATE_NOT_FILE, ACL_NO_MODE,
+                                &data, SMB2_OP_SET_INFO, cfile);
        if (tmprc == 0)
                cifs_i->cifsAttrs = dosattrs;
 }
@@ -536,7 +539,7 @@ smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
           struct cifs_sb_info *cifs_sb)
 {
        return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
-                               CREATE_NOT_FILE,
+                               CREATE_NOT_FILE, ACL_NO_MODE,
                                NULL, SMB2_OP_RMDIR, NULL);
 }
 
@@ -546,7 +549,7 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
 {
        return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
                                CREATE_DELETE_ON_CLOSE | OPEN_REPARSE_POINT,
-                               NULL, SMB2_OP_DELETE, NULL);
+                               ACL_NO_MODE, NULL, SMB2_OP_DELETE, NULL);
 }
 
 static int
@@ -564,7 +567,8 @@ smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon,
                goto smb2_rename_path;
        }
        rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, access,
-                             FILE_OPEN, 0, smb2_to_name, command, cfile);
+                             FILE_OPEN, 0, ACL_NO_MODE, smb2_to_name,
+                             command, cfile);
 smb2_rename_path:
        kfree(smb2_to_name);
        return rc;
@@ -601,8 +605,8 @@ smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon,
        __le64 eof = cpu_to_le64(size);
 
        return smb2_compound_op(xid, tcon, cifs_sb, full_path,
-                               FILE_WRITE_DATA, FILE_OPEN, 0, &eof,
-                               SMB2_OP_SET_EOF, NULL);
+                               FILE_WRITE_DATA, FILE_OPEN, 0, ACL_NO_MODE,
+                               &eof, SMB2_OP_SET_EOF, NULL);
 }
 
 int
@@ -623,8 +627,8 @@ smb2_set_file_info(struct inode *inode, const char *full_path,
                return PTR_ERR(tlink);
 
        rc = smb2_compound_op(xid, tlink_tcon(tlink), cifs_sb, full_path,
-                             FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, buf,
-                             SMB2_OP_SET_INFO, NULL);
+                             FILE_WRITE_ATTRIBUTES, FILE_OPEN,
+                             0, ACL_NO_MODE, buf, SMB2_OP_SET_INFO, NULL);
        cifs_put_tlink(tlink);
        return rc;
 }
index ea08e6159481eb5de51e310a8feb8ec8f9acae9a..85f9d614d96874c77b88fa7d5bfb2c58c6a1c079 100644 (file)
@@ -751,6 +751,8 @@ add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode)
        unsigned int num = *num_iovec;
 
        iov[num].iov_base = create_posix_buf(mode);
+       if (mode == -1)
+               cifs_dbg(VFS, "illegal mode\n"); /* BB REMOVEME */
        if (iov[num].iov_base == NULL)
                return -ENOMEM;
        iov[num].iov_len = sizeof(struct create_posix);
@@ -2417,6 +2419,7 @@ SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock,
        /* File attributes ignored on open (used in create though) */
        req->FileAttributes = cpu_to_le32(file_attributes);
        req->ShareAccess = FILE_SHARE_ALL_LE;
+
        req->CreateDisposition = cpu_to_le32(oparms->disposition);
        req->CreateOptions = cpu_to_le32(oparms->create_options & CREATE_OPTIONS_MASK);
        req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req));
@@ -2518,6 +2521,23 @@ SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock,
                        return rc;
        }
 
+       /* TODO: add handling for the mode on create */
+       if (oparms->disposition == FILE_CREATE)
+               cifs_dbg(VFS, "mode is 0x%x\n", oparms->mode); /* BB REMOVEME */
+
+       if ((oparms->disposition == FILE_CREATE) && (oparms->mode != -1)) {
+               if (n_iov > 2) {
+                       struct create_context *ccontext =
+                           (struct create_context *)iov[n_iov-1].iov_base;
+                       ccontext->Next =
+                               cpu_to_le32(iov[n_iov-1].iov_len);
+               }
+
+               /* rc = add_sd_context(iov, &n_iov, oparms->mode); */
+               if (rc)
+                       return rc;
+       }
+
        if (n_iov > 2) {
                struct create_context *ccontext =
                        (struct create_context *)iov[n_iov-1].iov_base;
index 67a91b11fd590a9bf666e78a85391ebe8b151ac1..da3a6d58080876d7912e031d8ab42f7db13b8f7b 100644 (file)
@@ -84,7 +84,8 @@ extern int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
                               umode_t mode, struct cifs_tcon *tcon,
                               const char *full_path,
                               struct cifs_sb_info *cifs_sb);
-extern int smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon,
+extern int smb2_mkdir(const unsigned int xid, struct inode *inode,
+                     umode_t mode, struct cifs_tcon *tcon,
                      const char *name, struct cifs_sb_info *cifs_sb);
 extern void smb2_mkdir_setinfo(struct inode *inode, const char *full_path,
                               struct cifs_sb_info *cifs_sb,