Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6

Pull CIFS fixes from Steve French:
"Four fixes from testing at the recent SMB3 Plugfest including two
important authentication ones (one fixes authentication problems to
some popular servers when clock times differ more than two hours
between systems, the other fixes Kerberos authentication for SMB3)"

* 'for-next' of git://git.samba.org/sfrench/cifs-2.6:
fix encryption error checks on mount
[SMB3] Fix sec=krb5 on smb3 mounts
cifs: use server timestamp for ntlmv2 authentication
disabling oplocks/leases via module parm enable_oplocks broken for SMB3

Changed files
+126 -19
fs
+51 -2
fs/cifs/cifsencrypt.c
··· 444 444 return 0; 445 445 } 446 446 447 + /* Server has provided av pairs/target info in the type 2 challenge 448 + * packet and we have plucked it and stored within smb session. 449 + * We parse that blob here to find the server given timestamp 450 + * as part of ntlmv2 authentication (or local current time as 451 + * default in case of failure) 452 + */ 453 + static __le64 454 + find_timestamp(struct cifs_ses *ses) 455 + { 456 + unsigned int attrsize; 457 + unsigned int type; 458 + unsigned int onesize = sizeof(struct ntlmssp2_name); 459 + unsigned char *blobptr; 460 + unsigned char *blobend; 461 + struct ntlmssp2_name *attrptr; 462 + 463 + if (!ses->auth_key.len || !ses->auth_key.response) 464 + return 0; 465 + 466 + blobptr = ses->auth_key.response; 467 + blobend = blobptr + ses->auth_key.len; 468 + 469 + while (blobptr + onesize < blobend) { 470 + attrptr = (struct ntlmssp2_name *) blobptr; 471 + type = le16_to_cpu(attrptr->type); 472 + if (type == NTLMSSP_AV_EOL) 473 + break; 474 + blobptr += 2; /* advance attr type */ 475 + attrsize = le16_to_cpu(attrptr->length); 476 + blobptr += 2; /* advance attr size */ 477 + if (blobptr + attrsize > blobend) 478 + break; 479 + if (type == NTLMSSP_AV_TIMESTAMP) { 480 + if (attrsize == sizeof(u64)) 481 + return *((__le64 *)blobptr); 482 + } 483 + blobptr += attrsize; /* advance attr value */ 484 + } 485 + 486 + return cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 487 + } 488 + 447 489 static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, 448 490 const struct nls_table *nls_cp) 449 491 { ··· 683 641 struct ntlmv2_resp *ntlmv2; 684 642 char ntlmv2_hash[16]; 685 643 unsigned char *tiblob = NULL; /* target info blob */ 644 + __le64 rsp_timestamp; 686 645 687 646 if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) { 688 647 if (!ses->domainName) { ··· 702 659 } 703 660 } 704 661 662 + /* Must be within 5 minutes of the server (or in range +/-2h 663 + * in case of Mac OS X), so simply carry over server timestamp 664 + * (as Windows 7 does) 665 + */ 666 + rsp_timestamp = find_timestamp(ses); 667 + 705 668 baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp); 706 669 tilen = ses->auth_key.len; 707 670 tiblob = ses->auth_key.response; ··· 724 675 (ses->auth_key.response + CIFS_SESS_KEY_SIZE); 725 676 ntlmv2->blob_signature = cpu_to_le32(0x00000101); 726 677 ntlmv2->reserved = 0; 727 - /* Must be within 5 minutes of the server */ 728 - ntlmv2->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 678 + ntlmv2->time = rsp_timestamp; 679 + 729 680 get_random_bytes(&ntlmv2->client_chal, sizeof(ntlmv2->client_chal)); 730 681 ntlmv2->reserved2 = 0; 731 682
+6 -2
fs/cifs/smb2ops.c
··· 50 50 break; 51 51 default: 52 52 server->echoes = true; 53 - server->oplocks = true; 53 + if (enable_oplocks) { 54 + server->oplocks = true; 55 + server->oplock_credits = 1; 56 + } else 57 + server->oplocks = false; 58 + 54 59 server->echo_credits = 1; 55 - server->oplock_credits = 1; 56 60 } 57 61 server->credits -= server->echo_credits + server->oplock_credits; 58 62 return 0;
+69 -15
fs/cifs/smb2pdu.c
··· 46 46 #include "smb2status.h" 47 47 #include "smb2glob.h" 48 48 #include "cifspdu.h" 49 + #include "cifs_spnego.h" 49 50 50 51 /* 51 52 * The following table defines the expected "StructureSize" of SMB2 requests ··· 487 486 cifs_dbg(FYI, "missing security blob on negprot\n"); 488 487 489 488 rc = cifs_enable_signing(server, ses->sign); 490 - #ifdef CONFIG_SMB2_ASN1 /* BB REMOVEME when updated asn1.c ready */ 491 489 if (rc) 492 490 goto neg_exit; 493 - if (blob_length) 491 + if (blob_length) { 494 492 rc = decode_negTokenInit(security_blob, blob_length, server); 495 - if (rc == 1) 496 - rc = 0; 497 - else if (rc == 0) { 498 - rc = -EIO; 499 - goto neg_exit; 493 + if (rc == 1) 494 + rc = 0; 495 + else if (rc == 0) 496 + rc = -EIO; 500 497 } 501 - #endif 502 - 503 498 neg_exit: 504 499 free_rsp_buf(resp_buftype, rsp); 505 500 return rc; ··· 589 592 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ 590 593 struct TCP_Server_Info *server = ses->server; 591 594 u16 blob_length = 0; 592 - char *security_blob; 595 + struct key *spnego_key = NULL; 596 + char *security_blob = NULL; 593 597 char *ntlmssp_blob = NULL; 594 598 bool use_spnego = false; /* else use raw ntlmssp */ 595 599 ··· 618 620 ses->ntlmssp->sesskey_per_smbsess = true; 619 621 620 622 /* FIXME: allow for other auth types besides NTLMSSP (e.g. krb5) */ 621 - ses->sectype = RawNTLMSSP; 623 + if (ses->sectype != Kerberos && ses->sectype != RawNTLMSSP) 624 + ses->sectype = RawNTLMSSP; 622 625 623 626 ssetup_ntlmssp_authenticate: 624 627 if (phase == NtLmChallenge) ··· 648 649 iov[0].iov_base = (char *)req; 649 650 /* 4 for rfc1002 length field and 1 for pad */ 650 651 iov[0].iov_len = get_rfc1002_length(req) + 4 - 1; 651 - if (phase == NtLmNegotiate) { 652 + 653 + if (ses->sectype == Kerberos) { 654 + #ifdef CONFIG_CIFS_UPCALL 655 + struct cifs_spnego_msg *msg; 656 + 657 + spnego_key = cifs_get_spnego_key(ses); 658 + if (IS_ERR(spnego_key)) { 659 + rc = PTR_ERR(spnego_key); 660 + spnego_key = NULL; 661 + goto ssetup_exit; 662 + } 663 + 664 + msg = spnego_key->payload.data; 665 + /* 666 + * check version field to make sure that cifs.upcall is 667 + * sending us a response in an expected form 668 + */ 669 + if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) { 670 + cifs_dbg(VFS, 671 + "bad cifs.upcall version. Expected %d got %d", 672 + CIFS_SPNEGO_UPCALL_VERSION, msg->version); 673 + rc = -EKEYREJECTED; 674 + goto ssetup_exit; 675 + } 676 + ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len, 677 + GFP_KERNEL); 678 + if (!ses->auth_key.response) { 679 + cifs_dbg(VFS, 680 + "Kerberos can't allocate (%u bytes) memory", 681 + msg->sesskey_len); 682 + rc = -ENOMEM; 683 + goto ssetup_exit; 684 + } 685 + ses->auth_key.len = msg->sesskey_len; 686 + blob_length = msg->secblob_len; 687 + iov[1].iov_base = msg->data + msg->sesskey_len; 688 + iov[1].iov_len = blob_length; 689 + #else 690 + rc = -EOPNOTSUPP; 691 + goto ssetup_exit; 692 + #endif /* CONFIG_CIFS_UPCALL */ 693 + } else if (phase == NtLmNegotiate) { /* if not krb5 must be ntlmssp */ 652 694 ntlmssp_blob = kmalloc(sizeof(struct _NEGOTIATE_MESSAGE), 653 695 GFP_KERNEL); 654 696 if (ntlmssp_blob == NULL) { ··· 712 672 /* with raw NTLMSSP we don't encapsulate in SPNEGO */ 713 673 security_blob = ntlmssp_blob; 714 674 } 675 + iov[1].iov_base = security_blob; 676 + iov[1].iov_len = blob_length; 715 677 } else if (phase == NtLmAuthenticate) { 716 678 req->hdr.SessionId = ses->Suid; 717 679 ntlmssp_blob = kzalloc(sizeof(struct _NEGOTIATE_MESSAGE) + 500, ··· 741 699 } else { 742 700 security_blob = ntlmssp_blob; 743 701 } 702 + iov[1].iov_base = security_blob; 703 + iov[1].iov_len = blob_length; 744 704 } else { 745 705 cifs_dbg(VFS, "illegal ntlmssp phase\n"); 746 706 rc = -EIO; ··· 754 710 cpu_to_le16(sizeof(struct smb2_sess_setup_req) - 755 711 1 /* pad */ - 4 /* rfc1001 len */); 756 712 req->SecurityBufferLength = cpu_to_le16(blob_length); 757 - iov[1].iov_base = security_blob; 758 - iov[1].iov_len = blob_length; 759 713 760 714 inc_rfc1001_len(req, blob_length - 1 /* pad */); 761 715 ··· 764 722 765 723 kfree(security_blob); 766 724 rsp = (struct smb2_sess_setup_rsp *)iov[0].iov_base; 725 + ses->Suid = rsp->hdr.SessionId; 767 726 if (resp_buftype != CIFS_NO_BUFFER && 768 727 rsp->hdr.Status == STATUS_MORE_PROCESSING_REQUIRED) { 769 728 if (phase != NtLmNegotiate) { ··· 782 739 /* NTLMSSP Negotiate sent now processing challenge (response) */ 783 740 phase = NtLmChallenge; /* process ntlmssp challenge */ 784 741 rc = 0; /* MORE_PROCESSING is not an error here but expected */ 785 - ses->Suid = rsp->hdr.SessionId; 786 742 rc = decode_ntlmssp_challenge(rsp->Buffer, 787 743 le16_to_cpu(rsp->SecurityBufferLength), ses); 788 744 } ··· 837 795 if (!server->sign) { 838 796 kfree(ses->auth_key.response); 839 797 ses->auth_key.response = NULL; 798 + } 799 + if (spnego_key) { 800 + key_invalidate(spnego_key); 801 + key_put(spnego_key); 840 802 } 841 803 kfree(ses->ntlmssp); 842 804 ··· 922 876 if (tcon && tcon->bad_network_name) 923 877 return -ENOENT; 924 878 879 + if ((tcon->seal) && 880 + ((ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) == 0)) { 881 + cifs_dbg(VFS, "encryption requested but no server support"); 882 + return -EOPNOTSUPP; 883 + } 884 + 925 885 unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL); 926 886 if (unc_path == NULL) 927 887 return -ENOMEM; ··· 1007 955 ((tcon->share_flags & SHI1005_FLAGS_DFS) == 0)) 1008 956 cifs_dbg(VFS, "DFS capability contradicts DFS flag\n"); 1009 957 init_copy_chunk_defaults(tcon); 958 + if (tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA) 959 + cifs_dbg(VFS, "Encrypted shares not supported"); 1010 960 if (tcon->ses->server->ops->validate_negotiate) 1011 961 rc = tcon->ses->server->ops->validate_negotiate(xid, tcon); 1012 962 tcon_exit: