aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <stfrench@microsoft.com>2019-01-03 03:37:21 -0500
committerSteve French <stfrench@microsoft.com>2019-01-03 15:45:58 -0500
commitd5c7076b772ad7dcdb92303397b36aee8fa0d25d (patch)
treea72d03762f58afc1eade699df3cf4d05fbfbcc00
parent55a7f0065533f71991c720457ea24ff2fe909f81 (diff)
smb3: add smb3.1.1 to default dialect list
SMB3.1.1 dialect has additional security (among other) features and should be requested when mounting to modern servers so it can be used if the server supports it. Add SMB3.1.1 to the default list of dialects requested. Signed-off-by: Steve French <stfrench@microsoft.com> Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
-rw-r--r--fs/cifs/smb2pdu.c40
-rw-r--r--fs/cifs/smb2pdu.h2
2 files changed, 28 insertions, 14 deletions
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index e283590955cd..e57f6aa1d638 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -451,10 +451,6 @@ smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon,
451} 451}
452 452
453 453
454/* offset is sizeof smb2_negotiate_req but rounded up to 8 bytes */
455#define OFFSET_OF_NEG_CONTEXT 0x68 /* sizeof(struct smb2_negotiate_req) */
456
457
458#define SMB2_PREAUTH_INTEGRITY_CAPABILITIES cpu_to_le16(1) 454#define SMB2_PREAUTH_INTEGRITY_CAPABILITIES cpu_to_le16(1)
459#define SMB2_ENCRYPTION_CAPABILITIES cpu_to_le16(2) 455#define SMB2_ENCRYPTION_CAPABILITIES cpu_to_le16(2)
460#define SMB2_POSIX_EXTENSIONS_AVAILABLE cpu_to_le16(0x100) 456#define SMB2_POSIX_EXTENSIONS_AVAILABLE cpu_to_le16(0x100)
@@ -491,10 +487,24 @@ static void
491assemble_neg_contexts(struct smb2_negotiate_req *req, 487assemble_neg_contexts(struct smb2_negotiate_req *req,
492 unsigned int *total_len) 488 unsigned int *total_len)
493{ 489{
494 char *pneg_ctxt = (char *)req + OFFSET_OF_NEG_CONTEXT; 490 char *pneg_ctxt = (char *)req;
495 unsigned int ctxt_len; 491 unsigned int ctxt_len;
496 492
497 *total_len += 2; /* Add 2 due to round to 8 byte boundary for 1st ctxt */ 493 if (*total_len > 200) {
494 /* In case length corrupted don't want to overrun smb buffer */
495 cifs_dbg(VFS, "Bad frame length assembling neg contexts\n");
496 return;
497 }
498
499 /*
500 * round up total_len of fixed part of SMB3 negotiate request to 8
501 * byte boundary before adding negotiate contexts
502 */
503 *total_len = roundup(*total_len, 8);
504
505 pneg_ctxt = (*total_len) + (char *)req;
506 req->NegotiateContextOffset = cpu_to_le32(*total_len);
507
498 build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt); 508 build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt);
499 ctxt_len = DIV_ROUND_UP(sizeof(struct smb2_preauth_neg_context), 8) * 8; 509 ctxt_len = DIV_ROUND_UP(sizeof(struct smb2_preauth_neg_context), 8) * 8;
500 *total_len += ctxt_len; 510 *total_len += ctxt_len;
@@ -508,7 +518,6 @@ assemble_neg_contexts(struct smb2_negotiate_req *req,
508 build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt); 518 build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt);
509 *total_len += sizeof(struct smb2_posix_neg_context); 519 *total_len += sizeof(struct smb2_posix_neg_context);
510 520
511 req->NegotiateContextOffset = cpu_to_le32(OFFSET_OF_NEG_CONTEXT);
512 req->NegotiateContextCount = cpu_to_le16(3); 521 req->NegotiateContextCount = cpu_to_le16(3);
513} 522}
514 523
@@ -724,8 +733,9 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
724 req->Dialects[0] = cpu_to_le16(SMB21_PROT_ID); 733 req->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
725 req->Dialects[1] = cpu_to_le16(SMB30_PROT_ID); 734 req->Dialects[1] = cpu_to_le16(SMB30_PROT_ID);
726 req->Dialects[2] = cpu_to_le16(SMB302_PROT_ID); 735 req->Dialects[2] = cpu_to_le16(SMB302_PROT_ID);
727 req->DialectCount = cpu_to_le16(3); 736 req->Dialects[3] = cpu_to_le16(SMB311_PROT_ID);
728 total_len += 6; 737 req->DialectCount = cpu_to_le16(4);
738 total_len += 8;
729 } else { 739 } else {
730 /* otherwise send specific dialect */ 740 /* otherwise send specific dialect */
731 req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id); 741 req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id);
@@ -749,7 +759,9 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
749 else { 759 else {
750 memcpy(req->ClientGUID, server->client_guid, 760 memcpy(req->ClientGUID, server->client_guid,
751 SMB2_CLIENT_GUID_SIZE); 761 SMB2_CLIENT_GUID_SIZE);
752 if (ses->server->vals->protocol_id == SMB311_PROT_ID) 762 if ((ses->server->vals->protocol_id == SMB311_PROT_ID) ||
763 (strcmp(ses->server->vals->version_string,
764 SMBDEFAULT_VERSION_STRING) == 0))
753 assemble_neg_contexts(req, &total_len); 765 assemble_neg_contexts(req, &total_len);
754 } 766 }
755 iov[0].iov_base = (char *)req; 767 iov[0].iov_base = (char *)req;
@@ -794,7 +806,8 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
794 } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) { 806 } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
795 /* ops set to 3.0 by default for default so update */ 807 /* ops set to 3.0 by default for default so update */
796 ses->server->ops = &smb21_operations; 808 ses->server->ops = &smb21_operations;
797 } 809 } else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID))
810 ses->server->ops = &smb311_operations;
798 } else if (le16_to_cpu(rsp->DialectRevision) != 811 } else if (le16_to_cpu(rsp->DialectRevision) !=
799 ses->server->vals->protocol_id) { 812 ses->server->vals->protocol_id) {
800 /* if requested single dialect ensure returned dialect matched */ 813 /* if requested single dialect ensure returned dialect matched */
@@ -941,13 +954,14 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon)
941 pneg_inbuf->DialectCount = cpu_to_le16(2); 954 pneg_inbuf->DialectCount = cpu_to_le16(2);
942 /* structure is big enough for 3 dialects, sending only 2 */ 955 /* structure is big enough for 3 dialects, sending only 2 */
943 inbuflen = sizeof(*pneg_inbuf) - 956 inbuflen = sizeof(*pneg_inbuf) -
944 sizeof(pneg_inbuf->Dialects[0]); 957 (2 * sizeof(pneg_inbuf->Dialects[0]));
945 } else if (strcmp(tcon->ses->server->vals->version_string, 958 } else if (strcmp(tcon->ses->server->vals->version_string,
946 SMBDEFAULT_VERSION_STRING) == 0) { 959 SMBDEFAULT_VERSION_STRING) == 0) {
947 pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID); 960 pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
948 pneg_inbuf->Dialects[1] = cpu_to_le16(SMB30_PROT_ID); 961 pneg_inbuf->Dialects[1] = cpu_to_le16(SMB30_PROT_ID);
949 pneg_inbuf->Dialects[2] = cpu_to_le16(SMB302_PROT_ID); 962 pneg_inbuf->Dialects[2] = cpu_to_le16(SMB302_PROT_ID);
950 pneg_inbuf->DialectCount = cpu_to_le16(3); 963 pneg_inbuf->Dialects[3] = cpu_to_le16(SMB311_PROT_ID);
964 pneg_inbuf->DialectCount = cpu_to_le16(4);
951 /* structure is big enough for 3 dialects */ 965 /* structure is big enough for 3 dialects */
952 inbuflen = sizeof(*pneg_inbuf); 966 inbuflen = sizeof(*pneg_inbuf);
953 } else { 967 } else {
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index 05dea6750c33..7a2d0a2255e6 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -898,7 +898,7 @@ struct validate_negotiate_info_req {
898 __u8 Guid[SMB2_CLIENT_GUID_SIZE]; 898 __u8 Guid[SMB2_CLIENT_GUID_SIZE];
899 __le16 SecurityMode; 899 __le16 SecurityMode;
900 __le16 DialectCount; 900 __le16 DialectCount;
901 __le16 Dialects[3]; /* BB expand this if autonegotiate > 3 dialects */ 901 __le16 Dialects[4]; /* BB expand this if autonegotiate > 4 dialects */
902} __packed; 902} __packed;
903 903
904struct validate_negotiate_info_rsp { 904struct validate_negotiate_info_rsp {