diff options
Diffstat (limited to 'fs/cifs/sess.c')
-rw-r--r-- | fs/cifs/sess.c | 103 |
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 | ||
77 | static void | ||
78 | unicode_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 | |||
100 | static 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 | |||
78 | static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, | 123 | static 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)); |