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.c141
1 files changed, 75 insertions, 66 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index c52a76ff4bb9..fd9147cdb5a9 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -438,9 +438,9 @@ incomplete_rcv:
438 csocket = server->ssocket; 438 csocket = server->ssocket;
439 wake_up(&server->response_q); 439 wake_up(&server->response_q);
440 continue; 440 continue;
441 } else if (length < 4) { 441 } else if (length < pdu_length) {
442 cFYI(1, ("less than four bytes received (%d bytes)", 442 cFYI(1, ("requested %d bytes but only got %d bytes",
443 length)); 443 pdu_length, length));
444 pdu_length -= length; 444 pdu_length -= length;
445 msleep(1); 445 msleep(1);
446 goto incomplete_rcv; 446 goto incomplete_rcv;
@@ -752,6 +752,7 @@ multi_t2_fnd:
752 } 752 }
753 write_unlock(&GlobalSMBSeslock); 753 write_unlock(&GlobalSMBSeslock);
754 754
755 kfree(server->hostname);
755 kfree(server); 756 kfree(server);
756 if (length > 0) 757 if (length > 0)
757 mempool_resize(cifs_req_poolp, length + cifs_min_rcv, 758 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
@@ -760,6 +761,34 @@ multi_t2_fnd:
760 return 0; 761 return 0;
761} 762}
762 763
764/* extract the host portion of the UNC string */
765static char *
766extract_hostname(const char *unc)
767{
768 const char *src;
769 char *dst, *delim;
770 unsigned int len;
771
772 /* skip double chars at beginning of string */
773 /* BB: check validity of these bytes? */
774 src = unc + 2;
775
776 /* delimiter between hostname and sharename is always '\\' now */
777 delim = strchr(src, '\\');
778 if (!delim)
779 return ERR_PTR(-EINVAL);
780
781 len = delim - src;
782 dst = kmalloc((len + 1), GFP_KERNEL);
783 if (dst == NULL)
784 return ERR_PTR(-ENOMEM);
785
786 memcpy(dst, src, len);
787 dst[len] = '\0';
788
789 return dst;
790}
791
763static int 792static int
764cifs_parse_mount_options(char *options, const char *devname, 793cifs_parse_mount_options(char *options, const char *devname,
765 struct smb_vol *vol) 794 struct smb_vol *vol)
@@ -1781,11 +1810,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1781 1810
1782 memset(&volume_info, 0, sizeof(struct smb_vol)); 1811 memset(&volume_info, 0, sizeof(struct smb_vol));
1783 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) { 1812 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1784 kfree(volume_info.UNC); 1813 rc = -EINVAL;
1785 kfree(volume_info.password); 1814 goto out;
1786 kfree(volume_info.prepath);
1787 FreeXid(xid);
1788 return -EINVAL;
1789 } 1815 }
1790 1816
1791 if (volume_info.nullauth) { 1817 if (volume_info.nullauth) {
@@ -1798,11 +1824,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1798 cifserror("No username specified"); 1824 cifserror("No username specified");
1799 /* In userspace mount helper we can get user name from alternate 1825 /* In userspace mount helper we can get user name from alternate
1800 locations such as env variables and files on disk */ 1826 locations such as env variables and files on disk */
1801 kfree(volume_info.UNC); 1827 rc = -EINVAL;
1802 kfree(volume_info.password); 1828 goto out;
1803 kfree(volume_info.prepath);
1804 FreeXid(xid);
1805 return -EINVAL;
1806 } 1829 }
1807 1830
1808 if (volume_info.UNCip && volume_info.UNC) { 1831 if (volume_info.UNCip && volume_info.UNC) {
@@ -1821,11 +1844,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1821 1844
1822 if (rc <= 0) { 1845 if (rc <= 0) {
1823 /* we failed translating address */ 1846 /* we failed translating address */
1824 kfree(volume_info.UNC); 1847 rc = -EINVAL;
1825 kfree(volume_info.password); 1848 goto out;
1826 kfree(volume_info.prepath);
1827 FreeXid(xid);
1828 return -EINVAL;
1829 } 1849 }
1830 1850
1831 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip)); 1851 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
@@ -1835,20 +1855,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1835 /* BB using ip addr as server name to connect to the 1855 /* BB using ip addr as server name to connect to the
1836 DFS root below */ 1856 DFS root below */
1837 cERROR(1, ("Connecting to DFS root not implemented yet")); 1857 cERROR(1, ("Connecting to DFS root not implemented yet"));
1838 kfree(volume_info.UNC); 1858 rc = -EINVAL;
1839 kfree(volume_info.password); 1859 goto out;
1840 kfree(volume_info.prepath);
1841 FreeXid(xid);
1842 return -EINVAL;
1843 } else /* which servers DFS root would we conect to */ { 1860 } else /* which servers DFS root would we conect to */ {
1844 cERROR(1, 1861 cERROR(1,
1845 ("CIFS mount error: No UNC path (e.g. -o " 1862 ("CIFS mount error: No UNC path (e.g. -o "
1846 "unc=//192.168.1.100/public) specified")); 1863 "unc=//192.168.1.100/public) specified"));
1847 kfree(volume_info.UNC); 1864 rc = -EINVAL;
1848 kfree(volume_info.password); 1865 goto out;
1849 kfree(volume_info.prepath);
1850 FreeXid(xid);
1851 return -EINVAL;
1852 } 1866 }
1853 1867
1854 /* this is needed for ASCII cp to Unicode converts */ 1868 /* this is needed for ASCII cp to Unicode converts */
@@ -1860,11 +1874,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1860 if (cifs_sb->local_nls == NULL) { 1874 if (cifs_sb->local_nls == NULL) {
1861 cERROR(1, ("CIFS mount error: iocharset %s not found", 1875 cERROR(1, ("CIFS mount error: iocharset %s not found",
1862 volume_info.iocharset)); 1876 volume_info.iocharset));
1863 kfree(volume_info.UNC); 1877 rc = -ELIBACC;
1864 kfree(volume_info.password); 1878 goto out;
1865 kfree(volume_info.prepath);
1866 FreeXid(xid);
1867 return -ELIBACC;
1868 } 1879 }
1869 } 1880 }
1870 1881
@@ -1878,11 +1889,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1878 &sin_server6.sin6_addr, 1889 &sin_server6.sin6_addr,
1879 volume_info.username, &srvTcp); 1890 volume_info.username, &srvTcp);
1880 } else { 1891 } else {
1881 kfree(volume_info.UNC); 1892 rc = -EINVAL;
1882 kfree(volume_info.password); 1893 goto out;
1883 kfree(volume_info.prepath);
1884 FreeXid(xid);
1885 return -EINVAL;
1886 } 1894 }
1887 1895
1888 if (srvTcp) { 1896 if (srvTcp) {
@@ -1906,22 +1914,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1906 "Aborting operation")); 1914 "Aborting operation"));
1907 if (csocket != NULL) 1915 if (csocket != NULL)
1908 sock_release(csocket); 1916 sock_release(csocket);
1909 kfree(volume_info.UNC); 1917 goto out;
1910 kfree(volume_info.password);
1911 kfree(volume_info.prepath);
1912 FreeXid(xid);
1913 return rc;
1914 } 1918 }
1915 1919
1916 srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL); 1920 srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
1917 if (!srvTcp) { 1921 if (!srvTcp) {
1918 rc = -ENOMEM; 1922 rc = -ENOMEM;
1919 sock_release(csocket); 1923 sock_release(csocket);
1920 kfree(volume_info.UNC); 1924 goto out;
1921 kfree(volume_info.password);
1922 kfree(volume_info.prepath);
1923 FreeXid(xid);
1924 return rc;
1925 } else { 1925 } else {
1926 memcpy(&srvTcp->addr.sockAddr, &sin_server, 1926 memcpy(&srvTcp->addr.sockAddr, &sin_server,
1927 sizeof(struct sockaddr_in)); 1927 sizeof(struct sockaddr_in));
@@ -1929,6 +1929,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1929 /* BB Add code for ipv6 case too */ 1929 /* BB Add code for ipv6 case too */
1930 srvTcp->ssocket = csocket; 1930 srvTcp->ssocket = csocket;
1931 srvTcp->protocolType = IPV4; 1931 srvTcp->protocolType = IPV4;
1932 srvTcp->hostname = extract_hostname(volume_info.UNC);
1933 if (IS_ERR(srvTcp->hostname)) {
1934 rc = PTR_ERR(srvTcp->hostname);
1935 sock_release(csocket);
1936 goto out;
1937 }
1932 init_waitqueue_head(&srvTcp->response_q); 1938 init_waitqueue_head(&srvTcp->response_q);
1933 init_waitqueue_head(&srvTcp->request_q); 1939 init_waitqueue_head(&srvTcp->request_q);
1934 INIT_LIST_HEAD(&srvTcp->pending_mid_q); 1940 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
@@ -1938,16 +1944,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1938 srvTcp->tcpStatus = CifsNew; 1944 srvTcp->tcpStatus = CifsNew;
1939 init_MUTEX(&srvTcp->tcpSem); 1945 init_MUTEX(&srvTcp->tcpSem);
1940 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd"); 1946 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
1941 if ( IS_ERR(srvTcp->tsk) ) { 1947 if (IS_ERR(srvTcp->tsk)) {
1942 rc = PTR_ERR(srvTcp->tsk); 1948 rc = PTR_ERR(srvTcp->tsk);
1943 cERROR(1, ("error %d create cifsd thread", rc)); 1949 cERROR(1, ("error %d create cifsd thread", rc));
1944 srvTcp->tsk = NULL; 1950 srvTcp->tsk = NULL;
1945 sock_release(csocket); 1951 sock_release(csocket);
1946 kfree(volume_info.UNC); 1952 kfree(srvTcp->hostname);
1947 kfree(volume_info.password); 1953 goto out;
1948 kfree(volume_info.prepath);
1949 FreeXid(xid);
1950 return rc;
1951 } 1954 }
1952 wait_for_completion(&cifsd_complete); 1955 wait_for_completion(&cifsd_complete);
1953 rc = 0; 1956 rc = 0;
@@ -1962,8 +1965,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1962 if (existingCifsSes) { 1965 if (existingCifsSes) {
1963 pSesInfo = existingCifsSes; 1966 pSesInfo = existingCifsSes;
1964 cFYI(1, ("Existing smb sess found")); 1967 cFYI(1, ("Existing smb sess found"));
1965 kfree(volume_info.password);
1966 /* volume_info.UNC freed at end of function */
1967 } else if (!rc) { 1968 } else if (!rc) {
1968 cFYI(1, ("Existing smb sess not found")); 1969 cFYI(1, ("Existing smb sess not found"));
1969 pSesInfo = sesInfoAlloc(); 1970 pSesInfo = sesInfoAlloc();
@@ -1977,8 +1978,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1977 1978
1978 if (!rc) { 1979 if (!rc) {
1979 /* volume_info.password freed at unmount */ 1980 /* volume_info.password freed at unmount */
1980 if (volume_info.password) 1981 if (volume_info.password) {
1981 pSesInfo->password = volume_info.password; 1982 pSesInfo->password = volume_info.password;
1983 /* set to NULL to prevent freeing on exit */
1984 volume_info.password = NULL;
1985 }
1982 if (volume_info.username) 1986 if (volume_info.username)
1983 strncpy(pSesInfo->userName, 1987 strncpy(pSesInfo->userName,
1984 volume_info.username, 1988 volume_info.username,
@@ -2000,8 +2004,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2000 up(&pSesInfo->sesSem); 2004 up(&pSesInfo->sesSem);
2001 if (!rc) 2005 if (!rc)
2002 atomic_inc(&srvTcp->socketUseCount); 2006 atomic_inc(&srvTcp->socketUseCount);
2003 } else 2007 }
2004 kfree(volume_info.password);
2005 } 2008 }
2006 2009
2007 /* search for existing tcon to this server share */ 2010 /* search for existing tcon to this server share */
@@ -2106,9 +2109,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2106 "", cifs_sb->local_nls, 2109 "", cifs_sb->local_nls,
2107 cifs_sb->mnt_cifs_flags & 2110 cifs_sb->mnt_cifs_flags &
2108 CIFS_MOUNT_MAP_SPECIAL_CHR); 2111 CIFS_MOUNT_MAP_SPECIAL_CHR);
2109 kfree(volume_info.UNC); 2112 rc = -ENODEV;
2110 FreeXid(xid); 2113 goto out;
2111 return -ENODEV;
2112 } else { 2114 } else {
2113 /* BB Do we need to wrap sesSem around 2115 /* BB Do we need to wrap sesSem around
2114 * this TCon call and Unix SetFS as 2116 * this TCon call and Unix SetFS as
@@ -2231,6 +2233,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2231 (in which case it is not needed anymore) but when new sesion is created 2233 (in which case it is not needed anymore) but when new sesion is created
2232 the password ptr is put in the new session structure (in which case the 2234 the password ptr is put in the new session structure (in which case the
2233 password will be freed at unmount time) */ 2235 password will be freed at unmount time) */
2236out:
2237 /* zero out password before freeing */
2238 if (volume_info.password != NULL) {
2239 memset(volume_info.password, 0, strlen(volume_info.password));
2240 kfree(volume_info.password);
2241 }
2234 kfree(volume_info.UNC); 2242 kfree(volume_info.UNC);
2235 kfree(volume_info.prepath); 2243 kfree(volume_info.prepath);
2236 FreeXid(xid); 2244 FreeXid(xid);
@@ -2374,7 +2382,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2374 pSMB->req_no_secext.ByteCount = cpu_to_le16(count); 2382 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2375 2383
2376 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, 2384 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2377 &bytes_returned, 1); 2385 &bytes_returned, CIFS_LONG_OP);
2378 if (rc) { 2386 if (rc) {
2379/* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */ 2387/* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2380 } else if ((smb_buffer_response->WordCount == 3) 2388 } else if ((smb_buffer_response->WordCount == 3)
@@ -2678,7 +2686,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2678 pSMB->req.ByteCount = cpu_to_le16(count); 2686 pSMB->req.ByteCount = cpu_to_le16(count);
2679 2687
2680 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, 2688 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2681 &bytes_returned, 1); 2689 &bytes_returned, CIFS_LONG_OP);
2682 2690
2683 if (smb_buffer_response->Status.CifsError == 2691 if (smb_buffer_response->Status.CifsError ==
2684 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED)) 2692 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
@@ -3105,7 +3113,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3105 pSMB->req.ByteCount = cpu_to_le16(count); 3113 pSMB->req.ByteCount = cpu_to_le16(count);
3106 3114
3107 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, 3115 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3108 &bytes_returned, 1); 3116 &bytes_returned, CIFS_LONG_OP);
3109 if (rc) { 3117 if (rc) {
3110/* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */ 3118/* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
3111 } else if ((smb_buffer_response->WordCount == 3) || 3119 } else if ((smb_buffer_response->WordCount == 3) ||
@@ -3381,7 +3389,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3381 pSMB->hdr.smb_buf_length += count; 3389 pSMB->hdr.smb_buf_length += count;
3382 pSMB->ByteCount = cpu_to_le16(count); 3390 pSMB->ByteCount = cpu_to_le16(count);
3383 3391
3384 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0); 3392 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3393 CIFS_STD_OP);
3385 3394
3386 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */ 3395 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3387 /* above now done in SendReceive */ 3396 /* above now done in SendReceive */