aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifsencrypt.c4
-rw-r--r--fs/cifs/cifsglob.h2
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/cifssmb.c92
-rw-r--r--fs/cifs/connect.c117
-rw-r--r--fs/cifs/sess.c57
-rw-r--r--fs/cifs/smb2pdu.c21
7 files changed, 115 insertions, 180 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index a85a83d1d00f..30bea6bd3023 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -535,7 +535,7 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
535 return rc; 535 return rc;
536 } 536 }
537 537
538 if (ses->server->secType == RawNTLMSSP) 538 if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED)
539 memcpy(ses->auth_key.response + offset, 539 memcpy(ses->auth_key.response + offset,
540 ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE); 540 ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
541 else 541 else
@@ -567,7 +567,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
567 char ntlmv2_hash[16]; 567 char ntlmv2_hash[16];
568 unsigned char *tiblob = NULL; /* target info blob */ 568 unsigned char *tiblob = NULL; /* target info blob */
569 569
570 if (ses->server->secType == RawNTLMSSP) { 570 if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) {
571 if (!ses->domainName) { 571 if (!ses->domainName) {
572 rc = find_domain_name(ses, nls_cp); 572 rc = find_domain_name(ses, nls_cp);
573 if (rc) { 573 if (rc) {
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 49020ae460cf..ad3408042ff0 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -401,7 +401,6 @@ struct smb_vol {
401 kgid_t backupgid; 401 kgid_t backupgid;
402 umode_t file_mode; 402 umode_t file_mode;
403 umode_t dir_mode; 403 umode_t dir_mode;
404 unsigned secFlg;
405 enum securityEnum sectype; /* sectype requested via mnt opts */ 404 enum securityEnum sectype; /* sectype requested via mnt opts */
406 bool sign; /* was signing requested via mnt opts? */ 405 bool sign; /* was signing requested via mnt opts? */
407 bool retry:1; 406 bool retry:1;
@@ -519,7 +518,6 @@ struct TCP_Server_Info {
519 bool echoes:1; /* enable echoes */ 518 bool echoes:1; /* enable echoes */
520#endif 519#endif
521 u16 dialect; /* dialect index that server chose */ 520 u16 dialect; /* dialect index that server chose */
522 enum securityEnum secType;
523 bool oplocks:1; /* enable oplocks */ 521 bool oplocks:1; /* enable oplocks */
524 unsigned int maxReq; /* Clients should submit no more */ 522 unsigned int maxReq; /* Clients should submit no more */
525 /* than maxReq distinct unanswered SMBs to the server when using */ 523 /* than maxReq distinct unanswered SMBs to the server when using */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index ede010fd046a..a82b3c09888b 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -118,6 +118,8 @@ extern void header_assemble(struct smb_hdr *, char /* command */ ,
118extern int small_smb_init_no_tc(const int smb_cmd, const int wct, 118extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
119 struct cifs_ses *ses, 119 struct cifs_ses *ses,
120 void **request_buf); 120 void **request_buf);
121extern enum securityEnum select_sectype(struct TCP_Server_Info *server,
122 enum securityEnum requested);
121extern int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses, 123extern int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
122 const struct nls_table *nls_cp); 124 const struct nls_table *nls_cp);
123extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); 125extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index dd7e2f61f607..a35aad2060c5 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -368,11 +368,12 @@ vt2_err:
368} 368}
369 369
370static int 370static int
371decode_ext_sec_blob(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr) 371decode_ext_sec_blob(struct cifs_ses *ses, NEGOTIATE_RSP *pSMBr)
372{ 372{
373 int rc = 0; 373 int rc = 0;
374 u16 count; 374 u16 count;
375 char *guid = pSMBr->u.extended_response.GUID; 375 char *guid = pSMBr->u.extended_response.GUID;
376 struct TCP_Server_Info *server = ses->server;
376 377
377 count = get_bcc(&pSMBr->hdr); 378 count = get_bcc(&pSMBr->hdr);
378 if (count < SMB1_CLIENT_GUID_SIZE) 379 if (count < SMB1_CLIENT_GUID_SIZE)
@@ -391,27 +392,13 @@ decode_ext_sec_blob(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
391 } 392 }
392 393
393 if (count == SMB1_CLIENT_GUID_SIZE) { 394 if (count == SMB1_CLIENT_GUID_SIZE) {
394 server->secType = RawNTLMSSP; 395 server->sec_ntlmssp = true;
395 } else { 396 } else {
396 count -= SMB1_CLIENT_GUID_SIZE; 397 count -= SMB1_CLIENT_GUID_SIZE;
397 rc = decode_negTokenInit( 398 rc = decode_negTokenInit(
398 pSMBr->u.extended_response.SecurityBlob, count, server); 399 pSMBr->u.extended_response.SecurityBlob, count, server);
399 if (rc != 1) 400 if (rc != 1)
400 return -EINVAL; 401 return -EINVAL;
401
402 /* Make sure server supports what we want to use */
403 switch(server->secType) {
404 case Kerberos:
405 if (!server->sec_kerberos && !server->sec_mskerberos)
406 return -EOPNOTSUPP;
407 break;
408 case RawNTLMSSP:
409 if (!server->sec_ntlmssp)
410 return -EOPNOTSUPP;
411 break;
412 default:
413 return -EOPNOTSUPP;
414 }
415 } 402 }
416 403
417 return 0; 404 return 0;
@@ -462,8 +449,7 @@ cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
462 449
463#ifdef CONFIG_CIFS_WEAK_PW_HASH 450#ifdef CONFIG_CIFS_WEAK_PW_HASH
464static int 451static int
465decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr, 452decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
466 unsigned int secFlags)
467{ 453{
468 __s16 tmp; 454 __s16 tmp;
469 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr; 455 struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
@@ -471,12 +457,6 @@ decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr,
471 if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT) 457 if (server->dialect != LANMAN_PROT && server->dialect != LANMAN2_PROT)
472 return -EOPNOTSUPP; 458 return -EOPNOTSUPP;
473 459
474 if ((secFlags & CIFSSEC_MAY_LANMAN) || (secFlags & CIFSSEC_MAY_PLNTXT))
475 server->secType = LANMAN;
476 else {
477 cifs_dbg(VFS, "mount failed weak security disabled in /proc/fs/cifs/SecurityFlags\n");
478 return -EOPNOTSUPP;
479 }
480 server->sec_mode = le16_to_cpu(rsp->SecurityMode); 460 server->sec_mode = le16_to_cpu(rsp->SecurityMode);
481 server->maxReq = min_t(unsigned int, 461 server->maxReq = min_t(unsigned int,
482 le16_to_cpu(rsp->MaxMpxCount), 462 le16_to_cpu(rsp->MaxMpxCount),
@@ -542,8 +522,7 @@ decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr,
542} 522}
543#else 523#else
544static inline int 524static inline int
545decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr, 525decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
546 unsigned int secFlags)
547{ 526{
548 cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n"); 527 cifs_dbg(VFS, "mount failed, cifs module not built with CIFS_WEAK_PW_HASH support\n");
549 return -EOPNOTSUPP; 528 return -EOPNOTSUPP;
@@ -551,17 +530,20 @@ decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr,
551#endif 530#endif
552 531
553static bool 532static bool
554should_set_ext_sec_flag(unsigned int secFlags) 533should_set_ext_sec_flag(enum securityEnum sectype)
555{ 534{
556 if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) 535 switch (sectype) {
557 return true; 536 case RawNTLMSSP:
558 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) 537 case Kerberos:
559 return true;
560 else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
561 return true;
562 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP)
563 return true; 538 return true;
564 return false; 539 case Unspecified:
540 if (global_secflags &
541 (CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP))
542 return true;
543 /* Fallthrough */
544 default:
545 return false;
546 }
565} 547}
566 548
567int 549int
@@ -574,7 +556,6 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
574 int i; 556 int i;
575 struct TCP_Server_Info *server = ses->server; 557 struct TCP_Server_Info *server = ses->server;
576 u16 count; 558 u16 count;
577 unsigned int secFlags;
578 559
579 if (!server) { 560 if (!server) {
580 WARN(1, "%s: server is NULL!\n", __func__); 561 WARN(1, "%s: server is NULL!\n", __func__);
@@ -586,18 +567,10 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
586 if (rc) 567 if (rc)
587 return rc; 568 return rc;
588 569
589 /* if any of auth flags (ie not sign or seal) are overriden use them */
590 if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
591 secFlags = ses->overrideSecFlg; /* BB FIXME fix sign flags? */
592 else /* if override flags set only sign/seal OR them with global auth */
593 secFlags = global_secflags | ses->overrideSecFlg;
594
595 cifs_dbg(FYI, "secFlags 0x%x\n", secFlags);
596
597 pSMB->hdr.Mid = get_next_mid(server); 570 pSMB->hdr.Mid = get_next_mid(server);
598 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS); 571 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
599 572
600 if (should_set_ext_sec_flag(secFlags)) { 573 if (should_set_ext_sec_flag(ses->sectype)) {
601 cifs_dbg(FYI, "Requesting extended security."); 574 cifs_dbg(FYI, "Requesting extended security.");
602 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 575 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
603 } 576 }
@@ -627,7 +600,7 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
627 goto neg_err_exit; 600 goto neg_err_exit;
628 } else if (pSMBr->hdr.WordCount == 13) { 601 } else if (pSMBr->hdr.WordCount == 13) {
629 server->negflavor = CIFS_NEGFLAVOR_LANMAN; 602 server->negflavor = CIFS_NEGFLAVOR_LANMAN;
630 rc = decode_lanman_negprot_rsp(server, pSMBr, secFlags); 603 rc = decode_lanman_negprot_rsp(server, pSMBr);
631 goto signing_check; 604 goto signing_check;
632 } else if (pSMBr->hdr.WordCount != 17) { 605 } else if (pSMBr->hdr.WordCount != 17) {
633 /* unknown wct */ 606 /* unknown wct */
@@ -640,31 +613,6 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
640 if ((server->sec_mode & SECMODE_USER) == 0) 613 if ((server->sec_mode & SECMODE_USER) == 0)
641 cifs_dbg(FYI, "share mode security\n"); 614 cifs_dbg(FYI, "share mode security\n");
642 615
643 if ((server->sec_mode & SECMODE_PW_ENCRYPT) == 0)
644#ifdef CONFIG_CIFS_WEAK_PW_HASH
645 if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
646#endif /* CIFS_WEAK_PW_HASH */
647 cifs_dbg(VFS, "Server requests plain text password but client support disabled\n");
648
649 if ((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
650 server->secType = NTLMv2;
651 else if (secFlags & CIFSSEC_MAY_NTLM)
652 server->secType = NTLM;
653 else if (secFlags & CIFSSEC_MAY_NTLMV2)
654 server->secType = NTLMv2;
655 else if (secFlags & CIFSSEC_MAY_KRB5)
656 server->secType = Kerberos;
657 else if (secFlags & CIFSSEC_MAY_NTLMSSP)
658 server->secType = RawNTLMSSP;
659 else if (secFlags & CIFSSEC_MAY_LANMAN)
660 server->secType = LANMAN;
661 else {
662 rc = -EOPNOTSUPP;
663 cifs_dbg(VFS, "Invalid security type\n");
664 goto neg_err_exit;
665 }
666 /* else ... any others ...? */
667
668 /* one byte, so no need to convert this or EncryptionKeyLen from 616 /* one byte, so no need to convert this or EncryptionKeyLen from
669 little endian */ 617 little endian */
670 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount), 618 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
@@ -686,7 +634,7 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
686 server->capabilities & CAP_EXTENDED_SECURITY) && 634 server->capabilities & CAP_EXTENDED_SECURITY) &&
687 (pSMBr->EncryptionKeyLength == 0)) { 635 (pSMBr->EncryptionKeyLength == 0)) {
688 server->negflavor = CIFS_NEGFLAVOR_EXTENDED; 636 server->negflavor = CIFS_NEGFLAVOR_EXTENDED;
689 rc = decode_ext_sec_blob(server, pSMBr); 637 rc = decode_ext_sec_blob(ses, pSMBr);
690 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) { 638 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
691 rc = -EIO; /* no crypt key only if plain text pwd */ 639 rc = -EIO; /* no crypt key only if plain text pwd */
692 } else { 640 } else {
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index acbb255352af..c4c6aa99ee1c 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1033,56 +1033,40 @@ static int cifs_parse_security_flavors(char *value,
1033 vol->sign = false; 1033 vol->sign = false;
1034 1034
1035 switch (match_token(value, cifs_secflavor_tokens, args)) { 1035 switch (match_token(value, cifs_secflavor_tokens, args)) {
1036 case Opt_sec_krb5p:
1037 cifs_dbg(VFS, "sec=krb5p is not supported!\n");
1038 return 1;
1039 case Opt_sec_krb5i:
1040 vol->sign = true;
1041 /* Fallthrough */
1036 case Opt_sec_krb5: 1042 case Opt_sec_krb5:
1037 vol->sectype = Kerberos; 1043 vol->sectype = Kerberos;
1038 vol->secFlg |= CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_SIGN;
1039 break; 1044 break;
1040 case Opt_sec_krb5i: 1045 case Opt_sec_ntlmsspi:
1041 vol->sectype = Kerberos;
1042 vol->sign = true; 1046 vol->sign = true;
1043 vol->secFlg |= CIFSSEC_MAY_KRB5 | CIFSSEC_MUST_SIGN; 1047 /* Fallthrough */
1044 break;
1045 case Opt_sec_krb5p:
1046 /* vol->secFlg |= CIFSSEC_MUST_SEAL | CIFSSEC_MAY_KRB5; */
1047 cifs_dbg(VFS, "Krb5 cifs privacy not supported\n");
1048 break;
1049 case Opt_sec_ntlmssp: 1048 case Opt_sec_ntlmssp:
1050 vol->sectype = RawNTLMSSP; 1049 vol->sectype = RawNTLMSSP;
1051 vol->secFlg |= CIFSSEC_MAY_NTLMSSP;
1052 break; 1050 break;
1053 case Opt_sec_ntlmsspi: 1051 case Opt_sec_ntlmi:
1054 vol->sectype = RawNTLMSSP;
1055 vol->sign = true; 1052 vol->sign = true;
1056 vol->secFlg |= CIFSSEC_MAY_NTLMSSP | CIFSSEC_MUST_SIGN; 1053 /* Fallthrough */
1057 break;
1058 case Opt_ntlm: 1054 case Opt_ntlm:
1059 /* ntlm is default so can be turned off too */
1060 vol->sectype = NTLM; 1055 vol->sectype = NTLM;
1061 vol->secFlg |= CIFSSEC_MAY_NTLM;
1062 break; 1056 break;
1063 case Opt_sec_ntlmi: 1057 case Opt_sec_ntlmv2i:
1064 vol->sectype = NTLM;
1065 vol->sign = true; 1058 vol->sign = true;
1066 vol->secFlg |= CIFSSEC_MAY_NTLM | CIFSSEC_MUST_SIGN; 1059 /* Fallthrough */
1067 break;
1068 case Opt_sec_ntlmv2: 1060 case Opt_sec_ntlmv2:
1069 vol->sectype = NTLMv2; 1061 vol->sectype = NTLMv2;
1070 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
1071 break;
1072 case Opt_sec_ntlmv2i:
1073 vol->sectype = NTLMv2;
1074 vol->sign = true;
1075 vol->secFlg |= CIFSSEC_MAY_NTLMV2 | CIFSSEC_MUST_SIGN;
1076 break; 1062 break;
1077#ifdef CONFIG_CIFS_WEAK_PW_HASH 1063#ifdef CONFIG_CIFS_WEAK_PW_HASH
1078 case Opt_sec_lanman: 1064 case Opt_sec_lanman:
1079 vol->sectype = LANMAN; 1065 vol->sectype = LANMAN;
1080 vol->secFlg |= CIFSSEC_MAY_LANMAN;
1081 break; 1066 break;
1082#endif 1067#endif
1083 case Opt_sec_none: 1068 case Opt_sec_none:
1084 vol->nullauth = 1; 1069 vol->nullauth = 1;
1085 vol->secFlg |= CIFSSEC_MAY_NTLM;
1086 break; 1070 break;
1087 default: 1071 default:
1088 cifs_dbg(VFS, "bad security option: %s\n", value); 1072 cifs_dbg(VFS, "bad security option: %s\n", value);
@@ -1445,7 +1429,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1445 vol->local_lease = 1; 1429 vol->local_lease = 1;
1446 break; 1430 break;
1447 case Opt_sign: 1431 case Opt_sign:
1448 vol->secFlg |= CIFSSEC_MUST_SIGN;
1449 vol->sign = true; 1432 vol->sign = true;
1450 break; 1433 break;
1451 case Opt_seal: 1434 case Opt_seal:
@@ -2003,40 +1986,19 @@ match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
2003static bool 1986static bool
2004match_security(struct TCP_Server_Info *server, struct smb_vol *vol) 1987match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
2005{ 1988{
2006 unsigned int secFlags; 1989 /*
2007 1990 * The select_sectype function should either return the vol->sectype
2008 if (vol->secFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL))) 1991 * that was specified, or "Unspecified" if that sectype was not
2009 secFlags = vol->secFlg; 1992 * compatible with the given NEGOTIATE request.
2010 else 1993 */
2011 secFlags = global_secflags | vol->secFlg; 1994 if (select_sectype(server, vol->sectype) == Unspecified)
2012
2013 switch (server->secType) {
2014 case LANMAN:
2015 if (!(secFlags & (CIFSSEC_MAY_LANMAN|CIFSSEC_MAY_PLNTXT)))
2016 return false;
2017 break;
2018 case NTLMv2:
2019 if (!(secFlags & CIFSSEC_MAY_NTLMV2))
2020 return false;
2021 break;
2022 case NTLM:
2023 if (!(secFlags & CIFSSEC_MAY_NTLM))
2024 return false;
2025 break;
2026 case Kerberos:
2027 if (!(secFlags & CIFSSEC_MAY_KRB5))
2028 return false;
2029 break;
2030 case RawNTLMSSP:
2031 if (!(secFlags & CIFSSEC_MAY_NTLMSSP))
2032 return false;
2033 break;
2034 default:
2035 /* shouldn't happen */
2036 return false; 1995 return false;
2037 }
2038 1996
2039 /* now check if signing mode is acceptable */ 1997 /*
1998 * Now check if signing mode is acceptable. No need to check
1999 * global_secflags at this point since if MUST_SIGN is set then
2000 * the server->sign had better be too.
2001 */
2040 if (vol->sign && !server->sign) 2002 if (vol->sign && !server->sign)
2041 return false; 2003 return false;
2042 2004
@@ -2239,7 +2201,11 @@ out_err:
2239 2201
2240static int match_session(struct cifs_ses *ses, struct smb_vol *vol) 2202static int match_session(struct cifs_ses *ses, struct smb_vol *vol)
2241{ 2203{
2242 switch (ses->server->secType) { 2204 if (vol->sectype != Unspecified &&
2205 vol->sectype != ses->sectype)
2206 return 0;
2207
2208 switch (ses->sectype) {
2243 case Kerberos: 2209 case Kerberos:
2244 if (!uid_eq(vol->cred_uid, ses->cred_uid)) 2210 if (!uid_eq(vol->cred_uid, ses->cred_uid))
2245 return 0; 2211 return 0;
@@ -2516,7 +2482,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
2516 ses->cred_uid = volume_info->cred_uid; 2482 ses->cred_uid = volume_info->cred_uid;
2517 ses->linux_uid = volume_info->linux_uid; 2483 ses->linux_uid = volume_info->linux_uid;
2518 2484
2519 ses->overrideSecFlg = volume_info->secFlg;
2520 ses->sectype = volume_info->sectype; 2485 ses->sectype = volume_info->sectype;
2521 ses->sign = volume_info->sign; 2486 ses->sign = volume_info->sign;
2522 2487
@@ -3681,7 +3646,7 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
3681 NTLMv2 password here) */ 3646 NTLMv2 password here) */
3682#ifdef CONFIG_CIFS_WEAK_PW_HASH 3647#ifdef CONFIG_CIFS_WEAK_PW_HASH
3683 if ((global_secflags & CIFSSEC_MAY_LANMAN) && 3648 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
3684 (ses->server->secType == LANMAN)) 3649 (ses->sectype == LANMAN))
3685 calc_lanman_hash(tcon->password, ses->server->cryptkey, 3650 calc_lanman_hash(tcon->password, ses->server->cryptkey,
3686 ses->server->sec_mode & 3651 ses->server->sec_mode &
3687 SECMODE_PW_ENCRYPT ? true : false, 3652 SECMODE_PW_ENCRYPT ? true : false,
@@ -3893,27 +3858,11 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
3893static int 3858static int
3894cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses) 3859cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses)
3895{ 3860{
3896 switch (ses->server->secType) { 3861 vol->sectype = ses->sectype;
3897 case Kerberos: 3862
3898 vol->secFlg = CIFSSEC_MUST_KRB5; 3863 /* krb5 is special, since we don't need username or pw */
3864 if (vol->sectype == Kerberos)
3899 return 0; 3865 return 0;
3900 case NTLMv2:
3901 vol->secFlg = CIFSSEC_MUST_NTLMV2;
3902 break;
3903 case NTLM:
3904 vol->secFlg = CIFSSEC_MUST_NTLM;
3905 break;
3906 case RawNTLMSSP:
3907 vol->secFlg = CIFSSEC_MUST_NTLMSSP;
3908 break;
3909 case LANMAN:
3910 vol->secFlg = CIFSSEC_MUST_LANMAN;
3911 break;
3912 default:
3913 /* should never happen */
3914 vol->secFlg = 0;
3915 break;
3916 }
3917 3866
3918 return cifs_set_cifscreds(vol, ses); 3867 return cifs_set_cifscreds(vol, ses);
3919} 3868}
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 82b784a62c16..79358e341fd2 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -550,6 +550,56 @@ setup_ntlmv2_ret:
550 return rc; 550 return rc;
551} 551}
552 552
553enum securityEnum
554select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
555{
556 switch (server->negflavor) {
557 case CIFS_NEGFLAVOR_EXTENDED:
558 switch (requested) {
559 case Kerberos:
560 case RawNTLMSSP:
561 return requested;
562 case Unspecified:
563 if (server->sec_ntlmssp &&
564 (global_secflags & CIFSSEC_MAY_NTLMSSP))
565 return RawNTLMSSP;
566 if ((server->sec_kerberos || server->sec_mskerberos) &&
567 (global_secflags & CIFSSEC_MAY_KRB5))
568 return Kerberos;
569 /* Fallthrough */
570 default:
571 return Unspecified;
572 }
573 case CIFS_NEGFLAVOR_UNENCAP:
574 switch (requested) {
575 case NTLM:
576 case NTLMv2:
577 return requested;
578 case Unspecified:
579 if (global_secflags & CIFSSEC_MAY_NTLMV2)
580 return NTLMv2;
581 if (global_secflags & CIFSSEC_MAY_NTLM)
582 return NTLM;
583 /* Fallthrough */
584 default:
585 return Unspecified;
586 }
587 case CIFS_NEGFLAVOR_LANMAN:
588 switch (requested) {
589 case LANMAN:
590 return requested;
591 case Unspecified:
592 if (global_secflags & CIFSSEC_MAY_LANMAN)
593 return LANMAN;
594 /* Fallthrough */
595 default:
596 return Unspecified;
597 }
598 default:
599 return Unspecified;
600 }
601}
602
553int 603int
554CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses, 604CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
555 const struct nls_table *nls_cp) 605 const struct nls_table *nls_cp)
@@ -576,8 +626,13 @@ CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
576 return -EINVAL; 626 return -EINVAL;
577 } 627 }
578 628
579 type = ses->server->secType; 629 type = select_sectype(ses->server, ses->sectype);
580 cifs_dbg(FYI, "sess setup type %d\n", type); 630 cifs_dbg(FYI, "sess setup type %d\n", type);
631 if (type == Unspecified) {
632 cifs_dbg(VFS, "Unable to select appropriate authentication method!");
633 return -EINVAL;
634 }
635
581 if (type == RawNTLMSSP) { 636 if (type == RawNTLMSSP) {
582 /* if memory allocation is successful, caller of this function 637 /* if memory allocation is successful, caller of this function
583 * frees it. 638 * frees it.
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index ad8ef10de0bd..fd2ea4271282 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -328,7 +328,6 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
328 int rc = 0; 328 int rc = 0;
329 int resp_buftype; 329 int resp_buftype;
330 struct TCP_Server_Info *server = ses->server; 330 struct TCP_Server_Info *server = ses->server;
331 unsigned int sec_flags;
332 int blob_offset, blob_length; 331 int blob_offset, blob_length;
333 char *security_blob; 332 char *security_blob;
334 int flags = CIFS_NEG_OP; 333 int flags = CIFS_NEG_OP;
@@ -344,14 +343,6 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
344 if (rc) 343 if (rc)
345 return rc; 344 return rc;
346 345
347 /* if any of auth flags (ie not sign or seal) are overriden use them */
348 if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
349 sec_flags = ses->overrideSecFlg; /* BB FIXME fix sign flags?*/
350 else /* if override flags set only sign/seal OR them with global auth */
351 sec_flags = global_secflags | ses->overrideSecFlg;
352
353 cifs_dbg(FYI, "sec_flags 0x%x\n", sec_flags);
354
355 req->hdr.SessionId = 0; 346 req->hdr.SessionId = 0;
356 347
357 req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id); 348 req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id);
@@ -453,7 +444,6 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
453 int resp_buftype; 444 int resp_buftype;
454 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ 445 __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
455 struct TCP_Server_Info *server = ses->server; 446 struct TCP_Server_Info *server = ses->server;
456 unsigned int sec_flags;
457 u16 blob_length = 0; 447 u16 blob_length = 0;
458 char *security_blob; 448 char *security_blob;
459 char *ntlmssp_blob = NULL; 449 char *ntlmssp_blob = NULL;
@@ -474,7 +464,8 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
474 if (!ses->ntlmssp) 464 if (!ses->ntlmssp)
475 return -ENOMEM; 465 return -ENOMEM;
476 466
477 ses->server->secType = RawNTLMSSP; 467 /* FIXME: allow for other auth types besides NTLMSSP (e.g. krb5) */
468 ses->sectype = RawNTLMSSP;
478 469
479ssetup_ntlmssp_authenticate: 470ssetup_ntlmssp_authenticate:
480 if (phase == NtLmChallenge) 471 if (phase == NtLmChallenge)
@@ -484,14 +475,6 @@ ssetup_ntlmssp_authenticate:
484 if (rc) 475 if (rc)
485 return rc; 476 return rc;
486 477
487 /* if any of auth flags (ie not sign or seal) are overriden use them */
488 if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
489 sec_flags = ses->overrideSecFlg; /* BB FIXME fix sign flags?*/
490 else /* if override flags set only sign/seal OR them with global auth */
491 sec_flags = global_secflags | ses->overrideSecFlg;
492
493 cifs_dbg(FYI, "sec_flags 0x%x\n", sec_flags);
494
495 req->hdr.SessionId = 0; /* First session, not a reauthenticate */ 478 req->hdr.SessionId = 0; /* First session, not a reauthenticate */
496 req->VcNumber = 0; /* MBZ */ 479 req->VcNumber = 0; /* MBZ */
497 /* to enable echos and oplocks */ 480 /* to enable echos and oplocks */