[CIFS] Finishup DFS code
Fixup GetDFSRefer to prepare for cleanup of SMB response processing Fix build warning in link.c Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
parent
f9ddcca4cf
commit
c2cf07d591
4 changed files with 76 additions and 93 deletions
|
@ -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,
|
||||||
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,
|
||||||
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,
|
||||||
(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? */
|
/* BB Also check if enough total bytes returned? */
|
||||||
if (rc || (pSMBr->ByteCount < 17))
|
if (rc || (pSMBr->ByteCount < 17))
|
||||||
rc = -EIO; /* bad smb */
|
rc = -EIO; /* bad smb */
|
||||||
else {
|
else {
|
||||||
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
||||||
__u16 data_count = le16_to_cpu(pSMBr->t2.DataCount);
|
__u16 data_count = le16_to_cpu(pSMBr->t2.DataCount);
|
||||||
|
|
||||||
cFYI(1,
|
cFYI(1, ("Decoding GetDFSRefer response BCC: %d Offset %d",
|
||||||
("Decoding GetDFSRefer response BCC: %d Offset %d",
|
pSMBr->ByteCount, data_offset));
|
||||||
pSMBr->ByteCount, data_offset));
|
referrals =
|
||||||
referrals =
|
(struct dfs_referral_level_3 *)
|
||||||
(struct dfs_referral_level_3 *)
|
(8 /* sizeof start of data block */ +
|
||||||
(8 /* sizeof start of data block */ +
|
data_offset +
|
||||||
data_offset +
|
(char *) &pSMBr->hdr.Protocol);
|
||||||
(char *) &pSMBr->hdr.Protocol);
|
cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n"
|
||||||
cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n"
|
"for referral one refer size: 0x%x srv "
|
||||||
"for referral one refer size: 0x%x srv "
|
"type: 0x%x refer flags: 0x%x ttl: 0x%x",
|
||||||
"type: 0x%x refer flags: 0x%x ttl: 0x%x",
|
le16_to_cpu(pSMBr->NumberOfReferrals),
|
||||||
le16_to_cpu(pSMBr->NumberOfReferrals),
|
le16_to_cpu(pSMBr->DFSFlags),
|
||||||
le16_to_cpu(pSMBr->DFSFlags),
|
le16_to_cpu(referrals->ReferralSize),
|
||||||
le16_to_cpu(referrals->ReferralSize),
|
le16_to_cpu(referrals->ServerType),
|
||||||
le16_to_cpu(referrals->ServerType),
|
le16_to_cpu(referrals->ReferralFlags),
|
||||||
le16_to_cpu(referrals->ReferralFlags),
|
le16_to_cpu(referrals->TimeToLive)));
|
||||||
le16_to_cpu(referrals->TimeToLive)));
|
/* BB This field is actually two bytes in from start of
|
||||||
/* BB This field is actually two bytes in from start of
|
data block so we could do safety check that DataBlock
|
||||||
data block so we could do safety check that DataBlock
|
begins at address of pSMBr->NumberOfReferrals */
|
||||||
begins at address of pSMBr->NumberOfReferrals */
|
*num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
|
||||||
*number_of_UNC_in_array =
|
|
||||||
le16_to_cpu(pSMBr->NumberOfReferrals);
|
|
||||||
|
|
||||||
/* BB Fix below so can return more than one referral */
|
/* BB Fix below so can return more than one referral */
|
||||||
if (*number_of_UNC_in_array > 1)
|
if (*num_of_nodes > 1)
|
||||||
*number_of_UNC_in_array = 1;
|
*num_of_nodes = 1;
|
||||||
|
|
||||||
/* get the length of the strings describing refs */
|
/* get the length of the strings describing refs */
|
||||||
name_len = 0;
|
name_len = 0;
|
||||||
for (i = 0; i < *number_of_UNC_in_array; i++) {
|
for (i = 0; i < *num_of_nodes; i++) {
|
||||||
/* make sure that DfsPathOffset not past end */
|
/* make sure that DfsPathOffset not past end */
|
||||||
__u16 offset =
|
__u16 offset = le16_to_cpu(referrals->DfsPathOffset);
|
||||||
le16_to_cpu(referrals->DfsPathOffset);
|
if (offset > data_count) {
|
||||||
if (offset > data_count) {
|
/* if invalid referral, stop here and do
|
||||||
/* if invalid referral, stop here and do
|
not try to copy any more */
|
||||||
not try to copy any more */
|
*num_of_nodes = i;
|
||||||
*number_of_UNC_in_array = i;
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
temp = ((char *)referrals) + offset;
|
|
||||||
|
|
||||||
if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
|
|
||||||
name_len += UniStrnlen((wchar_t *)temp,
|
|
||||||
data_count);
|
|
||||||
} else {
|
|
||||||
name_len += strnlen(temp, data_count);
|
|
||||||
}
|
|
||||||
referrals++;
|
|
||||||
/* BB add check that referral pointer does
|
|
||||||
not fall off end PDU */
|
|
||||||
}
|
}
|
||||||
/* BB add check for name_len bigger than bcc */
|
temp = ((char *)referrals) + offset;
|
||||||
*targetUNCs =
|
|
||||||
kmalloc(name_len+1+(*number_of_UNC_in_array),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (*targetUNCs == NULL) {
|
|
||||||
rc = -ENOMEM;
|
|
||||||
goto GetDFSRefExit;
|
|
||||||
}
|
|
||||||
/* copy the ref strings */
|
|
||||||
referrals = (struct dfs_referral_level_3 *)
|
|
||||||
(8 /* sizeof data hdr */ + data_offset +
|
|
||||||
(char *) &pSMBr->hdr.Protocol);
|
|
||||||
|
|
||||||
for (i = 0; i < *number_of_UNC_in_array; i++) {
|
if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
|
||||||
temp = ((char *)referrals) +
|
name_len += UniStrnlen((wchar_t *)temp,
|
||||||
le16_to_cpu(referrals->DfsPathOffset);
|
data_count);
|
||||||
if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
|
} else {
|
||||||
cifs_strfromUCS_le(*targetUNCs,
|
name_len += strnlen(temp, data_count);
|
||||||
(__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,
|
||||||
{
|
{
|
||||||
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,
|
||||||
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)
|
||||||
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;
|
||||||
|
|
Loading…
Reference in a new issue