Skip to content

Commit 64ce47c

Browse files
vlendecsmfrench
authored andcommitted
cifs: Parse owner/group for stat in smb311 posix extensions
stat was returning default owner and group (unlike readdir) for SMB3.1.1 POSIX extensions Signed-off-by: Volker Lendecke <[email protected]> Reviewed-by: Paulo Alcantara (SUSE) <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 83fb8ab commit 64ce47c

File tree

3 files changed

+59
-8
lines changed

3 files changed

+59
-8
lines changed

fs/cifs/inode.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,8 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
632632

633633
/* Fill a cifs_fattr struct with info from POSIX info struct */
634634
static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct cifs_open_info_data *data,
635+
struct cifs_sid *owner,
636+
struct cifs_sid *group,
635637
struct super_block *sb, bool adjust_tz, bool symlink)
636638
{
637639
struct smb311_posix_qinfo *info = &data->posix_fi;
@@ -680,8 +682,8 @@ static void smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct cifs_ope
680682
}
681683
/* else if reparse point ... TODO: add support for FIFO and blk dev; special file types */
682684

683-
fattr->cf_uid = cifs_sb->ctx->linux_uid; /* TODO: map uid and gid from SID */
684-
fattr->cf_gid = cifs_sb->ctx->linux_gid;
685+
sid_to_id(cifs_sb, owner, fattr, SIDOWNER);
686+
sid_to_id(cifs_sb, group, fattr, SIDGROUP);
685687

686688
cifs_dbg(FYI, "POSIX query info: mode 0x%x uniqueid 0x%llx nlink %d\n",
687689
fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink);
@@ -1175,6 +1177,7 @@ smb311_posix_get_inode_info(struct inode **inode,
11751177
struct cifs_fattr fattr = {0};
11761178
bool symlink = false;
11771179
struct cifs_open_info_data data = {};
1180+
struct cifs_sid owner, group;
11781181
int rc = 0;
11791182
int tmprc = 0;
11801183

@@ -1192,7 +1195,8 @@ smb311_posix_get_inode_info(struct inode **inode,
11921195
goto out;
11931196
}
11941197

1195-
rc = smb311_posix_query_path_info(xid, tcon, cifs_sb, full_path, &data, &adjust_tz,
1198+
rc = smb311_posix_query_path_info(xid, tcon, cifs_sb, full_path, &data,
1199+
&owner, &group, &adjust_tz,
11961200
&symlink);
11971201

11981202
/*
@@ -1201,7 +1205,8 @@ smb311_posix_get_inode_info(struct inode **inode,
12011205

12021206
switch (rc) {
12031207
case 0:
1204-
smb311_posix_info_to_fattr(&fattr, &data, sb, adjust_tz, symlink);
1208+
smb311_posix_info_to_fattr(&fattr, &data, &owner, &group,
1209+
sb, adjust_tz, symlink);
12051210
break;
12061211
case -EREMOTE:
12071212
/* DFS link, no metadata available on this server */

fs/cifs/smb2inode.c

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,21 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
431431
&rsp_iov[1], sizeof(idata->posix_fi) /* add SIDs */,
432432
(char *)&idata->posix_fi);
433433
}
434+
if (rc == 0) {
435+
unsigned int length = le32_to_cpu(qi_rsp->OutputBufferLength);
436+
437+
if (length > sizeof(idata->posix_fi)) {
438+
char *base = (char *)rsp_iov[1].iov_base +
439+
le16_to_cpu(qi_rsp->OutputBufferOffset) +
440+
sizeof(idata->posix_fi);
441+
*extbuflen = length - sizeof(idata->posix_fi);
442+
*extbuf = kmemdup(base, *extbuflen, GFP_KERNEL);
443+
if (!*extbuf)
444+
rc = -ENOMEM;
445+
} else {
446+
rc = -EINVAL;
447+
}
448+
}
434449
if (rqst[1].rq_iov)
435450
SMB2_query_info_free(&rqst[1]);
436451
if (rqst[2].rq_iov)
@@ -569,13 +584,20 @@ int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
569584

570585
int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
571586
struct cifs_sb_info *cifs_sb, const char *full_path,
572-
struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse)
587+
struct cifs_open_info_data *data,
588+
struct cifs_sid *owner,
589+
struct cifs_sid *group,
590+
bool *adjust_tz, bool *reparse)
573591
{
574592
int rc;
575593
__u32 create_options = 0;
576594
struct cifsFileInfo *cfile;
577595
struct kvec err_iov[3] = {};
578596
int err_buftype[3] = {};
597+
__u8 *sidsbuf = NULL;
598+
__u8 *sidsbuf_end = NULL;
599+
size_t sidsbuflen = 0;
600+
size_t owner_len, group_len;
579601

580602
*adjust_tz = false;
581603
*reparse = false;
@@ -590,7 +612,7 @@ int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
590612
cifs_get_readable_path(tcon, full_path, &cfile);
591613
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN,
592614
create_options, ACL_NO_MODE, data, SMB2_OP_POSIX_QUERY_INFO, cfile,
593-
NULL, NULL, err_iov, err_buftype);
615+
&sidsbuf, &sidsbuflen, err_iov, err_buftype);
594616
if (rc == -EOPNOTSUPP) {
595617
/* BB TODO: When support for special files added to Samba re-verify this path */
596618
if (err_iov[0].iov_base && err_buftype[0] != CIFS_NO_BUFFER &&
@@ -607,10 +629,31 @@ int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
607629
cifs_get_readable_path(tcon, full_path, &cfile);
608630
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES,
609631
FILE_OPEN, create_options, ACL_NO_MODE, data,
610-
SMB2_OP_POSIX_QUERY_INFO, cfile, NULL, NULL, NULL, NULL);
632+
SMB2_OP_POSIX_QUERY_INFO, cfile,
633+
&sidsbuf, &sidsbuflen, NULL, NULL);
634+
}
635+
636+
if (rc == 0) {
637+
sidsbuf_end = sidsbuf + sidsbuflen;
638+
639+
owner_len = posix_info_sid_size(sidsbuf, sidsbuf_end);
640+
if (owner_len == -1) {
641+
rc = -EINVAL;
642+
goto out;
643+
}
644+
memcpy(owner, sidsbuf, owner_len);
645+
646+
group_len = posix_info_sid_size(
647+
sidsbuf + owner_len, sidsbuf_end);
648+
if (group_len == -1) {
649+
rc = -EINVAL;
650+
goto out;
651+
}
652+
memcpy(group, sidsbuf + owner_len, group_len);
611653
}
612654

613655
out:
656+
kfree(sidsbuf);
614657
free_rsp_buf(err_buftype[0], err_iov[0].iov_base);
615658
free_rsp_buf(err_buftype[1], err_iov[1].iov_base);
616659
free_rsp_buf(err_buftype[2], err_iov[2].iov_base);

fs/cifs/smb2proto.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,10 @@ extern int smb2_query_info_compound(const unsigned int xid,
277277
/* query path info from the server using SMB311 POSIX extensions*/
278278
int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
279279
struct cifs_sb_info *cifs_sb, const char *full_path,
280-
struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse);
280+
struct cifs_open_info_data *data,
281+
struct cifs_sid *owner,
282+
struct cifs_sid *group,
283+
bool *adjust_tz, bool *reparse);
281284
int posix_info_parse(const void *beg, const void *end,
282285
struct smb2_posix_info_parsed *out);
283286
int posix_info_sid_size(const void *beg, const void *end);

0 commit comments

Comments
 (0)