[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:
Steve French 2008-05-15 06:20:02 +00:00
parent f9ddcca4cf
commit c2cf07d591
4 changed files with 76 additions and 93 deletions

View file

@ -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,

View file

@ -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)

View file

@ -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 */

View file

@ -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;