Commit c2cf07d5 authored by Steve French's avatar Steve French

[CIFS] Finishup DFS code

Fixup GetDFSRefer to prepare for cleanup of SMB response processing
Fix build warning in link.c
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent f9ddcca4
...@@ -146,8 +146,8 @@ extern int CIFSSMBUnixQPathInfo(const int xid, ...@@ -146,8 +146,8 @@ extern int CIFSSMBUnixQPathInfo(const int xid,
extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
const unsigned char *searchName, const unsigned char *searchName,
unsigned char **targetUNCs, struct dfs_info3_param **target_nodes,
unsigned int *number_of_UNC_in_array, unsigned int *number_of_nodes_in_array,
const struct nls_table *nls_codepage, int remap); const struct nls_table *nls_codepage, int remap);
extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
......
...@@ -3870,8 +3870,8 @@ CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, ...@@ -3870,8 +3870,8 @@ CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
int int
CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
const unsigned char *searchName, const unsigned char *searchName,
unsigned char **targetUNCs, struct dfs_info3_param **target_nodes,
unsigned int *number_of_UNC_in_array, unsigned int *num_of_nodes,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
{ {
/* TRANS2_GET_DFS_REFERRAL */ /* TRANS2_GET_DFS_REFERRAL */
...@@ -3884,8 +3884,8 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, ...@@ -3884,8 +3884,8 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
unsigned int i; unsigned int i;
char *temp; char *temp;
__u16 params, byte_count; __u16 params, byte_count;
*number_of_UNC_in_array = 0; *num_of_nodes = 0;
*targetUNCs = NULL; *target_nodes = NULL;
cFYI(1, ("In GetDFSRefer the path %s", searchName)); cFYI(1, ("In GetDFSRefer the path %s", searchName));
if (ses == NULL) if (ses == NULL)
...@@ -3955,99 +3955,84 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, ...@@ -3955,99 +3955,84 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1, ("Send error in GetDFSRefer = %d", rc)); cFYI(1, ("Send error in GetDFSRefer = %d", rc));
} else { /* decode response */ goto GetDFSRefExit;
/* BB Add logic to parse referrals here */ }
rc = validate_t2((struct smb_t2_rsp *)pSMBr); rc = validate_t2((struct smb_t2_rsp *)pSMBr);
/* BB Also check if enough total bytes returned? */
if (rc || (pSMBr->ByteCount < 17))
rc = -EIO; /* bad smb */
else {
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
__u16 data_count = le16_to_cpu(pSMBr->t2.DataCount);
cFYI(1,
("Decoding GetDFSRefer response BCC: %d Offset %d",
pSMBr->ByteCount, data_offset));
referrals =
(struct dfs_referral_level_3 *)
(8 /* sizeof start of data block */ +
data_offset +
(char *) &pSMBr->hdr.Protocol);
cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n"
"for referral one refer size: 0x%x srv "
"type: 0x%x refer flags: 0x%x ttl: 0x%x",
le16_to_cpu(pSMBr->NumberOfReferrals),
le16_to_cpu(pSMBr->DFSFlags),
le16_to_cpu(referrals->ReferralSize),
le16_to_cpu(referrals->ServerType),
le16_to_cpu(referrals->ReferralFlags),
le16_to_cpu(referrals->TimeToLive)));
/* BB This field is actually two bytes in from start of
data block so we could do safety check that DataBlock
begins at address of pSMBr->NumberOfReferrals */
*number_of_UNC_in_array =
le16_to_cpu(pSMBr->NumberOfReferrals);
/* BB Fix below so can return more than one referral */
if (*number_of_UNC_in_array > 1)
*number_of_UNC_in_array = 1;
/* get the length of the strings describing refs */
name_len = 0;
for (i = 0; i < *number_of_UNC_in_array; i++) {
/* make sure that DfsPathOffset not past end */
__u16 offset =
le16_to_cpu(referrals->DfsPathOffset);
if (offset > data_count) {
/* if invalid referral, stop here and do
not try to copy any more */
*number_of_UNC_in_array = i;
break;
}
temp = ((char *)referrals) + offset;
if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { /* BB Also check if enough total bytes returned? */
name_len += UniStrnlen((wchar_t *)temp, if (rc || (pSMBr->ByteCount < 17))
data_count); rc = -EIO; /* bad smb */
} else { else {
name_len += strnlen(temp, data_count); __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
} __u16 data_count = le16_to_cpu(pSMBr->t2.DataCount);
referrals++;
/* BB add check that referral pointer does cFYI(1, ("Decoding GetDFSRefer response BCC: %d Offset %d",
not fall off end PDU */ pSMBr->ByteCount, data_offset));
} referrals =
/* BB add check for name_len bigger than bcc */ (struct dfs_referral_level_3 *)
*targetUNCs = (8 /* sizeof start of data block */ +
kmalloc(name_len+1+(*number_of_UNC_in_array), data_offset +
GFP_KERNEL); (char *) &pSMBr->hdr.Protocol);
if (*targetUNCs == NULL) { cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n"
rc = -ENOMEM; "for referral one refer size: 0x%x srv "
goto GetDFSRefExit; "type: 0x%x refer flags: 0x%x ttl: 0x%x",
le16_to_cpu(pSMBr->NumberOfReferrals),
le16_to_cpu(pSMBr->DFSFlags),
le16_to_cpu(referrals->ReferralSize),
le16_to_cpu(referrals->ServerType),
le16_to_cpu(referrals->ReferralFlags),
le16_to_cpu(referrals->TimeToLive)));
/* BB This field is actually two bytes in from start of
data block so we could do safety check that DataBlock
begins at address of pSMBr->NumberOfReferrals */
*num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
/* BB Fix below so can return more than one referral */
if (*num_of_nodes > 1)
*num_of_nodes = 1;
/* get the length of the strings describing refs */
name_len = 0;
for (i = 0; i < *num_of_nodes; i++) {
/* make sure that DfsPathOffset not past end */
__u16 offset = le16_to_cpu(referrals->DfsPathOffset);
if (offset > data_count) {
/* if invalid referral, stop here and do
not try to copy any more */
*num_of_nodes = i;
break;
} }
/* copy the ref strings */ temp = ((char *)referrals) + offset;
referrals = (struct dfs_referral_level_3 *)
(8 /* sizeof data hdr */ + data_offset + if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
(char *) &pSMBr->hdr.Protocol); name_len += UniStrnlen((wchar_t *)temp,
data_count);
for (i = 0; i < *number_of_UNC_in_array; i++) { } else {
temp = ((char *)referrals) + name_len += strnlen(temp, data_count);
le16_to_cpu(referrals->DfsPathOffset);
if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
cifs_strfromUCS_le(*targetUNCs,
(__le16 *) temp,
name_len,
nls_codepage);
} else {
strncpy(*targetUNCs, temp, name_len);
}
/* BB update target_uncs pointers */
referrals++;
} }
temp = *targetUNCs; referrals++;
temp[name_len] = 0; /* BB add check that referral pointer does
not fall off end PDU */
}
/* BB add check for name_len bigger than bcc */
*target_nodes =
kmalloc(name_len+1+(*num_of_nodes),
GFP_KERNEL);
if (*target_nodes == NULL) {
rc = -ENOMEM;
goto GetDFSRefExit;
} }
referrals = (struct dfs_referral_level_3 *)
(8 /* sizeof data hdr */ + data_offset +
(char *) &pSMBr->hdr.Protocol);
for (i = 0; i < *num_of_nodes; i++) {
temp = ((char *)referrals) +
le16_to_cpu(referrals->DfsPathOffset);
/* BB update target_uncs pointers */
referrals++;
}
} }
GetDFSRefExit: GetDFSRefExit:
if (pSMB) if (pSMB)
......
...@@ -1425,7 +1425,6 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, ...@@ -1425,7 +1425,6 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
{ {
char *temp_unc; char *temp_unc;
int rc = 0; int rc = 0;
unsigned char *targetUNCs;
*pnum_referrals = 0; *pnum_referrals = 0;
*preferrals = NULL; *preferrals = NULL;
...@@ -1448,7 +1447,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, ...@@ -1448,7 +1447,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
kfree(temp_unc); kfree(temp_unc);
} }
if (rc == 0) if (rc == 0)
rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, &targetUNCs, rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
pnum_referrals, nls_codepage, remap); pnum_referrals, nls_codepage, remap);
/* BB map targetUNCs to dfs_info3 structures, here or /* BB map targetUNCs to dfs_info3 structures, here or
in CIFSGetDFSRefer BB */ in CIFSGetDFSRefer BB */
......
...@@ -234,7 +234,6 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) ...@@ -234,7 +234,6 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
char *full_path = NULL; char *full_path = NULL;
char *tmp_path = NULL;
char *tmpbuffer; char *tmpbuffer;
int len; int len;
__u16 fid; __u16 fid;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment