diff options
Diffstat (limited to 'fs/cifs/sess.c')
-rw-r--r-- | fs/cifs/sess.c | 81 |
1 files changed, 44 insertions, 37 deletions
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 7c3fd7463f44..7707389bdf2c 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
@@ -35,9 +35,11 @@ | |||
35 | extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, | 35 | extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, |
36 | unsigned char *p24); | 36 | unsigned char *p24); |
37 | 37 | ||
38 | /* Checks if this is the first smb session to be reconnected after | 38 | /* |
39 | the socket has been reestablished (so we know whether to use vc 0). | 39 | * Checks if this is the first smb session to be reconnected after |
40 | Called while holding the cifs_tcp_ses_lock, so do not block */ | 40 | * the socket has been reestablished (so we know whether to use vc 0). |
41 | * Called while holding the cifs_tcp_ses_lock, so do not block | ||
42 | */ | ||
41 | static bool is_first_ses_reconnect(struct cifsSesInfo *ses) | 43 | static bool is_first_ses_reconnect(struct cifsSesInfo *ses) |
42 | { | 44 | { |
43 | struct list_head *tmp; | 45 | struct list_head *tmp; |
@@ -284,7 +286,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses, | |||
284 | int len; | 286 | int len; |
285 | char *data = *pbcc_area; | 287 | char *data = *pbcc_area; |
286 | 288 | ||
287 | cFYI(1, ("bleft %d", bleft)); | 289 | cFYI(1, "bleft %d", bleft); |
288 | 290 | ||
289 | /* | 291 | /* |
290 | * Windows servers do not always double null terminate their final | 292 | * Windows servers do not always double null terminate their final |
@@ -301,7 +303,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses, | |||
301 | 303 | ||
302 | kfree(ses->serverOS); | 304 | kfree(ses->serverOS); |
303 | ses->serverOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp); | 305 | ses->serverOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp); |
304 | cFYI(1, ("serverOS=%s", ses->serverOS)); | 306 | cFYI(1, "serverOS=%s", ses->serverOS); |
305 | len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2; | 307 | len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2; |
306 | data += len; | 308 | data += len; |
307 | bleft -= len; | 309 | bleft -= len; |
@@ -310,7 +312,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses, | |||
310 | 312 | ||
311 | kfree(ses->serverNOS); | 313 | kfree(ses->serverNOS); |
312 | ses->serverNOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp); | 314 | ses->serverNOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp); |
313 | cFYI(1, ("serverNOS=%s", ses->serverNOS)); | 315 | cFYI(1, "serverNOS=%s", ses->serverNOS); |
314 | len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2; | 316 | len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2; |
315 | data += len; | 317 | data += len; |
316 | bleft -= len; | 318 | bleft -= len; |
@@ -319,7 +321,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses, | |||
319 | 321 | ||
320 | kfree(ses->serverDomain); | 322 | kfree(ses->serverDomain); |
321 | ses->serverDomain = cifs_strndup_from_ucs(data, bleft, true, nls_cp); | 323 | ses->serverDomain = cifs_strndup_from_ucs(data, bleft, true, nls_cp); |
322 | cFYI(1, ("serverDomain=%s", ses->serverDomain)); | 324 | cFYI(1, "serverDomain=%s", ses->serverDomain); |
323 | 325 | ||
324 | return; | 326 | return; |
325 | } | 327 | } |
@@ -332,7 +334,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft, | |||
332 | int len; | 334 | int len; |
333 | char *bcc_ptr = *pbcc_area; | 335 | char *bcc_ptr = *pbcc_area; |
334 | 336 | ||
335 | cFYI(1, ("decode sessetup ascii. bleft %d", bleft)); | 337 | cFYI(1, "decode sessetup ascii. bleft %d", bleft); |
336 | 338 | ||
337 | len = strnlen(bcc_ptr, bleft); | 339 | len = strnlen(bcc_ptr, bleft); |
338 | if (len >= bleft) | 340 | if (len >= bleft) |
@@ -344,7 +346,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft, | |||
344 | if (ses->serverOS) | 346 | if (ses->serverOS) |
345 | strncpy(ses->serverOS, bcc_ptr, len); | 347 | strncpy(ses->serverOS, bcc_ptr, len); |
346 | if (strncmp(ses->serverOS, "OS/2", 4) == 0) { | 348 | if (strncmp(ses->serverOS, "OS/2", 4) == 0) { |
347 | cFYI(1, ("OS/2 server")); | 349 | cFYI(1, "OS/2 server"); |
348 | ses->flags |= CIFS_SES_OS2; | 350 | ses->flags |= CIFS_SES_OS2; |
349 | } | 351 | } |
350 | 352 | ||
@@ -373,7 +375,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft, | |||
373 | /* BB For newer servers which do not support Unicode, | 375 | /* BB For newer servers which do not support Unicode, |
374 | but thus do return domain here we could add parsing | 376 | but thus do return domain here we could add parsing |
375 | for it later, but it is not very important */ | 377 | for it later, but it is not very important */ |
376 | cFYI(1, ("ascii: bytes left %d", bleft)); | 378 | cFYI(1, "ascii: bytes left %d", bleft); |
377 | 379 | ||
378 | return rc; | 380 | return rc; |
379 | } | 381 | } |
@@ -384,16 +386,16 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, | |||
384 | CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr; | 386 | CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr; |
385 | 387 | ||
386 | if (blob_len < sizeof(CHALLENGE_MESSAGE)) { | 388 | if (blob_len < sizeof(CHALLENGE_MESSAGE)) { |
387 | cERROR(1, ("challenge blob len %d too small", blob_len)); | 389 | cERROR(1, "challenge blob len %d too small", blob_len); |
388 | return -EINVAL; | 390 | return -EINVAL; |
389 | } | 391 | } |
390 | 392 | ||
391 | if (memcmp(pblob->Signature, "NTLMSSP", 8)) { | 393 | if (memcmp(pblob->Signature, "NTLMSSP", 8)) { |
392 | cERROR(1, ("blob signature incorrect %s", pblob->Signature)); | 394 | cERROR(1, "blob signature incorrect %s", pblob->Signature); |
393 | return -EINVAL; | 395 | return -EINVAL; |
394 | } | 396 | } |
395 | if (pblob->MessageType != NtLmChallenge) { | 397 | if (pblob->MessageType != NtLmChallenge) { |
396 | cERROR(1, ("Incorrect message type %d", pblob->MessageType)); | 398 | cERROR(1, "Incorrect message type %d", pblob->MessageType); |
397 | return -EINVAL; | 399 | return -EINVAL; |
398 | } | 400 | } |
399 | 401 | ||
@@ -447,7 +449,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, | |||
447 | This function returns the length of the data in the blob */ | 449 | This function returns the length of the data in the blob */ |
448 | static int build_ntlmssp_auth_blob(unsigned char *pbuffer, | 450 | static int build_ntlmssp_auth_blob(unsigned char *pbuffer, |
449 | struct cifsSesInfo *ses, | 451 | struct cifsSesInfo *ses, |
450 | const struct nls_table *nls_cp, int first) | 452 | const struct nls_table *nls_cp, bool first) |
451 | { | 453 | { |
452 | AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; | 454 | AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer; |
453 | __u32 flags; | 455 | __u32 flags; |
@@ -546,7 +548,7 @@ static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB, | |||
546 | 548 | ||
547 | static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB, | 549 | static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB, |
548 | struct cifsSesInfo *ses, | 550 | struct cifsSesInfo *ses, |
549 | const struct nls_table *nls, int first_time) | 551 | const struct nls_table *nls, bool first_time) |
550 | { | 552 | { |
551 | int bloblen; | 553 | int bloblen; |
552 | 554 | ||
@@ -559,8 +561,8 @@ static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB, | |||
559 | #endif | 561 | #endif |
560 | 562 | ||
561 | int | 563 | int |
562 | CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | 564 | CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, |
563 | const struct nls_table *nls_cp) | 565 | const struct nls_table *nls_cp) |
564 | { | 566 | { |
565 | int rc = 0; | 567 | int rc = 0; |
566 | int wct; | 568 | int wct; |
@@ -577,13 +579,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
577 | int bytes_remaining; | 579 | int bytes_remaining; |
578 | struct key *spnego_key = NULL; | 580 | struct key *spnego_key = NULL; |
579 | __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ | 581 | __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */ |
582 | bool first_time; | ||
580 | 583 | ||
581 | if (ses == NULL) | 584 | if (ses == NULL) |
582 | return -EINVAL; | 585 | return -EINVAL; |
583 | 586 | ||
587 | read_lock(&cifs_tcp_ses_lock); | ||
588 | first_time = is_first_ses_reconnect(ses); | ||
589 | read_unlock(&cifs_tcp_ses_lock); | ||
590 | |||
584 | type = ses->server->secType; | 591 | type = ses->server->secType; |
585 | 592 | ||
586 | cFYI(1, ("sess setup type %d", type)); | 593 | cFYI(1, "sess setup type %d", type); |
587 | ssetup_ntlmssp_authenticate: | 594 | ssetup_ntlmssp_authenticate: |
588 | if (phase == NtLmChallenge) | 595 | if (phase == NtLmChallenge) |
589 | phase = NtLmAuthenticate; /* if ntlmssp, now final phase */ | 596 | phase = NtLmAuthenticate; /* if ntlmssp, now final phase */ |
@@ -664,7 +671,7 @@ ssetup_ntlmssp_authenticate: | |||
664 | changed to do higher than lanman dialect and | 671 | changed to do higher than lanman dialect and |
665 | we reconnected would we ever calc signing_key? */ | 672 | we reconnected would we ever calc signing_key? */ |
666 | 673 | ||
667 | cFYI(1, ("Negotiating LANMAN setting up strings")); | 674 | cFYI(1, "Negotiating LANMAN setting up strings"); |
668 | /* Unicode not allowed for LANMAN dialects */ | 675 | /* Unicode not allowed for LANMAN dialects */ |
669 | ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); | 676 | ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); |
670 | #endif | 677 | #endif |
@@ -744,7 +751,7 @@ ssetup_ntlmssp_authenticate: | |||
744 | unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); | 751 | unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); |
745 | } else | 752 | } else |
746 | ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); | 753 | ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); |
747 | } else if (type == Kerberos || type == MSKerberos) { | 754 | } else if (type == Kerberos) { |
748 | #ifdef CONFIG_CIFS_UPCALL | 755 | #ifdef CONFIG_CIFS_UPCALL |
749 | struct cifs_spnego_msg *msg; | 756 | struct cifs_spnego_msg *msg; |
750 | spnego_key = cifs_get_spnego_key(ses); | 757 | spnego_key = cifs_get_spnego_key(ses); |
@@ -758,17 +765,17 @@ ssetup_ntlmssp_authenticate: | |||
758 | /* check version field to make sure that cifs.upcall is | 765 | /* check version field to make sure that cifs.upcall is |
759 | sending us a response in an expected form */ | 766 | sending us a response in an expected form */ |
760 | if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) { | 767 | if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) { |
761 | cERROR(1, ("incorrect version of cifs.upcall (expected" | 768 | cERROR(1, "incorrect version of cifs.upcall (expected" |
762 | " %d but got %d)", | 769 | " %d but got %d)", |
763 | CIFS_SPNEGO_UPCALL_VERSION, msg->version)); | 770 | CIFS_SPNEGO_UPCALL_VERSION, msg->version); |
764 | rc = -EKEYREJECTED; | 771 | rc = -EKEYREJECTED; |
765 | goto ssetup_exit; | 772 | goto ssetup_exit; |
766 | } | 773 | } |
767 | /* bail out if key is too long */ | 774 | /* bail out if key is too long */ |
768 | if (msg->sesskey_len > | 775 | if (msg->sesskey_len > |
769 | sizeof(ses->server->mac_signing_key.data.krb5)) { | 776 | sizeof(ses->server->mac_signing_key.data.krb5)) { |
770 | cERROR(1, ("Kerberos signing key too long (%u bytes)", | 777 | cERROR(1, "Kerberos signing key too long (%u bytes)", |
771 | msg->sesskey_len)); | 778 | msg->sesskey_len); |
772 | rc = -EOVERFLOW; | 779 | rc = -EOVERFLOW; |
773 | goto ssetup_exit; | 780 | goto ssetup_exit; |
774 | } | 781 | } |
@@ -796,7 +803,7 @@ ssetup_ntlmssp_authenticate: | |||
796 | /* BB: is this right? */ | 803 | /* BB: is this right? */ |
797 | ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); | 804 | ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); |
798 | #else /* ! CONFIG_CIFS_UPCALL */ | 805 | #else /* ! CONFIG_CIFS_UPCALL */ |
799 | cERROR(1, ("Kerberos negotiated but upcall support disabled!")); | 806 | cERROR(1, "Kerberos negotiated but upcall support disabled!"); |
800 | rc = -ENOSYS; | 807 | rc = -ENOSYS; |
801 | goto ssetup_exit; | 808 | goto ssetup_exit; |
802 | #endif /* CONFIG_CIFS_UPCALL */ | 809 | #endif /* CONFIG_CIFS_UPCALL */ |
@@ -804,12 +811,12 @@ ssetup_ntlmssp_authenticate: | |||
804 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 811 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
805 | if (type == RawNTLMSSP) { | 812 | if (type == RawNTLMSSP) { |
806 | if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) { | 813 | if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) { |
807 | cERROR(1, ("NTLMSSP requires Unicode support")); | 814 | cERROR(1, "NTLMSSP requires Unicode support"); |
808 | rc = -ENOSYS; | 815 | rc = -ENOSYS; |
809 | goto ssetup_exit; | 816 | goto ssetup_exit; |
810 | } | 817 | } |
811 | 818 | ||
812 | cFYI(1, ("ntlmssp session setup phase %d", phase)); | 819 | cFYI(1, "ntlmssp session setup phase %d", phase); |
813 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; | 820 | pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; |
814 | capabilities |= CAP_EXTENDED_SECURITY; | 821 | capabilities |= CAP_EXTENDED_SECURITY; |
815 | pSMB->req.Capabilities |= cpu_to_le32(capabilities); | 822 | pSMB->req.Capabilities |= cpu_to_le32(capabilities); |
@@ -827,7 +834,7 @@ ssetup_ntlmssp_authenticate: | |||
827 | on the response (challenge) */ | 834 | on the response (challenge) */ |
828 | smb_buf->Uid = ses->Suid; | 835 | smb_buf->Uid = ses->Suid; |
829 | } else { | 836 | } else { |
830 | cERROR(1, ("invalid phase %d", phase)); | 837 | cERROR(1, "invalid phase %d", phase); |
831 | rc = -ENOSYS; | 838 | rc = -ENOSYS; |
832 | goto ssetup_exit; | 839 | goto ssetup_exit; |
833 | } | 840 | } |
@@ -839,12 +846,12 @@ ssetup_ntlmssp_authenticate: | |||
839 | } | 846 | } |
840 | unicode_oslm_strings(&bcc_ptr, nls_cp); | 847 | unicode_oslm_strings(&bcc_ptr, nls_cp); |
841 | } else { | 848 | } else { |
842 | cERROR(1, ("secType %d not supported!", type)); | 849 | cERROR(1, "secType %d not supported!", type); |
843 | rc = -ENOSYS; | 850 | rc = -ENOSYS; |
844 | goto ssetup_exit; | 851 | goto ssetup_exit; |
845 | } | 852 | } |
846 | #else | 853 | #else |
847 | cERROR(1, ("secType %d not supported!", type)); | 854 | cERROR(1, "secType %d not supported!", type); |
848 | rc = -ENOSYS; | 855 | rc = -ENOSYS; |
849 | goto ssetup_exit; | 856 | goto ssetup_exit; |
850 | #endif | 857 | #endif |
@@ -862,7 +869,7 @@ ssetup_ntlmssp_authenticate: | |||
862 | CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR); | 869 | CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR); |
863 | /* SMB request buf freed in SendReceive2 */ | 870 | /* SMB request buf freed in SendReceive2 */ |
864 | 871 | ||
865 | cFYI(1, ("ssetup rc from sendrecv2 is %d", rc)); | 872 | cFYI(1, "ssetup rc from sendrecv2 is %d", rc); |
866 | 873 | ||
867 | pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base; | 874 | pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base; |
868 | smb_buf = (struct smb_hdr *)iov[0].iov_base; | 875 | smb_buf = (struct smb_hdr *)iov[0].iov_base; |
@@ -870,7 +877,7 @@ ssetup_ntlmssp_authenticate: | |||
870 | if ((type == RawNTLMSSP) && (smb_buf->Status.CifsError == | 877 | if ((type == RawNTLMSSP) && (smb_buf->Status.CifsError == |
871 | cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))) { | 878 | cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))) { |
872 | if (phase != NtLmNegotiate) { | 879 | if (phase != NtLmNegotiate) { |
873 | cERROR(1, ("Unexpected more processing error")); | 880 | cERROR(1, "Unexpected more processing error"); |
874 | goto ssetup_exit; | 881 | goto ssetup_exit; |
875 | } | 882 | } |
876 | /* NTLMSSP Negotiate sent now processing challenge (response) */ | 883 | /* NTLMSSP Negotiate sent now processing challenge (response) */ |
@@ -882,14 +889,14 @@ ssetup_ntlmssp_authenticate: | |||
882 | 889 | ||
883 | if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) { | 890 | if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) { |
884 | rc = -EIO; | 891 | rc = -EIO; |
885 | cERROR(1, ("bad word count %d", smb_buf->WordCount)); | 892 | cERROR(1, "bad word count %d", smb_buf->WordCount); |
886 | goto ssetup_exit; | 893 | goto ssetup_exit; |
887 | } | 894 | } |
888 | action = le16_to_cpu(pSMB->resp.Action); | 895 | action = le16_to_cpu(pSMB->resp.Action); |
889 | if (action & GUEST_LOGIN) | 896 | if (action & GUEST_LOGIN) |
890 | cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */ | 897 | cFYI(1, "Guest login"); /* BB mark SesInfo struct? */ |
891 | ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */ | 898 | ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */ |
892 | cFYI(1, ("UID = %d ", ses->Suid)); | 899 | cFYI(1, "UID = %d ", ses->Suid); |
893 | /* response can have either 3 or 4 word count - Samba sends 3 */ | 900 | /* response can have either 3 or 4 word count - Samba sends 3 */ |
894 | /* and lanman response is 3 */ | 901 | /* and lanman response is 3 */ |
895 | bytes_remaining = BCC(smb_buf); | 902 | bytes_remaining = BCC(smb_buf); |
@@ -899,7 +906,7 @@ ssetup_ntlmssp_authenticate: | |||
899 | __u16 blob_len; | 906 | __u16 blob_len; |
900 | blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength); | 907 | blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength); |
901 | if (blob_len > bytes_remaining) { | 908 | if (blob_len > bytes_remaining) { |
902 | cERROR(1, ("bad security blob length %d", blob_len)); | 909 | cERROR(1, "bad security blob length %d", blob_len); |
903 | rc = -EINVAL; | 910 | rc = -EINVAL; |
904 | goto ssetup_exit; | 911 | goto ssetup_exit; |
905 | } | 912 | } |
@@ -933,7 +940,7 @@ ssetup_exit: | |||
933 | } | 940 | } |
934 | kfree(str_area); | 941 | kfree(str_area); |
935 | if (resp_buf_type == CIFS_SMALL_BUFFER) { | 942 | if (resp_buf_type == CIFS_SMALL_BUFFER) { |
936 | cFYI(1, ("ssetup freeing small buf %p", iov[0].iov_base)); | 943 | cFYI(1, "ssetup freeing small buf %p", iov[0].iov_base); |
937 | cifs_small_buf_release(iov[0].iov_base); | 944 | cifs_small_buf_release(iov[0].iov_base); |
938 | } else if (resp_buf_type == CIFS_LARGE_BUFFER) | 945 | } else if (resp_buf_type == CIFS_LARGE_BUFFER) |
939 | cifs_buf_release(iov[0].iov_base); | 946 | cifs_buf_release(iov[0].iov_base); |