Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <vl@samba.org>
Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Signed-off-by: Steve French <stfrench@microsoft.com>

authored by

Volker Lendecke and committed by
Steve French
64ce47cb 83fb8abe

+59 -8
+9 -4
fs/cifs/inode.c
··· 632 632 633 633 /* Fill a cifs_fattr struct with info from POSIX info struct */ 634 634 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, 635 637 struct super_block *sb, bool adjust_tz, bool symlink) 636 638 { 637 639 struct smb311_posix_qinfo *info = &data->posix_fi; ··· 682 680 } 683 681 /* else if reparse point ... TODO: add support for FIFO and blk dev; special file types */ 684 682 685 - fattr->cf_uid = cifs_sb->ctx->linux_uid; /* TODO: map uid and gid from SID */ 686 - fattr->cf_gid = cifs_sb->ctx->linux_gid; 683 + sid_to_id(cifs_sb, owner, fattr, SIDOWNER); 684 + sid_to_id(cifs_sb, group, fattr, SIDGROUP); 687 685 688 686 cifs_dbg(FYI, "POSIX query info: mode 0x%x uniqueid 0x%llx nlink %d\n", 689 687 fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink); ··· 1177 1175 struct cifs_fattr fattr = {0}; 1178 1176 bool symlink = false; 1179 1177 struct cifs_open_info_data data = {}; 1178 + struct cifs_sid owner, group; 1180 1179 int rc = 0; 1181 1180 int tmprc = 0; 1182 1181 ··· 1195 1192 goto out; 1196 1193 } 1197 1194 1198 - rc = smb311_posix_query_path_info(xid, tcon, cifs_sb, full_path, &data, &adjust_tz, 1195 + rc = smb311_posix_query_path_info(xid, tcon, cifs_sb, full_path, &data, 1196 + &owner, &group, &adjust_tz, 1199 1197 &symlink); 1200 1198 1201 1199 /* ··· 1205 1201 1206 1202 switch (rc) { 1207 1203 case 0: 1208 - smb311_posix_info_to_fattr(&fattr, &data, sb, adjust_tz, symlink); 1204 + smb311_posix_info_to_fattr(&fattr, &data, &owner, &group, 1205 + sb, adjust_tz, symlink); 1209 1206 break; 1210 1207 case -EREMOTE: 1211 1208 /* DFS link, no metadata available on this server */
+46 -3
fs/cifs/smb2inode.c
··· 431 431 &rsp_iov[1], sizeof(idata->posix_fi) /* add SIDs */, 432 432 (char *)&idata->posix_fi); 433 433 } 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 + } 434 449 if (rqst[1].rq_iov) 435 450 SMB2_query_info_free(&rqst[1]); 436 451 if (rqst[2].rq_iov) ··· 584 569 585 570 int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, 586 571 struct cifs_sb_info *cifs_sb, const char *full_path, 587 - struct cifs_open_info_data *data, bool *adjust_tz, bool *reparse) 572 + struct cifs_open_info_data *data, 573 + struct cifs_sid *owner, 574 + struct cifs_sid *group, 575 + bool *adjust_tz, bool *reparse) 588 576 { 589 577 int rc; 590 578 __u32 create_options = 0; 591 579 struct cifsFileInfo *cfile; 592 580 struct kvec err_iov[3] = {}; 593 581 int err_buftype[3] = {}; 582 + __u8 *sidsbuf = NULL; 583 + __u8 *sidsbuf_end = NULL; 584 + size_t sidsbuflen = 0; 585 + size_t owner_len, group_len; 594 586 595 587 *adjust_tz = false; 596 588 *reparse = false; ··· 612 590 cifs_get_readable_path(tcon, full_path, &cfile); 613 591 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, 614 592 create_options, ACL_NO_MODE, data, SMB2_OP_POSIX_QUERY_INFO, cfile, 615 - NULL, NULL, err_iov, err_buftype); 593 + &sidsbuf, &sidsbuflen, err_iov, err_buftype); 616 594 if (rc == -EOPNOTSUPP) { 617 595 /* BB TODO: When support for special files added to Samba re-verify this path */ 618 596 if (err_iov[0].iov_base && err_buftype[0] != CIFS_NO_BUFFER && ··· 629 607 cifs_get_readable_path(tcon, full_path, &cfile); 630 608 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, 631 609 FILE_OPEN, create_options, ACL_NO_MODE, data, 632 - SMB2_OP_POSIX_QUERY_INFO, cfile, NULL, NULL, NULL, NULL); 610 + SMB2_OP_POSIX_QUERY_INFO, cfile, 611 + &sidsbuf, &sidsbuflen, NULL, NULL); 612 + } 613 + 614 + if (rc == 0) { 615 + sidsbuf_end = sidsbuf + sidsbuflen; 616 + 617 + owner_len = posix_info_sid_size(sidsbuf, sidsbuf_end); 618 + if (owner_len == -1) { 619 + rc = -EINVAL; 620 + goto out; 621 + } 622 + memcpy(owner, sidsbuf, owner_len); 623 + 624 + group_len = posix_info_sid_size( 625 + sidsbuf + owner_len, sidsbuf_end); 626 + if (group_len == -1) { 627 + rc = -EINVAL; 628 + goto out; 629 + } 630 + memcpy(group, sidsbuf + owner_len, group_len); 633 631 } 634 632 635 633 out: 634 + kfree(sidsbuf); 636 635 free_rsp_buf(err_buftype[0], err_iov[0].iov_base); 637 636 free_rsp_buf(err_buftype[1], err_iov[1].iov_base); 638 637 free_rsp_buf(err_buftype[2], err_iov[2].iov_base);
+4 -1
fs/cifs/smb2proto.h
··· 277 277 /* query path info from the server using SMB311 POSIX extensions*/ 278 278 int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, 279 279 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); 281 284 int posix_info_parse(const void *beg, const void *end, 282 285 struct smb2_posix_info_parsed *out); 283 286 int posix_info_sid_size(const void *beg, const void *end);