aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c210
1 files changed, 117 insertions, 93 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index e8fa46c7cff2..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
@@ -455,7 +451,7 @@ incomplete_rcv:
455 /* Note that FC 1001 length is big endian on the wire, 451 /* Note that FC 1001 length is big endian on the wire,
456 but we convert it here so it is always manipulated 452 but we convert it here so it is always manipulated
457 as host byte order */ 453 as host byte order */
458 pdu_length = ntohl(smb_buffer->smb_buf_length); 454 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
459 smb_buffer->smb_buf_length = pdu_length; 455 smb_buffer->smb_buf_length = pdu_length;
460 456
461 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4)); 457 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
@@ -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);
@@ -1461,6 +1456,39 @@ get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1461 return rc; 1456 return rc;
1462} 1457}
1463 1458
1459#ifdef CONFIG_DEBUG_LOCK_ALLOC
1460static struct lock_class_key cifs_key[2];
1461static struct lock_class_key cifs_slock_key[2];
1462
1463static inline void
1464cifs_reclassify_socket4(struct socket *sock)
1465{
1466 struct sock *sk = sock->sk;
1467 BUG_ON(sock_owned_by_user(sk));
1468 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
1469 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
1470}
1471
1472static inline void
1473cifs_reclassify_socket6(struct socket *sock)
1474{
1475 struct sock *sk = sock->sk;
1476 BUG_ON(sock_owned_by_user(sk));
1477 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
1478 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
1479}
1480#else
1481static inline void
1482cifs_reclassify_socket4(struct socket *sock)
1483{
1484}
1485
1486static inline void
1487cifs_reclassify_socket6(struct socket *sock)
1488{
1489}
1490#endif
1491
1464/* See RFC1001 section 14 on representation of Netbios names */ 1492/* See RFC1001 section 14 on representation of Netbios names */
1465static void rfc1002mangle(char *target, char *source, unsigned int length) 1493static void rfc1002mangle(char *target, char *source, unsigned int length)
1466{ 1494{
@@ -1495,6 +1523,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1495 /* BB other socket options to set KEEPALIVE, NODELAY? */ 1523 /* BB other socket options to set KEEPALIVE, NODELAY? */
1496 cFYI(1, ("Socket created")); 1524 cFYI(1, ("Socket created"));
1497 (*csocket)->sk->sk_allocation = GFP_NOFS; 1525 (*csocket)->sk->sk_allocation = GFP_NOFS;
1526 cifs_reclassify_socket4(*csocket);
1498 } 1527 }
1499 } 1528 }
1500 1529
@@ -1627,6 +1656,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1627 /* BB other socket options to set KEEPALIVE, NODELAY? */ 1656 /* BB other socket options to set KEEPALIVE, NODELAY? */
1628 cFYI(1, ("ipv6 Socket created")); 1657 cFYI(1, ("ipv6 Socket created"));
1629 (*csocket)->sk->sk_allocation = GFP_NOFS; 1658 (*csocket)->sk->sk_allocation = GFP_NOFS;
1659 cifs_reclassify_socket6(*csocket);
1630 } 1660 }
1631 } 1661 }
1632 1662
@@ -3588,97 +3618,91 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3588 } 3618 }
3589 first_time = 1; 3619 first_time = 1;
3590 } 3620 }
3591 if (!rc) { 3621
3592 pSesInfo->flags = 0; 3622 if (rc)
3593 pSesInfo->capabilities = pSesInfo->server->capabilities; 3623 goto ss_err_exit;
3594 if (linuxExtEnabled == 0) 3624
3595 pSesInfo->capabilities &= (~CAP_UNIX); 3625 pSesInfo->flags = 0;
3626 pSesInfo->capabilities = pSesInfo->server->capabilities;
3627 if (linuxExtEnabled == 0)
3628 pSesInfo->capabilities &= (~CAP_UNIX);
3596 /* pSesInfo->sequence_number = 0;*/ 3629 /* pSesInfo->sequence_number = 0;*/
3597 cFYI(1, 3630 cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3598 ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d", 3631 pSesInfo->server->secMode,
3599 pSesInfo->server->secMode, 3632 pSesInfo->server->capabilities,
3600 pSesInfo->server->capabilities, 3633 pSesInfo->server->timeAdj));
3601 pSesInfo->server->timeAdj)); 3634 if (experimEnabled < 2)
3602 if (experimEnabled < 2) 3635 rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
3603 rc = CIFS_SessSetup(xid, pSesInfo, 3636 else if (extended_security
3604 first_time, nls_info); 3637 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3605 else if (extended_security 3638 && (pSesInfo->server->secType == NTLMSSP)) {
3606 && (pSesInfo->capabilities 3639 rc = -EOPNOTSUPP;
3607 & CAP_EXTENDED_SECURITY) 3640 } else if (extended_security
3608 && (pSesInfo->server->secType == NTLMSSP)) { 3641 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3609 rc = -EOPNOTSUPP; 3642 && (pSesInfo->server->secType == RawNTLMSSP)) {
3610 } else if (extended_security 3643 cFYI(1, ("NTLMSSP sesssetup"));
3611 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) 3644 rc = CIFSNTLMSSPNegotiateSessSetup(xid, pSesInfo, &ntlmv2_flag,
3612 && (pSesInfo->server->secType == RawNTLMSSP)) { 3645 nls_info);
3613 cFYI(1, ("NTLMSSP sesssetup")); 3646 if (!rc) {
3614 rc = CIFSNTLMSSPNegotiateSessSetup(xid, 3647 if (ntlmv2_flag) {
3615 pSesInfo, 3648 char *v2_response;
3616 &ntlmv2_flag, 3649 cFYI(1, ("more secure NTLM ver2 hash"));
3617 nls_info); 3650 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3618 if (!rc) { 3651 nls_info)) {
3619 if (ntlmv2_flag) { 3652 rc = -ENOMEM;
3620 char *v2_response; 3653 goto ss_err_exit;
3621 cFYI(1, ("more secure NTLM ver2 hash")); 3654 } else
3622 if (CalcNTLMv2_partial_mac_key(pSesInfo, 3655 v2_response = kmalloc(16 + 64 /* blob*/,
3623 nls_info)) { 3656 GFP_KERNEL);
3624 rc = -ENOMEM; 3657 if (v2_response) {
3625 goto ss_err_exit; 3658 CalcNTLMv2_response(pSesInfo,
3626 } else 3659 v2_response);
3627 v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL); 3660 /* if (first_time)
3628 if (v2_response) { 3661 cifs_calculate_ntlmv2_mac_key */
3629 CalcNTLMv2_response(pSesInfo, 3662 kfree(v2_response);
3630 v2_response);
3631 /* if (first_time)
3632 cifs_calculate_ntlmv2_mac_key(
3633 pSesInfo->server->mac_signing_key,
3634 response, ntlm_session_key,*/
3635 kfree(v2_response);
3636 /* BB Put dummy sig in SessSetup PDU? */ 3663 /* BB Put dummy sig in SessSetup PDU? */
3637 } else {
3638 rc = -ENOMEM;
3639 goto ss_err_exit;
3640 }
3641
3642 } else { 3664 } else {
3643 SMBNTencrypt(pSesInfo->password, 3665 rc = -ENOMEM;
3644 pSesInfo->server->cryptKey, 3666 goto ss_err_exit;
3645 ntlm_session_key);
3646
3647 if (first_time)
3648 cifs_calculate_mac_key(
3649 &pSesInfo->server->mac_signing_key,
3650 ntlm_session_key,
3651 pSesInfo->password);
3652 } 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 }
3653 /* for better security the weaker lanman hash not sent 3680 /* for better security the weaker lanman hash not sent
3654 in AuthSessSetup so we no longer calculate it */ 3681 in AuthSessSetup so we no longer calculate it */
3655 3682
3656 rc = CIFSNTLMSSPAuthSessSetup(xid, 3683 rc = CIFSNTLMSSPAuthSessSetup(xid, pSesInfo,
3657 pSesInfo, 3684 ntlm_session_key,
3658 ntlm_session_key, 3685 ntlmv2_flag,
3659 ntlmv2_flag, 3686 nls_info);
3660 nls_info); 3687 }
3661 } 3688 } else { /* old style NTLM 0.12 session setup */
3662 } else { /* old style NTLM 0.12 session setup */ 3689 SMBNTencrypt(pSesInfo->password, pSesInfo->server->cryptKey,
3663 SMBNTencrypt(pSesInfo->password, 3690 ntlm_session_key);
3664 pSesInfo->server->cryptKey,
3665 ntlm_session_key);
3666 3691
3667 if (first_time) 3692 if (first_time)
3668 cifs_calculate_mac_key( 3693 cifs_calculate_mac_key(
3669 &pSesInfo->server->mac_signing_key, 3694 &pSesInfo->server->mac_signing_key,
3670 ntlm_session_key, pSesInfo->password); 3695 ntlm_session_key, pSesInfo->password);
3671 3696
3672 rc = CIFSSessSetup(xid, pSesInfo, 3697 rc = CIFSSessSetup(xid, pSesInfo, ntlm_session_key, nls_info);
3673 ntlm_session_key, nls_info); 3698 }
3674 } 3699 if (rc) {
3675 if (rc) { 3700 cERROR(1, ("Send error in SessSetup = %d", rc));
3676 cERROR(1, ("Send error in SessSetup = %d", rc)); 3701 } else {
3677 } else { 3702 cFYI(1, ("CIFS Session Established successfully"));
3678 cFYI(1, ("CIFS Session Established successfully"));
3679 pSesInfo->status = CifsGood; 3703 pSesInfo->status = CifsGood;
3680 }
3681 } 3704 }
3705
3682ss_err_exit: 3706ss_err_exit:
3683 return rc; 3707 return rc;
3684} 3708}