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.c70
1 files changed, 52 insertions, 18 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 18d3c7724d6e..8d6c17ab593d 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -55,9 +55,6 @@
55/* SMB echo "timeout" -- FIXME: tunable? */ 55/* SMB echo "timeout" -- FIXME: tunable? */
56#define SMB_ECHO_INTERVAL (60 * HZ) 56#define SMB_ECHO_INTERVAL (60 * HZ)
57 57
58extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
59 unsigned char *p24);
60
61extern mempool_t *cifs_req_poolp; 58extern mempool_t *cifs_req_poolp;
62 59
63struct smb_vol { 60struct smb_vol {
@@ -87,6 +84,7 @@ struct smb_vol {
87 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/ 84 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
88 bool server_ino:1; /* use inode numbers from server ie UniqueId */ 85 bool server_ino:1; /* use inode numbers from server ie UniqueId */
89 bool direct_io:1; 86 bool direct_io:1;
87 bool strict_io:1; /* strict cache behavior */
90 bool remap:1; /* set to remap seven reserved chars in filenames */ 88 bool remap:1; /* set to remap seven reserved chars in filenames */
91 bool posix_paths:1; /* unset to not ask for posix pathnames. */ 89 bool posix_paths:1; /* unset to not ask for posix pathnames. */
92 bool no_linux_ext:1; 90 bool no_linux_ext:1;
@@ -339,8 +337,13 @@ cifs_echo_request(struct work_struct *work)
339 struct TCP_Server_Info *server = container_of(work, 337 struct TCP_Server_Info *server = container_of(work,
340 struct TCP_Server_Info, echo.work); 338 struct TCP_Server_Info, echo.work);
341 339
342 /* no need to ping if we got a response recently */ 340 /*
343 if (time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ)) 341 * We cannot send an echo until the NEGOTIATE_PROTOCOL request is
342 * done, which is indicated by maxBuf != 0. Also, no need to ping if
343 * we got a response recently
344 */
345 if (server->maxBuf == 0 ||
346 time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ))
344 goto requeue_echo; 347 goto requeue_echo;
345 348
346 rc = CIFSSMBEcho(server); 349 rc = CIFSSMBEcho(server);
@@ -580,14 +583,23 @@ incomplete_rcv:
580 else if (reconnect == 1) 583 else if (reconnect == 1)
581 continue; 584 continue;
582 585
583 length += 4; /* account for rfc1002 hdr */ 586 total_read += 4; /* account for rfc1002 hdr */
584 587
588 dump_smb(smb_buffer, total_read);
585 589
586 dump_smb(smb_buffer, length); 590 /*
587 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) { 591 * We know that we received enough to get to the MID as we
588 cifs_dump_mem("Bad SMB: ", smb_buffer, 48); 592 * checked the pdu_length earlier. Now check to see
589 continue; 593 * if the rest of the header is OK. We borrow the length
590 } 594 * var for the rest of the loop to avoid a new stack var.
595 *
596 * 48 bytes is enough to display the header and a little bit
597 * into the payload for debugging purposes.
598 */
599 length = checkSMB(smb_buffer, smb_buffer->Mid, total_read);
600 if (length != 0)
601 cifs_dump_mem("Bad SMB: ", smb_buffer,
602 min_t(unsigned int, total_read, 48));
591 603
592 mid_entry = NULL; 604 mid_entry = NULL;
593 server->lstrp = jiffies; 605 server->lstrp = jiffies;
@@ -599,7 +611,8 @@ incomplete_rcv:
599 if ((mid_entry->mid == smb_buffer->Mid) && 611 if ((mid_entry->mid == smb_buffer->Mid) &&
600 (mid_entry->midState == MID_REQUEST_SUBMITTED) && 612 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
601 (mid_entry->command == smb_buffer->Command)) { 613 (mid_entry->command == smb_buffer->Command)) {
602 if (check2ndT2(smb_buffer,server->maxBuf) > 0) { 614 if (length == 0 &&
615 check2ndT2(smb_buffer, server->maxBuf) > 0) {
603 /* We have a multipart transact2 resp */ 616 /* We have a multipart transact2 resp */
604 isMultiRsp = true; 617 isMultiRsp = true;
605 if (mid_entry->resp_buf) { 618 if (mid_entry->resp_buf) {
@@ -634,12 +647,17 @@ incomplete_rcv:
634 mid_entry->resp_buf = smb_buffer; 647 mid_entry->resp_buf = smb_buffer;
635 mid_entry->largeBuf = isLargeBuf; 648 mid_entry->largeBuf = isLargeBuf;
636multi_t2_fnd: 649multi_t2_fnd:
637 mid_entry->midState = MID_RESPONSE_RECEIVED; 650 if (length == 0)
638 list_del_init(&mid_entry->qhead); 651 mid_entry->midState =
639 mid_entry->callback(mid_entry); 652 MID_RESPONSE_RECEIVED;
653 else
654 mid_entry->midState =
655 MID_RESPONSE_MALFORMED;
640#ifdef CONFIG_CIFS_STATS2 656#ifdef CONFIG_CIFS_STATS2
641 mid_entry->when_received = jiffies; 657 mid_entry->when_received = jiffies;
642#endif 658#endif
659 list_del_init(&mid_entry->qhead);
660 mid_entry->callback(mid_entry);
643 break; 661 break;
644 } 662 }
645 mid_entry = NULL; 663 mid_entry = NULL;
@@ -655,6 +673,9 @@ multi_t2_fnd:
655 else 673 else
656 smallbuf = NULL; 674 smallbuf = NULL;
657 } 675 }
676 } else if (length != 0) {
677 /* response sanity checks failed */
678 continue;
658 } else if (!is_valid_oplock_break(smb_buffer, server) && 679 } else if (!is_valid_oplock_break(smb_buffer, server) &&
659 !isMultiRsp) { 680 !isMultiRsp) {
660 cERROR(1, "No task to wake, unknown frame received! " 681 cERROR(1, "No task to wake, unknown frame received! "
@@ -1344,6 +1365,8 @@ cifs_parse_mount_options(char *options, const char *devname,
1344 vol->direct_io = 1; 1365 vol->direct_io = 1;
1345 } else if (strnicmp(data, "forcedirectio", 13) == 0) { 1366 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1346 vol->direct_io = 1; 1367 vol->direct_io = 1;
1368 } else if (strnicmp(data, "strictcache", 11) == 0) {
1369 vol->strict_io = 1;
1347 } else if (strnicmp(data, "noac", 4) == 0) { 1370 } else if (strnicmp(data, "noac", 4) == 0) {
1348 printk(KERN_WARNING "CIFS: Mount option noac not " 1371 printk(KERN_WARNING "CIFS: Mount option noac not "
1349 "supported. Instead set " 1372 "supported. Instead set "
@@ -1568,6 +1591,9 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1568 1591
1569 spin_lock(&cifs_tcp_ses_lock); 1592 spin_lock(&cifs_tcp_ses_lock);
1570 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { 1593 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
1594 if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
1595 continue;
1596
1571 if (!match_address(server, addr, 1597 if (!match_address(server, addr,
1572 (struct sockaddr *)&vol->srcaddr)) 1598 (struct sockaddr *)&vol->srcaddr))
1573 continue; 1599 continue;
@@ -1598,6 +1624,8 @@ cifs_put_tcp_session(struct TCP_Server_Info *server)
1598 return; 1624 return;
1599 } 1625 }
1600 1626
1627 put_net(cifs_net_ns(server));
1628
1601 list_del_init(&server->tcp_ses_list); 1629 list_del_init(&server->tcp_ses_list);
1602 spin_unlock(&cifs_tcp_ses_lock); 1630 spin_unlock(&cifs_tcp_ses_lock);
1603 1631
@@ -1672,6 +1700,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1672 goto out_err; 1700 goto out_err;
1673 } 1701 }
1674 1702
1703 cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns));
1675 tcp_ses->hostname = extract_hostname(volume_info->UNC); 1704 tcp_ses->hostname = extract_hostname(volume_info->UNC);
1676 if (IS_ERR(tcp_ses->hostname)) { 1705 if (IS_ERR(tcp_ses->hostname)) {
1677 rc = PTR_ERR(tcp_ses->hostname); 1706 rc = PTR_ERR(tcp_ses->hostname);
@@ -1752,6 +1781,8 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1752out_err_crypto_release: 1781out_err_crypto_release:
1753 cifs_crypto_shash_release(tcp_ses); 1782 cifs_crypto_shash_release(tcp_ses);
1754 1783
1784 put_net(cifs_net_ns(tcp_ses));
1785
1755out_err: 1786out_err:
1756 if (tcp_ses) { 1787 if (tcp_ses) {
1757 if (!IS_ERR(tcp_ses->hostname)) 1788 if (!IS_ERR(tcp_ses->hostname))
@@ -2263,8 +2294,8 @@ generic_ip_connect(struct TCP_Server_Info *server)
2263 } 2294 }
2264 2295
2265 if (socket == NULL) { 2296 if (socket == NULL) {
2266 rc = sock_create_kern(sfamily, SOCK_STREAM, 2297 rc = __sock_create(cifs_net_ns(server), sfamily, SOCK_STREAM,
2267 IPPROTO_TCP, &socket); 2298 IPPROTO_TCP, &socket, 1);
2268 if (rc < 0) { 2299 if (rc < 0) {
2269 cERROR(1, "Error %d creating socket", rc); 2300 cERROR(1, "Error %d creating socket", rc);
2270 server->ssocket = NULL; 2301 server->ssocket = NULL;
@@ -2576,6 +2607,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
2576 if (pvolume_info->multiuser) 2607 if (pvolume_info->multiuser)
2577 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER | 2608 cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
2578 CIFS_MOUNT_NO_PERM); 2609 CIFS_MOUNT_NO_PERM);
2610 if (pvolume_info->strict_io)
2611 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO;
2579 if (pvolume_info->direct_io) { 2612 if (pvolume_info->direct_io) {
2580 cFYI(1, "mounting share using direct i/o"); 2613 cFYI(1, "mounting share using direct i/o");
2581 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; 2614 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
@@ -2977,7 +3010,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2977 bcc_ptr); 3010 bcc_ptr);
2978 else 3011 else
2979#endif /* CIFS_WEAK_PW_HASH */ 3012#endif /* CIFS_WEAK_PW_HASH */
2980 SMBNTencrypt(tcon->password, ses->server->cryptkey, bcc_ptr); 3013 rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
3014 bcc_ptr);
2981 3015
2982 bcc_ptr += CIFS_AUTH_RESP_SIZE; 3016 bcc_ptr += CIFS_AUTH_RESP_SIZE;
2983 if (ses->capabilities & CAP_UNICODE) { 3017 if (ses->capabilities & CAP_UNICODE) {