diff options
-rw-r--r-- | fs/cifs/connect.c | 90 |
1 files changed, 56 insertions, 34 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 1067473b5ed1..37b8ead2f60e 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -1642,6 +1642,25 @@ match_security(struct TCP_Server_Info *server, struct smb_vol *vol) | |||
1642 | return true; | 1642 | return true; |
1643 | } | 1643 | } |
1644 | 1644 | ||
1645 | static int match_server(struct TCP_Server_Info *server, struct sockaddr *addr, | ||
1646 | struct smb_vol *vol) | ||
1647 | { | ||
1648 | if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns)) | ||
1649 | return 0; | ||
1650 | |||
1651 | if (!match_address(server, addr, | ||
1652 | (struct sockaddr *)&vol->srcaddr)) | ||
1653 | return 0; | ||
1654 | |||
1655 | if (!match_port(server, addr)) | ||
1656 | return 0; | ||
1657 | |||
1658 | if (!match_security(server, vol)) | ||
1659 | return 0; | ||
1660 | |||
1661 | return 1; | ||
1662 | } | ||
1663 | |||
1645 | static struct TCP_Server_Info * | 1664 | static struct TCP_Server_Info * |
1646 | cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol) | 1665 | cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol) |
1647 | { | 1666 | { |
@@ -1649,17 +1668,7 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol) | |||
1649 | 1668 | ||
1650 | spin_lock(&cifs_tcp_ses_lock); | 1669 | spin_lock(&cifs_tcp_ses_lock); |
1651 | list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { | 1670 | list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { |
1652 | if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns)) | 1671 | if (!match_server(server, addr, vol)) |
1653 | continue; | ||
1654 | |||
1655 | if (!match_address(server, addr, | ||
1656 | (struct sockaddr *)&vol->srcaddr)) | ||
1657 | continue; | ||
1658 | |||
1659 | if (!match_port(server, addr)) | ||
1660 | continue; | ||
1661 | |||
1662 | if (!match_security(server, vol)) | ||
1663 | continue; | 1672 | continue; |
1664 | 1673 | ||
1665 | ++server->srv_count; | 1674 | ++server->srv_count; |
@@ -1853,6 +1862,30 @@ out_err: | |||
1853 | return ERR_PTR(rc); | 1862 | return ERR_PTR(rc); |
1854 | } | 1863 | } |
1855 | 1864 | ||
1865 | static int match_session(struct cifsSesInfo *ses, struct smb_vol *vol) | ||
1866 | { | ||
1867 | switch (ses->server->secType) { | ||
1868 | case Kerberos: | ||
1869 | if (vol->cred_uid != ses->cred_uid) | ||
1870 | return 0; | ||
1871 | break; | ||
1872 | default: | ||
1873 | /* anything else takes username/password */ | ||
1874 | if (ses->user_name == NULL) | ||
1875 | return 0; | ||
1876 | if (strncmp(ses->user_name, vol->username, | ||
1877 | MAX_USERNAME_SIZE)) | ||
1878 | return 0; | ||
1879 | if (strlen(vol->username) != 0 && | ||
1880 | ses->password != NULL && | ||
1881 | strncmp(ses->password, | ||
1882 | vol->password ? vol->password : "", | ||
1883 | MAX_PASSWORD_SIZE)) | ||
1884 | return 0; | ||
1885 | } | ||
1886 | return 1; | ||
1887 | } | ||
1888 | |||
1856 | static struct cifsSesInfo * | 1889 | static struct cifsSesInfo * |
1857 | cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) | 1890 | cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) |
1858 | { | 1891 | { |
@@ -1860,25 +1893,8 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) | |||
1860 | 1893 | ||
1861 | spin_lock(&cifs_tcp_ses_lock); | 1894 | spin_lock(&cifs_tcp_ses_lock); |
1862 | list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { | 1895 | list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { |
1863 | switch (server->secType) { | 1896 | if (!match_session(ses, vol)) |
1864 | case Kerberos: | 1897 | continue; |
1865 | if (vol->cred_uid != ses->cred_uid) | ||
1866 | continue; | ||
1867 | break; | ||
1868 | default: | ||
1869 | /* anything else takes username/password */ | ||
1870 | if (ses->user_name == NULL) | ||
1871 | continue; | ||
1872 | if (strncmp(ses->user_name, vol->username, | ||
1873 | MAX_USERNAME_SIZE)) | ||
1874 | continue; | ||
1875 | if (strlen(vol->username) != 0 && | ||
1876 | ses->password != NULL && | ||
1877 | strncmp(ses->password, | ||
1878 | vol->password ? vol->password : "", | ||
1879 | MAX_PASSWORD_SIZE)) | ||
1880 | continue; | ||
1881 | } | ||
1882 | ++ses->ses_count; | 1898 | ++ses->ses_count; |
1883 | spin_unlock(&cifs_tcp_ses_lock); | 1899 | spin_unlock(&cifs_tcp_ses_lock); |
1884 | return ses; | 1900 | return ses; |
@@ -2021,6 +2037,15 @@ get_ses_fail: | |||
2021 | return ERR_PTR(rc); | 2037 | return ERR_PTR(rc); |
2022 | } | 2038 | } |
2023 | 2039 | ||
2040 | static int match_tcon(struct cifsTconInfo *tcon, const char *unc) | ||
2041 | { | ||
2042 | if (tcon->tidStatus == CifsExiting) | ||
2043 | return 0; | ||
2044 | if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE)) | ||
2045 | return 0; | ||
2046 | return 1; | ||
2047 | } | ||
2048 | |||
2024 | static struct cifsTconInfo * | 2049 | static struct cifsTconInfo * |
2025 | cifs_find_tcon(struct cifsSesInfo *ses, const char *unc) | 2050 | cifs_find_tcon(struct cifsSesInfo *ses, const char *unc) |
2026 | { | 2051 | { |
@@ -2030,11 +2055,8 @@ cifs_find_tcon(struct cifsSesInfo *ses, const char *unc) | |||
2030 | spin_lock(&cifs_tcp_ses_lock); | 2055 | spin_lock(&cifs_tcp_ses_lock); |
2031 | list_for_each(tmp, &ses->tcon_list) { | 2056 | list_for_each(tmp, &ses->tcon_list) { |
2032 | tcon = list_entry(tmp, struct cifsTconInfo, tcon_list); | 2057 | tcon = list_entry(tmp, struct cifsTconInfo, tcon_list); |
2033 | if (tcon->tidStatus == CifsExiting) | 2058 | if (!match_tcon(tcon, unc)) |
2034 | continue; | 2059 | continue; |
2035 | if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE)) | ||
2036 | continue; | ||
2037 | |||
2038 | ++tcon->tc_count; | 2060 | ++tcon->tc_count; |
2039 | spin_unlock(&cifs_tcp_ses_lock); | 2061 | spin_unlock(&cifs_tcp_ses_lock); |
2040 | return tcon; | 2062 | return tcon; |