mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 22:54:05 +08:00
cifs: add SMB2_open() arg to return POSIX data
allows SMB2_open() callers to pass down a POSIX data buffer that will trigger requesting POSIX create context and parsing the response into the provided buffer. Signed-off-by: Aurelien Aptel <aaptel@suse.com> Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
This commit is contained in:
parent
3d519bd126
commit
69dda3059e
@ -416,7 +416,7 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
}
|
}
|
||||||
|
|
||||||
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, pfile_info, NULL,
|
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, pfile_info, NULL,
|
||||||
NULL);
|
NULL, NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto qmf_out_open_fail;
|
goto qmf_out_open_fail;
|
||||||
|
|
||||||
@ -470,7 +470,7 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
oparms.reconnect = false;
|
oparms.reconnect = false;
|
||||||
|
|
||||||
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
|
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
|
||||||
NULL);
|
NULL, NULL);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
kfree(utf16_path);
|
kfree(utf16_path);
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -62,7 +62,7 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
|
|||||||
smb2_oplock = SMB2_OPLOCK_LEVEL_BATCH;
|
smb2_oplock = SMB2_OPLOCK_LEVEL_BATCH;
|
||||||
|
|
||||||
rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL,
|
rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL,
|
||||||
NULL);
|
NULL, NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
@ -794,7 +794,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
tcon->crfid.has_lease = true;
|
tcon->crfid.has_lease = true;
|
||||||
smb2_parse_contexts(server, o_rsp,
|
smb2_parse_contexts(server, o_rsp,
|
||||||
&oparms.fid->epoch,
|
&oparms.fid->epoch,
|
||||||
oparms.fid->lease_key, &oplock, NULL);
|
oparms.fid->lease_key, &oplock,
|
||||||
|
NULL, NULL);
|
||||||
} else
|
} else
|
||||||
goto oshr_exit;
|
goto oshr_exit;
|
||||||
|
|
||||||
@ -838,7 +839,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
|
|
||||||
if (no_cached_open)
|
if (no_cached_open)
|
||||||
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
|
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
|
||||||
NULL);
|
NULL, NULL);
|
||||||
else
|
else
|
||||||
rc = open_shroot(xid, tcon, cifs_sb, &fid);
|
rc = open_shroot(xid, tcon, cifs_sb, &fid);
|
||||||
|
|
||||||
@ -878,7 +879,8 @@ smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
oparms.fid = &fid;
|
oparms.fid = &fid;
|
||||||
oparms.reconnect = false;
|
oparms.reconnect = false;
|
||||||
|
|
||||||
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL, NULL);
|
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
|
||||||
|
NULL, NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -913,7 +915,8 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
oparms.fid = &fid;
|
oparms.fid = &fid;
|
||||||
oparms.reconnect = false;
|
oparms.reconnect = false;
|
||||||
|
|
||||||
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL);
|
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL,
|
||||||
|
NULL);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
kfree(utf16_path);
|
kfree(utf16_path);
|
||||||
return rc;
|
return rc;
|
||||||
@ -2122,7 +2125,8 @@ smb3_notify(const unsigned int xid, struct file *pfile,
|
|||||||
oparms.fid = &fid;
|
oparms.fid = &fid;
|
||||||
oparms.reconnect = false;
|
oparms.reconnect = false;
|
||||||
|
|
||||||
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL);
|
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL,
|
||||||
|
NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto notify_exit;
|
goto notify_exit;
|
||||||
|
|
||||||
@ -2543,7 +2547,8 @@ smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
|
|||||||
oparms.fid = &fid;
|
oparms.fid = &fid;
|
||||||
oparms.reconnect = false;
|
oparms.reconnect = false;
|
||||||
|
|
||||||
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL, NULL);
|
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
|
||||||
|
NULL, NULL);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
@ -3028,7 +3033,8 @@ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb,
|
|||||||
oparms.fid = &fid;
|
oparms.fid = &fid;
|
||||||
oparms.reconnect = false;
|
oparms.reconnect = false;
|
||||||
|
|
||||||
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL);
|
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL,
|
||||||
|
NULL);
|
||||||
kfree(utf16_path);
|
kfree(utf16_path);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
rc = SMB2_query_acl(xid, tlink_tcon(tlink), fid.persistent_fid,
|
rc = SMB2_query_acl(xid, tlink_tcon(tlink), fid.persistent_fid,
|
||||||
@ -3086,7 +3092,8 @@ set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
|
|||||||
oparms.fid = &fid;
|
oparms.fid = &fid;
|
||||||
oparms.reconnect = false;
|
oparms.reconnect = false;
|
||||||
|
|
||||||
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL);
|
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
|
||||||
|
NULL, NULL);
|
||||||
kfree(utf16_path);
|
kfree(utf16_path);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
rc = SMB2_set_acl(xid, tlink_tcon(tlink), fid.persistent_fid,
|
rc = SMB2_set_acl(xid, tlink_tcon(tlink), fid.persistent_fid,
|
||||||
|
@ -1951,25 +1951,46 @@ parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *info)
|
parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *info,
|
||||||
|
struct create_posix_rsp *posix)
|
||||||
{
|
{
|
||||||
/* struct create_posix_rsp *posix = (struct create_posix_rsp *)cc; */
|
int sid_len;
|
||||||
|
u8 *beg = (u8 *)cc + le16_to_cpu(cc->DataOffset);
|
||||||
|
u8 *end = beg + le32_to_cpu(cc->DataLength);
|
||||||
|
u8 *sid;
|
||||||
|
|
||||||
/*
|
memset(posix, 0, sizeof(*posix));
|
||||||
* TODO: Need to add parsing for the context and return. Can
|
|
||||||
* smb2_file_all_info hold POSIX data? Need to change the
|
|
||||||
* passed type from SMB2_open.
|
|
||||||
*/
|
|
||||||
printk_once(KERN_WARNING
|
|
||||||
"SMB3 3.11 POSIX response context not completed yet\n");
|
|
||||||
|
|
||||||
|
posix->nlink = le32_to_cpu(*(__le32 *)(beg + 0));
|
||||||
|
posix->reparse_tag = le32_to_cpu(*(__le32 *)(beg + 4));
|
||||||
|
posix->mode = le32_to_cpu(*(__le32 *)(beg + 8));
|
||||||
|
|
||||||
|
sid = beg + 12;
|
||||||
|
sid_len = posix_info_sid_size(sid, end);
|
||||||
|
if (sid_len < 0) {
|
||||||
|
cifs_dbg(VFS, "bad owner sid in posix create response\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(&posix->owner, sid, sid_len);
|
||||||
|
|
||||||
|
sid = sid + sid_len;
|
||||||
|
sid_len = posix_info_sid_size(sid, end);
|
||||||
|
if (sid_len < 0) {
|
||||||
|
cifs_dbg(VFS, "bad group sid in posix create response\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(&posix->group, sid, sid_len);
|
||||||
|
|
||||||
|
cifs_dbg(FYI, "nlink=%d mode=%o reparse_tag=%x\n",
|
||||||
|
posix->nlink, posix->mode, posix->reparse_tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
smb2_parse_contexts(struct TCP_Server_Info *server,
|
smb2_parse_contexts(struct TCP_Server_Info *server,
|
||||||
struct smb2_create_rsp *rsp,
|
struct smb2_create_rsp *rsp,
|
||||||
unsigned int *epoch, char *lease_key, __u8 *oplock,
|
unsigned int *epoch, char *lease_key, __u8 *oplock,
|
||||||
struct smb2_file_all_info *buf)
|
struct smb2_file_all_info *buf,
|
||||||
|
struct create_posix_rsp *posix)
|
||||||
{
|
{
|
||||||
char *data_offset;
|
char *data_offset;
|
||||||
struct create_context *cc;
|
struct create_context *cc;
|
||||||
@ -1999,8 +2020,9 @@ smb2_parse_contexts(struct TCP_Server_Info *server,
|
|||||||
strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4) == 0)
|
strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4) == 0)
|
||||||
parse_query_id_ctxt(cc, buf);
|
parse_query_id_ctxt(cc, buf);
|
||||||
else if ((le16_to_cpu(cc->NameLength) == 16)) {
|
else if ((le16_to_cpu(cc->NameLength) == 16)) {
|
||||||
if (memcmp(name, smb3_create_tag_posix, 16) == 0)
|
if (posix &&
|
||||||
parse_posix_ctxt(cc, buf);
|
memcmp(name, smb3_create_tag_posix, 16) == 0)
|
||||||
|
parse_posix_ctxt(cc, buf, posix);
|
||||||
}
|
}
|
||||||
/* else {
|
/* else {
|
||||||
cifs_dbg(FYI, "Context not matched with len %d\n",
|
cifs_dbg(FYI, "Context not matched with len %d\n",
|
||||||
@ -2725,6 +2747,7 @@ SMB2_open_free(struct smb_rqst *rqst)
|
|||||||
int
|
int
|
||||||
SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
|
SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
|
||||||
__u8 *oplock, struct smb2_file_all_info *buf,
|
__u8 *oplock, struct smb2_file_all_info *buf,
|
||||||
|
struct create_posix_rsp *posix,
|
||||||
struct kvec *err_iov, int *buftype)
|
struct kvec *err_iov, int *buftype)
|
||||||
{
|
{
|
||||||
struct smb_rqst rqst;
|
struct smb_rqst rqst;
|
||||||
@ -2803,7 +2826,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
|
|||||||
|
|
||||||
|
|
||||||
smb2_parse_contexts(server, rsp, &oparms->fid->epoch,
|
smb2_parse_contexts(server, rsp, &oparms->fid->epoch,
|
||||||
oparms->fid->lease_key, oplock, buf);
|
oparms->fid->lease_key, oplock, buf, posix);
|
||||||
creat_exit:
|
creat_exit:
|
||||||
SMB2_open_free(&rqst);
|
SMB2_open_free(&rqst);
|
||||||
free_rsp_buf(resp_buftype, rsp);
|
free_rsp_buf(resp_buftype, rsp);
|
||||||
@ -4302,7 +4325,7 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int posix_info_sid_size(const void *beg, const void *end)
|
int posix_info_sid_size(const void *beg, const void *end)
|
||||||
{
|
{
|
||||||
size_t subauth;
|
size_t subauth;
|
||||||
int total;
|
int total;
|
||||||
|
@ -1605,13 +1605,11 @@ extern char smb2_padding[7];
|
|||||||
|
|
||||||
/* equivalent of the contents of SMB3.1.1 POSIX open context response */
|
/* equivalent of the contents of SMB3.1.1 POSIX open context response */
|
||||||
struct create_posix_rsp {
|
struct create_posix_rsp {
|
||||||
__le32 nlink;
|
u32 nlink;
|
||||||
__le32 reparse_tag;
|
u32 reparse_tag;
|
||||||
__le32 mode;
|
u32 mode;
|
||||||
/*
|
struct cifs_sid owner; /* var-sized on the wire */
|
||||||
* var sized owner SID
|
struct cifs_sid group; /* var-sized on the wire */
|
||||||
* var sized group SID
|
|
||||||
*/
|
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -139,6 +139,7 @@ extern int SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon);
|
|||||||
extern int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms,
|
extern int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms,
|
||||||
__le16 *path, __u8 *oplock,
|
__le16 *path, __u8 *oplock,
|
||||||
struct smb2_file_all_info *buf,
|
struct smb2_file_all_info *buf,
|
||||||
|
struct create_posix_rsp *posix,
|
||||||
struct kvec *err_iov, int *resp_buftype);
|
struct kvec *err_iov, int *resp_buftype);
|
||||||
extern int SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
|
extern int SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
|
||||||
__u8 *oplock, struct cifs_open_parms *oparms,
|
__u8 *oplock, struct cifs_open_parms *oparms,
|
||||||
@ -252,7 +253,8 @@ extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *,
|
|||||||
extern void smb2_parse_contexts(struct TCP_Server_Info *server,
|
extern void smb2_parse_contexts(struct TCP_Server_Info *server,
|
||||||
struct smb2_create_rsp *rsp,
|
struct smb2_create_rsp *rsp,
|
||||||
unsigned int *epoch, char *lease_key,
|
unsigned int *epoch, char *lease_key,
|
||||||
__u8 *oplock, struct smb2_file_all_info *buf);
|
__u8 *oplock, struct smb2_file_all_info *buf,
|
||||||
|
struct create_posix_rsp *posix);
|
||||||
extern int smb3_encryption_required(const struct cifs_tcon *tcon);
|
extern int smb3_encryption_required(const struct cifs_tcon *tcon);
|
||||||
extern int smb2_validate_iov(unsigned int offset, unsigned int buffer_length,
|
extern int smb2_validate_iov(unsigned int offset, unsigned int buffer_length,
|
||||||
struct kvec *iov, unsigned int min_buf_size);
|
struct kvec *iov, unsigned int min_buf_size);
|
||||||
@ -274,4 +276,5 @@ extern int smb2_query_info_compound(const unsigned int xid,
|
|||||||
struct cifs_sb_info *cifs_sb);
|
struct cifs_sb_info *cifs_sb);
|
||||||
int posix_info_parse(const void *beg, const void *end,
|
int posix_info_parse(const void *beg, const void *end,
|
||||||
struct smb2_posix_info_parsed *out);
|
struct smb2_posix_info_parsed *out);
|
||||||
|
int posix_info_sid_size(const void *beg, const void *end);
|
||||||
#endif /* _SMB2PROTO_H */
|
#endif /* _SMB2PROTO_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user