diff options
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/cifsproto.h | 1 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 68 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 33 |
3 files changed, 40 insertions, 62 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index dda188a94332..f0e93ffe654c 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -212,6 +212,7 @@ extern int cifs_negotiate_protocol(const unsigned int xid, | |||
212 | struct cifs_ses *ses); | 212 | struct cifs_ses *ses); |
213 | extern int cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, | 213 | extern int cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, |
214 | struct nls_table *nls_info); | 214 | struct nls_table *nls_info); |
215 | extern int cifs_enable_signing(struct TCP_Server_Info *server, unsigned int secFlags); | ||
215 | extern int CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses); | 216 | extern int CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses); |
216 | 217 | ||
217 | extern int CIFSTCon(const unsigned int xid, struct cifs_ses *ses, | 218 | extern int CIFSTCon(const unsigned int xid, struct cifs_ses *ses, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 5dd4f8a51e0c..1a3776322c71 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -417,6 +417,38 @@ decode_ext_sec_blob(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr) | |||
417 | return 0; | 417 | return 0; |
418 | } | 418 | } |
419 | 419 | ||
420 | int | ||
421 | cifs_enable_signing(struct TCP_Server_Info *server, unsigned int secFlags) | ||
422 | { | ||
423 | if ((secFlags & CIFSSEC_MAY_SIGN) == 0) { | ||
424 | /* MUST_SIGN already includes the MAY_SIGN FLAG | ||
425 | so if this is zero it means that signing is disabled */ | ||
426 | cifs_dbg(FYI, "Signing disabled\n"); | ||
427 | if (server->sec_mode & SECMODE_SIGN_REQUIRED) { | ||
428 | cifs_dbg(VFS, "Server requires packet signing to be enabled in /proc/fs/cifs/SecurityFlags\n"); | ||
429 | return -EOPNOTSUPP; | ||
430 | } | ||
431 | server->sec_mode &= | ||
432 | ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); | ||
433 | } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) { | ||
434 | /* signing required */ | ||
435 | cifs_dbg(FYI, "Must sign - secFlags 0x%x\n", secFlags); | ||
436 | if ((server->sec_mode & | ||
437 | (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) { | ||
438 | cifs_dbg(VFS, "signing required but server lacks support\n"); | ||
439 | return -EOPNOTSUPP; | ||
440 | } else | ||
441 | server->sec_mode |= SECMODE_SIGN_REQUIRED; | ||
442 | } else { | ||
443 | /* signing optional ie CIFSSEC_MAY_SIGN */ | ||
444 | if ((server->sec_mode & SECMODE_SIGN_REQUIRED) == 0) | ||
445 | server->sec_mode &= | ||
446 | ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); | ||
447 | } | ||
448 | |||
449 | return 0; | ||
450 | } | ||
451 | |||
420 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 452 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
421 | static int | 453 | static int |
422 | decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr, | 454 | decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr, |
@@ -577,10 +609,7 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses) | |||
577 | goto neg_err_exit; | 609 | goto neg_err_exit; |
578 | } else if (pSMBr->hdr.WordCount == 13) { | 610 | } else if (pSMBr->hdr.WordCount == 13) { |
579 | rc = decode_lanman_negprot_rsp(server, pSMBr, secFlags); | 611 | rc = decode_lanman_negprot_rsp(server, pSMBr, secFlags); |
580 | if (!rc) | 612 | goto signing_check; |
581 | goto signing_check; | ||
582 | else | ||
583 | goto neg_err_exit; | ||
584 | } else if (pSMBr->hdr.WordCount != 17) { | 613 | } else if (pSMBr->hdr.WordCount != 17) { |
585 | /* unknown wct */ | 614 | /* unknown wct */ |
586 | rc = -EOPNOTSUPP; | 615 | rc = -EOPNOTSUPP; |
@@ -642,36 +671,9 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses) | |||
642 | else | 671 | else |
643 | server->capabilities &= ~CAP_EXTENDED_SECURITY; | 672 | server->capabilities &= ~CAP_EXTENDED_SECURITY; |
644 | 673 | ||
645 | if (rc) | ||
646 | goto neg_err_exit; | ||
647 | |||
648 | signing_check: | 674 | signing_check: |
649 | if ((secFlags & CIFSSEC_MAY_SIGN) == 0) { | 675 | if (!rc) |
650 | /* MUST_SIGN already includes the MAY_SIGN FLAG | 676 | rc = cifs_enable_signing(server, secFlags); |
651 | so if this is zero it means that signing is disabled */ | ||
652 | cifs_dbg(FYI, "Signing disabled\n"); | ||
653 | if (server->sec_mode & SECMODE_SIGN_REQUIRED) { | ||
654 | cifs_dbg(VFS, "Server requires packet signing to be enabled in /proc/fs/cifs/SecurityFlags\n"); | ||
655 | rc = -EOPNOTSUPP; | ||
656 | } | ||
657 | server->sec_mode &= | ||
658 | ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); | ||
659 | } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) { | ||
660 | /* signing required */ | ||
661 | cifs_dbg(FYI, "Must sign - secFlags 0x%x\n", secFlags); | ||
662 | if ((server->sec_mode & | ||
663 | (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) { | ||
664 | cifs_dbg(VFS, "signing required but server lacks support\n"); | ||
665 | rc = -EOPNOTSUPP; | ||
666 | } else | ||
667 | server->sec_mode |= SECMODE_SIGN_REQUIRED; | ||
668 | } else { | ||
669 | /* signing optional ie CIFSSEC_MAY_SIGN */ | ||
670 | if ((server->sec_mode & SECMODE_SIGN_REQUIRED) == 0) | ||
671 | server->sec_mode &= | ||
672 | ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); | ||
673 | } | ||
674 | |||
675 | neg_err_exit: | 677 | neg_err_exit: |
676 | cifs_buf_release(pSMB); | 678 | cifs_buf_release(pSMB); |
677 | 679 | ||
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 3af66aa18d3b..ebb97b484ab1 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -423,36 +423,11 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) | |||
423 | } | 423 | } |
424 | 424 | ||
425 | cifs_dbg(FYI, "sec_flags 0x%x\n", sec_flags); | 425 | cifs_dbg(FYI, "sec_flags 0x%x\n", sec_flags); |
426 | if ((sec_flags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) { | 426 | rc = cifs_enable_signing(server, sec_flags); |
427 | cifs_dbg(FYI, "Signing required\n"); | ||
428 | if (!(server->sec_mode & (SMB2_NEGOTIATE_SIGNING_REQUIRED | | ||
429 | SMB2_NEGOTIATE_SIGNING_ENABLED))) { | ||
430 | cifs_dbg(VFS, "signing required but server lacks support\n"); | ||
431 | rc = -EOPNOTSUPP; | ||
432 | goto neg_exit; | ||
433 | } | ||
434 | server->sec_mode |= SECMODE_SIGN_REQUIRED; | ||
435 | } else if (sec_flags & CIFSSEC_MAY_SIGN) { | ||
436 | cifs_dbg(FYI, "Signing optional\n"); | ||
437 | if (server->sec_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) { | ||
438 | cifs_dbg(FYI, "Server requires signing\n"); | ||
439 | server->sec_mode |= SECMODE_SIGN_REQUIRED; | ||
440 | } else { | ||
441 | server->sec_mode &= | ||
442 | ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); | ||
443 | } | ||
444 | } else { | ||
445 | cifs_dbg(FYI, "Signing disabled\n"); | ||
446 | if (server->sec_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) { | ||
447 | cifs_dbg(VFS, "Server requires packet signing to be enabled in /proc/fs/cifs/SecurityFlags\n"); | ||
448 | rc = -EOPNOTSUPP; | ||
449 | goto neg_exit; | ||
450 | } | ||
451 | server->sec_mode &= | ||
452 | ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); | ||
453 | } | ||
454 | |||
455 | #ifdef CONFIG_SMB2_ASN1 /* BB REMOVEME when updated asn1.c ready */ | 427 | #ifdef CONFIG_SMB2_ASN1 /* BB REMOVEME when updated asn1.c ready */ |
428 | if (rc) | ||
429 | goto neg_exit; | ||
430 | |||
456 | rc = decode_neg_token_init(security_blob, blob_length, | 431 | rc = decode_neg_token_init(security_blob, blob_length, |
457 | &server->sec_type); | 432 | &server->sec_type); |
458 | if (rc == 1) | 433 | if (rc == 1) |