aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/sess.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/sess.c')
-rw-r--r--fs/cifs/sess.c103
1 files changed, 60 insertions, 43 deletions
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 892be9b4d1f3..899dc6078d9a 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -67,14 +67,59 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
67 pSMB->req.hdr.Flags2 |= SMBFLG2_DFS; 67 pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
68 capabilities |= CAP_DFS; 68 capabilities |= CAP_DFS;
69 } 69 }
70 if (ses->capabilities & CAP_UNIX) { 70 if (ses->capabilities & CAP_UNIX)
71 capabilities |= CAP_UNIX; 71 capabilities |= CAP_UNIX;
72 }
73 72
74 /* BB check whether to init vcnum BB */ 73 /* BB check whether to init vcnum BB */
75 return capabilities; 74 return capabilities;
76} 75}
77 76
77static void
78unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
79{
80 char *bcc_ptr = *pbcc_area;
81 int bytes_ret = 0;
82
83 /* Copy OS version */
84 bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
85 nls_cp);
86 bcc_ptr += 2 * bytes_ret;
87 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
88 32, nls_cp);
89 bcc_ptr += 2 * bytes_ret;
90 bcc_ptr += 2; /* trailing null */
91
92 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
93 32, nls_cp);
94 bcc_ptr += 2 * bytes_ret;
95 bcc_ptr += 2; /* trailing null */
96
97 *pbcc_area = bcc_ptr;
98}
99
100static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses,
101 const struct nls_table *nls_cp)
102{
103 char *bcc_ptr = *pbcc_area;
104 int bytes_ret = 0;
105
106 /* copy domain */
107 if (ses->domainName == NULL) {
108 /* Sending null domain better than using a bogus domain name (as
109 we did briefly in 2.6.18) since server will use its default */
110 *bcc_ptr = 0;
111 *(bcc_ptr+1) = 0;
112 bytes_ret = 0;
113 } else
114 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
115 256, nls_cp);
116 bcc_ptr += 2 * bytes_ret;
117 bcc_ptr += 2; /* account for null terminator */
118
119 *pbcc_area = bcc_ptr;
120}
121
122
78static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, 123static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
79 const struct nls_table *nls_cp) 124 const struct nls_table *nls_cp)
80{ 125{
@@ -100,32 +145,9 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
100 } 145 }
101 bcc_ptr += 2 * bytes_ret; 146 bcc_ptr += 2 * bytes_ret;
102 bcc_ptr += 2; /* account for null termination */ 147 bcc_ptr += 2; /* account for null termination */
103 /* copy domain */
104 if (ses->domainName == NULL) {
105 /* Sending null domain better than using a bogus domain name (as
106 we did briefly in 2.6.18) since server will use its default */
107 *bcc_ptr = 0;
108 *(bcc_ptr+1) = 0;
109 bytes_ret = 0;
110 } else
111 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
112 256, nls_cp);
113 bcc_ptr += 2 * bytes_ret;
114 bcc_ptr += 2; /* account for null terminator */
115
116 /* Copy OS version */
117 bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
118 nls_cp);
119 bcc_ptr += 2 * bytes_ret;
120 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
121 32, nls_cp);
122 bcc_ptr += 2 * bytes_ret;
123 bcc_ptr += 2; /* trailing null */
124 148
125 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS, 149 unicode_domain_string(&bcc_ptr, ses, nls_cp);
126 32, nls_cp); 150 unicode_oslm_strings(&bcc_ptr, nls_cp);
127 bcc_ptr += 2 * bytes_ret;
128 bcc_ptr += 2; /* trailing null */
129 151
130 *pbcc_area = bcc_ptr; 152 *pbcc_area = bcc_ptr;
131} 153}
@@ -203,14 +225,11 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
203 if (len >= words_left) 225 if (len >= words_left)
204 return rc; 226 return rc;
205 227
206 if (ses->serverOS) 228 kfree(ses->serverOS);
207 kfree(ses->serverOS);
208 /* UTF-8 string will not grow more than four times as big as UCS-16 */ 229 /* UTF-8 string will not grow more than four times as big as UCS-16 */
209 ses->serverOS = kzalloc(4 * len, GFP_KERNEL); 230 ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
210 if (ses->serverOS != NULL) { 231 if (ses->serverOS != NULL)
211 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, 232 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp);
212 nls_cp);
213 }
214 data += 2 * (len + 1); 233 data += 2 * (len + 1);
215 words_left -= len + 1; 234 words_left -= len + 1;
216 235
@@ -220,8 +239,7 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
220 if (len >= words_left) 239 if (len >= words_left)
221 return rc; 240 return rc;
222 241
223 if (ses->serverNOS) 242 kfree(ses->serverNOS);
224 kfree(ses->serverNOS);
225 ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */ 243 ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */
226 if (ses->serverNOS != NULL) { 244 if (ses->serverNOS != NULL) {
227 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, 245 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
@@ -240,8 +258,7 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
240 if (len > words_left) 258 if (len > words_left)
241 return rc; 259 return rc;
242 260
243 if (ses->serverDomain) 261 kfree(ses->serverDomain);
244 kfree(ses->serverDomain);
245 ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */ 262 ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */
246 if (ses->serverDomain != NULL) { 263 if (ses->serverDomain != NULL) {
247 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len, 264 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
@@ -271,8 +288,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
271 if (len >= bleft) 288 if (len >= bleft)
272 return rc; 289 return rc;
273 290
274 if (ses->serverOS) 291 kfree(ses->serverOS);
275 kfree(ses->serverOS);
276 292
277 ses->serverOS = kzalloc(len + 1, GFP_KERNEL); 293 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
278 if (ses->serverOS) 294 if (ses->serverOS)
@@ -289,8 +305,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
289 if (len >= bleft) 305 if (len >= bleft)
290 return rc; 306 return rc;
291 307
292 if (ses->serverNOS) 308 kfree(ses->serverNOS);
293 kfree(ses->serverNOS);
294 309
295 ses->serverNOS = kzalloc(len + 1, GFP_KERNEL); 310 ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
296 if (ses->serverNOS) 311 if (ses->serverNOS)
@@ -479,7 +494,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
479 if (ses->capabilities & CAP_UNICODE) { 494 if (ses->capabilities & CAP_UNICODE) {
480 if (iov[0].iov_len % 2) { 495 if (iov[0].iov_len % 2) {
481 *bcc_ptr = 0; 496 *bcc_ptr = 0;
482 } bcc_ptr++; 497 bcc_ptr++;
498 }
483 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); 499 unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
484 } else 500 } else
485 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); 501 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
@@ -497,7 +513,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
497 513
498 iov[1].iov_base = str_area; 514 iov[1].iov_base = str_area;
499 iov[1].iov_len = count; 515 iov[1].iov_len = count;
500 rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0); 516 rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type,
517 0 /* not long op */, 1 /* log NT STATUS if any */ );
501 /* SMB request buf freed in SendReceive2 */ 518 /* SMB request buf freed in SendReceive2 */
502 519
503 cFYI(1, ("ssetup rc from sendrecv2 is %d", rc)); 520 cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));