Skip to content

Commit 69dda30

Browse files
aaptelsmfrench
authored andcommitted
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 <[email protected]> Signed-off-by: Steve French <[email protected]> Reviewed-by: Paulo Alcantara (SUSE) <[email protected]>
1 parent 3d519bd commit 69dda30

File tree

6 files changed

+66
-35
lines changed

6 files changed

+66
-35
lines changed

fs/cifs/link.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
416416
}
417417

418418
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, pfile_info, NULL,
419-
NULL);
419+
NULL, NULL);
420420
if (rc)
421421
goto qmf_out_open_fail;
422422

@@ -470,7 +470,7 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
470470
oparms.reconnect = false;
471471

472472
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
473-
NULL);
473+
NULL, NULL);
474474
if (rc) {
475475
kfree(utf16_path);
476476
return rc;

fs/cifs/smb2file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
6262
smb2_oplock = SMB2_OPLOCK_LEVEL_BATCH;
6363

6464
rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL,
65-
NULL);
65+
NULL, NULL);
6666
if (rc)
6767
goto out;
6868

fs/cifs/smb2ops.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
794794
tcon->crfid.has_lease = true;
795795
smb2_parse_contexts(server, o_rsp,
796796
&oparms.fid->epoch,
797-
oparms.fid->lease_key, &oplock, NULL);
797+
oparms.fid->lease_key, &oplock,
798+
NULL, NULL);
798799
} else
799800
goto oshr_exit;
800801

@@ -838,7 +839,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
838839

839840
if (no_cached_open)
840841
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
841-
NULL);
842+
NULL, NULL);
842843
else
843844
rc = open_shroot(xid, tcon, cifs_sb, &fid);
844845

@@ -878,7 +879,8 @@ smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
878879
oparms.fid = &fid;
879880
oparms.reconnect = false;
880881

881-
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL, NULL);
882+
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
883+
NULL, NULL);
882884
if (rc)
883885
return;
884886

@@ -913,7 +915,8 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
913915
oparms.fid = &fid;
914916
oparms.reconnect = false;
915917

916-
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL);
918+
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL,
919+
NULL);
917920
if (rc) {
918921
kfree(utf16_path);
919922
return rc;
@@ -2122,7 +2125,8 @@ smb3_notify(const unsigned int xid, struct file *pfile,
21222125
oparms.fid = &fid;
21232126
oparms.reconnect = false;
21242127

2125-
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL);
2128+
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL,
2129+
NULL);
21262130
if (rc)
21272131
goto notify_exit;
21282132

@@ -2543,7 +2547,8 @@ smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
25432547
oparms.fid = &fid;
25442548
oparms.reconnect = false;
25452549

2546-
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL, NULL);
2550+
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
2551+
NULL, NULL);
25472552
if (rc)
25482553
return rc;
25492554

@@ -3028,7 +3033,8 @@ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb,
30283033
oparms.fid = &fid;
30293034
oparms.reconnect = false;
30303035

3031-
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL);
3036+
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL,
3037+
NULL);
30323038
kfree(utf16_path);
30333039
if (!rc) {
30343040
rc = SMB2_query_acl(xid, tlink_tcon(tlink), fid.persistent_fid,
@@ -3086,7 +3092,8 @@ set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
30863092
oparms.fid = &fid;
30873093
oparms.reconnect = false;
30883094

3089-
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL);
3095+
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
3096+
NULL, NULL);
30903097
kfree(utf16_path);
30913098
if (!rc) {
30923099
rc = SMB2_set_acl(xid, tlink_tcon(tlink), fid.persistent_fid,

fs/cifs/smb2pdu.c

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1951,25 +1951,46 @@ parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *buf)
19511951
}
19521952

19531953
static void
1954-
parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *info)
1954+
parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *info,
1955+
struct create_posix_rsp *posix)
19551956
{
1956-
/* struct create_posix_rsp *posix = (struct create_posix_rsp *)cc; */
1957+
int sid_len;
1958+
u8 *beg = (u8 *)cc + le16_to_cpu(cc->DataOffset);
1959+
u8 *end = beg + le32_to_cpu(cc->DataLength);
1960+
u8 *sid;
19571961

1958-
/*
1959-
* TODO: Need to add parsing for the context and return. Can
1960-
* smb2_file_all_info hold POSIX data? Need to change the
1961-
* passed type from SMB2_open.
1962-
*/
1963-
printk_once(KERN_WARNING
1964-
"SMB3 3.11 POSIX response context not completed yet\n");
1962+
memset(posix, 0, sizeof(*posix));
1963+
1964+
posix->nlink = le32_to_cpu(*(__le32 *)(beg + 0));
1965+
posix->reparse_tag = le32_to_cpu(*(__le32 *)(beg + 4));
1966+
posix->mode = le32_to_cpu(*(__le32 *)(beg + 8));
1967+
1968+
sid = beg + 12;
1969+
sid_len = posix_info_sid_size(sid, end);
1970+
if (sid_len < 0) {
1971+
cifs_dbg(VFS, "bad owner sid in posix create response\n");
1972+
return;
1973+
}
1974+
memcpy(&posix->owner, sid, sid_len);
1975+
1976+
sid = sid + sid_len;
1977+
sid_len = posix_info_sid_size(sid, end);
1978+
if (sid_len < 0) {
1979+
cifs_dbg(VFS, "bad group sid in posix create response\n");
1980+
return;
1981+
}
1982+
memcpy(&posix->group, sid, sid_len);
19651983

1984+
cifs_dbg(FYI, "nlink=%d mode=%o reparse_tag=%x\n",
1985+
posix->nlink, posix->mode, posix->reparse_tag);
19661986
}
19671987

19681988
void
19691989
smb2_parse_contexts(struct TCP_Server_Info *server,
1970-
struct smb2_create_rsp *rsp,
1971-
unsigned int *epoch, char *lease_key, __u8 *oplock,
1972-
struct smb2_file_all_info *buf)
1990+
struct smb2_create_rsp *rsp,
1991+
unsigned int *epoch, char *lease_key, __u8 *oplock,
1992+
struct smb2_file_all_info *buf,
1993+
struct create_posix_rsp *posix)
19731994
{
19741995
char *data_offset;
19751996
struct create_context *cc;
@@ -1999,8 +2020,9 @@ smb2_parse_contexts(struct TCP_Server_Info *server,
19992020
strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4) == 0)
20002021
parse_query_id_ctxt(cc, buf);
20012022
else if ((le16_to_cpu(cc->NameLength) == 16)) {
2002-
if (memcmp(name, smb3_create_tag_posix, 16) == 0)
2003-
parse_posix_ctxt(cc, buf);
2023+
if (posix &&
2024+
memcmp(name, smb3_create_tag_posix, 16) == 0)
2025+
parse_posix_ctxt(cc, buf, posix);
20042026
}
20052027
/* else {
20062028
cifs_dbg(FYI, "Context not matched with len %d\n",
@@ -2725,6 +2747,7 @@ SMB2_open_free(struct smb_rqst *rqst)
27252747
int
27262748
SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
27272749
__u8 *oplock, struct smb2_file_all_info *buf,
2750+
struct create_posix_rsp *posix,
27282751
struct kvec *err_iov, int *buftype)
27292752
{
27302753
struct smb_rqst rqst;
@@ -2803,7 +2826,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
28032826

28042827

28052828
smb2_parse_contexts(server, rsp, &oparms->fid->epoch,
2806-
oparms->fid->lease_key, oplock, buf);
2829+
oparms->fid->lease_key, oplock, buf, posix);
28072830
creat_exit:
28082831
SMB2_open_free(&rqst);
28092832
free_rsp_buf(resp_buftype, rsp);
@@ -4302,7 +4325,7 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
43024325
return rc;
43034326
}
43044327

4305-
static int posix_info_sid_size(const void *beg, const void *end)
4328+
int posix_info_sid_size(const void *beg, const void *end)
43064329
{
43074330
size_t subauth;
43084331
int total;

fs/cifs/smb2pdu.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1605,13 +1605,11 @@ extern char smb2_padding[7];
16051605

16061606
/* equivalent of the contents of SMB3.1.1 POSIX open context response */
16071607
struct create_posix_rsp {
1608-
__le32 nlink;
1609-
__le32 reparse_tag;
1610-
__le32 mode;
1611-
/*
1612-
* var sized owner SID
1613-
* var sized group SID
1614-
*/
1608+
u32 nlink;
1609+
u32 reparse_tag;
1610+
u32 mode;
1611+
struct cifs_sid owner; /* var-sized on the wire */
1612+
struct cifs_sid group; /* var-sized on the wire */
16151613
} __packed;
16161614

16171615
/*

fs/cifs/smb2proto.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ extern int SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon);
139139
extern int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms,
140140
__le16 *path, __u8 *oplock,
141141
struct smb2_file_all_info *buf,
142+
struct create_posix_rsp *posix,
142143
struct kvec *err_iov, int *resp_buftype);
143144
extern int SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
144145
__u8 *oplock, struct cifs_open_parms *oparms,
@@ -252,7 +253,8 @@ extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *,
252253
extern void smb2_parse_contexts(struct TCP_Server_Info *server,
253254
struct smb2_create_rsp *rsp,
254255
unsigned int *epoch, char *lease_key,
255-
__u8 *oplock, struct smb2_file_all_info *buf);
256+
__u8 *oplock, struct smb2_file_all_info *buf,
257+
struct create_posix_rsp *posix);
256258
extern int smb3_encryption_required(const struct cifs_tcon *tcon);
257259
extern int smb2_validate_iov(unsigned int offset, unsigned int buffer_length,
258260
struct kvec *iov, unsigned int min_buf_size);
@@ -274,4 +276,5 @@ extern int smb2_query_info_compound(const unsigned int xid,
274276
struct cifs_sb_info *cifs_sb);
275277
int posix_info_parse(const void *beg, const void *end,
276278
struct smb2_posix_info_parsed *out);
279+
int posix_info_sid_size(const void *beg, const void *end);
277280
#endif /* _SMB2PROTO_H */

0 commit comments

Comments
 (0)