Skip to content

Commit c3ca78e

Browse files
committed
smb3: pass mode bits into create calls
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 <[email protected]> Reviewed-by: Aurelien Aptel <[email protected]>
1 parent 131ea1e commit c3ca78e

File tree

7 files changed

+51
-21
lines changed

7 files changed

+51
-21
lines changed

fs/cifs/cifsglob.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,9 @@ struct smb_version_operations {
331331
umode_t mode, struct cifs_tcon *tcon,
332332
const char *full_path,
333333
struct cifs_sb_info *cifs_sb);
334-
int (*mkdir)(const unsigned int, struct cifs_tcon *, const char *,
335-
struct cifs_sb_info *);
334+
int (*mkdir)(const unsigned int xid, struct inode *inode, umode_t mode,
335+
struct cifs_tcon *tcon, const char *name,
336+
struct cifs_sb_info *sb);
336337
/* set info on created directory */
337338
void (*mkdir_setinfo)(struct inode *, const char *,
338339
struct cifs_sb_info *, struct cifs_tcon *,
@@ -1209,6 +1210,7 @@ struct cifs_search_info {
12091210
bool smallBuf:1; /* so we know which buf_release function to call */
12101211
};
12111212

1213+
#define ACL_NO_MODE -1
12121214
struct cifs_open_parms {
12131215
struct cifs_tcon *tcon;
12141216
struct cifs_sb_info *cifs_sb;

fs/cifs/cifsproto.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,8 @@ extern int CIFSSMBUnixSetPathInfo(const unsigned int xid,
372372
const struct nls_table *nls_codepage,
373373
int remap);
374374

375-
extern int CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon,
375+
extern int CIFSSMBMkDir(const unsigned int xid, struct inode *inode,
376+
umode_t mode, struct cifs_tcon *tcon,
376377
const char *name, struct cifs_sb_info *cifs_sb);
377378
extern int CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon,
378379
const char *name, struct cifs_sb_info *cifs_sb);

fs/cifs/cifssmb.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,8 @@ CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
10781078
}
10791079

10801080
int
1081-
CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
1081+
CIFSSMBMkDir(const unsigned int xid, struct inode *inode, umode_t mode,
1082+
struct cifs_tcon *tcon, const char *name,
10821083
struct cifs_sb_info *cifs_sb)
10831084
{
10841085
int rc = 0;

fs/cifs/inode.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1622,13 +1622,14 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
16221622
}
16231623

16241624
/* BB add setting the equivalent of mode via CreateX w/ACLs */
1625-
rc = server->ops->mkdir(xid, tcon, full_path, cifs_sb);
1625+
rc = server->ops->mkdir(xid, inode, mode, tcon, full_path, cifs_sb);
16261626
if (rc) {
16271627
cifs_dbg(FYI, "cifs_mkdir returned 0x%x\n", rc);
16281628
d_drop(direntry);
16291629
goto mkdir_out;
16301630
}
16311631

1632+
/* TODO: skip this for smb2/smb3 */
16321633
rc = cifs_mkdir_qinfo(inode, direntry, mode, full_path, cifs_sb, tcon,
16331634
xid);
16341635
mkdir_out:

fs/cifs/smb2inode.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ static int
5151
smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
5252
struct cifs_sb_info *cifs_sb, const char *full_path,
5353
__u32 desired_access, __u32 create_disposition,
54-
__u32 create_options, void *ptr, int command,
54+
__u32 create_options, umode_t mode, void *ptr, int command,
5555
struct cifsFileInfo *cfile)
5656
{
5757
int rc;
@@ -103,6 +103,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
103103
oparms.create_options |= CREATE_OPEN_BACKUP_INTENT;
104104
oparms.fid = &fid;
105105
oparms.reconnect = false;
106+
oparms.mode = mode;
106107

107108
memset(&open_iov, 0, sizeof(open_iov));
108109
rqst[num_rqst].rq_iov = open_iov;
@@ -478,16 +479,16 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
478479
cifs_get_readable_path(tcon, full_path, &cfile);
479480
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
480481
FILE_READ_ATTRIBUTES, FILE_OPEN, create_options,
481-
smb2_data, SMB2_OP_QUERY_INFO, cfile);
482+
ACL_NO_MODE, smb2_data, SMB2_OP_QUERY_INFO, cfile);
482483
if (rc == -EOPNOTSUPP) {
483484
*symlink = true;
484485
create_options |= OPEN_REPARSE_POINT;
485486

486487
/* Failed on a symbolic link - query a reparse point info */
487488
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
488489
FILE_READ_ATTRIBUTES, FILE_OPEN,
489-
create_options, smb2_data,
490-
SMB2_OP_QUERY_INFO, NULL);
490+
create_options, ACL_NO_MODE,
491+
smb2_data, SMB2_OP_QUERY_INFO, NULL);
491492
}
492493
if (rc)
493494
goto out;
@@ -499,12 +500,14 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
499500
}
500501

501502
int
502-
smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
503+
smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode,
504+
struct cifs_tcon *tcon, const char *name,
503505
struct cifs_sb_info *cifs_sb)
504506
{
505507
return smb2_compound_op(xid, tcon, cifs_sb, name,
506508
FILE_WRITE_ATTRIBUTES, FILE_CREATE,
507-
CREATE_NOT_FILE, NULL, SMB2_OP_MKDIR, NULL);
509+
CREATE_NOT_FILE, mode, NULL, SMB2_OP_MKDIR,
510+
NULL);
508511
}
509512

510513
void
@@ -525,8 +528,8 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name,
525528
cifs_get_writable_path(tcon, name, &cfile);
526529
tmprc = smb2_compound_op(xid, tcon, cifs_sb, name,
527530
FILE_WRITE_ATTRIBUTES, FILE_CREATE,
528-
CREATE_NOT_FILE, &data, SMB2_OP_SET_INFO,
529-
cfile);
531+
CREATE_NOT_FILE, ACL_NO_MODE,
532+
&data, SMB2_OP_SET_INFO, cfile);
530533
if (tmprc == 0)
531534
cifs_i->cifsAttrs = dosattrs;
532535
}
@@ -536,7 +539,7 @@ smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
536539
struct cifs_sb_info *cifs_sb)
537540
{
538541
return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
539-
CREATE_NOT_FILE,
542+
CREATE_NOT_FILE, ACL_NO_MODE,
540543
NULL, SMB2_OP_RMDIR, NULL);
541544
}
542545

@@ -546,7 +549,7 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
546549
{
547550
return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
548551
CREATE_DELETE_ON_CLOSE | OPEN_REPARSE_POINT,
549-
NULL, SMB2_OP_DELETE, NULL);
552+
ACL_NO_MODE, NULL, SMB2_OP_DELETE, NULL);
550553
}
551554

552555
static int
@@ -564,7 +567,8 @@ smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon,
564567
goto smb2_rename_path;
565568
}
566569
rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, access,
567-
FILE_OPEN, 0, smb2_to_name, command, cfile);
570+
FILE_OPEN, 0, ACL_NO_MODE, smb2_to_name,
571+
command, cfile);
568572
smb2_rename_path:
569573
kfree(smb2_to_name);
570574
return rc;
@@ -601,8 +605,8 @@ smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon,
601605
__le64 eof = cpu_to_le64(size);
602606

603607
return smb2_compound_op(xid, tcon, cifs_sb, full_path,
604-
FILE_WRITE_DATA, FILE_OPEN, 0, &eof,
605-
SMB2_OP_SET_EOF, NULL);
608+
FILE_WRITE_DATA, FILE_OPEN, 0, ACL_NO_MODE,
609+
&eof, SMB2_OP_SET_EOF, NULL);
606610
}
607611

608612
int
@@ -623,8 +627,8 @@ smb2_set_file_info(struct inode *inode, const char *full_path,
623627
return PTR_ERR(tlink);
624628

625629
rc = smb2_compound_op(xid, tlink_tcon(tlink), cifs_sb, full_path,
626-
FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, buf,
627-
SMB2_OP_SET_INFO, NULL);
630+
FILE_WRITE_ATTRIBUTES, FILE_OPEN,
631+
0, ACL_NO_MODE, buf, SMB2_OP_SET_INFO, NULL);
628632
cifs_put_tlink(tlink);
629633
return rc;
630634
}

fs/cifs/smb2pdu.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,8 @@ add_posix_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode)
751751
unsigned int num = *num_iovec;
752752

753753
iov[num].iov_base = create_posix_buf(mode);
754+
if (mode == -1)
755+
cifs_dbg(VFS, "illegal mode\n"); /* BB REMOVEME */
754756
if (iov[num].iov_base == NULL)
755757
return -ENOMEM;
756758
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,
24172419
/* File attributes ignored on open (used in create though) */
24182420
req->FileAttributes = cpu_to_le32(file_attributes);
24192421
req->ShareAccess = FILE_SHARE_ALL_LE;
2422+
24202423
req->CreateDisposition = cpu_to_le32(oparms->disposition);
24212424
req->CreateOptions = cpu_to_le32(oparms->create_options & CREATE_OPTIONS_MASK);
24222425
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,
25182521
return rc;
25192522
}
25202523

2524+
/* TODO: add handling for the mode on create */
2525+
if (oparms->disposition == FILE_CREATE)
2526+
cifs_dbg(VFS, "mode is 0x%x\n", oparms->mode); /* BB REMOVEME */
2527+
2528+
if ((oparms->disposition == FILE_CREATE) && (oparms->mode != -1)) {
2529+
if (n_iov > 2) {
2530+
struct create_context *ccontext =
2531+
(struct create_context *)iov[n_iov-1].iov_base;
2532+
ccontext->Next =
2533+
cpu_to_le32(iov[n_iov-1].iov_len);
2534+
}
2535+
2536+
/* rc = add_sd_context(iov, &n_iov, oparms->mode); */
2537+
if (rc)
2538+
return rc;
2539+
}
2540+
25212541
if (n_iov > 2) {
25222542
struct create_context *ccontext =
25232543
(struct create_context *)iov[n_iov-1].iov_base;

fs/cifs/smb2proto.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ extern int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
8484
umode_t mode, struct cifs_tcon *tcon,
8585
const char *full_path,
8686
struct cifs_sb_info *cifs_sb);
87-
extern int smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon,
87+
extern int smb2_mkdir(const unsigned int xid, struct inode *inode,
88+
umode_t mode, struct cifs_tcon *tcon,
8889
const char *name, struct cifs_sb_info *cifs_sb);
8990
extern void smb2_mkdir_setinfo(struct inode *inode, const char *full_path,
9091
struct cifs_sb_info *cifs_sb,

0 commit comments

Comments
 (0)