diff options
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r-- | fs/cifs/connect.c | 173 |
1 files changed, 81 insertions, 92 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index b51d5777cde6..0711db65afe8 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -151,7 +151,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
151 | } | 151 | } |
152 | list_for_each(tmp, &GlobalTreeConnectionList) { | 152 | list_for_each(tmp, &GlobalTreeConnectionList) { |
153 | tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); | 153 | tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); |
154 | if ((tcon) && (tcon->ses) && (tcon->ses->server == server)) | 154 | if ((tcon->ses) && (tcon->ses->server == server)) |
155 | tcon->tidStatus = CifsNeedReconnect; | 155 | tcon->tidStatus = CifsNeedReconnect; |
156 | } | 156 | } |
157 | read_unlock(&GlobalSMBSeslock); | 157 | read_unlock(&GlobalSMBSeslock); |
@@ -173,14 +173,12 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
173 | mid_entry = list_entry(tmp, struct | 173 | mid_entry = list_entry(tmp, struct |
174 | mid_q_entry, | 174 | mid_q_entry, |
175 | qhead); | 175 | qhead); |
176 | if (mid_entry) { | 176 | if (mid_entry->midState == MID_REQUEST_SUBMITTED) { |
177 | if (mid_entry->midState == MID_REQUEST_SUBMITTED) { | ||
178 | /* Mark other intransit requests as needing | 177 | /* Mark other intransit requests as needing |
179 | retry so we do not immediately mark the | 178 | retry so we do not immediately mark the |
180 | session bad again (ie after we reconnect | 179 | session bad again (ie after we reconnect |
181 | below) as they timeout too */ | 180 | below) as they timeout too */ |
182 | mid_entry->midState = MID_RETRY_NEEDED; | 181 | mid_entry->midState = MID_RETRY_NEEDED; |
183 | } | ||
184 | } | 182 | } |
185 | } | 183 | } |
186 | spin_unlock(&GlobalMid_Lock); | 184 | spin_unlock(&GlobalMid_Lock); |
@@ -351,11 +349,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
351 | 349 | ||
352 | current->flags |= PF_MEMALLOC; | 350 | current->flags |= PF_MEMALLOC; |
353 | cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current))); | 351 | cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current))); |
354 | write_lock(&GlobalSMBSeslock); | 352 | |
355 | atomic_inc(&tcpSesAllocCount); | 353 | length = atomic_inc_return(&tcpSesAllocCount); |
356 | length = tcpSesAllocCount.counter; | 354 | if (length > 1) |
357 | write_unlock(&GlobalSMBSeslock); | ||
358 | if (length > 1) | ||
359 | mempool_resize(cifs_req_poolp, length + cifs_min_rcv, | 355 | mempool_resize(cifs_req_poolp, length + cifs_min_rcv, |
360 | GFP_KERNEL); | 356 | GFP_KERNEL); |
361 | 357 | ||
@@ -745,14 +741,11 @@ multi_t2_fnd: | |||
745 | coming home not much else we can do but free the memory */ | 741 | coming home not much else we can do but free the memory */ |
746 | } | 742 | } |
747 | 743 | ||
748 | write_lock(&GlobalSMBSeslock); | ||
749 | atomic_dec(&tcpSesAllocCount); | ||
750 | length = tcpSesAllocCount.counter; | ||
751 | |||
752 | /* last chance to mark ses pointers invalid | 744 | /* last chance to mark ses pointers invalid |
753 | if there are any pointing to this (e.g | 745 | if there are any pointing to this (e.g |
754 | if a crazy root user tried to kill cifsd | 746 | if a crazy root user tried to kill cifsd |
755 | kernel thread explicitly this might happen) */ | 747 | kernel thread explicitly this might happen) */ |
748 | write_lock(&GlobalSMBSeslock); | ||
756 | list_for_each(tmp, &GlobalSMBSessionList) { | 749 | list_for_each(tmp, &GlobalSMBSessionList) { |
757 | ses = list_entry(tmp, struct cifsSesInfo, | 750 | ses = list_entry(tmp, struct cifsSesInfo, |
758 | cifsSessionList); | 751 | cifsSessionList); |
@@ -763,6 +756,8 @@ multi_t2_fnd: | |||
763 | 756 | ||
764 | kfree(server->hostname); | 757 | kfree(server->hostname); |
765 | kfree(server); | 758 | kfree(server); |
759 | |||
760 | length = atomic_dec_return(&tcpSesAllocCount); | ||
766 | if (length > 0) | 761 | if (length > 0) |
767 | mempool_resize(cifs_req_poolp, length + cifs_min_rcv, | 762 | mempool_resize(cifs_req_poolp, length + cifs_min_rcv, |
768 | GFP_KERNEL); | 763 | GFP_KERNEL); |
@@ -3623,97 +3618,91 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, | |||
3623 | } | 3618 | } |
3624 | first_time = 1; | 3619 | first_time = 1; |
3625 | } | 3620 | } |
3626 | if (!rc) { | 3621 | |
3627 | pSesInfo->flags = 0; | 3622 | if (rc) |
3628 | pSesInfo->capabilities = pSesInfo->server->capabilities; | 3623 | goto ss_err_exit; |
3629 | if (linuxExtEnabled == 0) | 3624 | |
3630 | pSesInfo->capabilities &= (~CAP_UNIX); | 3625 | pSesInfo->flags = 0; |
3626 | pSesInfo->capabilities = pSesInfo->server->capabilities; | ||
3627 | if (linuxExtEnabled == 0) | ||
3628 | pSesInfo->capabilities &= (~CAP_UNIX); | ||
3631 | /* pSesInfo->sequence_number = 0;*/ | 3629 | /* pSesInfo->sequence_number = 0;*/ |
3632 | cFYI(1, | 3630 | cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d", |
3633 | ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d", | 3631 | pSesInfo->server->secMode, |
3634 | pSesInfo->server->secMode, | 3632 | pSesInfo->server->capabilities, |
3635 | pSesInfo->server->capabilities, | 3633 | pSesInfo->server->timeAdj)); |
3636 | pSesInfo->server->timeAdj)); | 3634 | if (experimEnabled < 2) |
3637 | if (experimEnabled < 2) | 3635 | rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info); |
3638 | rc = CIFS_SessSetup(xid, pSesInfo, | 3636 | else if (extended_security |
3639 | first_time, nls_info); | 3637 | && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) |
3640 | else if (extended_security | 3638 | && (pSesInfo->server->secType == NTLMSSP)) { |
3641 | && (pSesInfo->capabilities | 3639 | rc = -EOPNOTSUPP; |
3642 | & CAP_EXTENDED_SECURITY) | 3640 | } else if (extended_security |
3643 | && (pSesInfo->server->secType == NTLMSSP)) { | 3641 | && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) |
3644 | rc = -EOPNOTSUPP; | 3642 | && (pSesInfo->server->secType == RawNTLMSSP)) { |
3645 | } else if (extended_security | 3643 | cFYI(1, ("NTLMSSP sesssetup")); |
3646 | && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) | 3644 | rc = CIFSNTLMSSPNegotiateSessSetup(xid, pSesInfo, &ntlmv2_flag, |
3647 | && (pSesInfo->server->secType == RawNTLMSSP)) { | 3645 | nls_info); |
3648 | cFYI(1, ("NTLMSSP sesssetup")); | 3646 | if (!rc) { |
3649 | rc = CIFSNTLMSSPNegotiateSessSetup(xid, | 3647 | if (ntlmv2_flag) { |
3650 | pSesInfo, | 3648 | char *v2_response; |
3651 | &ntlmv2_flag, | 3649 | cFYI(1, ("more secure NTLM ver2 hash")); |
3652 | nls_info); | 3650 | if (CalcNTLMv2_partial_mac_key(pSesInfo, |
3653 | if (!rc) { | 3651 | nls_info)) { |
3654 | if (ntlmv2_flag) { | 3652 | rc = -ENOMEM; |
3655 | char *v2_response; | 3653 | goto ss_err_exit; |
3656 | cFYI(1, ("more secure NTLM ver2 hash")); | 3654 | } else |
3657 | if (CalcNTLMv2_partial_mac_key(pSesInfo, | 3655 | v2_response = kmalloc(16 + 64 /* blob*/, |
3658 | nls_info)) { | 3656 | GFP_KERNEL); |
3659 | rc = -ENOMEM; | 3657 | if (v2_response) { |
3660 | goto ss_err_exit; | 3658 | CalcNTLMv2_response(pSesInfo, |
3661 | } else | 3659 | v2_response); |
3662 | v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL); | 3660 | /* if (first_time) |
3663 | if (v2_response) { | 3661 | cifs_calculate_ntlmv2_mac_key */ |
3664 | CalcNTLMv2_response(pSesInfo, | 3662 | kfree(v2_response); |
3665 | v2_response); | ||
3666 | /* if (first_time) | ||
3667 | cifs_calculate_ntlmv2_mac_key( | ||
3668 | pSesInfo->server->mac_signing_key, | ||
3669 | response, ntlm_session_key,*/ | ||
3670 | kfree(v2_response); | ||
3671 | /* BB Put dummy sig in SessSetup PDU? */ | 3663 | /* BB Put dummy sig in SessSetup PDU? */ |
3672 | } else { | ||
3673 | rc = -ENOMEM; | ||
3674 | goto ss_err_exit; | ||
3675 | } | ||
3676 | |||
3677 | } else { | 3664 | } else { |
3678 | SMBNTencrypt(pSesInfo->password, | 3665 | rc = -ENOMEM; |
3679 | pSesInfo->server->cryptKey, | 3666 | goto ss_err_exit; |
3680 | ntlm_session_key); | ||
3681 | |||
3682 | if (first_time) | ||
3683 | cifs_calculate_mac_key( | ||
3684 | &pSesInfo->server->mac_signing_key, | ||
3685 | ntlm_session_key, | ||
3686 | pSesInfo->password); | ||
3687 | } | 3667 | } |
3668 | |||
3669 | } else { | ||
3670 | SMBNTencrypt(pSesInfo->password, | ||
3671 | pSesInfo->server->cryptKey, | ||
3672 | ntlm_session_key); | ||
3673 | |||
3674 | if (first_time) | ||
3675 | cifs_calculate_mac_key( | ||
3676 | &pSesInfo->server->mac_signing_key, | ||
3677 | ntlm_session_key, | ||
3678 | pSesInfo->password); | ||
3679 | } | ||
3688 | /* for better security the weaker lanman hash not sent | 3680 | /* for better security the weaker lanman hash not sent |
3689 | in AuthSessSetup so we no longer calculate it */ | 3681 | in AuthSessSetup so we no longer calculate it */ |
3690 | 3682 | ||
3691 | rc = CIFSNTLMSSPAuthSessSetup(xid, | 3683 | rc = CIFSNTLMSSPAuthSessSetup(xid, pSesInfo, |
3692 | pSesInfo, | 3684 | ntlm_session_key, |
3693 | ntlm_session_key, | 3685 | ntlmv2_flag, |
3694 | ntlmv2_flag, | 3686 | nls_info); |
3695 | nls_info); | 3687 | } |
3696 | } | 3688 | } else { /* old style NTLM 0.12 session setup */ |
3697 | } else { /* old style NTLM 0.12 session setup */ | 3689 | SMBNTencrypt(pSesInfo->password, pSesInfo->server->cryptKey, |
3698 | SMBNTencrypt(pSesInfo->password, | 3690 | ntlm_session_key); |
3699 | pSesInfo->server->cryptKey, | ||
3700 | ntlm_session_key); | ||
3701 | 3691 | ||
3702 | if (first_time) | 3692 | if (first_time) |
3703 | cifs_calculate_mac_key( | 3693 | cifs_calculate_mac_key( |
3704 | &pSesInfo->server->mac_signing_key, | 3694 | &pSesInfo->server->mac_signing_key, |
3705 | ntlm_session_key, pSesInfo->password); | 3695 | ntlm_session_key, pSesInfo->password); |
3706 | 3696 | ||
3707 | rc = CIFSSessSetup(xid, pSesInfo, | 3697 | rc = CIFSSessSetup(xid, pSesInfo, ntlm_session_key, nls_info); |
3708 | ntlm_session_key, nls_info); | 3698 | } |
3709 | } | 3699 | if (rc) { |
3710 | if (rc) { | 3700 | cERROR(1, ("Send error in SessSetup = %d", rc)); |
3711 | cERROR(1, ("Send error in SessSetup = %d", rc)); | 3701 | } else { |
3712 | } else { | 3702 | cFYI(1, ("CIFS Session Established successfully")); |
3713 | cFYI(1, ("CIFS Session Established successfully")); | ||
3714 | pSesInfo->status = CifsGood; | 3703 | pSesInfo->status = CifsGood; |
3715 | } | ||
3716 | } | 3704 | } |
3705 | |||
3717 | ss_err_exit: | 3706 | ss_err_exit: |
3718 | return rc; | 3707 | return rc; |
3719 | } | 3708 | } |