aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 15:37:14 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-12-28 15:37:14 -0500
commit54a696bd07c14d3b1192d03ce7269bc59b45209a (patch)
tree2da3a0ce28e08bde17a0fba8bb807480849cf410 /fs/cifs/connect.c
parent1d248b2593e92db6c51ca07235985a95c625a93f (diff)
parent359d67d6ad054ae11ad459665fdfb883aca87782 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: (31 commits) [CIFS] Remove redundant test [CIFS] make sure that DFS pathnames are properly formed Remove an already-checked error condition in SendReceiveBlockingLock Streamline SendReceiveBlockingLock: Use "goto out:" in an error condition Streamline SendReceiveBlockingLock: Use "goto out:" in an error condition [CIFS] Streamline SendReceive[2] by using "goto out:" in an error condition Slightly streamline SendReceive[2] Check the return value of cifs_sign_smb[2] [CIFS] Cleanup: Move the check for too large R/W requests [CIFS] Slightly simplify wait_for_free_request(), remove an unnecessary "else" branch Simplify allocate_mid() slightly: Remove some unnecessary "else" branches [CIFS] In SendReceive, move consistency check out of the mutexed region cifs: store password in tcon cifs: have calc_lanman_hash take more granular args cifs: zero out session password before freeing it cifs: fix wait_for_response to time out sleeping processes correctly [CIFS] Can not mount with prefixpath if root directory of share is inaccessible [CIFS] various minor cleanups pointed out by checkpatch script [CIFS] fix typo [CIFS] remove sparse warning ... Fix trivial conflict in fs/cifs/cifs_fs_sb.h due to comment changes for the CIFS_MOUNT_xyz bit definitions between cifs updates and security updates.
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c681
1 files changed, 370 insertions, 311 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 683dee4d2f76..d2ea95bef1c1 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -89,6 +89,7 @@ struct smb_vol {
89 bool nullauth:1; /* attempt to authenticate with null user */ 89 bool nullauth:1; /* attempt to authenticate with null user */
90 bool nocase:1; /* request case insensitive filenames */ 90 bool nocase:1; /* request case insensitive filenames */
91 bool nobrl:1; /* disable sending byte range locks to srv */ 91 bool nobrl:1; /* disable sending byte range locks to srv */
92 bool mand_lock:1; /* send mandatory not posix byte range lock reqs */
92 bool seal:1; /* request transport encryption on share */ 93 bool seal:1; /* request transport encryption on share */
93 bool nodfs:1; /* Do not request DFS, even if available */ 94 bool nodfs:1; /* Do not request DFS, even if available */
94 bool local_lease:1; /* check leases only on local system, not remote */ 95 bool local_lease:1; /* check leases only on local system, not remote */
@@ -101,25 +102,17 @@ struct smb_vol {
101 char *prepath; 102 char *prepath;
102}; 103};
103 104
104static int ipv4_connect(struct sockaddr_in *psin_server, 105static int ipv4_connect(struct TCP_Server_Info *server);
105 struct socket **csocket, 106static int ipv6_connect(struct TCP_Server_Info *server);
106 char *netb_name,
107 char *server_netb_name,
108 bool noblocksnd,
109 bool nosndbuf); /* ipv6 never set sndbuf size */
110static int ipv6_connect(struct sockaddr_in6 *psin_server,
111 struct socket **csocket, bool noblocksnd);
112
113
114 /*
115 * cifs tcp session reconnection
116 *
117 * mark tcp session as reconnecting so temporarily locked
118 * mark all smb sessions as reconnecting for tcp session
119 * reconnect tcp session
120 * wake up waiters on reconnection? - (not needed currently)
121 */
122 107
108/*
109 * cifs tcp session reconnection
110 *
111 * mark tcp session as reconnecting so temporarily locked
112 * mark all smb sessions as reconnecting for tcp session
113 * reconnect tcp session
114 * wake up waiters on reconnection? - (not needed currently)
115 */
123static int 116static int
124cifs_reconnect(struct TCP_Server_Info *server) 117cifs_reconnect(struct TCP_Server_Info *server)
125{ 118{
@@ -156,7 +149,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
156 } 149 }
157 read_unlock(&cifs_tcp_ses_lock); 150 read_unlock(&cifs_tcp_ses_lock);
158 /* do not want to be sending data on a socket we are freeing */ 151 /* do not want to be sending data on a socket we are freeing */
159 down(&server->tcpSem); 152 mutex_lock(&server->srv_mutex);
160 if (server->ssocket) { 153 if (server->ssocket) {
161 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state, 154 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
162 server->ssocket->flags)); 155 server->ssocket->flags));
@@ -182,21 +175,15 @@ cifs_reconnect(struct TCP_Server_Info *server)
182 } 175 }
183 } 176 }
184 spin_unlock(&GlobalMid_Lock); 177 spin_unlock(&GlobalMid_Lock);
185 up(&server->tcpSem); 178 mutex_unlock(&server->srv_mutex);
186 179
187 while ((server->tcpStatus != CifsExiting) && 180 while ((server->tcpStatus != CifsExiting) &&
188 (server->tcpStatus != CifsGood)) { 181 (server->tcpStatus != CifsGood)) {
189 try_to_freeze(); 182 try_to_freeze();
190 if (server->addr.sockAddr6.sin6_family == AF_INET6) { 183 if (server->addr.sockAddr6.sin6_family == AF_INET6)
191 rc = ipv6_connect(&server->addr.sockAddr6, 184 rc = ipv6_connect(server);
192 &server->ssocket, server->noautotune); 185 else
193 } else { 186 rc = ipv4_connect(server);
194 rc = ipv4_connect(&server->addr.sockAddr,
195 &server->ssocket,
196 server->workstation_RFC1001_name,
197 server->server_RFC1001_name,
198 server->noblocksnd, server->noautotune);
199 }
200 if (rc) { 187 if (rc) {
201 cFYI(1, ("reconnect error %d", rc)); 188 cFYI(1, ("reconnect error %d", rc));
202 msleep(3000); 189 msleep(3000);
@@ -776,7 +763,7 @@ multi_t2_fnd:
776 set_current_state(TASK_RUNNING); 763 set_current_state(TASK_RUNNING);
777 } 764 }
778 765
779 return 0; 766 module_put_and_exit(0);
780} 767}
781 768
782/* extract the host portion of the UNC string */ 769/* extract the host portion of the UNC string */
@@ -1260,6 +1247,17 @@ cifs_parse_mount_options(char *options, const char *devname,
1260 if (vol->file_mode == 1247 if (vol->file_mode ==
1261 (S_IALLUGO & ~(S_ISUID | S_IXGRP))) 1248 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1262 vol->file_mode = S_IALLUGO; 1249 vol->file_mode = S_IALLUGO;
1250 } else if (strnicmp(data, "forcemandatorylock", 9) == 0) {
1251 /* will take the shorter form "forcemand" as well */
1252 /* This mount option will force use of mandatory
1253 (DOS/Windows style) byte range locks, instead of
1254 using posix advisory byte range locks, even if the
1255 Unix extensions are available and posix locks would
1256 be supported otherwise. If Unix extensions are not
1257 negotiated this has no effect since mandatory locks
1258 would be used (mandatory locks is all that those
1259 those servers support) */
1260 vol->mand_lock = 1;
1263 } else if (strnicmp(data, "setuids", 7) == 0) { 1261 } else if (strnicmp(data, "setuids", 7) == 0) {
1264 vol->setuids = 1; 1262 vol->setuids = 1;
1265 } else if (strnicmp(data, "nosetuids", 9) == 0) { 1263 } else if (strnicmp(data, "nosetuids", 9) == 0) {
@@ -1417,6 +1415,143 @@ cifs_put_tcp_session(struct TCP_Server_Info *server)
1417 force_sig(SIGKILL, task); 1415 force_sig(SIGKILL, task);
1418} 1416}
1419 1417
1418static struct TCP_Server_Info *
1419cifs_get_tcp_session(struct smb_vol *volume_info)
1420{
1421 struct TCP_Server_Info *tcp_ses = NULL;
1422 struct sockaddr addr;
1423 struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
1424 struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
1425 int rc;
1426
1427 memset(&addr, 0, sizeof(struct sockaddr));
1428
1429 if (volume_info->UNCip && volume_info->UNC) {
1430 rc = cifs_inet_pton(AF_INET, volume_info->UNCip,
1431 &sin_server->sin_addr.s_addr);
1432
1433 if (rc <= 0) {
1434 /* not ipv4 address, try ipv6 */
1435 rc = cifs_inet_pton(AF_INET6, volume_info->UNCip,
1436 &sin_server6->sin6_addr.in6_u);
1437 if (rc > 0)
1438 addr.sa_family = AF_INET6;
1439 } else {
1440 addr.sa_family = AF_INET;
1441 }
1442
1443 if (rc <= 0) {
1444 /* we failed translating address */
1445 rc = -EINVAL;
1446 goto out_err;
1447 }
1448
1449 cFYI(1, ("UNC: %s ip: %s", volume_info->UNC,
1450 volume_info->UNCip));
1451 } else if (volume_info->UNCip) {
1452 /* BB using ip addr as tcp_ses name to connect to the
1453 DFS root below */
1454 cERROR(1, ("Connecting to DFS root not implemented yet"));
1455 rc = -EINVAL;
1456 goto out_err;
1457 } else /* which tcp_sess DFS root would we conect to */ {
1458 cERROR(1,
1459 ("CIFS mount error: No UNC path (e.g. -o "
1460 "unc=//192.168.1.100/public) specified"));
1461 rc = -EINVAL;
1462 goto out_err;
1463 }
1464
1465 /* see if we already have a matching tcp_ses */
1466 tcp_ses = cifs_find_tcp_session(&addr);
1467 if (tcp_ses)
1468 return tcp_ses;
1469
1470 tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
1471 if (!tcp_ses) {
1472 rc = -ENOMEM;
1473 goto out_err;
1474 }
1475
1476 tcp_ses->hostname = extract_hostname(volume_info->UNC);
1477 if (IS_ERR(tcp_ses->hostname)) {
1478 rc = PTR_ERR(tcp_ses->hostname);
1479 goto out_err;
1480 }
1481
1482 tcp_ses->noblocksnd = volume_info->noblocksnd;
1483 tcp_ses->noautotune = volume_info->noautotune;
1484 atomic_set(&tcp_ses->inFlight, 0);
1485 init_waitqueue_head(&tcp_ses->response_q);
1486 init_waitqueue_head(&tcp_ses->request_q);
1487 INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
1488 mutex_init(&tcp_ses->srv_mutex);
1489 memcpy(tcp_ses->workstation_RFC1001_name,
1490 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1491 memcpy(tcp_ses->server_RFC1001_name,
1492 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1493 tcp_ses->sequence_number = 0;
1494 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
1495 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
1496
1497 /*
1498 * at this point we are the only ones with the pointer
1499 * to the struct since the kernel thread not created yet
1500 * no need to spinlock this init of tcpStatus or srv_count
1501 */
1502 tcp_ses->tcpStatus = CifsNew;
1503 ++tcp_ses->srv_count;
1504
1505 if (addr.sa_family == AF_INET6) {
1506 cFYI(1, ("attempting ipv6 connect"));
1507 /* BB should we allow ipv6 on port 139? */
1508 /* other OS never observed in Wild doing 139 with v6 */
1509 memcpy(&tcp_ses->addr.sockAddr6, sin_server6,
1510 sizeof(struct sockaddr_in6));
1511 sin_server6->sin6_port = htons(volume_info->port);
1512 rc = ipv6_connect(tcp_ses);
1513 } else {
1514 memcpy(&tcp_ses->addr.sockAddr, sin_server,
1515 sizeof(struct sockaddr_in));
1516 sin_server->sin_port = htons(volume_info->port);
1517 rc = ipv4_connect(tcp_ses);
1518 }
1519 if (rc < 0) {
1520 cERROR(1, ("Error connecting to socket. Aborting operation"));
1521 goto out_err;
1522 }
1523
1524 /*
1525 * since we're in a cifs function already, we know that
1526 * this will succeed. No need for try_module_get().
1527 */
1528 __module_get(THIS_MODULE);
1529 tcp_ses->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread,
1530 tcp_ses, "cifsd");
1531 if (IS_ERR(tcp_ses->tsk)) {
1532 rc = PTR_ERR(tcp_ses->tsk);
1533 cERROR(1, ("error %d create cifsd thread", rc));
1534 module_put(THIS_MODULE);
1535 goto out_err;
1536 }
1537
1538 /* thread spawned, put it on the list */
1539 write_lock(&cifs_tcp_ses_lock);
1540 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1541 write_unlock(&cifs_tcp_ses_lock);
1542
1543 return tcp_ses;
1544
1545out_err:
1546 if (tcp_ses) {
1547 kfree(tcp_ses->hostname);
1548 if (tcp_ses->ssocket)
1549 sock_release(tcp_ses->ssocket);
1550 kfree(tcp_ses);
1551 }
1552 return ERR_PTR(rc);
1553}
1554
1420static struct cifsSesInfo * 1555static struct cifsSesInfo *
1421cifs_find_smb_ses(struct TCP_Server_Info *server, char *username) 1556cifs_find_smb_ses(struct TCP_Server_Info *server, char *username)
1422{ 1557{
@@ -1593,93 +1728,96 @@ static void rfc1002mangle(char *target, char *source, unsigned int length)
1593 1728
1594 1729
1595static int 1730static int
1596ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, 1731ipv4_connect(struct TCP_Server_Info *server)
1597 char *netbios_name, char *target_name,
1598 bool noblocksnd, bool noautotune)
1599{ 1732{
1600 int rc = 0; 1733 int rc = 0;
1601 int connected = 0; 1734 bool connected = false;
1602 __be16 orig_port = 0; 1735 __be16 orig_port = 0;
1736 struct socket *socket = server->ssocket;
1603 1737
1604 if (*csocket == NULL) { 1738 if (socket == NULL) {
1605 rc = sock_create_kern(PF_INET, SOCK_STREAM, 1739 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1606 IPPROTO_TCP, csocket); 1740 IPPROTO_TCP, &socket);
1607 if (rc < 0) { 1741 if (rc < 0) {
1608 cERROR(1, ("Error %d creating socket", rc)); 1742 cERROR(1, ("Error %d creating socket", rc));
1609 *csocket = NULL;
1610 return rc; 1743 return rc;
1611 } else {
1612 /* BB other socket options to set KEEPALIVE, NODELAY? */
1613 cFYI(1, ("Socket created"));
1614 (*csocket)->sk->sk_allocation = GFP_NOFS;
1615 cifs_reclassify_socket4(*csocket);
1616 } 1744 }
1745
1746 /* BB other socket options to set KEEPALIVE, NODELAY? */
1747 cFYI(1, ("Socket created"));
1748 server->ssocket = socket;
1749 socket->sk->sk_allocation = GFP_NOFS;
1750 cifs_reclassify_socket4(socket);
1617 } 1751 }
1618 1752
1619 psin_server->sin_family = AF_INET; 1753 /* user overrode default port */
1620 if (psin_server->sin_port) { /* user overrode default port */ 1754 if (server->addr.sockAddr.sin_port) {
1621 rc = (*csocket)->ops->connect(*csocket, 1755 rc = socket->ops->connect(socket, (struct sockaddr *)
1622 (struct sockaddr *) psin_server, 1756 &server->addr.sockAddr,
1623 sizeof(struct sockaddr_in), 0); 1757 sizeof(struct sockaddr_in), 0);
1624 if (rc >= 0) 1758 if (rc >= 0)
1625 connected = 1; 1759 connected = true;
1626 } 1760 }
1627 1761
1628 if (!connected) { 1762 if (!connected) {
1629 /* save original port so we can retry user specified port 1763 /* save original port so we can retry user specified port
1630 later if fall back ports fail this time */ 1764 later if fall back ports fail this time */
1631 orig_port = psin_server->sin_port; 1765 orig_port = server->addr.sockAddr.sin_port;
1632 1766
1633 /* do not retry on the same port we just failed on */ 1767 /* do not retry on the same port we just failed on */
1634 if (psin_server->sin_port != htons(CIFS_PORT)) { 1768 if (server->addr.sockAddr.sin_port != htons(CIFS_PORT)) {
1635 psin_server->sin_port = htons(CIFS_PORT); 1769 server->addr.sockAddr.sin_port = htons(CIFS_PORT);
1636 1770 rc = socket->ops->connect(socket,
1637 rc = (*csocket)->ops->connect(*csocket, 1771 (struct sockaddr *)
1638 (struct sockaddr *) psin_server, 1772 &server->addr.sockAddr,
1639 sizeof(struct sockaddr_in), 0); 1773 sizeof(struct sockaddr_in), 0);
1640 if (rc >= 0) 1774 if (rc >= 0)
1641 connected = 1; 1775 connected = true;
1642 } 1776 }
1643 } 1777 }
1644 if (!connected) { 1778 if (!connected) {
1645 psin_server->sin_port = htons(RFC1001_PORT); 1779 server->addr.sockAddr.sin_port = htons(RFC1001_PORT);
1646 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) 1780 rc = socket->ops->connect(socket, (struct sockaddr *)
1647 psin_server, 1781 &server->addr.sockAddr,
1648 sizeof(struct sockaddr_in), 0); 1782 sizeof(struct sockaddr_in), 0);
1649 if (rc >= 0) 1783 if (rc >= 0)
1650 connected = 1; 1784 connected = true;
1651 } 1785 }
1652 1786
1653 /* give up here - unless we want to retry on different 1787 /* give up here - unless we want to retry on different
1654 protocol families some day */ 1788 protocol families some day */
1655 if (!connected) { 1789 if (!connected) {
1656 if (orig_port) 1790 if (orig_port)
1657 psin_server->sin_port = orig_port; 1791 server->addr.sockAddr.sin_port = orig_port;
1658 cFYI(1, ("Error %d connecting to server via ipv4", rc)); 1792 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1659 sock_release(*csocket); 1793 sock_release(socket);
1660 *csocket = NULL; 1794 server->ssocket = NULL;
1661 return rc; 1795 return rc;
1662 } 1796 }
1663 /* Eventually check for other socket options to change from 1797
1664 the default. sock_setsockopt not used because it expects 1798
1665 user space buffer */ 1799 /*
1666 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx", 1800 * Eventually check for other socket options to change from
1667 (*csocket)->sk->sk_sndbuf, 1801 * the default. sock_setsockopt not used because it expects
1668 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo)); 1802 * user space buffer
1669 (*csocket)->sk->sk_rcvtimeo = 7 * HZ; 1803 */
1670 if (!noblocksnd) 1804 socket->sk->sk_rcvtimeo = 7 * HZ;
1671 (*csocket)->sk->sk_sndtimeo = 3 * HZ; 1805 socket->sk->sk_sndtimeo = 3 * HZ;
1672 1806
1673 /* make the bufsizes depend on wsize/rsize and max requests */ 1807 /* make the bufsizes depend on wsize/rsize and max requests */
1674 if (noautotune) { 1808 if (server->noautotune) {
1675 if ((*csocket)->sk->sk_sndbuf < (200 * 1024)) 1809 if (socket->sk->sk_sndbuf < (200 * 1024))
1676 (*csocket)->sk->sk_sndbuf = 200 * 1024; 1810 socket->sk->sk_sndbuf = 200 * 1024;
1677 if ((*csocket)->sk->sk_rcvbuf < (140 * 1024)) 1811 if (socket->sk->sk_rcvbuf < (140 * 1024))
1678 (*csocket)->sk->sk_rcvbuf = 140 * 1024; 1812 socket->sk->sk_rcvbuf = 140 * 1024;
1679 } 1813 }
1680 1814
1815 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1816 socket->sk->sk_sndbuf,
1817 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo));
1818
1681 /* send RFC1001 sessinit */ 1819 /* send RFC1001 sessinit */
1682 if (psin_server->sin_port == htons(RFC1001_PORT)) { 1820 if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) {
1683 /* some servers require RFC1001 sessinit before sending 1821 /* some servers require RFC1001 sessinit before sending
1684 negprot - BB check reconnection in case where second 1822 negprot - BB check reconnection in case where second
1685 sessinit is sent but no second negprot */ 1823 sessinit is sent but no second negprot */
@@ -1689,31 +1827,42 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1689 GFP_KERNEL); 1827 GFP_KERNEL);
1690 if (ses_init_buf) { 1828 if (ses_init_buf) {
1691 ses_init_buf->trailer.session_req.called_len = 32; 1829 ses_init_buf->trailer.session_req.called_len = 32;
1692 if (target_name && (target_name[0] != 0)) { 1830 if (server->server_RFC1001_name &&
1693 rfc1002mangle(ses_init_buf->trailer.session_req.called_name, 1831 server->server_RFC1001_name[0] != 0)
1694 target_name, 16); 1832 rfc1002mangle(ses_init_buf->trailer.
1695 } else { 1833 session_req.called_name,
1696 rfc1002mangle(ses_init_buf->trailer.session_req.called_name, 1834 server->server_RFC1001_name,
1697 DEFAULT_CIFS_CALLED_NAME, 16); 1835 RFC1001_NAME_LEN_WITH_NULL);
1698 } 1836 else
1837 rfc1002mangle(ses_init_buf->trailer.
1838 session_req.called_name,
1839 DEFAULT_CIFS_CALLED_NAME,
1840 RFC1001_NAME_LEN_WITH_NULL);
1699 1841
1700 ses_init_buf->trailer.session_req.calling_len = 32; 1842 ses_init_buf->trailer.session_req.calling_len = 32;
1843
1701 /* calling name ends in null (byte 16) from old smb 1844 /* calling name ends in null (byte 16) from old smb
1702 convention. */ 1845 convention. */
1703 if (netbios_name && (netbios_name[0] != 0)) { 1846 if (server->workstation_RFC1001_name &&
1704 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name, 1847 server->workstation_RFC1001_name[0] != 0)
1705 netbios_name, 16); 1848 rfc1002mangle(ses_init_buf->trailer.
1706 } else { 1849 session_req.calling_name,
1707 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name, 1850 server->workstation_RFC1001_name,
1708 "LINUX_CIFS_CLNT", 16); 1851 RFC1001_NAME_LEN_WITH_NULL);
1709 } 1852 else
1853 rfc1002mangle(ses_init_buf->trailer.
1854 session_req.calling_name,
1855 "LINUX_CIFS_CLNT",
1856 RFC1001_NAME_LEN_WITH_NULL);
1857
1710 ses_init_buf->trailer.session_req.scope1 = 0; 1858 ses_init_buf->trailer.session_req.scope1 = 0;
1711 ses_init_buf->trailer.session_req.scope2 = 0; 1859 ses_init_buf->trailer.session_req.scope2 = 0;
1712 smb_buf = (struct smb_hdr *)ses_init_buf; 1860 smb_buf = (struct smb_hdr *)ses_init_buf;
1713 /* sizeof RFC1002_SESSION_REQUEST with no scope */ 1861 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1714 smb_buf->smb_buf_length = 0x81000044; 1862 smb_buf->smb_buf_length = 0x81000044;
1715 rc = smb_send(*csocket, smb_buf, 0x44, 1863 rc = smb_send(socket, smb_buf, 0x44,
1716 (struct sockaddr *)psin_server, noblocksnd); 1864 (struct sockaddr *) &server->addr.sockAddr,
1865 server->noblocksnd);
1717 kfree(ses_init_buf); 1866 kfree(ses_init_buf);
1718 msleep(1); /* RFC1001 layer in at least one server 1867 msleep(1); /* RFC1001 layer in at least one server
1719 requires very short break before negprot 1868 requires very short break before negprot
@@ -1733,79 +1882,81 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1733} 1882}
1734 1883
1735static int 1884static int
1736ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket, 1885ipv6_connect(struct TCP_Server_Info *server)
1737 bool noblocksnd)
1738{ 1886{
1739 int rc = 0; 1887 int rc = 0;
1740 int connected = 0; 1888 bool connected = false;
1741 __be16 orig_port = 0; 1889 __be16 orig_port = 0;
1890 struct socket *socket = server->ssocket;
1742 1891
1743 if (*csocket == NULL) { 1892 if (socket == NULL) {
1744 rc = sock_create_kern(PF_INET6, SOCK_STREAM, 1893 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1745 IPPROTO_TCP, csocket); 1894 IPPROTO_TCP, &socket);
1746 if (rc < 0) { 1895 if (rc < 0) {
1747 cERROR(1, ("Error %d creating ipv6 socket", rc)); 1896 cERROR(1, ("Error %d creating ipv6 socket", rc));
1748 *csocket = NULL; 1897 socket = NULL;
1749 return rc; 1898 return rc;
1750 } else {
1751 /* BB other socket options to set KEEPALIVE, NODELAY? */
1752 cFYI(1, ("ipv6 Socket created"));
1753 (*csocket)->sk->sk_allocation = GFP_NOFS;
1754 cifs_reclassify_socket6(*csocket);
1755 } 1899 }
1756 }
1757 1900
1758 psin_server->sin6_family = AF_INET6; 1901 /* BB other socket options to set KEEPALIVE, NODELAY? */
1902 cFYI(1, ("ipv6 Socket created"));
1903 server->ssocket = socket;
1904 socket->sk->sk_allocation = GFP_NOFS;
1905 cifs_reclassify_socket6(socket);
1906 }
1759 1907
1760 if (psin_server->sin6_port) { /* user overrode default port */ 1908 /* user overrode default port */
1761 rc = (*csocket)->ops->connect(*csocket, 1909 if (server->addr.sockAddr6.sin6_port) {
1762 (struct sockaddr *) psin_server, 1910 rc = socket->ops->connect(socket,
1911 (struct sockaddr *) &server->addr.sockAddr6,
1763 sizeof(struct sockaddr_in6), 0); 1912 sizeof(struct sockaddr_in6), 0);
1764 if (rc >= 0) 1913 if (rc >= 0)
1765 connected = 1; 1914 connected = true;
1766 } 1915 }
1767 1916
1768 if (!connected) { 1917 if (!connected) {
1769 /* save original port so we can retry user specified port 1918 /* save original port so we can retry user specified port
1770 later if fall back ports fail this time */ 1919 later if fall back ports fail this time */
1771 1920
1772 orig_port = psin_server->sin6_port; 1921 orig_port = server->addr.sockAddr6.sin6_port;
1773 /* do not retry on the same port we just failed on */ 1922 /* do not retry on the same port we just failed on */
1774 if (psin_server->sin6_port != htons(CIFS_PORT)) { 1923 if (server->addr.sockAddr6.sin6_port != htons(CIFS_PORT)) {
1775 psin_server->sin6_port = htons(CIFS_PORT); 1924 server->addr.sockAddr6.sin6_port = htons(CIFS_PORT);
1776 1925 rc = socket->ops->connect(socket, (struct sockaddr *)
1777 rc = (*csocket)->ops->connect(*csocket, 1926 &server->addr.sockAddr6,
1778 (struct sockaddr *) psin_server,
1779 sizeof(struct sockaddr_in6), 0); 1927 sizeof(struct sockaddr_in6), 0);
1780 if (rc >= 0) 1928 if (rc >= 0)
1781 connected = 1; 1929 connected = true;
1782 } 1930 }
1783 } 1931 }
1784 if (!connected) { 1932 if (!connected) {
1785 psin_server->sin6_port = htons(RFC1001_PORT); 1933 server->addr.sockAddr6.sin6_port = htons(RFC1001_PORT);
1786 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) 1934 rc = socket->ops->connect(socket, (struct sockaddr *)
1787 psin_server, sizeof(struct sockaddr_in6), 0); 1935 &server->addr.sockAddr6,
1936 sizeof(struct sockaddr_in6), 0);
1788 if (rc >= 0) 1937 if (rc >= 0)
1789 connected = 1; 1938 connected = true;
1790 } 1939 }
1791 1940
1792 /* give up here - unless we want to retry on different 1941 /* give up here - unless we want to retry on different
1793 protocol families some day */ 1942 protocol families some day */
1794 if (!connected) { 1943 if (!connected) {
1795 if (orig_port) 1944 if (orig_port)
1796 psin_server->sin6_port = orig_port; 1945 server->addr.sockAddr6.sin6_port = orig_port;
1797 cFYI(1, ("Error %d connecting to server via ipv6", rc)); 1946 cFYI(1, ("Error %d connecting to server via ipv6", rc));
1798 sock_release(*csocket); 1947 sock_release(socket);
1799 *csocket = NULL; 1948 server->ssocket = NULL;
1800 return rc; 1949 return rc;
1801 } 1950 }
1802 /* Eventually check for other socket options to change from
1803 the default. sock_setsockopt not used because it expects
1804 user space buffer */
1805 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1806 if (!noblocksnd)
1807 (*csocket)->sk->sk_sndtimeo = 3 * HZ;
1808 1951
1952 /*
1953 * Eventually check for other socket options to change from
1954 * the default. sock_setsockopt not used because it expects
1955 * user space buffer
1956 */
1957 socket->sk->sk_rcvtimeo = 7 * HZ;
1958 socket->sk->sk_sndtimeo = 3 * HZ;
1959 server->ssocket = socket;
1809 1960
1810 return rc; 1961 return rc;
1811} 1962}
@@ -2011,6 +2162,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
2011 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; 2162 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2012 if (pvolume_info->nobrl) 2163 if (pvolume_info->nobrl)
2013 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; 2164 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2165 if (pvolume_info->mand_lock)
2166 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
2014 if (pvolume_info->cifs_acl) 2167 if (pvolume_info->cifs_acl)
2015 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; 2168 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2016 if (pvolume_info->override_uid) 2169 if (pvolume_info->override_uid)
@@ -2035,32 +2188,30 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2035{ 2188{
2036 int rc = 0; 2189 int rc = 0;
2037 int xid; 2190 int xid;
2038 struct socket *csocket = NULL; 2191 struct smb_vol *volume_info;
2039 struct sockaddr addr;
2040 struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
2041 struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
2042 struct smb_vol volume_info;
2043 struct cifsSesInfo *pSesInfo = NULL; 2192 struct cifsSesInfo *pSesInfo = NULL;
2044 struct cifsTconInfo *tcon = NULL; 2193 struct cifsTconInfo *tcon = NULL;
2045 struct TCP_Server_Info *srvTcp = NULL; 2194 struct TCP_Server_Info *srvTcp = NULL;
2046 2195
2047 xid = GetXid(); 2196 xid = GetXid();
2048 2197
2049/* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */ 2198 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
2199 if (!volume_info) {
2200 rc = -ENOMEM;
2201 goto out;
2202 }
2050 2203
2051 memset(&addr, 0, sizeof(struct sockaddr)); 2204 if (cifs_parse_mount_options(mount_data, devname, volume_info)) {
2052 memset(&volume_info, 0, sizeof(struct smb_vol));
2053 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
2054 rc = -EINVAL; 2205 rc = -EINVAL;
2055 goto out; 2206 goto out;
2056 } 2207 }
2057 2208
2058 if (volume_info.nullauth) { 2209 if (volume_info->nullauth) {
2059 cFYI(1, ("null user")); 2210 cFYI(1, ("null user"));
2060 volume_info.username = ""; 2211 volume_info->username = "";
2061 } else if (volume_info.username) { 2212 } else if (volume_info->username) {
2062 /* BB fixme parse for domain name here */ 2213 /* BB fixme parse for domain name here */
2063 cFYI(1, ("Username: %s", volume_info.username)); 2214 cFYI(1, ("Username: %s", volume_info->username));
2064 } else { 2215 } else {
2065 cifserror("No username specified"); 2216 cifserror("No username specified");
2066 /* In userspace mount helper we can get user name from alternate 2217 /* In userspace mount helper we can get user name from alternate
@@ -2069,139 +2220,29 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2069 goto out; 2220 goto out;
2070 } 2221 }
2071 2222
2072 if (volume_info.UNCip && volume_info.UNC) {
2073 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
2074 &sin_server->sin_addr.s_addr);
2075
2076 if (rc <= 0) {
2077 /* not ipv4 address, try ipv6 */
2078 rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
2079 &sin_server6->sin6_addr.in6_u);
2080 if (rc > 0)
2081 addr.sa_family = AF_INET6;
2082 } else {
2083 addr.sa_family = AF_INET;
2084 }
2085
2086 if (rc <= 0) {
2087 /* we failed translating address */
2088 rc = -EINVAL;
2089 goto out;
2090 }
2091
2092 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
2093 /* success */
2094 rc = 0;
2095 } else if (volume_info.UNCip) {
2096 /* BB using ip addr as server name to connect to the
2097 DFS root below */
2098 cERROR(1, ("Connecting to DFS root not implemented yet"));
2099 rc = -EINVAL;
2100 goto out;
2101 } else /* which servers DFS root would we conect to */ {
2102 cERROR(1,
2103 ("CIFS mount error: No UNC path (e.g. -o "
2104 "unc=//192.168.1.100/public) specified"));
2105 rc = -EINVAL;
2106 goto out;
2107 }
2108 2223
2109 /* this is needed for ASCII cp to Unicode converts */ 2224 /* this is needed for ASCII cp to Unicode converts */
2110 if (volume_info.iocharset == NULL) { 2225 if (volume_info->iocharset == NULL) {
2111 cifs_sb->local_nls = load_nls_default(); 2226 cifs_sb->local_nls = load_nls_default();
2112 /* load_nls_default can not return null */ 2227 /* load_nls_default can not return null */
2113 } else { 2228 } else {
2114 cifs_sb->local_nls = load_nls(volume_info.iocharset); 2229 cifs_sb->local_nls = load_nls(volume_info->iocharset);
2115 if (cifs_sb->local_nls == NULL) { 2230 if (cifs_sb->local_nls == NULL) {
2116 cERROR(1, ("CIFS mount error: iocharset %s not found", 2231 cERROR(1, ("CIFS mount error: iocharset %s not found",
2117 volume_info.iocharset)); 2232 volume_info->iocharset));
2118 rc = -ELIBACC; 2233 rc = -ELIBACC;
2119 goto out; 2234 goto out;
2120 } 2235 }
2121 } 2236 }
2122 2237
2123 srvTcp = cifs_find_tcp_session(&addr); 2238 /* get a reference to a tcp session */
2124 if (!srvTcp) { /* create socket */ 2239 srvTcp = cifs_get_tcp_session(volume_info);
2125 if (addr.sa_family == AF_INET6) { 2240 if (IS_ERR(srvTcp)) {
2126 cFYI(1, ("attempting ipv6 connect")); 2241 rc = PTR_ERR(srvTcp);
2127 /* BB should we allow ipv6 on port 139? */ 2242 goto out;
2128 /* other OS never observed in Wild doing 139 with v6 */
2129 sin_server6->sin6_port = htons(volume_info.port);
2130 rc = ipv6_connect(sin_server6, &csocket,
2131 volume_info.noblocksnd);
2132 } else {
2133 sin_server->sin_port = htons(volume_info.port);
2134 rc = ipv4_connect(sin_server, &csocket,
2135 volume_info.source_rfc1001_name,
2136 volume_info.target_rfc1001_name,
2137 volume_info.noblocksnd,
2138 volume_info.noautotune);
2139 }
2140 if (rc < 0) {
2141 cERROR(1, ("Error connecting to socket. "
2142 "Aborting operation"));
2143 if (csocket != NULL)
2144 sock_release(csocket);
2145 goto out;
2146 }
2147
2148 srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
2149 if (!srvTcp) {
2150 rc = -ENOMEM;
2151 sock_release(csocket);
2152 goto out;
2153 } else {
2154 srvTcp->noblocksnd = volume_info.noblocksnd;
2155 srvTcp->noautotune = volume_info.noautotune;
2156 if (addr.sa_family == AF_INET6)
2157 memcpy(&srvTcp->addr.sockAddr6, sin_server6,
2158 sizeof(struct sockaddr_in6));
2159 else
2160 memcpy(&srvTcp->addr.sockAddr, sin_server,
2161 sizeof(struct sockaddr_in));
2162 atomic_set(&srvTcp->inFlight, 0);
2163 /* BB Add code for ipv6 case too */
2164 srvTcp->ssocket = csocket;
2165 srvTcp->hostname = extract_hostname(volume_info.UNC);
2166 if (IS_ERR(srvTcp->hostname)) {
2167 rc = PTR_ERR(srvTcp->hostname);
2168 sock_release(csocket);
2169 goto out;
2170 }
2171 init_waitqueue_head(&srvTcp->response_q);
2172 init_waitqueue_head(&srvTcp->request_q);
2173 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
2174 /* at this point we are the only ones with the pointer
2175 to the struct since the kernel thread not created yet
2176 so no need to spinlock this init of tcpStatus */
2177 srvTcp->tcpStatus = CifsNew;
2178 init_MUTEX(&srvTcp->tcpSem);
2179 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
2180 if (IS_ERR(srvTcp->tsk)) {
2181 rc = PTR_ERR(srvTcp->tsk);
2182 cERROR(1, ("error %d create cifsd thread", rc));
2183 srvTcp->tsk = NULL;
2184 sock_release(csocket);
2185 kfree(srvTcp->hostname);
2186 goto out;
2187 }
2188 rc = 0;
2189 memcpy(srvTcp->workstation_RFC1001_name,
2190 volume_info.source_rfc1001_name, 16);
2191 memcpy(srvTcp->server_RFC1001_name,
2192 volume_info.target_rfc1001_name, 16);
2193 srvTcp->sequence_number = 0;
2194 INIT_LIST_HEAD(&srvTcp->tcp_ses_list);
2195 INIT_LIST_HEAD(&srvTcp->smb_ses_list);
2196 ++srvTcp->srv_count;
2197 write_lock(&cifs_tcp_ses_lock);
2198 list_add(&srvTcp->tcp_ses_list,
2199 &cifs_tcp_ses_list);
2200 write_unlock(&cifs_tcp_ses_lock);
2201 }
2202 } 2243 }
2203 2244
2204 pSesInfo = cifs_find_smb_ses(srvTcp, volume_info.username); 2245 pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username);
2205 if (pSesInfo) { 2246 if (pSesInfo) {
2206 cFYI(1, ("Existing smb sess found (status=%d)", 2247 cFYI(1, ("Existing smb sess found (status=%d)",
2207 pSesInfo->status)); 2248 pSesInfo->status));
@@ -2228,31 +2269,38 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2228 2269
2229 /* new SMB session uses our srvTcp ref */ 2270 /* new SMB session uses our srvTcp ref */
2230 pSesInfo->server = srvTcp; 2271 pSesInfo->server = srvTcp;
2231 sprintf(pSesInfo->serverName, "%u.%u.%u.%u", 2272 if (srvTcp->addr.sockAddr6.sin6_family == AF_INET6)
2232 NIPQUAD(sin_server->sin_addr.s_addr)); 2273 sprintf(pSesInfo->serverName, NIP6_FMT,
2274 NIP6(srvTcp->addr.sockAddr6.sin6_addr));
2275 else
2276 sprintf(pSesInfo->serverName, NIPQUAD_FMT,
2277 NIPQUAD(srvTcp->addr.sockAddr.sin_addr.s_addr));
2233 2278
2234 write_lock(&cifs_tcp_ses_lock); 2279 write_lock(&cifs_tcp_ses_lock);
2235 list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list); 2280 list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list);
2236 write_unlock(&cifs_tcp_ses_lock); 2281 write_unlock(&cifs_tcp_ses_lock);
2237 2282
2238 /* volume_info.password freed at unmount */ 2283 /* volume_info->password freed at unmount */
2239 if (volume_info.password) { 2284 if (volume_info->password) {
2240 pSesInfo->password = volume_info.password; 2285 pSesInfo->password = kstrdup(volume_info->password,
2241 /* set to NULL to prevent freeing on exit */ 2286 GFP_KERNEL);
2242 volume_info.password = NULL; 2287 if (!pSesInfo->password) {
2288 rc = -ENOMEM;
2289 goto mount_fail_check;
2290 }
2243 } 2291 }
2244 if (volume_info.username) 2292 if (volume_info->username)
2245 strncpy(pSesInfo->userName, volume_info.username, 2293 strncpy(pSesInfo->userName, volume_info->username,
2246 MAX_USERNAME_SIZE); 2294 MAX_USERNAME_SIZE);
2247 if (volume_info.domainname) { 2295 if (volume_info->domainname) {
2248 int len = strlen(volume_info.domainname); 2296 int len = strlen(volume_info->domainname);
2249 pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL); 2297 pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL);
2250 if (pSesInfo->domainName) 2298 if (pSesInfo->domainName)
2251 strcpy(pSesInfo->domainName, 2299 strcpy(pSesInfo->domainName,
2252 volume_info.domainname); 2300 volume_info->domainname);
2253 } 2301 }
2254 pSesInfo->linux_uid = volume_info.linux_uid; 2302 pSesInfo->linux_uid = volume_info->linux_uid;
2255 pSesInfo->overrideSecFlg = volume_info.secFlg; 2303 pSesInfo->overrideSecFlg = volume_info->secFlg;
2256 down(&pSesInfo->sesSem); 2304 down(&pSesInfo->sesSem);
2257 2305
2258 /* BB FIXME need to pass vol->secFlgs BB */ 2306 /* BB FIXME need to pass vol->secFlgs BB */
@@ -2263,14 +2311,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2263 2311
2264 /* search for existing tcon to this server share */ 2312 /* search for existing tcon to this server share */
2265 if (!rc) { 2313 if (!rc) {
2266 setup_cifs_sb(&volume_info, cifs_sb); 2314 setup_cifs_sb(volume_info, cifs_sb);
2267 2315
2268 tcon = cifs_find_tcon(pSesInfo, volume_info.UNC); 2316 tcon = cifs_find_tcon(pSesInfo, volume_info->UNC);
2269 if (tcon) { 2317 if (tcon) {
2270 cFYI(1, ("Found match on UNC path")); 2318 cFYI(1, ("Found match on UNC path"));
2271 /* existing tcon already has a reference */ 2319 /* existing tcon already has a reference */
2272 cifs_put_smb_ses(pSesInfo); 2320 cifs_put_smb_ses(pSesInfo);
2273 if (tcon->seal != volume_info.seal) 2321 if (tcon->seal != volume_info->seal)
2274 cERROR(1, ("transport encryption setting " 2322 cERROR(1, ("transport encryption setting "
2275 "conflicts with existing tid")); 2323 "conflicts with existing tid"));
2276 } else { 2324 } else {
@@ -2279,11 +2327,20 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2279 rc = -ENOMEM; 2327 rc = -ENOMEM;
2280 goto mount_fail_check; 2328 goto mount_fail_check;
2281 } 2329 }
2330
2282 tcon->ses = pSesInfo; 2331 tcon->ses = pSesInfo;
2332 if (volume_info->password) {
2333 tcon->password = kstrdup(volume_info->password,
2334 GFP_KERNEL);
2335 if (!tcon->password) {
2336 rc = -ENOMEM;
2337 goto mount_fail_check;
2338 }
2339 }
2283 2340
2284 /* check for null share name ie connect to dfs root */ 2341 /* check for null share name ie connect to dfs root */
2285 if ((strchr(volume_info.UNC + 3, '\\') == NULL) 2342 if ((strchr(volume_info->UNC + 3, '\\') == NULL)
2286 && (strchr(volume_info.UNC + 3, '/') == NULL)) { 2343 && (strchr(volume_info->UNC + 3, '/') == NULL)) {
2287 /* rc = connect_to_dfs_path(...) */ 2344 /* rc = connect_to_dfs_path(...) */
2288 cFYI(1, ("DFS root not supported")); 2345 cFYI(1, ("DFS root not supported"));
2289 rc = -ENODEV; 2346 rc = -ENODEV;
@@ -2292,10 +2349,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2292 /* BB Do we need to wrap sesSem around 2349 /* BB Do we need to wrap sesSem around
2293 * this TCon call and Unix SetFS as 2350 * this TCon call and Unix SetFS as
2294 * we do on SessSetup and reconnect? */ 2351 * we do on SessSetup and reconnect? */
2295 rc = CIFSTCon(xid, pSesInfo, volume_info.UNC, 2352 rc = CIFSTCon(xid, pSesInfo, volume_info->UNC,
2296 tcon, cifs_sb->local_nls); 2353 tcon, cifs_sb->local_nls);
2297 cFYI(1, ("CIFS Tcon rc = %d", rc)); 2354 cFYI(1, ("CIFS Tcon rc = %d", rc));
2298 if (volume_info.nodfs) { 2355 if (volume_info->nodfs) {
2299 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS; 2356 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
2300 cFYI(1, ("DFS disabled (%d)", 2357 cFYI(1, ("DFS disabled (%d)",
2301 tcon->Flags)); 2358 tcon->Flags));
@@ -2303,7 +2360,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2303 } 2360 }
2304 if (rc) 2361 if (rc)
2305 goto mount_fail_check; 2362 goto mount_fail_check;
2306 tcon->seal = volume_info.seal; 2363 tcon->seal = volume_info->seal;
2307 write_lock(&cifs_tcp_ses_lock); 2364 write_lock(&cifs_tcp_ses_lock);
2308 list_add(&tcon->tcon_list, &pSesInfo->tcon_list); 2365 list_add(&tcon->tcon_list, &pSesInfo->tcon_list);
2309 write_unlock(&cifs_tcp_ses_lock); 2366 write_unlock(&cifs_tcp_ses_lock);
@@ -2313,9 +2370,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2313 to a share so for resources mounted more than once 2370 to a share so for resources mounted more than once
2314 to the same server share the last value passed in 2371 to the same server share the last value passed in
2315 for the retry flag is used */ 2372 for the retry flag is used */
2316 tcon->retry = volume_info.retry; 2373 tcon->retry = volume_info->retry;
2317 tcon->nocase = volume_info.nocase; 2374 tcon->nocase = volume_info->nocase;
2318 tcon->local_lease = volume_info.local_lease; 2375 tcon->local_lease = volume_info->local_lease;
2319 } 2376 }
2320 if (pSesInfo) { 2377 if (pSesInfo) {
2321 if (pSesInfo->capabilities & CAP_LARGE_FILES) { 2378 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
@@ -2352,7 +2409,7 @@ mount_fail_check:
2352 if (tcon->ses->capabilities & CAP_UNIX) 2409 if (tcon->ses->capabilities & CAP_UNIX)
2353 /* reset of caps checks mount to see if unix extensions 2410 /* reset of caps checks mount to see if unix extensions
2354 disabled for just this mount */ 2411 disabled for just this mount */
2355 reset_cifs_unix_caps(xid, tcon, sb, &volume_info); 2412 reset_cifs_unix_caps(xid, tcon, sb, volume_info);
2356 else 2413 else
2357 tcon->unix_ext = 0; /* server does not support them */ 2414 tcon->unix_ext = 0; /* server does not support them */
2358 2415
@@ -2371,18 +2428,22 @@ mount_fail_check:
2371 cifs_sb->rsize = min(cifs_sb->rsize, 2428 cifs_sb->rsize = min(cifs_sb->rsize,
2372 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); 2429 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2373 2430
2374 /* volume_info.password is freed above when existing session found 2431 /* volume_info->password is freed above when existing session found
2375 (in which case it is not needed anymore) but when new sesion is created 2432 (in which case it is not needed anymore) but when new sesion is created
2376 the password ptr is put in the new session structure (in which case the 2433 the password ptr is put in the new session structure (in which case the
2377 password will be freed at unmount time) */ 2434 password will be freed at unmount time) */
2378out: 2435out:
2379 /* zero out password before freeing */ 2436 /* zero out password before freeing */
2380 if (volume_info.password != NULL) { 2437 if (volume_info) {
2381 memset(volume_info.password, 0, strlen(volume_info.password)); 2438 if (volume_info->password != NULL) {
2382 kfree(volume_info.password); 2439 memset(volume_info->password, 0,
2440 strlen(volume_info->password));
2441 kfree(volume_info->password);
2442 }
2443 kfree(volume_info->UNC);
2444 kfree(volume_info->prepath);
2445 kfree(volume_info);
2383 } 2446 }
2384 kfree(volume_info.UNC);
2385 kfree(volume_info.prepath);
2386 FreeXid(xid); 2447 FreeXid(xid);
2387 return rc; 2448 return rc;
2388} 2449}
@@ -2533,7 +2594,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2533 __u16 action = le16_to_cpu(pSMBr->resp.Action); 2594 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2534 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); 2595 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2535 if (action & GUEST_LOGIN) 2596 if (action & GUEST_LOGIN)
2536 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */ 2597 cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
2537 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format 2598 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2538 (little endian) */ 2599 (little endian) */
2539 cFYI(1, ("UID = %d ", ses->Suid)); 2600 cFYI(1, ("UID = %d ", ses->Suid));
@@ -2679,13 +2740,11 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2679 len)); 2740 len));
2680 } 2741 }
2681 } else { 2742 } else {
2682 cERROR(1, 2743 cERROR(1, ("Security Blob Length extends beyond "
2683 (" Security Blob Length extends beyond "
2684 "end of SMB")); 2744 "end of SMB"));
2685 } 2745 }
2686 } else { 2746 } else {
2687 cERROR(1, 2747 cERROR(1, ("Invalid Word count %d: ",
2688 (" Invalid Word count %d: ",
2689 smb_buffer_response->WordCount)); 2748 smb_buffer_response->WordCount));
2690 rc = -EIO; 2749 rc = -EIO;
2691 } 2750 }
@@ -2843,7 +2902,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2843 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); 2902 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2844 2903
2845 if (action & GUEST_LOGIN) 2904 if (action & GUEST_LOGIN)
2846 cFYI(1, (" Guest login")); 2905 cFYI(1, ("Guest login"));
2847 /* Do we want to set anything in SesInfo struct when guest login? */ 2906 /* Do we want to set anything in SesInfo struct when guest login? */
2848 2907
2849 bcc_ptr = pByteArea(smb_buffer_response); 2908 bcc_ptr = pByteArea(smb_buffer_response);
@@ -2851,8 +2910,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2851 2910
2852 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr; 2911 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2853 if (SecurityBlob2->MessageType != NtLmChallenge) { 2912 if (SecurityBlob2->MessageType != NtLmChallenge) {
2854 cFYI(1, 2913 cFYI(1, ("Unexpected NTLMSSP message type received %d",
2855 ("Unexpected NTLMSSP message type received %d",
2856 SecurityBlob2->MessageType)); 2914 SecurityBlob2->MessageType));
2857 } else if (ses) { 2915 } else if (ses) {
2858 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */ 2916 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
@@ -3024,8 +3082,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
3024 cERROR(1, ("No session structure passed in.")); 3082 cERROR(1, ("No session structure passed in."));
3025 } 3083 }
3026 } else { 3084 } else {
3027 cERROR(1, 3085 cERROR(1, ("Invalid Word count %d:",
3028 (" Invalid Word count %d:",
3029 smb_buffer_response->WordCount)); 3086 smb_buffer_response->WordCount));
3030 rc = -EIO; 3087 rc = -EIO;
3031 } 3088 }
@@ -3264,7 +3321,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3264 __u16 action = le16_to_cpu(pSMBr->resp.Action); 3321 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3265 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); 3322 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3266 if (action & GUEST_LOGIN) 3323 if (action & GUEST_LOGIN)
3267 cFYI(1, (" Guest login")); /* BB Should we set anything 3324 cFYI(1, ("Guest login")); /* BB Should we set anything
3268 in SesInfo struct ? */ 3325 in SesInfo struct ? */
3269/* if (SecurityBlob2->MessageType != NtLm??) { 3326/* if (SecurityBlob2->MessageType != NtLm??) {
3270 cFYI("Unexpected message type on auth response is %d")); 3327 cFYI("Unexpected message type on auth response is %d"));
@@ -3487,12 +3544,14 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3487 NTLMv2 password here) */ 3544 NTLMv2 password here) */
3488#ifdef CONFIG_CIFS_WEAK_PW_HASH 3545#ifdef CONFIG_CIFS_WEAK_PW_HASH
3489 if ((extended_security & CIFSSEC_MAY_LANMAN) && 3546 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3490 (ses->server->secType == LANMAN)) 3547 (ses->server->secType == LANMAN))
3491 calc_lanman_hash(ses, bcc_ptr); 3548 calc_lanman_hash(tcon->password, ses->server->cryptKey,
3549 ses->server->secMode &
3550 SECMODE_PW_ENCRYPT ? true : false,
3551 bcc_ptr);
3492 else 3552 else
3493#endif /* CIFS_WEAK_PW_HASH */ 3553#endif /* CIFS_WEAK_PW_HASH */
3494 SMBNTencrypt(ses->password, 3554 SMBNTencrypt(tcon->password, ses->server->cryptKey,
3495 ses->server->cryptKey,
3496 bcc_ptr); 3555 bcc_ptr);
3497 3556
3498 bcc_ptr += CIFS_SESS_KEY_SIZE; 3557 bcc_ptr += CIFS_SESS_KEY_SIZE;