aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifsproto.h4
-rw-r--r--fs/cifs/cifssmb.c169
-rw-r--r--fs/cifs/connect.c3
-rw-r--r--fs/cifs/link.c1
4 files changed, 80 insertions, 97 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 845b18e1abe5..b9f5e935f821 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -146,8 +146,8 @@ extern int CIFSSMBUnixQPathInfo(const int xid,
146 146
147extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, 147extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
148 const unsigned char *searchName, 148 const unsigned char *searchName,
149 unsigned char **targetUNCs, 149 struct dfs_info3_param **target_nodes,
150 unsigned int *number_of_UNC_in_array, 150 unsigned int *number_of_nodes_in_array,
151 const struct nls_table *nls_codepage, int remap); 151 const struct nls_table *nls_codepage, int remap);
152 152
153extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, 153extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 9c04ad404553..fc297383cb0e 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -3870,8 +3870,8 @@ GetInodeNumOut:
3870int 3870int
3871CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, 3871CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
3872 const unsigned char *searchName, 3872 const unsigned char *searchName,
3873 unsigned char **targetUNCs, 3873 struct dfs_info3_param **target_nodes,
3874 unsigned int *number_of_UNC_in_array, 3874 unsigned int *num_of_nodes,
3875 const struct nls_table *nls_codepage, int remap) 3875 const struct nls_table *nls_codepage, int remap)
3876{ 3876{
3877/* TRANS2_GET_DFS_REFERRAL */ 3877/* TRANS2_GET_DFS_REFERRAL */
@@ -3884,8 +3884,8 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
3884 unsigned int i; 3884 unsigned int i;
3885 char *temp; 3885 char *temp;
3886 __u16 params, byte_count; 3886 __u16 params, byte_count;
3887 *number_of_UNC_in_array = 0; 3887 *num_of_nodes = 0;
3888 *targetUNCs = NULL; 3888 *target_nodes = NULL;
3889 3889
3890 cFYI(1, ("In GetDFSRefer the path %s", searchName)); 3890 cFYI(1, ("In GetDFSRefer the path %s", searchName));
3891 if (ses == NULL) 3891 if (ses == NULL)
@@ -3955,99 +3955,84 @@ getDFSRetry:
3955 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3955 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3956 if (rc) { 3956 if (rc) {
3957 cFYI(1, ("Send error in GetDFSRefer = %d", rc)); 3957 cFYI(1, ("Send error in GetDFSRefer = %d", rc));
3958 } else { /* decode response */ 3958 goto GetDFSRefExit;
3959/* BB Add logic to parse referrals here */ 3959 }
3960 rc = validate_t2((struct smb_t2_rsp *)pSMBr); 3960 rc = validate_t2((struct smb_t2_rsp *)pSMBr);
3961
3962 /* BB Also check if enough total bytes returned? */
3963 if (rc || (pSMBr->ByteCount < 17))
3964 rc = -EIO; /* bad smb */
3965 else {
3966 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
3967 __u16 data_count = le16_to_cpu(pSMBr->t2.DataCount);
3968
3969 cFYI(1,
3970 ("Decoding GetDFSRefer response BCC: %d Offset %d",
3971 pSMBr->ByteCount, data_offset));
3972 referrals =
3973 (struct dfs_referral_level_3 *)
3974 (8 /* sizeof start of data block */ +
3975 data_offset +
3976 (char *) &pSMBr->hdr.Protocol);
3977 cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n"
3978 "for referral one refer size: 0x%x srv "
3979 "type: 0x%x refer flags: 0x%x ttl: 0x%x",
3980 le16_to_cpu(pSMBr->NumberOfReferrals),
3981 le16_to_cpu(pSMBr->DFSFlags),
3982 le16_to_cpu(referrals->ReferralSize),
3983 le16_to_cpu(referrals->ServerType),
3984 le16_to_cpu(referrals->ReferralFlags),
3985 le16_to_cpu(referrals->TimeToLive)));
3986 /* BB This field is actually two bytes in from start of
3987 data block so we could do safety check that DataBlock
3988 begins at address of pSMBr->NumberOfReferrals */
3989 *number_of_UNC_in_array =
3990 le16_to_cpu(pSMBr->NumberOfReferrals);
3991
3992 /* BB Fix below so can return more than one referral */
3993 if (*number_of_UNC_in_array > 1)
3994 *number_of_UNC_in_array = 1;
3995
3996 /* get the length of the strings describing refs */
3997 name_len = 0;
3998 for (i = 0; i < *number_of_UNC_in_array; i++) {
3999 /* make sure that DfsPathOffset not past end */
4000 __u16 offset =
4001 le16_to_cpu(referrals->DfsPathOffset);
4002 if (offset > data_count) {
4003 /* if invalid referral, stop here and do
4004 not try to copy any more */
4005 *number_of_UNC_in_array = i;
4006 break;
4007 }
4008 temp = ((char *)referrals) + offset;
4009 3961
4010 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { 3962 /* BB Also check if enough total bytes returned? */
4011 name_len += UniStrnlen((wchar_t *)temp, 3963 if (rc || (pSMBr->ByteCount < 17))
4012 data_count); 3964 rc = -EIO; /* bad smb */
4013 } else { 3965 else {
4014 name_len += strnlen(temp, data_count); 3966 __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
4015 } 3967 __u16 data_count = le16_to_cpu(pSMBr->t2.DataCount);
4016 referrals++; 3968
4017 /* BB add check that referral pointer does 3969 cFYI(1, ("Decoding GetDFSRefer response BCC: %d Offset %d",
4018 not fall off end PDU */ 3970 pSMBr->ByteCount, data_offset));
4019 } 3971 referrals =
4020 /* BB add check for name_len bigger than bcc */ 3972 (struct dfs_referral_level_3 *)
4021 *targetUNCs = 3973 (8 /* sizeof start of data block */ +
4022 kmalloc(name_len+1+(*number_of_UNC_in_array), 3974 data_offset +
4023 GFP_KERNEL); 3975 (char *) &pSMBr->hdr.Protocol);
4024 if (*targetUNCs == NULL) { 3976 cFYI(1, ("num_referrals: %d dfs flags: 0x%x ... \n"
4025 rc = -ENOMEM; 3977 "for referral one refer size: 0x%x srv "
4026 goto GetDFSRefExit; 3978 "type: 0x%x refer flags: 0x%x ttl: 0x%x",
3979 le16_to_cpu(pSMBr->NumberOfReferrals),
3980 le16_to_cpu(pSMBr->DFSFlags),
3981 le16_to_cpu(referrals->ReferralSize),
3982 le16_to_cpu(referrals->ServerType),
3983 le16_to_cpu(referrals->ReferralFlags),
3984 le16_to_cpu(referrals->TimeToLive)));
3985 /* BB This field is actually two bytes in from start of
3986 data block so we could do safety check that DataBlock
3987 begins at address of pSMBr->NumberOfReferrals */
3988 *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
3989
3990 /* BB Fix below so can return more than one referral */
3991 if (*num_of_nodes > 1)
3992 *num_of_nodes = 1;
3993
3994 /* get the length of the strings describing refs */
3995 name_len = 0;
3996 for (i = 0; i < *num_of_nodes; i++) {
3997 /* make sure that DfsPathOffset not past end */
3998 __u16 offset = le16_to_cpu(referrals->DfsPathOffset);
3999 if (offset > data_count) {
4000 /* if invalid referral, stop here and do
4001 not try to copy any more */
4002 *num_of_nodes = i;
4003 break;
4027 } 4004 }
4028 /* copy the ref strings */ 4005 temp = ((char *)referrals) + offset;
4029 referrals = (struct dfs_referral_level_3 *) 4006
4030 (8 /* sizeof data hdr */ + data_offset + 4007 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
4031 (char *) &pSMBr->hdr.Protocol); 4008 name_len += UniStrnlen((wchar_t *)temp,
4032 4009 data_count);
4033 for (i = 0; i < *number_of_UNC_in_array; i++) { 4010 } else {
4034 temp = ((char *)referrals) + 4011 name_len += strnlen(temp, data_count);
4035 le16_to_cpu(referrals->DfsPathOffset);
4036 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
4037 cifs_strfromUCS_le(*targetUNCs,
4038 (__le16 *) temp,
4039 name_len,
4040 nls_codepage);
4041 } else {
4042 strncpy(*targetUNCs, temp, name_len);
4043 }
4044 /* BB update target_uncs pointers */
4045 referrals++;
4046 } 4012 }
4047 temp = *targetUNCs; 4013 referrals++;
4048 temp[name_len] = 0; 4014 /* BB add check that referral pointer does
4015 not fall off end PDU */
4016 }
4017 /* BB add check for name_len bigger than bcc */
4018 *target_nodes =
4019 kmalloc(name_len+1+(*num_of_nodes),
4020 GFP_KERNEL);
4021 if (*target_nodes == NULL) {
4022 rc = -ENOMEM;
4023 goto GetDFSRefExit;
4049 } 4024 }
4050 4025
4026 referrals = (struct dfs_referral_level_3 *)
4027 (8 /* sizeof data hdr */ + data_offset +
4028 (char *) &pSMBr->hdr.Protocol);
4029
4030 for (i = 0; i < *num_of_nodes; i++) {
4031 temp = ((char *)referrals) +
4032 le16_to_cpu(referrals->DfsPathOffset);
4033 /* BB update target_uncs pointers */
4034 referrals++;
4035 }
4051 } 4036 }
4052GetDFSRefExit: 4037GetDFSRefExit:
4053 if (pSMB) 4038 if (pSMB)
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index d5747e30f1c9..c397fcfd9f1a 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1425,7 +1425,6 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1425{ 1425{
1426 char *temp_unc; 1426 char *temp_unc;
1427 int rc = 0; 1427 int rc = 0;
1428 unsigned char *targetUNCs;
1429 1428
1430 *pnum_referrals = 0; 1429 *pnum_referrals = 0;
1431 *preferrals = NULL; 1430 *preferrals = NULL;
@@ -1448,7 +1447,7 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1448 kfree(temp_unc); 1447 kfree(temp_unc);
1449 } 1448 }
1450 if (rc == 0) 1449 if (rc == 0)
1451 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, &targetUNCs, 1450 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1452 pnum_referrals, nls_codepage, remap); 1451 pnum_referrals, nls_codepage, remap);
1453 /* BB map targetUNCs to dfs_info3 structures, here or 1452 /* BB map targetUNCs to dfs_info3 structures, here or
1454 in CIFSGetDFSRefer BB */ 1453 in CIFSGetDFSRefer BB */
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 316f9830ce3b..63f644000ce5 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -234,7 +234,6 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
234 struct cifs_sb_info *cifs_sb; 234 struct cifs_sb_info *cifs_sb;
235 struct cifsTconInfo *pTcon; 235 struct cifsTconInfo *pTcon;
236 char *full_path = NULL; 236 char *full_path = NULL;
237 char *tmp_path = NULL;
238 char *tmpbuffer; 237 char *tmpbuffer;
239 int len; 238 int len;
240 __u16 fid; 239 __u16 fid;