History

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

Linus Torvalds committed 11 years ago

Commit 69ea8b82 parents d8cc397 88627143 files · +126 −19Browse files

Unified · Split

3 files
  1. fs/cifs/cifsencrypt.c +51 −2
  2. fs/cifs/smb2ops.c +6 −2
  3. fs/cifs/smb2pdu.c +69 −15
fs/cifs/cifsencrypt.c+51−2
@@ -444,6 +444,48 @@ find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp) · 443 unmodified lines
444444 return 0;
445445 }
446446
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+
447489 static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
448490 const struct nls_table *nls_cp)
449491 {
@@ -641,6 +683,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) · 191 unmodified lines
641683 struct ntlmv2_resp *ntlmv2;
642684 char ntlmv2_hash[16];
643685 unsigned char *tiblob = NULL; /* target info blob */
686+ __le64 rsp_timestamp;
644687
645688 if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) {
646689 if (!ses->domainName) {
@@ -659,6 +702,12 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) · 12 unmodified lines
659702 }
660703 }
661704
705+ /* Must be within 5 minutes of the server (or in range +/-2h
706+ * in case of Mac OS X), so simply carry over server timestamp
707+ * (as Windows 7 does)
708+ */
709+ rsp_timestamp = find_timestamp(ses);
710+
662711 baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp);
663712 tilen = ses->auth_key.len;
664713 tiblob = ses->auth_key.response;
@@ -675,8 +724,8 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) · 10 unmodified lines
675724 (ses->auth_key.response + CIFS_SESS_KEY_SIZE);
676725 ntlmv2->blob_signature = cpu_to_le32(0x00000101);
677726 ntlmv2->reserved = 0;
678− /* Must be within 5 minutes of the server */
679− ntlmv2->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
727+ ntlmv2->time = rsp_timestamp;
728+
680729 get_random_bytes(&ntlmv2->client_chal, sizeof(ntlmv2->client_chal));
681730 ntlmv2->reserved2 = 0;
682731
fs/cifs/smb2ops.c+6−2
@@ -50,9 +50,13 @@ change_conf(struct TCP_Server_Info *server) · 49 unmodified lines
5050 break;
5151 default:
5252 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+
5459 server->echo_credits = 1;
55− server->oplock_credits = 1;
5660 }
5761 server->credits -= server->echo_credits + server->oplock_credits;
5862 return 0;
fs/cifs/smb2pdu.c+69−15
@@ -46,6 +46,7 @@ · 45 unmodified lines
4646 #include "smb2status.h"
4747 #include "smb2glob.h"
4848 #include "cifspdu.h"
49+#include "cifs_spnego.h"
4950
5051 /*
5152 * The following table defines the expected "StructureSize" of SMB2 requests
@@ -486,19 +487,15 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) · 434 unmodified lines
486487 cifs_dbg(FYI, "missing security blob on negprot\n");
487488
488489 rc = cifs_enable_signing(server, ses->sign);
489−#ifdef CONFIG_SMB2_ASN1 /* BB REMOVEME when updated asn1.c ready */
490490 if (rc)
491491 goto neg_exit;
492− if (blob_length)
492+ if (blob_length) {
493493 rc = decode_negTokenInit(security_blob, blob_length, server);
494− if (rc == 1)
495− rc = 0;
496− else if (rc == 0) {
497− rc = -EIO;
498− goto neg_exit;
494+ if (rc == 1)
495+ rc = 0;
496+ else if (rc == 0)
497+ rc = -EIO;
499498 }
500−#endif
501−
502499 neg_exit:
503500 free_rsp_buf(resp_buftype, rsp);
504501 return rc;
@@ -592,7 +589,8 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses, · 87 unmodified lines
592589 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
593590 struct TCP_Server_Info *server = ses->server;
594591 u16 blob_length = 0;
595− char *security_blob;
592+ struct key *spnego_key = NULL;
593+ char *security_blob = NULL;
596594 char *ntlmssp_blob = NULL;
597595 bool use_spnego = false; /* else use raw ntlmssp */
598596
@@ -620,7 +618,8 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses, · 21 unmodified lines
620618 ses->ntlmssp->sesskey_per_smbsess = true;
621619
622620 /* FIXME: allow for other auth types besides NTLMSSP (e.g. krb5) */
623− ses->sectype = RawNTLMSSP;
621+ if (ses->sectype != Kerberos && ses->sectype != RawNTLMSSP)
622+ ses->sectype = RawNTLMSSP;
624623
625624 ssetup_ntlmssp_authenticate:
626625 if (phase == NtLmChallenge)
@@ -649,7 +648,48 @@ ssetup_ntlmssp_authenticate: · 22 unmodified lines
649648 iov[0].iov_base = (char *)req;
650649 /* 4 for rfc1002 length field and 1 for pad */
651650 iov[0].iov_len = get_rfc1002_length(req) + 4 - 1;
652− if (phase == NtLmNegotiate) {
651+
652+ if (ses->sectype == Kerberos) {
653+#ifdef CONFIG_CIFS_UPCALL
654+ struct cifs_spnego_msg *msg;
655+
656+ spnego_key = cifs_get_spnego_key(ses);
657+ if (IS_ERR(spnego_key)) {
658+ rc = PTR_ERR(spnego_key);
659+ spnego_key = NULL;
660+ goto ssetup_exit;
661+ }
662+
663+ msg = spnego_key->payload.data;
664+ /*
665+ * check version field to make sure that cifs.upcall is
666+ * sending us a response in an expected form
667+ */
668+ if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
669+ cifs_dbg(VFS,
670+ "bad cifs.upcall version. Expected %d got %d",
671+ CIFS_SPNEGO_UPCALL_VERSION, msg->version);
672+ rc = -EKEYREJECTED;
673+ goto ssetup_exit;
674+ }
675+ ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
676+ GFP_KERNEL);
677+ if (!ses->auth_key.response) {
678+ cifs_dbg(VFS,
679+ "Kerberos can't allocate (%u bytes) memory",
680+ msg->sesskey_len);
681+ rc = -ENOMEM;
682+ goto ssetup_exit;
683+ }
684+ ses->auth_key.len = msg->sesskey_len;
685+ blob_length = msg->secblob_len;
686+ iov[1].iov_base = msg->data + msg->sesskey_len;
687+ iov[1].iov_len = blob_length;
688+#else
689+ rc = -EOPNOTSUPP;
690+ goto ssetup_exit;
691+#endif /* CONFIG_CIFS_UPCALL */
692+ } else if (phase == NtLmNegotiate) { /* if not krb5 must be ntlmssp */
653693 ntlmssp_blob = kmalloc(sizeof(struct _NEGOTIATE_MESSAGE),
654694 GFP_KERNEL);
655695 if (ntlmssp_blob == NULL) {
@@ -672,6 +712,8 @@ ssetup_ntlmssp_authenticate: · 16 unmodified lines
672712 /* with raw NTLMSSP we don't encapsulate in SPNEGO */
673713 security_blob = ntlmssp_blob;
674714 }
715+ iov[1].iov_base = security_blob;
716+ iov[1].iov_len = blob_length;
675717 } else if (phase == NtLmAuthenticate) {
676718 req->hdr.SessionId = ses->Suid;
677719 ntlmssp_blob = kzalloc(sizeof(struct _NEGOTIATE_MESSAGE) + 500,
@@ -699,6 +741,8 @@ ssetup_ntlmssp_authenticate: · 21 unmodified lines
699741 } else {
700742 security_blob = ntlmssp_blob;
701743 }
744+ iov[1].iov_base = security_blob;
745+ iov[1].iov_len = blob_length;
702746 } else {
703747 cifs_dbg(VFS, "illegal ntlmssp phase\n");
704748 rc = -EIO;
@@ -710,8 +754,6 @@ ssetup_ntlmssp_authenticate: · 5 unmodified lines
710754 cpu_to_le16(sizeof(struct smb2_sess_setup_req) -
711755 1 /* pad */ - 4 /* rfc1001 len */);
712756 req->SecurityBufferLength = cpu_to_le16(blob_length);
713− iov[1].iov_base = security_blob;
714− iov[1].iov_len = blob_length;
715757
716758 inc_rfc1001_len(req, blob_length - 1 /* pad */);
717759
@@ -722,6 +764,7 @@ ssetup_ntlmssp_authenticate: · 4 unmodified lines
722764
723765 kfree(security_blob);
724766 rsp = (struct smb2_sess_setup_rsp *)iov[0].iov_base;
767+ ses->Suid = rsp->hdr.SessionId;
725768 if (resp_buftype != CIFS_NO_BUFFER &&
726769 rsp->hdr.Status == STATUS_MORE_PROCESSING_REQUIRED) {
727770 if (phase != NtLmNegotiate) {
@@ -739,7 +782,6 @@ ssetup_ntlmssp_authenticate: · 11 unmodified lines
739782 /* NTLMSSP Negotiate sent now processing challenge (response) */
740783 phase = NtLmChallenge; /* process ntlmssp challenge */
741784 rc = 0; /* MORE_PROCESSING is not an error here but expected */
742− ses->Suid = rsp->hdr.SessionId;
743785 rc = decode_ntlmssp_challenge(rsp->Buffer,
744786 le16_to_cpu(rsp->SecurityBufferLength), ses);
745787 }
@@ -796,6 +838,10 @@ keygen_exit: · 50 unmodified lines
796838 kfree(ses->auth_key.response);
797839 ses->auth_key.response = NULL;
798840 }
841+ if (spnego_key) {
842+ key_invalidate(spnego_key);
843+ key_put(spnego_key);
844+ }
799845 kfree(ses->ntlmssp);
800846
801847 return rc;
@@ -876,6 +922,12 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, · 74 unmodified lines
876922 if (tcon && tcon->bad_network_name)
877923 return -ENOENT;
878924
925+ if ((tcon->seal) &&
926+ ((ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) == 0)) {
927+ cifs_dbg(VFS, "encryption requested but no server support");
928+ return -EOPNOTSUPP;
929+ }
930+
879931 unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL);
880932 if (unc_path == NULL)
881933 return -ENOMEM;
@@ -955,6 +1007,8 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, · 73 unmodified lines
9551007 ((tcon->share_flags & SHI1005_FLAGS_DFS) == 0))
9561008 cifs_dbg(VFS, "DFS capability contradicts DFS flag\n");
9571009 init_copy_chunk_defaults(tcon);
1010+ if (tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA)
1011+ cifs_dbg(VFS, "Encrypted shares not supported");
9581012 if (tcon->ses->server->ops->validate_negotiate)
9591013 rc = tcon->ses->server->ops->validate_negotiate(xid, tcon);
9601014 tcon_exit: