aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/Kconfig3
-rw-r--r--fs/cifs/cifsencrypt.c427
-rw-r--r--fs/cifs/cifsfs.c1
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsglob.h55
-rw-r--r--fs/cifs/cifspdu.h13
-rw-r--r--fs/cifs/cifsproto.h14
-rw-r--r--fs/cifs/cifssmb.c4
-rw-r--r--fs/cifs/connect.c51
-rw-r--r--fs/cifs/file.c57
-rw-r--r--fs/cifs/inode.c15
-rw-r--r--fs/cifs/misc.c2
-rw-r--r--fs/cifs/sess.c166
-rw-r--r--fs/cifs/transport.c6
14 files changed, 526 insertions, 290 deletions
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index 917b7d449bb2..0ed213970ced 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -2,6 +2,9 @@ config CIFS
2 tristate "CIFS support (advanced network filesystem, SMBFS successor)" 2 tristate "CIFS support (advanced network filesystem, SMBFS successor)"
3 depends on INET 3 depends on INET
4 select NLS 4 select NLS
5 select CRYPTO
6 select CRYPTO_MD5
7 select CRYPTO_ARC4
5 help 8 help
6 This is the client VFS module for the Common Internet File System 9 This is the client VFS module for the Common Internet File System
7 (CIFS) protocol which is the successor to the Server Message Block 10 (CIFS) protocol which is the successor to the Server Message Block
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 7ac0056294cf..f856732161ab 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -43,18 +43,32 @@ extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
43 unsigned char *p24); 43 unsigned char *p24);
44 44
45static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, 45static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
46 const struct session_key *key, char *signature) 46 struct TCP_Server_Info *server, char *signature)
47{ 47{
48 struct MD5Context context; 48 int rc;
49 49
50 if ((cifs_pdu == NULL) || (signature == NULL) || (key == NULL)) 50 if (cifs_pdu == NULL || signature == NULL || server == NULL)
51 return -EINVAL; 51 return -EINVAL;
52 52
53 cifs_MD5_init(&context); 53 if (!server->secmech.sdescmd5) {
54 cifs_MD5_update(&context, (char *)&key->data, key->len); 54 cERROR(1, "%s: Can't generate signature\n", __func__);
55 cifs_MD5_update(&context, cifs_pdu->Protocol, cifs_pdu->smb_buf_length); 55 return -1;
56 }
57
58 rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
59 if (rc) {
60 cERROR(1, "%s: Oould not init md5\n", __func__);
61 return rc;
62 }
63
64 crypto_shash_update(&server->secmech.sdescmd5->shash,
65 server->session_key.response, server->session_key.len);
66
67 crypto_shash_update(&server->secmech.sdescmd5->shash,
68 cifs_pdu->Protocol, cifs_pdu->smb_buf_length);
69
70 rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
56 71
57 cifs_MD5_final(signature, &context);
58 return 0; 72 return 0;
59} 73}
60 74
@@ -79,8 +93,7 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
79 server->sequence_number++; 93 server->sequence_number++;
80 spin_unlock(&GlobalMid_Lock); 94 spin_unlock(&GlobalMid_Lock);
81 95
82 rc = cifs_calculate_signature(cifs_pdu, &server->session_key, 96 rc = cifs_calculate_signature(cifs_pdu, server, smb_signature);
83 smb_signature);
84 if (rc) 97 if (rc)
85 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 98 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
86 else 99 else
@@ -90,16 +103,28 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
90} 103}
91 104
92static int cifs_calc_signature2(const struct kvec *iov, int n_vec, 105static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
93 const struct session_key *key, char *signature) 106 struct TCP_Server_Info *server, char *signature)
94{ 107{
95 struct MD5Context context;
96 int i; 108 int i;
109 int rc;
97 110
98 if ((iov == NULL) || (signature == NULL) || (key == NULL)) 111 if (iov == NULL || signature == NULL || server == NULL)
99 return -EINVAL; 112 return -EINVAL;
100 113
101 cifs_MD5_init(&context); 114 if (!server->secmech.sdescmd5) {
102 cifs_MD5_update(&context, (char *)&key->data, key->len); 115 cERROR(1, "%s: Can't generate signature\n", __func__);
116 return -1;
117 }
118
119 rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
120 if (rc) {
121 cERROR(1, "%s: Oould not init md5\n", __func__);
122 return rc;
123 }
124
125 crypto_shash_update(&server->secmech.sdescmd5->shash,
126 server->session_key.response, server->session_key.len);
127
103 for (i = 0; i < n_vec; i++) { 128 for (i = 0; i < n_vec; i++) {
104 if (iov[i].iov_len == 0) 129 if (iov[i].iov_len == 0)
105 continue; 130 continue;
@@ -112,18 +137,18 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
112 if (i == 0) { 137 if (i == 0) {
113 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */ 138 if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
114 break; /* nothing to sign or corrupt header */ 139 break; /* nothing to sign or corrupt header */
115 cifs_MD5_update(&context, iov[0].iov_base+4, 140 crypto_shash_update(&server->secmech.sdescmd5->shash,
116 iov[0].iov_len-4); 141 iov[i].iov_base + 4, iov[i].iov_len - 4);
117 } else 142 } else
118 cifs_MD5_update(&context, iov[i].iov_base, iov[i].iov_len); 143 crypto_shash_update(&server->secmech.sdescmd5->shash,
144 iov[i].iov_base, iov[i].iov_len);
119 } 145 }
120 146
121 cifs_MD5_final(signature, &context); 147 rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
122 148
123 return 0; 149 return rc;
124} 150}
125 151
126
127int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, 152int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
128 __u32 *pexpected_response_sequence_number) 153 __u32 *pexpected_response_sequence_number)
129{ 154{
@@ -146,8 +171,7 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
146 server->sequence_number++; 171 server->sequence_number++;
147 spin_unlock(&GlobalMid_Lock); 172 spin_unlock(&GlobalMid_Lock);
148 173
149 rc = cifs_calc_signature2(iov, n_vec, &server->session_key, 174 rc = cifs_calc_signature2(iov, n_vec, server, smb_signature);
150 smb_signature);
151 if (rc) 175 if (rc)
152 memset(cifs_pdu->Signature.SecuritySignature, 0, 8); 176 memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
153 else 177 else
@@ -157,14 +181,14 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
157} 181}
158 182
159int cifs_verify_signature(struct smb_hdr *cifs_pdu, 183int cifs_verify_signature(struct smb_hdr *cifs_pdu,
160 const struct session_key *session_key, 184 struct TCP_Server_Info *server,
161 __u32 expected_sequence_number) 185 __u32 expected_sequence_number)
162{ 186{
163 unsigned int rc; 187 unsigned int rc;
164 char server_response_sig[8]; 188 char server_response_sig[8];
165 char what_we_think_sig_should_be[20]; 189 char what_we_think_sig_should_be[20];
166 190
167 if (cifs_pdu == NULL || session_key == NULL) 191 if (cifs_pdu == NULL || server == NULL)
168 return -EINVAL; 192 return -EINVAL;
169 193
170 if (cifs_pdu->Command == SMB_COM_NEGOTIATE) 194 if (cifs_pdu->Command == SMB_COM_NEGOTIATE)
@@ -193,7 +217,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
193 cpu_to_le32(expected_sequence_number); 217 cpu_to_le32(expected_sequence_number);
194 cifs_pdu->Signature.Sequence.Reserved = 0; 218 cifs_pdu->Signature.Sequence.Reserved = 0;
195 219
196 rc = cifs_calculate_signature(cifs_pdu, session_key, 220 rc = cifs_calculate_signature(cifs_pdu, server,
197 what_we_think_sig_should_be); 221 what_we_think_sig_should_be);
198 222
199 if (rc) 223 if (rc)
@@ -209,18 +233,28 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
209 233
210} 234}
211 235
212/* We fill in key by putting in 40 byte array which was allocated by caller */ 236/* first calculate 24 bytes ntlm response and then 16 byte session key */
213int cifs_calculate_session_key(struct session_key *key, const char *rn, 237int setup_ntlm_response(struct cifsSesInfo *ses)
214 const char *password)
215{ 238{
216 char temp_key[16]; 239 unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
217 if ((key == NULL) || (rn == NULL)) 240 char temp_key[CIFS_SESS_KEY_SIZE];
241
242 if (!ses)
218 return -EINVAL; 243 return -EINVAL;
219 244
220 E_md4hash(password, temp_key); 245 ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
221 mdfour(key->data.ntlm, temp_key, 16); 246 if (!ses->auth_key.response) {
222 memcpy(key->data.ntlm+16, rn, CIFS_SESS_KEY_SIZE); 247 cERROR(1, "NTLM can't allocate (%u bytes) memory", temp_len);
223 key->len = 40; 248 return -ENOMEM;
249 }
250 ses->auth_key.len = temp_len;
251
252 SMBNTencrypt(ses->password, ses->server->cryptkey,
253 ses->auth_key.response + CIFS_SESS_KEY_SIZE);
254
255 E_md4hash(ses->password, temp_key);
256 mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
257
224 return 0; 258 return 0;
225} 259}
226 260
@@ -294,15 +328,15 @@ build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
294 * two times the unicode length of a server name + 328 * two times the unicode length of a server name +
295 * size of a timestamp (which is 8 bytes). 329 * size of a timestamp (which is 8 bytes).
296 */ 330 */
297 ses->tilen = size + 2 * (2 * dlen) + 2 * (2 * wlen) + 8; 331 ses->auth_key.len = size + 2 * (2 * dlen) + 2 * (2 * wlen) + 8;
298 ses->tiblob = kzalloc(ses->tilen, GFP_KERNEL); 332 ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL);
299 if (!ses->tiblob) { 333 if (!ses->auth_key.response) {
300 ses->tilen = 0; 334 ses->auth_key.len = 0;
301 cERROR(1, "Challenge target info allocation failure"); 335 cERROR(1, "Challenge target info allocation failure");
302 return -ENOMEM; 336 return -ENOMEM;
303 } 337 }
304 338
305 blobptr = ses->tiblob; 339 blobptr = ses->auth_key.response;
306 attrptr = (struct ntlmssp2_name *) blobptr; 340 attrptr = (struct ntlmssp2_name *) blobptr;
307 341
308 attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME); 342 attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME);
@@ -357,7 +391,7 @@ build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
357 * about target string i.e. for some, just user name might suffice. 391 * about target string i.e. for some, just user name might suffice.
358 */ 392 */
359static int 393static int
360find_domain_name(struct cifsSesInfo *ses) 394find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
361{ 395{
362 unsigned int attrsize; 396 unsigned int attrsize;
363 unsigned int type; 397 unsigned int type;
@@ -366,11 +400,11 @@ find_domain_name(struct cifsSesInfo *ses)
366 unsigned char *blobend; 400 unsigned char *blobend;
367 struct ntlmssp2_name *attrptr; 401 struct ntlmssp2_name *attrptr;
368 402
369 if (!ses->tilen || !ses->tiblob) 403 if (!ses->auth_key.len || !ses->auth_key.response)
370 return 0; 404 return 0;
371 405
372 blobptr = ses->tiblob; 406 blobptr = ses->auth_key.response;
373 blobend = ses->tiblob + ses->tilen; 407 blobend = blobptr + ses->auth_key.len;
374 408
375 while (blobptr + onesize < blobend) { 409 while (blobptr + onesize < blobend) {
376 attrptr = (struct ntlmssp2_name *) blobptr; 410 attrptr = (struct ntlmssp2_name *) blobptr;
@@ -386,16 +420,13 @@ find_domain_name(struct cifsSesInfo *ses)
386 if (!attrsize) 420 if (!attrsize)
387 break; 421 break;
388 if (!ses->domainName) { 422 if (!ses->domainName) {
389 struct nls_table *default_nls;
390 ses->domainName = 423 ses->domainName =
391 kmalloc(attrsize + 1, GFP_KERNEL); 424 kmalloc(attrsize + 1, GFP_KERNEL);
392 if (!ses->domainName) 425 if (!ses->domainName)
393 return -ENOMEM; 426 return -ENOMEM;
394 default_nls = load_nls_default();
395 cifs_from_ucs2(ses->domainName, 427 cifs_from_ucs2(ses->domainName,
396 (__le16 *)blobptr, attrsize, attrsize, 428 (__le16 *)blobptr, attrsize, attrsize,
397 default_nls, false); 429 nls_cp, false);
398 unload_nls(default_nls);
399 break; 430 break;
400 } 431 }
401 } 432 }
@@ -405,82 +436,136 @@ find_domain_name(struct cifsSesInfo *ses)
405 return 0; 436 return 0;
406} 437}
407 438
408static int calc_ntlmv2_hash(struct cifsSesInfo *ses, 439static int calc_ntlmv2_hash(struct cifsSesInfo *ses, char *ntlmv2_hash,
409 const struct nls_table *nls_cp) 440 const struct nls_table *nls_cp)
410{ 441{
411 int rc = 0; 442 int rc = 0;
412 int len; 443 int len;
413 char nt_hash[16]; 444 char nt_hash[CIFS_NTHASH_SIZE];
414 struct HMACMD5Context *pctxt;
415 wchar_t *user; 445 wchar_t *user;
416 wchar_t *domain; 446 wchar_t *domain;
447 wchar_t *server;
417 448
418 pctxt = kmalloc(sizeof(struct HMACMD5Context), GFP_KERNEL); 449 if (!ses->server->secmech.sdeschmacmd5) {
419 450 cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
420 if (pctxt == NULL) 451 return -1;
421 return -ENOMEM; 452 }
422 453
423 /* calculate md4 hash of password */ 454 /* calculate md4 hash of password */
424 E_md4hash(ses->password, nt_hash); 455 E_md4hash(ses->password, nt_hash);
425 456
426 /* convert Domainname to unicode and uppercase */ 457 crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash,
427 hmac_md5_init_limK_to_64(nt_hash, 16, pctxt); 458 CIFS_NTHASH_SIZE);
459
460 rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
461 if (rc) {
462 cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n");
463 return rc;
464 }
428 465
429 /* convert ses->userName to unicode and uppercase */ 466 /* convert ses->userName to unicode and uppercase */
430 len = strlen(ses->userName); 467 len = strlen(ses->userName);
431 user = kmalloc(2 + (len * 2), GFP_KERNEL); 468 user = kmalloc(2 + (len * 2), GFP_KERNEL);
432 if (user == NULL) 469 if (user == NULL) {
470 cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n");
471 rc = -ENOMEM;
433 goto calc_exit_2; 472 goto calc_exit_2;
473 }
434 len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); 474 len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp);
435 UniStrupr(user); 475 UniStrupr(user);
436 hmac_md5_update((char *)user, 2*len, pctxt); 476
477 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
478 (char *)user, 2 * len);
437 479
438 /* convert ses->domainName to unicode and uppercase */ 480 /* convert ses->domainName to unicode and uppercase */
439 if (ses->domainName) { 481 if (ses->domainName) {
440 len = strlen(ses->domainName); 482 len = strlen(ses->domainName);
441 483
442 domain = kmalloc(2 + (len * 2), GFP_KERNEL); 484 domain = kmalloc(2 + (len * 2), GFP_KERNEL);
443 if (domain == NULL) 485 if (domain == NULL) {
486 cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure");
487 rc = -ENOMEM;
444 goto calc_exit_1; 488 goto calc_exit_1;
489 }
445 len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len, 490 len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len,
446 nls_cp); 491 nls_cp);
447 /* the following line was removed since it didn't work well 492 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
448 with lower cased domain name that passed as an option. 493 (char *)domain, 2 * len);
449 Maybe converting the domain name earlier makes sense */
450 /* UniStrupr(domain); */
451
452 hmac_md5_update((char *)domain, 2*len, pctxt);
453
454 kfree(domain); 494 kfree(domain);
495 } else if (ses->serverName) {
496 len = strlen(ses->serverName);
497
498 server = kmalloc(2 + (len * 2), GFP_KERNEL);
499 if (server == NULL) {
500 cERROR(1, "calc_ntlmv2_hash: server mem alloc failure");
501 rc = -ENOMEM;
502 goto calc_exit_1;
503 }
504 len = cifs_strtoUCS((__le16 *)server, ses->serverName, len,
505 nls_cp);
506 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
507 (char *)server, 2 * len);
508 kfree(server);
455 } 509 }
510
511 rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
512 ntlmv2_hash);
513
456calc_exit_1: 514calc_exit_1:
457 kfree(user); 515 kfree(user);
458calc_exit_2: 516calc_exit_2:
459 /* BB FIXME what about bytes 24 through 40 of the signing key? 517 return rc;
460 compare with the NTLM example */ 518}
461 hmac_md5_final(ses->ntlmv2_hash, pctxt); 519
520static int
521CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash)
522{
523 int rc;
524 unsigned int offset = CIFS_SESS_KEY_SIZE + 8;
525
526 if (!ses->server->secmech.sdeschmacmd5) {
527 cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
528 return -1;
529 }
530
531 crypto_shash_setkey(ses->server->secmech.hmacmd5,
532 ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
533
534 rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
535 if (rc) {
536 cERROR(1, "CalcNTLMv2_response: could not init hmacmd5");
537 return rc;
538 }
539
540 if (ses->server->secType == RawNTLMSSP)
541 memcpy(ses->auth_key.response + offset,
542 ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
543 else
544 memcpy(ses->auth_key.response + offset,
545 ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
546 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
547 ses->auth_key.response + offset, ses->auth_key.len - offset);
548
549 rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
550 ses->auth_key.response + CIFS_SESS_KEY_SIZE);
462 551
463 kfree(pctxt);
464 return rc; 552 return rc;
465} 553}
466 554
555
467int 556int
468setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf, 557setup_ntlmv2_rsp(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
469 const struct nls_table *nls_cp)
470{ 558{
471 int rc; 559 int rc;
472 struct ntlmv2_resp *buf = (struct ntlmv2_resp *)resp_buf; 560 int baselen;
473 struct HMACMD5Context context; 561 unsigned int tilen;
474 562 struct ntlmv2_resp *buf;
475 buf->blob_signature = cpu_to_le32(0x00000101); 563 char ntlmv2_hash[16];
476 buf->reserved = 0; 564 unsigned char *tiblob = NULL; /* target info blob */
477 buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
478 get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
479 buf->reserved2 = 0;
480 565
481 if (ses->server->secType == RawNTLMSSP) { 566 if (ses->server->secType == RawNTLMSSP) {
482 if (!ses->domainName) { 567 if (!ses->domainName) {
483 rc = find_domain_name(ses); 568 rc = find_domain_name(ses, nls_cp);
484 if (rc) { 569 if (rc) {
485 cERROR(1, "error %d finding domain name", rc); 570 cERROR(1, "error %d finding domain name", rc);
486 goto setup_ntlmv2_rsp_ret; 571 goto setup_ntlmv2_rsp_ret;
@@ -490,51 +575,179 @@ setup_ntlmv2_rsp(struct cifsSesInfo *ses, char *resp_buf,
490 rc = build_avpair_blob(ses, nls_cp); 575 rc = build_avpair_blob(ses, nls_cp);
491 if (rc) { 576 if (rc) {
492 cERROR(1, "error %d building av pair blob", rc); 577 cERROR(1, "error %d building av pair blob", rc);
493 return rc; 578 goto setup_ntlmv2_rsp_ret;
494 } 579 }
495 } 580 }
496 581
497 /* calculate buf->ntlmv2_hash */ 582 baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp);
498 rc = calc_ntlmv2_hash(ses, nls_cp); 583 tilen = ses->auth_key.len;
584 tiblob = ses->auth_key.response;
585
586 ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL);
587 if (!ses->auth_key.response) {
588 rc = ENOMEM;
589 ses->auth_key.len = 0;
590 cERROR(1, "%s: Can't allocate auth blob", __func__);
591 goto setup_ntlmv2_rsp_ret;
592 }
593 ses->auth_key.len += baselen;
594
595 buf = (struct ntlmv2_resp *)
596 (ses->auth_key.response + CIFS_SESS_KEY_SIZE);
597 buf->blob_signature = cpu_to_le32(0x00000101);
598 buf->reserved = 0;
599 buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
600 get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
601 buf->reserved2 = 0;
602
603 memcpy(ses->auth_key.response + baselen, tiblob, tilen);
604
605 /* calculate ntlmv2_hash */
606 rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp);
499 if (rc) { 607 if (rc) {
500 cERROR(1, "could not get v2 hash rc %d", rc); 608 cERROR(1, "could not get v2 hash rc %d", rc);
501 goto setup_ntlmv2_rsp_ret; 609 goto setup_ntlmv2_rsp_ret;
502 } 610 }
503 CalcNTLMv2_response(ses, resp_buf); 611
612 /* calculate first part of the client response (CR1) */
613 rc = CalcNTLMv2_response(ses, ntlmv2_hash);
614 if (rc) {
615 cERROR(1, "Could not calculate CR1 rc: %d", rc);
616 goto setup_ntlmv2_rsp_ret;
617 }
504 618
505 /* now calculate the session key for NTLMv2 */ 619 /* now calculate the session key for NTLMv2 */
506 hmac_md5_init_limK_to_64(ses->ntlmv2_hash, 16, &context); 620 crypto_shash_setkey(ses->server->secmech.hmacmd5,
507 hmac_md5_update(resp_buf, 16, &context); 621 ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
508 hmac_md5_final(ses->auth_key.data.ntlmv2.key, &context); 622
623 rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
624 if (rc) {
625 cERROR(1, "%s: Could not init hmacmd5\n", __func__);
626 goto setup_ntlmv2_rsp_ret;
627 }
509 628
510 memcpy(&ses->auth_key.data.ntlmv2.resp, resp_buf, 629 crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
511 sizeof(struct ntlmv2_resp)); 630 ses->auth_key.response + CIFS_SESS_KEY_SIZE,
512 ses->auth_key.len = 16 + sizeof(struct ntlmv2_resp); 631 CIFS_HMAC_MD5_HASH_SIZE);
513 632
514 return 0; 633 rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
634 ses->auth_key.response);
515 635
516setup_ntlmv2_rsp_ret: 636setup_ntlmv2_rsp_ret:
517 kfree(ses->tiblob); 637 kfree(tiblob);
518 ses->tiblob = NULL;
519 ses->tilen = 0;
520 638
521 return rc; 639 return rc;
522} 640}
523 641
524void CalcNTLMv2_response(const struct cifsSesInfo *ses, 642int
525 char *v2_session_response) 643calc_seckey(struct cifsSesInfo *ses)
526{ 644{
527 struct HMACMD5Context context; 645 int rc;
528 /* rest of v2 struct already generated */ 646 struct crypto_blkcipher *tfm_arc4;
529 memcpy(v2_session_response + 8, ses->cryptKey, 8); 647 struct scatterlist sgin, sgout;
530 hmac_md5_init_limK_to_64(ses->ntlmv2_hash, 16, &context); 648 struct blkcipher_desc desc;
649 unsigned char sec_key[CIFS_SESS_KEY_SIZE]; /* a nonce */
650
651 get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE);
652
653 tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
654 if (!tfm_arc4 || IS_ERR(tfm_arc4)) {
655 cERROR(1, "could not allocate crypto API arc4\n");
656 return PTR_ERR(tfm_arc4);
657 }
531 658
532 hmac_md5_update(v2_session_response+8, 659 desc.tfm = tfm_arc4;
533 sizeof(struct ntlmv2_resp) - 8, &context);
534 660
535 if (ses->tilen) 661 crypto_blkcipher_setkey(tfm_arc4, ses->auth_key.response,
536 hmac_md5_update(ses->tiblob, ses->tilen, &context); 662 CIFS_SESS_KEY_SIZE);
537 663
538 hmac_md5_final(v2_session_response, &context); 664 sg_init_one(&sgin, sec_key, CIFS_SESS_KEY_SIZE);
539/* cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); */ 665 sg_init_one(&sgout, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
666
667 rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE);
668 if (rc) {
669 cERROR(1, "could not encrypt session key rc: %d\n", rc);
670 crypto_free_blkcipher(tfm_arc4);
671 return rc;
672 }
673
674 /* make secondary_key/nonce as session key */
675 memcpy(ses->auth_key.response, sec_key, CIFS_SESS_KEY_SIZE);
676 /* and make len as that of session key only */
677 ses->auth_key.len = CIFS_SESS_KEY_SIZE;
678
679 crypto_free_blkcipher(tfm_arc4);
680
681 return 0;
682}
683
684void
685cifs_crypto_shash_release(struct TCP_Server_Info *server)
686{
687 if (server->secmech.md5)
688 crypto_free_shash(server->secmech.md5);
689
690 if (server->secmech.hmacmd5)
691 crypto_free_shash(server->secmech.hmacmd5);
692
693 kfree(server->secmech.sdeschmacmd5);
694
695 kfree(server->secmech.sdescmd5);
696}
697
698int
699cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
700{
701 int rc;
702 unsigned int size;
703
704 server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
705 if (!server->secmech.hmacmd5 ||
706 IS_ERR(server->secmech.hmacmd5)) {
707 cERROR(1, "could not allocate crypto hmacmd5\n");
708 return PTR_ERR(server->secmech.hmacmd5);
709 }
710
711 server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
712 if (!server->secmech.md5 || IS_ERR(server->secmech.md5)) {
713 cERROR(1, "could not allocate crypto md5\n");
714 rc = PTR_ERR(server->secmech.md5);
715 goto crypto_allocate_md5_fail;
716 }
717
718 size = sizeof(struct shash_desc) +
719 crypto_shash_descsize(server->secmech.hmacmd5);
720 server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
721 if (!server->secmech.sdeschmacmd5) {
722 cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5\n");
723 rc = -ENOMEM;
724 goto crypto_allocate_hmacmd5_sdesc_fail;
725 }
726 server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
727 server->secmech.sdeschmacmd5->shash.flags = 0x0;
728
729
730 size = sizeof(struct shash_desc) +
731 crypto_shash_descsize(server->secmech.md5);
732 server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
733 if (!server->secmech.sdescmd5) {
734 cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5\n");
735 rc = -ENOMEM;
736 goto crypto_allocate_md5_sdesc_fail;
737 }
738 server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
739 server->secmech.sdescmd5->shash.flags = 0x0;
740
741 return 0;
742
743crypto_allocate_md5_sdesc_fail:
744 kfree(server->secmech.sdeschmacmd5);
745
746crypto_allocate_hmacmd5_sdesc_fail:
747 crypto_free_shash(server->secmech.md5);
748
749crypto_allocate_md5_fail:
750 crypto_free_shash(server->secmech.hmacmd5);
751
752 return rc;
540} 753}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 8bd5c2c243a5..75c4eaa79588 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -318,7 +318,6 @@ cifs_alloc_inode(struct super_block *sb)
318 return NULL; 318 return NULL;
319 cifs_inode->cifsAttrs = 0x20; /* default */ 319 cifs_inode->cifsAttrs = 0x20; /* default */
320 cifs_inode->time = 0; 320 cifs_inode->time = 0;
321 cifs_inode->write_behind_rc = 0;
322 /* Until the file is open and we have gotten oplock 321 /* Until the file is open and we have gotten oplock
323 info back from the server, can not assume caching of 322 info back from the server, can not assume caching of
324 file data or metadata */ 323 file data or metadata */
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index f35795a16b42..897b2b2b28b5 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -112,5 +112,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
112extern const struct export_operations cifs_export_ops; 112extern const struct export_operations cifs_export_ops;
113#endif /* EXPERIMENTAL */ 113#endif /* EXPERIMENTAL */
114 114
115#define CIFS_VERSION "1.67" 115#define CIFS_VERSION "1.68"
116#endif /* _CIFSFS_H */ 116#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 3365e77f6f24..f259e4d7612d 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -25,6 +25,9 @@
25#include <linux/workqueue.h> 25#include <linux/workqueue.h>
26#include "cifs_fs_sb.h" 26#include "cifs_fs_sb.h"
27#include "cifsacl.h" 27#include "cifsacl.h"
28#include <crypto/internal/hash.h>
29#include <linux/scatterlist.h>
30
28/* 31/*
29 * The sizes of various internal tables and strings 32 * The sizes of various internal tables and strings
30 */ 33 */
@@ -74,7 +77,7 @@
74 * CIFS vfs client Status information (based on what we know.) 77 * CIFS vfs client Status information (based on what we know.)
75 */ 78 */
76 79
77 /* associated with each tcp and smb session */ 80/* associated with each tcp and smb session */
78enum statusEnum { 81enum statusEnum {
79 CifsNew = 0, 82 CifsNew = 0,
80 CifsGood, 83 CifsGood,
@@ -99,14 +102,29 @@ enum protocolEnum {
99 102
100struct session_key { 103struct session_key {
101 unsigned int len; 104 unsigned int len;
102 union { 105 char *response;
103 char ntlm[CIFS_SESS_KEY_SIZE + 16]; 106};
104 char krb5[CIFS_SESS_KEY_SIZE + 16]; /* BB: length correct? */ 107
105 struct { 108/* crypto security descriptor definition */
106 char key[16]; 109struct sdesc {
107 struct ntlmv2_resp resp; 110 struct shash_desc shash;
108 } ntlmv2; 111 char ctx[];
109 } data; 112};
113
114/* crypto hashing related structure/fields, not specific to a sec mech */
115struct cifs_secmech {
116 struct crypto_shash *hmacmd5; /* hmac-md5 hash function */
117 struct crypto_shash *md5; /* md5 hash function */
118 struct sdesc *sdeschmacmd5; /* ctxt to generate ntlmv2 hash, CR1 */
119 struct sdesc *sdescmd5; /* ctxt to generate cifs/smb signature */
120};
121
122/* per smb session structure/fields */
123struct ntlmssp_auth {
124 __u32 client_flags; /* sent by client in type 1 ntlmsssp exchange */
125 __u32 server_flags; /* sent by server in type 2 ntlmssp exchange */
126 unsigned char ciphertext[CIFS_CPHTXT_SIZE]; /* sent to server */
127 char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlmssp */
110}; 128};
111 129
112struct cifs_cred { 130struct cifs_cred {
@@ -179,12 +197,14 @@ struct TCP_Server_Info {
179 int capabilities; /* allow selective disabling of caps by smb sess */ 197 int capabilities; /* allow selective disabling of caps by smb sess */
180 int timeAdj; /* Adjust for difference in server time zone in sec */ 198 int timeAdj; /* Adjust for difference in server time zone in sec */
181 __u16 CurrentMid; /* multiplex id - rotating counter */ 199 __u16 CurrentMid; /* multiplex id - rotating counter */
200 char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlm, ntlmv2 etc */
182 /* 16th byte of RFC1001 workstation name is always null */ 201 /* 16th byte of RFC1001 workstation name is always null */
183 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; 202 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
184 __u32 sequence_number; /* needed for CIFS PDU signature */ 203 __u32 sequence_number; /* needed for CIFS PDU signature */
185 struct session_key session_key; 204 struct session_key session_key;
186 unsigned long lstrp; /* when we got last response from this server */ 205 unsigned long lstrp; /* when we got last response from this server */
187 u16 dialect; /* dialect index that server chose */ 206 u16 dialect; /* dialect index that server chose */
207 struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */
188 /* extended security flavors that server supports */ 208 /* extended security flavors that server supports */
189 bool sec_kerberos; /* supports plain Kerberos */ 209 bool sec_kerberos; /* supports plain Kerberos */
190 bool sec_mskerberos; /* supports legacy MS Kerberos */ 210 bool sec_mskerberos; /* supports legacy MS Kerberos */
@@ -222,11 +242,8 @@ struct cifsSesInfo {
222 char userName[MAX_USERNAME_SIZE + 1]; 242 char userName[MAX_USERNAME_SIZE + 1];
223 char *domainName; 243 char *domainName;
224 char *password; 244 char *password;
225 char cryptKey[CIFS_CRYPTO_KEY_SIZE];
226 struct session_key auth_key; 245 struct session_key auth_key;
227 char ntlmv2_hash[16]; 246 struct ntlmssp_auth *ntlmssp; /* ciphertext, flags, server challenge */
228 unsigned int tilen; /* length of the target info blob */
229 unsigned char *tiblob; /* target info blob in challenge response */
230 bool need_reconnect:1; /* connection reset, uid now invalid */ 247 bool need_reconnect:1; /* connection reset, uid now invalid */
231}; 248};
232/* no more than one of the following three session flags may be set */ 249/* no more than one of the following three session flags may be set */
@@ -395,16 +412,19 @@ struct cifsFileInfo {
395 struct list_head llist; /* list of byte range locks we have. */ 412 struct list_head llist; /* list of byte range locks we have. */
396 bool invalidHandle:1; /* file closed via session abend */ 413 bool invalidHandle:1; /* file closed via session abend */
397 bool oplock_break_cancelled:1; 414 bool oplock_break_cancelled:1;
398 atomic_t count; /* reference count */ 415 int count; /* refcount protected by cifs_file_list_lock */
399 struct mutex fh_mutex; /* prevents reopen race after dead ses*/ 416 struct mutex fh_mutex; /* prevents reopen race after dead ses*/
400 struct cifs_search_info srch_inf; 417 struct cifs_search_info srch_inf;
401 struct work_struct oplock_break; /* work for oplock breaks */ 418 struct work_struct oplock_break; /* work for oplock breaks */
402}; 419};
403 420
404/* Take a reference on the file private data */ 421/*
422 * Take a reference on the file private data. Must be called with
423 * cifs_file_list_lock held.
424 */
405static inline void cifsFileInfo_get(struct cifsFileInfo *cifs_file) 425static inline void cifsFileInfo_get(struct cifsFileInfo *cifs_file)
406{ 426{
407 atomic_inc(&cifs_file->count); 427 ++cifs_file->count;
408} 428}
409 429
410void cifsFileInfo_put(struct cifsFileInfo *cifs_file); 430void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
@@ -417,7 +437,6 @@ struct cifsInodeInfo {
417 struct list_head lockList; 437 struct list_head lockList;
418 /* BB add in lists for dirty pages i.e. write caching info for oplock */ 438 /* BB add in lists for dirty pages i.e. write caching info for oplock */
419 struct list_head openFileList; 439 struct list_head openFileList;
420 int write_behind_rc;
421 __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */ 440 __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
422 unsigned long time; /* jiffies of last update/check of inode */ 441 unsigned long time; /* jiffies of last update/check of inode */
423 bool clientCanCacheRead:1; /* read oplock */ 442 bool clientCanCacheRead:1; /* read oplock */
@@ -668,7 +687,7 @@ require use of the stronger protocol */
668 * GlobalMid_Lock protects: 687 * GlobalMid_Lock protects:
669 * list operations on pending_mid_q and oplockQ 688 * list operations on pending_mid_q and oplockQ
670 * updates to XID counters, multiplex id and SMB sequence numbers 689 * updates to XID counters, multiplex id and SMB sequence numbers
671 * GlobalSMBSesLock protects: 690 * cifs_file_list_lock protects:
672 * list operations on tcp and SMB session lists and tCon lists 691 * list operations on tcp and SMB session lists and tCon lists
673 * f_owner.lock protects certain per file struct operations 692 * f_owner.lock protects certain per file struct operations
674 * mapping->page_lock protects certain per page operations 693 * mapping->page_lock protects certain per page operations
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index b0f4b5656d4c..de36b09763a8 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -131,9 +131,20 @@
131#define CIFS_CRYPTO_KEY_SIZE (8) 131#define CIFS_CRYPTO_KEY_SIZE (8)
132 132
133/* 133/*
134 * Size of the ntlm client response
135 */
136#define CIFS_AUTH_RESP_SIZE (24)
137
138/*
134 * Size of the session key (crypto key encrypted with the password 139 * Size of the session key (crypto key encrypted with the password
135 */ 140 */
136#define CIFS_SESS_KEY_SIZE (24) 141#define CIFS_SESS_KEY_SIZE (16)
142
143#define CIFS_CLIENT_CHALLENGE_SIZE (8)
144#define CIFS_SERVER_CHALLENGE_SIZE (8)
145#define CIFS_HMAC_MD5_HASH_SIZE (16)
146#define CIFS_CPHTXT_SIZE (16)
147#define CIFS_NTHASH_SIZE (16)
137 148
138/* 149/*
139 * Maximum user name length 150 * Maximum user name length
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index e593c40ba7ba..edb6d90efdf2 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -362,13 +362,15 @@ extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
362extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, 362extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
363 __u32 *); 363 __u32 *);
364extern int cifs_verify_signature(struct smb_hdr *, 364extern int cifs_verify_signature(struct smb_hdr *,
365 const struct session_key *session_key, 365 struct TCP_Server_Info *server,
366 __u32 expected_sequence_number); 366 __u32 expected_sequence_number);
367extern int cifs_calculate_session_key(struct session_key *key, const char *rn, 367extern void SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *);
368 const char *pass); 368extern int setup_ntlm_response(struct cifsSesInfo *);
369extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *); 369extern int setup_ntlmv2_rsp(struct cifsSesInfo *, const struct nls_table *);
370extern int setup_ntlmv2_rsp(struct cifsSesInfo *, char *, 370extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);
371 const struct nls_table *); 371extern void cifs_crypto_shash_release(struct TCP_Server_Info *);
372extern int calc_seckey(struct cifsSesInfo *);
373
372#ifdef CONFIG_CIFS_WEAK_PW_HASH 374#ifdef CONFIG_CIFS_WEAK_PW_HASH
373extern void calc_lanman_hash(const char *password, const char *cryptkey, 375extern void calc_lanman_hash(const char *password, const char *cryptkey,
374 bool encrypt, char *lnm_session_key); 376 bool encrypt, char *lnm_session_key);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index e98f1f317b15..2f2632b6df5a 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -503,7 +503,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
503 503
504 if (rsp->EncryptionKeyLength == 504 if (rsp->EncryptionKeyLength ==
505 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { 505 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
506 memcpy(ses->cryptKey, rsp->EncryptionKey, 506 memcpy(ses->server->cryptkey, rsp->EncryptionKey,
507 CIFS_CRYPTO_KEY_SIZE); 507 CIFS_CRYPTO_KEY_SIZE);
508 } else if (server->secMode & SECMODE_PW_ENCRYPT) { 508 } else if (server->secMode & SECMODE_PW_ENCRYPT) {
509 rc = -EIO; /* need cryptkey unless plain text */ 509 rc = -EIO; /* need cryptkey unless plain text */
@@ -574,7 +574,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
574 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); 574 server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
575 server->timeAdj *= 60; 575 server->timeAdj *= 60;
576 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { 576 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
577 memcpy(ses->cryptKey, pSMBr->u.EncryptionKey, 577 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
578 CIFS_CRYPTO_KEY_SIZE); 578 CIFS_CRYPTO_KEY_SIZE);
579 } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) 579 } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC)
580 && (pSMBr->EncryptionKeyLength == 0)) { 580 && (pSMBr->EncryptionKeyLength == 0)) {
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 7e73176acb58..9eb327defa1d 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -175,6 +175,9 @@ cifs_reconnect(struct TCP_Server_Info *server)
175 } 175 }
176 server->sequence_number = 0; 176 server->sequence_number = 0;
177 server->session_estab = false; 177 server->session_estab = false;
178 kfree(server->session_key.response);
179 server->session_key.response = NULL;
180 server->session_key.len = 0;
178 181
179 spin_lock(&GlobalMid_Lock); 182 spin_lock(&GlobalMid_Lock);
180 list_for_each(tmp, &server->pending_mid_q) { 183 list_for_each(tmp, &server->pending_mid_q) {
@@ -1064,7 +1067,7 @@ cifs_parse_mount_options(char *options, const char *devname,
1064 } 1067 }
1065 i = cifs_convert_address((struct sockaddr *)&vol->srcaddr, 1068 i = cifs_convert_address((struct sockaddr *)&vol->srcaddr,
1066 value, strlen(value)); 1069 value, strlen(value));
1067 if (i < 0) { 1070 if (i == 0) {
1068 printk(KERN_WARNING "CIFS: Could not parse" 1071 printk(KERN_WARNING "CIFS: Could not parse"
1069 " srcaddr: %s\n", 1072 " srcaddr: %s\n",
1070 value); 1073 value);
@@ -1560,8 +1563,13 @@ cifs_put_tcp_session(struct TCP_Server_Info *server)
1560 server->tcpStatus = CifsExiting; 1563 server->tcpStatus = CifsExiting;
1561 spin_unlock(&GlobalMid_Lock); 1564 spin_unlock(&GlobalMid_Lock);
1562 1565
1566 cifs_crypto_shash_release(server);
1563 cifs_fscache_release_client_cookie(server); 1567 cifs_fscache_release_client_cookie(server);
1564 1568
1569 kfree(server->session_key.response);
1570 server->session_key.response = NULL;
1571 server->session_key.len = 0;
1572
1565 task = xchg(&server->tsk, NULL); 1573 task = xchg(&server->tsk, NULL);
1566 if (task) 1574 if (task)
1567 force_sig(SIGKILL, task); 1575 force_sig(SIGKILL, task);
@@ -1614,10 +1622,16 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1614 goto out_err; 1622 goto out_err;
1615 } 1623 }
1616 1624
1625 rc = cifs_crypto_shash_allocate(tcp_ses);
1626 if (rc) {
1627 cERROR(1, "could not setup hash structures rc %d", rc);
1628 goto out_err;
1629 }
1630
1617 tcp_ses->hostname = extract_hostname(volume_info->UNC); 1631 tcp_ses->hostname = extract_hostname(volume_info->UNC);
1618 if (IS_ERR(tcp_ses->hostname)) { 1632 if (IS_ERR(tcp_ses->hostname)) {
1619 rc = PTR_ERR(tcp_ses->hostname); 1633 rc = PTR_ERR(tcp_ses->hostname);
1620 goto out_err; 1634 goto out_err_crypto_release;
1621 } 1635 }
1622 1636
1623 tcp_ses->noblocksnd = volume_info->noblocksnd; 1637 tcp_ses->noblocksnd = volume_info->noblocksnd;
@@ -1661,7 +1675,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1661 } 1675 }
1662 if (rc < 0) { 1676 if (rc < 0) {
1663 cERROR(1, "Error connecting to socket. Aborting operation"); 1677 cERROR(1, "Error connecting to socket. Aborting operation");
1664 goto out_err; 1678 goto out_err_crypto_release;
1665 } 1679 }
1666 1680
1667 /* 1681 /*
@@ -1675,7 +1689,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1675 rc = PTR_ERR(tcp_ses->tsk); 1689 rc = PTR_ERR(tcp_ses->tsk);
1676 cERROR(1, "error %d create cifsd thread", rc); 1690 cERROR(1, "error %d create cifsd thread", rc);
1677 module_put(THIS_MODULE); 1691 module_put(THIS_MODULE);
1678 goto out_err; 1692 goto out_err_crypto_release;
1679 } 1693 }
1680 1694
1681 /* thread spawned, put it on the list */ 1695 /* thread spawned, put it on the list */
@@ -1687,6 +1701,9 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1687 1701
1688 return tcp_ses; 1702 return tcp_ses;
1689 1703
1704out_err_crypto_release:
1705 cifs_crypto_shash_release(tcp_ses);
1706
1690out_err: 1707out_err:
1691 if (tcp_ses) { 1708 if (tcp_ses) {
1692 if (!IS_ERR(tcp_ses->hostname)) 1709 if (!IS_ERR(tcp_ses->hostname))
@@ -1801,8 +1818,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1801 if (ses == NULL) 1818 if (ses == NULL)
1802 goto get_ses_fail; 1819 goto get_ses_fail;
1803 1820
1804 ses->tilen = 0;
1805 ses->tiblob = NULL;
1806 /* new SMB session uses our server ref */ 1821 /* new SMB session uses our server ref */
1807 ses->server = server; 1822 ses->server = server;
1808 if (server->addr.sockAddr6.sin6_family == AF_INET6) 1823 if (server->addr.sockAddr6.sin6_family == AF_INET6)
@@ -1823,10 +1838,9 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1823 goto get_ses_fail; 1838 goto get_ses_fail;
1824 } 1839 }
1825 if (volume_info->domainname) { 1840 if (volume_info->domainname) {
1826 int len = strlen(volume_info->domainname); 1841 ses->domainName = kstrdup(volume_info->domainname, GFP_KERNEL);
1827 ses->domainName = kmalloc(len + 1, GFP_KERNEL); 1842 if (!ses->domainName)
1828 if (ses->domainName) 1843 goto get_ses_fail;
1829 strcpy(ses->domainName, volume_info->domainname);
1830 } 1844 }
1831 ses->cred_uid = volume_info->cred_uid; 1845 ses->cred_uid = volume_info->cred_uid;
1832 ses->linux_uid = volume_info->linux_uid; 1846 ses->linux_uid = volume_info->linux_uid;
@@ -2985,13 +2999,13 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2985#ifdef CONFIG_CIFS_WEAK_PW_HASH 2999#ifdef CONFIG_CIFS_WEAK_PW_HASH
2986 if ((global_secflags & CIFSSEC_MAY_LANMAN) && 3000 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
2987 (ses->server->secType == LANMAN)) 3001 (ses->server->secType == LANMAN))
2988 calc_lanman_hash(tcon->password, ses->cryptKey, 3002 calc_lanman_hash(tcon->password, ses->server->cryptkey,
2989 ses->server->secMode & 3003 ses->server->secMode &
2990 SECMODE_PW_ENCRYPT ? true : false, 3004 SECMODE_PW_ENCRYPT ? true : false,
2991 bcc_ptr); 3005 bcc_ptr);
2992 else 3006 else
2993#endif /* CIFS_WEAK_PW_HASH */ 3007#endif /* CIFS_WEAK_PW_HASH */
2994 SMBNTencrypt(tcon->password, ses->cryptKey, bcc_ptr); 3008 SMBNTencrypt(tcon->password, ses->server->cryptkey, bcc_ptr);
2995 3009
2996 bcc_ptr += CIFS_SESS_KEY_SIZE; 3010 bcc_ptr += CIFS_SESS_KEY_SIZE;
2997 if (ses->capabilities & CAP_UNICODE) { 3011 if (ses->capabilities & CAP_UNICODE) {
@@ -3178,10 +3192,11 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
3178 } else { 3192 } else {
3179 mutex_lock(&ses->server->srv_mutex); 3193 mutex_lock(&ses->server->srv_mutex);
3180 if (!server->session_estab) { 3194 if (!server->session_estab) {
3181 memcpy(&server->session_key.data, 3195 server->session_key.response = ses->auth_key.response;
3182 &ses->auth_key.data, ses->auth_key.len);
3183 server->session_key.len = ses->auth_key.len; 3196 server->session_key.len = ses->auth_key.len;
3184 ses->server->session_estab = true; 3197 server->sequence_number = 0x2;
3198 server->session_estab = true;
3199 ses->auth_key.response = NULL;
3185 } 3200 }
3186 mutex_unlock(&server->srv_mutex); 3201 mutex_unlock(&server->srv_mutex);
3187 3202
@@ -3192,6 +3207,12 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
3192 spin_unlock(&GlobalMid_Lock); 3207 spin_unlock(&GlobalMid_Lock);
3193 } 3208 }
3194 3209
3210 kfree(ses->auth_key.response);
3211 ses->auth_key.response = NULL;
3212 ses->auth_key.len = 0;
3213 kfree(ses->ntlmssp);
3214 ses->ntlmssp = NULL;
3215
3195 return rc; 3216 return rc;
3196} 3217}
3197 3218
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 45af003865d2..ae82159cf7fa 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -131,8 +131,7 @@ static inline int cifs_open_inode_helper(struct inode *inode,
131 /* BB no need to lock inode until after invalidate 131 /* BB no need to lock inode until after invalidate
132 since namei code should already have it locked? */ 132 since namei code should already have it locked? */
133 rc = filemap_write_and_wait(inode->i_mapping); 133 rc = filemap_write_and_wait(inode->i_mapping);
134 if (rc != 0) 134 mapping_set_error(inode->i_mapping, rc);
135 pCifsInode->write_behind_rc = rc;
136 } 135 }
137 cFYI(1, "invalidating remote inode since open detected it " 136 cFYI(1, "invalidating remote inode since open detected it "
138 "changed"); 137 "changed");
@@ -232,6 +231,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
232 if (pCifsFile == NULL) 231 if (pCifsFile == NULL)
233 return pCifsFile; 232 return pCifsFile;
234 233
234 pCifsFile->count = 1;
235 pCifsFile->netfid = fileHandle; 235 pCifsFile->netfid = fileHandle;
236 pCifsFile->pid = current->tgid; 236 pCifsFile->pid = current->tgid;
237 pCifsFile->uid = current_fsuid(); 237 pCifsFile->uid = current_fsuid();
@@ -242,7 +242,6 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
242 mutex_init(&pCifsFile->fh_mutex); 242 mutex_init(&pCifsFile->fh_mutex);
243 mutex_init(&pCifsFile->lock_mutex); 243 mutex_init(&pCifsFile->lock_mutex);
244 INIT_LIST_HEAD(&pCifsFile->llist); 244 INIT_LIST_HEAD(&pCifsFile->llist);
245 atomic_set(&pCifsFile->count, 1);
246 INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break); 245 INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break);
247 246
248 spin_lock(&cifs_file_list_lock); 247 spin_lock(&cifs_file_list_lock);
@@ -267,7 +266,8 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
267 266
268/* 267/*
269 * Release a reference on the file private data. This may involve closing 268 * Release a reference on the file private data. This may involve closing
270 * the filehandle out on the server. 269 * the filehandle out on the server. Must be called without holding
270 * cifs_file_list_lock.
271 */ 271 */
272void cifsFileInfo_put(struct cifsFileInfo *cifs_file) 272void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
273{ 273{
@@ -276,7 +276,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
276 struct cifsLockInfo *li, *tmp; 276 struct cifsLockInfo *li, *tmp;
277 277
278 spin_lock(&cifs_file_list_lock); 278 spin_lock(&cifs_file_list_lock);
279 if (!atomic_dec_and_test(&cifs_file->count)) { 279 if (--cifs_file->count > 0) {
280 spin_unlock(&cifs_file_list_lock); 280 spin_unlock(&cifs_file_list_lock);
281 return; 281 return;
282 } 282 }
@@ -605,8 +605,7 @@ reopen_success:
605 605
606 if (can_flush) { 606 if (can_flush) {
607 rc = filemap_write_and_wait(inode->i_mapping); 607 rc = filemap_write_and_wait(inode->i_mapping);
608 if (rc != 0) 608 mapping_set_error(inode->i_mapping, rc);
609 CIFS_I(inode)->write_behind_rc = rc;
610 609
611 pCifsInode->clientCanCacheAll = false; 610 pCifsInode->clientCanCacheAll = false;
612 pCifsInode->clientCanCacheRead = false; 611 pCifsInode->clientCanCacheRead = false;
@@ -1353,6 +1352,7 @@ static int cifs_writepages(struct address_space *mapping,
1353 if (!experimEnabled && tcon->ses->server->secMode & 1352 if (!experimEnabled && tcon->ses->server->secMode &
1354 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { 1353 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
1355 cifsFileInfo_put(open_file); 1354 cifsFileInfo_put(open_file);
1355 kfree(iov);
1356 return generic_writepages(mapping, wbc); 1356 return generic_writepages(mapping, wbc);
1357 } 1357 }
1358 cifsFileInfo_put(open_file); 1358 cifsFileInfo_put(open_file);
@@ -1478,12 +1478,7 @@ retry:
1478 if (rc || bytes_written < bytes_to_write) { 1478 if (rc || bytes_written < bytes_to_write) {
1479 cERROR(1, "Write2 ret %d, wrote %d", 1479 cERROR(1, "Write2 ret %d, wrote %d",
1480 rc, bytes_written); 1480 rc, bytes_written);
1481 /* BB what if continued retry is 1481 mapping_set_error(mapping, rc);
1482 requested via mount flags? */
1483 if (rc == -ENOSPC)
1484 set_bit(AS_ENOSPC, &mapping->flags);
1485 else
1486 set_bit(AS_EIO, &mapping->flags);
1487 } else { 1482 } else {
1488 cifs_stats_bytes_written(tcon, bytes_written); 1483 cifs_stats_bytes_written(tcon, bytes_written);
1489 } 1484 }
@@ -1628,11 +1623,10 @@ int cifs_fsync(struct file *file, int datasync)
1628 1623
1629 rc = filemap_write_and_wait(inode->i_mapping); 1624 rc = filemap_write_and_wait(inode->i_mapping);
1630 if (rc == 0) { 1625 if (rc == 0) {
1631 rc = CIFS_I(inode)->write_behind_rc; 1626 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1632 CIFS_I(inode)->write_behind_rc = 0; 1627
1633 tcon = tlink_tcon(smbfile->tlink); 1628 tcon = tlink_tcon(smbfile->tlink);
1634 if (!rc && tcon && smbfile && 1629 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
1635 !(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
1636 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid); 1630 rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
1637 } 1631 }
1638 1632
@@ -1677,21 +1671,8 @@ int cifs_flush(struct file *file, fl_owner_t id)
1677 struct inode *inode = file->f_path.dentry->d_inode; 1671 struct inode *inode = file->f_path.dentry->d_inode;
1678 int rc = 0; 1672 int rc = 0;
1679 1673
1680 /* Rather than do the steps manually: 1674 if (file->f_mode & FMODE_WRITE)
1681 lock the inode for writing 1675 rc = filemap_write_and_wait(inode->i_mapping);
1682 loop through pages looking for write behind data (dirty pages)
1683 coalesce into contiguous 16K (or smaller) chunks to write to server
1684 send to server (prefer in parallel)
1685 deal with writebehind errors
1686 unlock inode for writing
1687 filemapfdatawrite appears easier for the time being */
1688
1689 rc = filemap_fdatawrite(inode->i_mapping);
1690 /* reset wb rc if we were able to write out dirty pages */
1691 if (!rc) {
1692 rc = CIFS_I(inode)->write_behind_rc;
1693 CIFS_I(inode)->write_behind_rc = 0;
1694 }
1695 1676
1696 cFYI(1, "Flush inode %p file %p rc %d", inode, file, rc); 1677 cFYI(1, "Flush inode %p file %p rc %d", inode, file, rc);
1697 1678
@@ -2270,7 +2251,7 @@ void cifs_oplock_break(struct work_struct *work)
2270 oplock_break); 2251 oplock_break);
2271 struct inode *inode = cfile->dentry->d_inode; 2252 struct inode *inode = cfile->dentry->d_inode;
2272 struct cifsInodeInfo *cinode = CIFS_I(inode); 2253 struct cifsInodeInfo *cinode = CIFS_I(inode);
2273 int rc, waitrc = 0; 2254 int rc = 0;
2274 2255
2275 if (inode && S_ISREG(inode->i_mode)) { 2256 if (inode && S_ISREG(inode->i_mode)) {
2276 if (cinode->clientCanCacheRead) 2257 if (cinode->clientCanCacheRead)
@@ -2279,13 +2260,10 @@ void cifs_oplock_break(struct work_struct *work)
2279 break_lease(inode, O_WRONLY); 2260 break_lease(inode, O_WRONLY);
2280 rc = filemap_fdatawrite(inode->i_mapping); 2261 rc = filemap_fdatawrite(inode->i_mapping);
2281 if (cinode->clientCanCacheRead == 0) { 2262 if (cinode->clientCanCacheRead == 0) {
2282 waitrc = filemap_fdatawait(inode->i_mapping); 2263 rc = filemap_fdatawait(inode->i_mapping);
2264 mapping_set_error(inode->i_mapping, rc);
2283 invalidate_remote_inode(inode); 2265 invalidate_remote_inode(inode);
2284 } 2266 }
2285 if (!rc)
2286 rc = waitrc;
2287 if (rc)
2288 cinode->write_behind_rc = rc;
2289 cFYI(1, "Oplock flush inode %p rc %d", inode, rc); 2267 cFYI(1, "Oplock flush inode %p rc %d", inode, rc);
2290 } 2268 }
2291 2269
@@ -2304,7 +2282,7 @@ void cifs_oplock_break(struct work_struct *work)
2304 /* 2282 /*
2305 * We might have kicked in before is_valid_oplock_break() 2283 * We might have kicked in before is_valid_oplock_break()
2306 * finished grabbing reference for us. Make sure it's done by 2284 * finished grabbing reference for us. Make sure it's done by
2307 * waiting for GlobalSMSSeslock. 2285 * waiting for cifs_file_list_lock.
2308 */ 2286 */
2309 spin_lock(&cifs_file_list_lock); 2287 spin_lock(&cifs_file_list_lock);
2310 spin_unlock(&cifs_file_list_lock); 2288 spin_unlock(&cifs_file_list_lock);
@@ -2312,6 +2290,7 @@ void cifs_oplock_break(struct work_struct *work)
2312 cifs_oplock_break_put(cfile); 2290 cifs_oplock_break_put(cfile);
2313} 2291}
2314 2292
2293/* must be called while holding cifs_file_list_lock */
2315void cifs_oplock_break_get(struct cifsFileInfo *cfile) 2294void cifs_oplock_break_get(struct cifsFileInfo *cfile)
2316{ 2295{
2317 cifs_sb_active(cfile->dentry->d_sb); 2296 cifs_sb_active(cfile->dentry->d_sb);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 94979309698a..39869c3c3efb 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1682,8 +1682,7 @@ cifs_invalidate_mapping(struct inode *inode)
1682 /* write back any cached data */ 1682 /* write back any cached data */
1683 if (inode->i_mapping && inode->i_mapping->nrpages != 0) { 1683 if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
1684 rc = filemap_write_and_wait(inode->i_mapping); 1684 rc = filemap_write_and_wait(inode->i_mapping);
1685 if (rc) 1685 mapping_set_error(inode->i_mapping, rc);
1686 cifs_i->write_behind_rc = rc;
1687 } 1686 }
1688 invalidate_remote_inode(inode); 1687 invalidate_remote_inode(inode);
1689 cifs_fscache_reset_inode_cookie(inode); 1688 cifs_fscache_reset_inode_cookie(inode);
@@ -1943,10 +1942,8 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1943 * the flush returns error? 1942 * the flush returns error?
1944 */ 1943 */
1945 rc = filemap_write_and_wait(inode->i_mapping); 1944 rc = filemap_write_and_wait(inode->i_mapping);
1946 if (rc != 0) { 1945 mapping_set_error(inode->i_mapping, rc);
1947 cifsInode->write_behind_rc = rc; 1946 rc = 0;
1948 rc = 0;
1949 }
1950 1947
1951 if (attrs->ia_valid & ATTR_SIZE) { 1948 if (attrs->ia_valid & ATTR_SIZE) {
1952 rc = cifs_set_file_size(inode, attrs, xid, full_path); 1949 rc = cifs_set_file_size(inode, attrs, xid, full_path);
@@ -2087,10 +2084,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
2087 * the flush returns error? 2084 * the flush returns error?
2088 */ 2085 */
2089 rc = filemap_write_and_wait(inode->i_mapping); 2086 rc = filemap_write_and_wait(inode->i_mapping);
2090 if (rc != 0) { 2087 mapping_set_error(inode->i_mapping, rc);
2091 cifsInode->write_behind_rc = rc; 2088 rc = 0;
2092 rc = 0;
2093 }
2094 2089
2095 if (attrs->ia_valid & ATTR_SIZE) { 2090 if (attrs->ia_valid & ATTR_SIZE) {
2096 rc = cifs_set_file_size(inode, attrs, xid, full_path); 2091 rc = cifs_set_file_size(inode, attrs, xid, full_path);
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 1c681f6a6803..c4e296fe3518 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -577,7 +577,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
577 * cifs_oplock_break_put() can't be called 577 * cifs_oplock_break_put() can't be called
578 * from here. Get reference after queueing 578 * from here. Get reference after queueing
579 * succeeded. cifs_oplock_break() will 579 * succeeded. cifs_oplock_break() will
580 * synchronize using GlobalSMSSeslock. 580 * synchronize using cifs_file_list_lock.
581 */ 581 */
582 if (queue_work(system_nrt_wq, 582 if (queue_work(system_nrt_wq,
583 &netfile->oplock_break)) 583 &netfile->oplock_break))
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 2a11efd96592..7b01d3f6eed6 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -32,9 +32,6 @@
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include "cifs_spnego.h" 33#include "cifs_spnego.h"
34 34
35extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
36 unsigned char *p24);
37
38/* 35/*
39 * Checks if this is the first smb session to be reconnected after 36 * Checks if this is the first smb session to be reconnected after
40 * the socket has been reestablished (so we know whether to use vc 0). 37 * the socket has been reestablished (so we know whether to use vc 0).
@@ -402,23 +399,22 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
402 return -EINVAL; 399 return -EINVAL;
403 } 400 }
404 401
405 memcpy(ses->cryptKey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE); 402 memcpy(ses->ntlmssp->cryptkey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
406 /* BB we could decode pblob->NegotiateFlags; some may be useful */ 403 /* BB we could decode pblob->NegotiateFlags; some may be useful */
407 /* In particular we can examine sign flags */ 404 /* In particular we can examine sign flags */
408 /* BB spec says that if AvId field of MsvAvTimestamp is populated then 405 /* BB spec says that if AvId field of MsvAvTimestamp is populated then
409 we must set the MIC field of the AUTHENTICATE_MESSAGE */ 406 we must set the MIC field of the AUTHENTICATE_MESSAGE */
410 407 ses->ntlmssp->server_flags = le32_to_cpu(pblob->NegotiateFlags);
411 tioffset = cpu_to_le16(pblob->TargetInfoArray.BufferOffset); 408 tioffset = cpu_to_le16(pblob->TargetInfoArray.BufferOffset);
412 tilen = cpu_to_le16(pblob->TargetInfoArray.Length); 409 tilen = cpu_to_le16(pblob->TargetInfoArray.Length);
413 ses->tilen = tilen; 410 if (tilen) {
414 if (ses->tilen) { 411 ses->auth_key.response = kmalloc(tilen, GFP_KERNEL);
415 ses->tiblob = kmalloc(tilen, GFP_KERNEL); 412 if (!ses->auth_key.response) {
416 if (!ses->tiblob) {
417 cERROR(1, "Challenge target info allocation failure"); 413 cERROR(1, "Challenge target info allocation failure");
418 ses->tilen = 0;
419 return -ENOMEM; 414 return -ENOMEM;
420 } 415 }
421 memcpy(ses->tiblob, bcc_ptr + tioffset, ses->tilen); 416 memcpy(ses->auth_key.response, bcc_ptr + tioffset, tilen);
417 ses->auth_key.len = tilen;
422 } 418 }
423 419
424 return 0; 420 return 0;
@@ -443,10 +439,12 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
443 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | 439 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
444 NTLMSSP_NEGOTIATE_NTLM; 440 NTLMSSP_NEGOTIATE_NTLM;
445 if (ses->server->secMode & 441 if (ses->server->secMode &
446 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 442 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
447 flags |= NTLMSSP_NEGOTIATE_SIGN; 443 flags |= NTLMSSP_NEGOTIATE_SIGN;
448 if (ses->server->secMode & SECMODE_SIGN_REQUIRED) 444 if (!ses->server->session_estab)
449 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; 445 flags |= NTLMSSP_NEGOTIATE_KEY_XCH |
446 NTLMSSP_NEGOTIATE_EXTENDED_SEC;
447 }
450 448
451 sec_blob->NegotiateFlags |= cpu_to_le32(flags); 449 sec_blob->NegotiateFlags |= cpu_to_le32(flags);
452 450
@@ -469,11 +467,9 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
469 const struct nls_table *nls_cp) 467 const struct nls_table *nls_cp)
470{ 468{
471 int rc; 469 int rc;
472 unsigned int size;
473 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; 470 AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
474 __u32 flags; 471 __u32 flags;
475 unsigned char *tmp; 472 unsigned char *tmp;
476 struct ntlmv2_resp ntlmv2_response = {};
477 473
478 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); 474 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
479 sec_blob->MessageType = NtLmAuthenticate; 475 sec_blob->MessageType = NtLmAuthenticate;
@@ -497,25 +493,19 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
497 sec_blob->LmChallengeResponse.MaximumLength = 0; 493 sec_blob->LmChallengeResponse.MaximumLength = 0;
498 494
499 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer); 495 sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
500 rc = setup_ntlmv2_rsp(ses, (char *)&ntlmv2_response, nls_cp); 496 rc = setup_ntlmv2_rsp(ses, nls_cp);
501 if (rc) { 497 if (rc) {
502 cERROR(1, "Error %d during NTLMSSP authentication", rc); 498 cERROR(1, "Error %d during NTLMSSP authentication", rc);
503 goto setup_ntlmv2_ret; 499 goto setup_ntlmv2_ret;
504 } 500 }
505 size = sizeof(struct ntlmv2_resp); 501 memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
506 memcpy(tmp, (char *)&ntlmv2_response, size); 502 ses->auth_key.len - CIFS_SESS_KEY_SIZE);
507 tmp += size; 503 tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
508 if (ses->tilen > 0) {
509 memcpy(tmp, ses->tiblob, ses->tilen);
510 tmp += ses->tilen;
511 }
512 504
513 sec_blob->NtChallengeResponse.Length = cpu_to_le16(size + ses->tilen); 505 sec_blob->NtChallengeResponse.Length =
506 cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
514 sec_blob->NtChallengeResponse.MaximumLength = 507 sec_blob->NtChallengeResponse.MaximumLength =
515 cpu_to_le16(size + ses->tilen); 508 cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
516 kfree(ses->tiblob);
517 ses->tiblob = NULL;
518 ses->tilen = 0;
519 509
520 if (ses->domainName == NULL) { 510 if (ses->domainName == NULL) {
521 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); 511 sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
@@ -554,9 +544,19 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
554 sec_blob->WorkstationName.MaximumLength = 0; 544 sec_blob->WorkstationName.MaximumLength = 0;
555 tmp += 2; 545 tmp += 2;
556 546
557 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); 547 if ((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) &&
558 sec_blob->SessionKey.Length = 0; 548 !calc_seckey(ses)) {
559 sec_blob->SessionKey.MaximumLength = 0; 549 memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
550 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
551 sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
552 sec_blob->SessionKey.MaximumLength =
553 cpu_to_le16(CIFS_CPHTXT_SIZE);
554 tmp += CIFS_CPHTXT_SIZE;
555 } else {
556 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
557 sec_blob->SessionKey.Length = 0;
558 sec_blob->SessionKey.MaximumLength = 0;
559 }
560 560
561setup_ntlmv2_ret: 561setup_ntlmv2_ret:
562 *buflen = tmp - pbuffer; 562 *buflen = tmp - pbuffer;
@@ -600,8 +600,16 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
600 return -EINVAL; 600 return -EINVAL;
601 601
602 type = ses->server->secType; 602 type = ses->server->secType;
603
604 cFYI(1, "sess setup type %d", type); 603 cFYI(1, "sess setup type %d", type);
604 if (type == RawNTLMSSP) {
605 /* if memory allocation is successful, caller of this function
606 * frees it.
607 */
608 ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL);
609 if (!ses->ntlmssp)
610 return -ENOMEM;
611 }
612
605ssetup_ntlmssp_authenticate: 613ssetup_ntlmssp_authenticate:
606 if (phase == NtLmChallenge) 614 if (phase == NtLmChallenge)
607 phase = NtLmAuthenticate; /* if ntlmssp, now final phase */ 615 phase = NtLmAuthenticate; /* if ntlmssp, now final phase */
@@ -666,10 +674,14 @@ ssetup_ntlmssp_authenticate:
666 /* no capabilities flags in old lanman negotiation */ 674 /* no capabilities flags in old lanman negotiation */
667 675
668 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE); 676 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
669 /* BB calculate hash with password */
670 /* and copy into bcc */
671 677
672 calc_lanman_hash(ses->password, ses->cryptKey, 678 /* Calculate hash with password and copy into bcc_ptr.
679 * Encryption Key (stored as in cryptkey) gets used if the
680 * security mode bit in Negottiate Protocol response states
681 * to use challenge/response method (i.e. Password bit is 1).
682 */
683
684 calc_lanman_hash(ses->password, ses->server->cryptkey,
673 ses->server->secMode & SECMODE_PW_ENCRYPT ? 685 ses->server->secMode & SECMODE_PW_ENCRYPT ?
674 true : false, lnm_session_key); 686 true : false, lnm_session_key);
675 687
@@ -687,24 +699,27 @@ ssetup_ntlmssp_authenticate:
687 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); 699 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
688#endif 700#endif
689 } else if (type == NTLM) { 701 } else if (type == NTLM) {
690 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
691
692 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); 702 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
693 pSMB->req_no_secext.CaseInsensitivePasswordLength = 703 pSMB->req_no_secext.CaseInsensitivePasswordLength =
694 cpu_to_le16(CIFS_SESS_KEY_SIZE); 704 cpu_to_le16(CIFS_AUTH_RESP_SIZE);
695 pSMB->req_no_secext.CaseSensitivePasswordLength = 705 pSMB->req_no_secext.CaseSensitivePasswordLength =
696 cpu_to_le16(CIFS_SESS_KEY_SIZE); 706 cpu_to_le16(CIFS_AUTH_RESP_SIZE);
707
708 /* calculate ntlm response and session key */
709 rc = setup_ntlm_response(ses);
710 if (rc) {
711 cERROR(1, "Error %d during NTLM authentication", rc);
712 goto ssetup_exit;
713 }
697 714
698 /* calculate session key */ 715 /* copy ntlm response */
699 SMBNTencrypt(ses->password, ses->cryptKey, ntlm_session_key); 716 memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
717 CIFS_AUTH_RESP_SIZE);
718 bcc_ptr += CIFS_AUTH_RESP_SIZE;
719 memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
720 CIFS_AUTH_RESP_SIZE);
721 bcc_ptr += CIFS_AUTH_RESP_SIZE;
700 722
701 cifs_calculate_session_key(&ses->auth_key,
702 ntlm_session_key, ses->password);
703 /* copy session key */
704 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
705 bcc_ptr += CIFS_SESS_KEY_SIZE;
706 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
707 bcc_ptr += CIFS_SESS_KEY_SIZE;
708 if (ses->capabilities & CAP_UNICODE) { 723 if (ses->capabilities & CAP_UNICODE) {
709 /* unicode strings must be word aligned */ 724 /* unicode strings must be word aligned */
710 if (iov[0].iov_len % 2) { 725 if (iov[0].iov_len % 2) {
@@ -715,47 +730,26 @@ ssetup_ntlmssp_authenticate:
715 } else 730 } else
716 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); 731 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
717 } else if (type == NTLMv2) { 732 } else if (type == NTLMv2) {
718 char *v2_sess_key =
719 kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
720
721 /* BB FIXME change all users of v2_sess_key to
722 struct ntlmv2_resp */
723
724 if (v2_sess_key == NULL) {
725 rc = -ENOMEM;
726 goto ssetup_exit;
727 }
728
729 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); 733 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
730 734
731 /* LM2 password would be here if we supported it */ 735 /* LM2 password would be here if we supported it */
732 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0; 736 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
733 /* cpu_to_le16(LM2_SESS_KEY_SIZE); */
734 737
735 /* calculate session key */ 738 /* calculate nlmv2 response and session key */
736 rc = setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); 739 rc = setup_ntlmv2_rsp(ses, nls_cp);
737 if (rc) { 740 if (rc) {
738 cERROR(1, "Error %d during NTLMv2 authentication", rc); 741 cERROR(1, "Error %d during NTLMv2 authentication", rc);
739 kfree(v2_sess_key);
740 goto ssetup_exit; 742 goto ssetup_exit;
741 } 743 }
742 memcpy(bcc_ptr, (char *)v2_sess_key, 744 memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
743 sizeof(struct ntlmv2_resp)); 745 ses->auth_key.len - CIFS_SESS_KEY_SIZE);
744 bcc_ptr += sizeof(struct ntlmv2_resp); 746 bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
745 kfree(v2_sess_key); 747
746 /* set case sensitive password length after tilen may get 748 /* set case sensitive password length after tilen may get
747 * assigned, tilen is 0 otherwise. 749 * assigned, tilen is 0 otherwise.
748 */ 750 */
749 pSMB->req_no_secext.CaseSensitivePasswordLength = 751 pSMB->req_no_secext.CaseSensitivePasswordLength =
750 cpu_to_le16(sizeof(struct ntlmv2_resp) + ses->tilen); 752 cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
751 if (ses->tilen > 0) {
752 memcpy(bcc_ptr, ses->tiblob, ses->tilen);
753 bcc_ptr += ses->tilen;
754 /* we never did allocate ses->domainName to free */
755 kfree(ses->tiblob);
756 ses->tiblob = NULL;
757 ses->tilen = 0;
758 }
759 753
760 if (ses->capabilities & CAP_UNICODE) { 754 if (ses->capabilities & CAP_UNICODE) {
761 if (iov[0].iov_len % 2) { 755 if (iov[0].iov_len % 2) {
@@ -768,6 +762,7 @@ ssetup_ntlmssp_authenticate:
768 } else if (type == Kerberos) { 762 } else if (type == Kerberos) {
769#ifdef CONFIG_CIFS_UPCALL 763#ifdef CONFIG_CIFS_UPCALL
770 struct cifs_spnego_msg *msg; 764 struct cifs_spnego_msg *msg;
765
771 spnego_key = cifs_get_spnego_key(ses); 766 spnego_key = cifs_get_spnego_key(ses);
772 if (IS_ERR(spnego_key)) { 767 if (IS_ERR(spnego_key)) {
773 rc = PTR_ERR(spnego_key); 768 rc = PTR_ERR(spnego_key);
@@ -785,16 +780,17 @@ ssetup_ntlmssp_authenticate:
785 rc = -EKEYREJECTED; 780 rc = -EKEYREJECTED;
786 goto ssetup_exit; 781 goto ssetup_exit;
787 } 782 }
788 /* bail out if key is too long */ 783
789 if (msg->sesskey_len > 784 ses->auth_key.response = kmalloc(msg->sesskey_len, GFP_KERNEL);
790 sizeof(ses->auth_key.data.krb5)) { 785 if (!ses->auth_key.response) {
791 cERROR(1, "Kerberos signing key too long (%u bytes)", 786 cERROR(1, "Kerberos can't allocate (%u bytes) memory",
792 msg->sesskey_len); 787 msg->sesskey_len);
793 rc = -EOVERFLOW; 788 rc = -ENOMEM;
794 goto ssetup_exit; 789 goto ssetup_exit;
795 } 790 }
791 memcpy(ses->auth_key.response, msg->data, msg->sesskey_len);
796 ses->auth_key.len = msg->sesskey_len; 792 ses->auth_key.len = msg->sesskey_len;
797 memcpy(ses->auth_key.data.krb5, msg->data, msg->sesskey_len); 793
798 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 794 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
799 capabilities |= CAP_EXTENDED_SECURITY; 795 capabilities |= CAP_EXTENDED_SECURITY;
800 pSMB->req.Capabilities = cpu_to_le32(capabilities); 796 pSMB->req.Capabilities = cpu_to_le32(capabilities);
@@ -897,8 +893,6 @@ ssetup_ntlmssp_authenticate:
897 CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR); 893 CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR);
898 /* SMB request buf freed in SendReceive2 */ 894 /* SMB request buf freed in SendReceive2 */
899 895
900 cFYI(1, "ssetup rc from sendrecv2 is %d", rc);
901
902 pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base; 896 pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
903 smb_buf = (struct smb_hdr *)iov[0].iov_base; 897 smb_buf = (struct smb_hdr *)iov[0].iov_base;
904 898
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index a66c91eb6eb4..e0588cdf4cc5 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -543,7 +543,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
543 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 543 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
544 SECMODE_SIGN_ENABLED))) { 544 SECMODE_SIGN_ENABLED))) {
545 rc = cifs_verify_signature(midQ->resp_buf, 545 rc = cifs_verify_signature(midQ->resp_buf,
546 &ses->server->session_key, 546 ses->server,
547 midQ->sequence_number+1); 547 midQ->sequence_number+1);
548 if (rc) { 548 if (rc) {
549 cERROR(1, "Unexpected SMB signature"); 549 cERROR(1, "Unexpected SMB signature");
@@ -731,7 +731,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
731 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 731 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
732 SECMODE_SIGN_ENABLED))) { 732 SECMODE_SIGN_ENABLED))) {
733 rc = cifs_verify_signature(out_buf, 733 rc = cifs_verify_signature(out_buf,
734 &ses->server->session_key, 734 ses->server,
735 midQ->sequence_number+1); 735 midQ->sequence_number+1);
736 if (rc) { 736 if (rc) {
737 cERROR(1, "Unexpected SMB signature"); 737 cERROR(1, "Unexpected SMB signature");
@@ -981,7 +981,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
981 (ses->server->secMode & (SECMODE_SIGN_REQUIRED | 981 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
982 SECMODE_SIGN_ENABLED))) { 982 SECMODE_SIGN_ENABLED))) {
983 rc = cifs_verify_signature(out_buf, 983 rc = cifs_verify_signature(out_buf,
984 &ses->server->session_key, 984 ses->server,
985 midQ->sequence_number+1); 985 midQ->sequence_number+1);
986 if (rc) { 986 if (rc) {
987 cERROR(1, "Unexpected SMB signature"); 987 cERROR(1, "Unexpected SMB signature");