diff options
Diffstat (limited to 'fs/cifs/sess.c')
| -rw-r--r-- | fs/cifs/sess.c | 95 |
1 files changed, 70 insertions, 25 deletions
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index f230571a7ab3..79358e341fd2 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
| @@ -138,8 +138,7 @@ static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB) | |||
| 138 | capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | | 138 | capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | |
| 139 | CAP_LARGE_WRITE_X | CAP_LARGE_READ_X; | 139 | CAP_LARGE_WRITE_X | CAP_LARGE_READ_X; |
| 140 | 140 | ||
| 141 | if (ses->server->sec_mode & | 141 | if (ses->server->sign) |
| 142 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | ||
| 143 | pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; | 142 | pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; |
| 144 | 143 | ||
| 145 | if (ses->capabilities & CAP_UNICODE) { | 144 | if (ses->capabilities & CAP_UNICODE) { |
| @@ -310,11 +309,10 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses, | |||
| 310 | return; | 309 | return; |
| 311 | } | 310 | } |
| 312 | 311 | ||
| 313 | static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft, | 312 | static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft, |
| 314 | struct cifs_ses *ses, | 313 | struct cifs_ses *ses, |
| 315 | const struct nls_table *nls_cp) | 314 | const struct nls_table *nls_cp) |
| 316 | { | 315 | { |
| 317 | int rc = 0; | ||
| 318 | int len; | 316 | int len; |
| 319 | char *bcc_ptr = *pbcc_area; | 317 | char *bcc_ptr = *pbcc_area; |
| 320 | 318 | ||
| @@ -322,24 +320,22 @@ static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft, | |||
| 322 | 320 | ||
| 323 | len = strnlen(bcc_ptr, bleft); | 321 | len = strnlen(bcc_ptr, bleft); |
| 324 | if (len >= bleft) | 322 | if (len >= bleft) |
| 325 | return rc; | 323 | return; |
| 326 | 324 | ||
| 327 | kfree(ses->serverOS); | 325 | kfree(ses->serverOS); |
| 328 | 326 | ||
| 329 | ses->serverOS = kzalloc(len + 1, GFP_KERNEL); | 327 | ses->serverOS = kzalloc(len + 1, GFP_KERNEL); |
| 330 | if (ses->serverOS) | 328 | if (ses->serverOS) |
| 331 | strncpy(ses->serverOS, bcc_ptr, len); | 329 | strncpy(ses->serverOS, bcc_ptr, len); |
| 332 | if (strncmp(ses->serverOS, "OS/2", 4) == 0) { | 330 | if (strncmp(ses->serverOS, "OS/2", 4) == 0) |
| 333 | cifs_dbg(FYI, "OS/2 server\n"); | 331 | cifs_dbg(FYI, "OS/2 server\n"); |
| 334 | ses->flags |= CIFS_SES_OS2; | ||
| 335 | } | ||
| 336 | 332 | ||
| 337 | bcc_ptr += len + 1; | 333 | bcc_ptr += len + 1; |
| 338 | bleft -= len + 1; | 334 | bleft -= len + 1; |
| 339 | 335 | ||
| 340 | len = strnlen(bcc_ptr, bleft); | 336 | len = strnlen(bcc_ptr, bleft); |
| 341 | if (len >= bleft) | 337 | if (len >= bleft) |
| 342 | return rc; | 338 | return; |
| 343 | 339 | ||
| 344 | kfree(ses->serverNOS); | 340 | kfree(ses->serverNOS); |
| 345 | 341 | ||
| @@ -352,7 +348,7 @@ static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft, | |||
| 352 | 348 | ||
| 353 | len = strnlen(bcc_ptr, bleft); | 349 | len = strnlen(bcc_ptr, bleft); |
| 354 | if (len > bleft) | 350 | if (len > bleft) |
| 355 | return rc; | 351 | return; |
| 356 | 352 | ||
| 357 | /* No domain field in LANMAN case. Domain is | 353 | /* No domain field in LANMAN case. Domain is |
| 358 | returned by old servers in the SMB negprot response */ | 354 | returned by old servers in the SMB negprot response */ |
| @@ -360,8 +356,6 @@ static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft, | |||
| 360 | but thus do return domain here we could add parsing | 356 | but thus do return domain here we could add parsing |
| 361 | for it later, but it is not very important */ | 357 | for it later, but it is not very important */ |
| 362 | cifs_dbg(FYI, "ascii: bytes left %d\n", bleft); | 358 | cifs_dbg(FYI, "ascii: bytes left %d\n", bleft); |
| 363 | |||
| 364 | return rc; | ||
| 365 | } | 359 | } |
| 366 | 360 | ||
| 367 | int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, | 361 | int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, |
| @@ -432,8 +426,7 @@ void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, | |||
| 432 | flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | | 426 | flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | |
| 433 | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | | 427 | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | |
| 434 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC; | 428 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC; |
| 435 | if (ses->server->sec_mode & | 429 | if (ses->server->sign) { |
| 436 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { | ||
| 437 | flags |= NTLMSSP_NEGOTIATE_SIGN; | 430 | flags |= NTLMSSP_NEGOTIATE_SIGN; |
| 438 | if (!ses->server->session_estab) | 431 | if (!ses->server->session_estab) |
| 439 | flags |= NTLMSSP_NEGOTIATE_KEY_XCH; | 432 | flags |= NTLMSSP_NEGOTIATE_KEY_XCH; |
| @@ -471,8 +464,7 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer, | |||
| 471 | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO | | 464 | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO | |
| 472 | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | | 465 | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | |
| 473 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC; | 466 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC; |
| 474 | if (ses->server->sec_mode & | 467 | if (ses->server->sign) { |
| 475 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { | ||
| 476 | flags |= NTLMSSP_NEGOTIATE_SIGN; | 468 | flags |= NTLMSSP_NEGOTIATE_SIGN; |
| 477 | if (!ses->server->session_estab) | 469 | if (!ses->server->session_estab) |
| 478 | flags |= NTLMSSP_NEGOTIATE_KEY_XCH; | 470 | flags |= NTLMSSP_NEGOTIATE_KEY_XCH; |
| @@ -558,6 +550,56 @@ setup_ntlmv2_ret: | |||
| 558 | return rc; | 550 | return rc; |
| 559 | } | 551 | } |
| 560 | 552 | ||
| 553 | enum securityEnum | ||
| 554 | select_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 | |||
| 561 | int | 603 | int |
| 562 | CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses, | 604 | CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses, |
| 563 | const struct nls_table *nls_cp) | 605 | const struct nls_table *nls_cp) |
| @@ -579,11 +621,18 @@ CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses, | |||
| 579 | u16 blob_len; | 621 | u16 blob_len; |
| 580 | char *ntlmsspblob = NULL; | 622 | char *ntlmsspblob = NULL; |
| 581 | 623 | ||
| 582 | if (ses == NULL) | 624 | if (ses == NULL) { |
| 625 | WARN(1, "%s: ses == NULL!", __func__); | ||
| 583 | return -EINVAL; | 626 | return -EINVAL; |
| 627 | } | ||
| 584 | 628 | ||
| 585 | type = ses->server->secType; | 629 | type = select_sectype(ses->server, ses->sectype); |
| 586 | 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 | |||
| 587 | if (type == RawNTLMSSP) { | 636 | if (type == RawNTLMSSP) { |
| 588 | /* if memory allocation is successful, caller of this function | 637 | /* if memory allocation is successful, caller of this function |
| 589 | * frees it. | 638 | * frees it. |
| @@ -643,8 +692,6 @@ ssetup_ntlmssp_authenticate: | |||
| 643 | } | 692 | } |
| 644 | bcc_ptr = str_area; | 693 | bcc_ptr = str_area; |
| 645 | 694 | ||
| 646 | ses->flags &= ~CIFS_SES_LANMAN; | ||
| 647 | |||
| 648 | iov[1].iov_base = NULL; | 695 | iov[1].iov_base = NULL; |
| 649 | iov[1].iov_len = 0; | 696 | iov[1].iov_len = 0; |
| 650 | 697 | ||
| @@ -668,7 +715,6 @@ ssetup_ntlmssp_authenticate: | |||
| 668 | ses->server->sec_mode & SECMODE_PW_ENCRYPT ? | 715 | ses->server->sec_mode & SECMODE_PW_ENCRYPT ? |
| 669 | true : false, lnm_session_key); | 716 | true : false, lnm_session_key); |
| 670 | 717 | ||
| 671 | ses->flags |= CIFS_SES_LANMAN; | ||
| 672 | memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE); | 718 | memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE); |
| 673 | bcc_ptr += CIFS_AUTH_RESP_SIZE; | 719 | bcc_ptr += CIFS_AUTH_RESP_SIZE; |
| 674 | 720 | ||
| @@ -938,8 +984,7 @@ ssetup_ntlmssp_authenticate: | |||
| 938 | } | 984 | } |
| 939 | decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses, nls_cp); | 985 | decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses, nls_cp); |
| 940 | } else { | 986 | } else { |
| 941 | rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, | 987 | decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses, nls_cp); |
| 942 | ses, nls_cp); | ||
| 943 | } | 988 | } |
| 944 | 989 | ||
| 945 | ssetup_exit: | 990 | ssetup_exit: |
