aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2013-07-12 06:34:42 -0400
committerThomas Gleixner <tglx@linutronix.de>2013-07-12 06:34:42 -0400
commitf2006e27396f55276f24434f56e208d86e7f9908 (patch)
tree71896db916d33888b4286f80117d3cac0da40e6d /fs/cifs/connect.c
parente399eb56a6110e13f97e644658648602e2b08de7 (diff)
parent9903883f1dd6e86f286b7bfa6e4b423f98c1cd9e (diff)
Merge branch 'linus' into timers/urgent
Get upstream changes so we can apply fixes against them Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c159
1 files changed, 72 insertions, 87 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index e3bc39bb9d12..afcb8a1a33b7 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -85,7 +85,7 @@ enum {
85 Opt_acl, Opt_noacl, Opt_locallease, 85 Opt_acl, Opt_noacl, Opt_locallease,
86 Opt_sign, Opt_seal, Opt_noac, 86 Opt_sign, Opt_seal, Opt_noac,
87 Opt_fsc, Opt_mfsymlinks, 87 Opt_fsc, Opt_mfsymlinks,
88 Opt_multiuser, Opt_sloppy, 88 Opt_multiuser, Opt_sloppy, Opt_nosharesock,
89 89
90 /* Mount options which take numeric value */ 90 /* Mount options which take numeric value */
91 Opt_backupuid, Opt_backupgid, Opt_uid, 91 Opt_backupuid, Opt_backupgid, Opt_uid,
@@ -165,6 +165,7 @@ static const match_table_t cifs_mount_option_tokens = {
165 { Opt_mfsymlinks, "mfsymlinks" }, 165 { Opt_mfsymlinks, "mfsymlinks" },
166 { Opt_multiuser, "multiuser" }, 166 { Opt_multiuser, "multiuser" },
167 { Opt_sloppy, "sloppy" }, 167 { Opt_sloppy, "sloppy" },
168 { Opt_nosharesock, "nosharesock" },
168 169
169 { Opt_backupuid, "backupuid=%s" }, 170 { Opt_backupuid, "backupuid=%s" },
170 { Opt_backupgid, "backupgid=%s" }, 171 { Opt_backupgid, "backupgid=%s" },
@@ -275,6 +276,7 @@ static const match_table_t cifs_smb_version_tokens = {
275 { Smb_20, SMB20_VERSION_STRING}, 276 { Smb_20, SMB20_VERSION_STRING},
276 { Smb_21, SMB21_VERSION_STRING }, 277 { Smb_21, SMB21_VERSION_STRING },
277 { Smb_30, SMB30_VERSION_STRING }, 278 { Smb_30, SMB30_VERSION_STRING },
279 { Smb_302, SMB302_VERSION_STRING },
278}; 280};
279 281
280static int ip_connect(struct TCP_Server_Info *server); 282static int ip_connect(struct TCP_Server_Info *server);
@@ -1024,44 +1026,48 @@ static int cifs_parse_security_flavors(char *value,
1024 1026
1025 substring_t args[MAX_OPT_ARGS]; 1027 substring_t args[MAX_OPT_ARGS];
1026 1028
1029 /*
1030 * With mount options, the last one should win. Reset any existing
1031 * settings back to default.
1032 */
1033 vol->sectype = Unspecified;
1034 vol->sign = false;
1035
1027 switch (match_token(value, cifs_secflavor_tokens, args)) { 1036 switch (match_token(value, cifs_secflavor_tokens, args)) {
1028 case Opt_sec_krb5:
1029 vol->secFlg |= CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_SIGN;
1030 break;
1031 case Opt_sec_krb5i:
1032 vol->secFlg |= CIFSSEC_MAY_KRB5 | CIFSSEC_MUST_SIGN;
1033 break;
1034 case Opt_sec_krb5p: 1037 case Opt_sec_krb5p:
1035 /* vol->secFlg |= CIFSSEC_MUST_SEAL | CIFSSEC_MAY_KRB5; */ 1038 cifs_dbg(VFS, "sec=krb5p is not supported!\n");
1036 cifs_dbg(VFS, "Krb5 cifs privacy not supported\n"); 1039 return 1;
1037 break; 1040 case Opt_sec_krb5i:
1038 case Opt_sec_ntlmssp: 1041 vol->sign = true;
1039 vol->secFlg |= CIFSSEC_MAY_NTLMSSP; 1042 /* Fallthrough */
1043 case Opt_sec_krb5:
1044 vol->sectype = Kerberos;
1040 break; 1045 break;
1041 case Opt_sec_ntlmsspi: 1046 case Opt_sec_ntlmsspi:
1042 vol->secFlg |= CIFSSEC_MAY_NTLMSSP | CIFSSEC_MUST_SIGN; 1047 vol->sign = true;
1043 break; 1048 /* Fallthrough */
1044 case Opt_ntlm: 1049 case Opt_sec_ntlmssp:
1045 /* ntlm is default so can be turned off too */ 1050 vol->sectype = RawNTLMSSP;
1046 vol->secFlg |= CIFSSEC_MAY_NTLM;
1047 break; 1051 break;
1048 case Opt_sec_ntlmi: 1052 case Opt_sec_ntlmi:
1049 vol->secFlg |= CIFSSEC_MAY_NTLM | CIFSSEC_MUST_SIGN; 1053 vol->sign = true;
1050 break; 1054 /* Fallthrough */
1051 case Opt_sec_ntlmv2: 1055 case Opt_ntlm:
1052 vol->secFlg |= CIFSSEC_MAY_NTLMV2; 1056 vol->sectype = NTLM;
1053 break; 1057 break;
1054 case Opt_sec_ntlmv2i: 1058 case Opt_sec_ntlmv2i:
1055 vol->secFlg |= CIFSSEC_MAY_NTLMV2 | CIFSSEC_MUST_SIGN; 1059 vol->sign = true;
1060 /* Fallthrough */
1061 case Opt_sec_ntlmv2:
1062 vol->sectype = NTLMv2;
1056 break; 1063 break;
1057#ifdef CONFIG_CIFS_WEAK_PW_HASH 1064#ifdef CONFIG_CIFS_WEAK_PW_HASH
1058 case Opt_sec_lanman: 1065 case Opt_sec_lanman:
1059 vol->secFlg |= CIFSSEC_MAY_LANMAN; 1066 vol->sectype = LANMAN;
1060 break; 1067 break;
1061#endif 1068#endif
1062 case Opt_sec_none: 1069 case Opt_sec_none:
1063 vol->nullauth = 1; 1070 vol->nullauth = 1;
1064 vol->secFlg |= CIFSSEC_MAY_NTLM;
1065 break; 1071 break;
1066 default: 1072 default:
1067 cifs_dbg(VFS, "bad security option: %s\n", value); 1073 cifs_dbg(VFS, "bad security option: %s\n", value);
@@ -1119,6 +1125,10 @@ cifs_parse_smb_version(char *value, struct smb_vol *vol)
1119 vol->ops = &smb30_operations; 1125 vol->ops = &smb30_operations;
1120 vol->vals = &smb30_values; 1126 vol->vals = &smb30_values;
1121 break; 1127 break;
1128 case Smb_302:
1129 vol->ops = &smb30_operations; /* currently identical with 3.0 */
1130 vol->vals = &smb302_values;
1131 break;
1122#endif 1132#endif
1123 default: 1133 default:
1124 cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value); 1134 cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value);
@@ -1424,7 +1434,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1424 vol->local_lease = 1; 1434 vol->local_lease = 1;
1425 break; 1435 break;
1426 case Opt_sign: 1436 case Opt_sign:
1427 vol->secFlg |= CIFSSEC_MUST_SIGN; 1437 vol->sign = true;
1428 break; 1438 break;
1429 case Opt_seal: 1439 case Opt_seal:
1430 /* we do not do the following in secFlags because seal 1440 /* we do not do the following in secFlags because seal
@@ -1455,6 +1465,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1455 case Opt_sloppy: 1465 case Opt_sloppy:
1456 sloppy = true; 1466 sloppy = true;
1457 break; 1467 break;
1468 case Opt_nosharesock:
1469 vol->nosharesock = true;
1470 break;
1458 1471
1459 /* Numeric Values */ 1472 /* Numeric Values */
1460 case Opt_backupuid: 1473 case Opt_backupuid:
@@ -1978,47 +1991,21 @@ match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
1978static bool 1991static bool
1979match_security(struct TCP_Server_Info *server, struct smb_vol *vol) 1992match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
1980{ 1993{
1981 unsigned int secFlags; 1994 /*
1982 1995 * The select_sectype function should either return the vol->sectype
1983 if (vol->secFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL))) 1996 * that was specified, or "Unspecified" if that sectype was not
1984 secFlags = vol->secFlg; 1997 * compatible with the given NEGOTIATE request.
1985 else 1998 */
1986 secFlags = global_secflags | vol->secFlg; 1999 if (select_sectype(server, vol->sectype) == Unspecified)
1987
1988 switch (server->secType) {
1989 case LANMAN:
1990 if (!(secFlags & (CIFSSEC_MAY_LANMAN|CIFSSEC_MAY_PLNTXT)))
1991 return false;
1992 break;
1993 case NTLMv2:
1994 if (!(secFlags & CIFSSEC_MAY_NTLMV2))
1995 return false;
1996 break;
1997 case NTLM:
1998 if (!(secFlags & CIFSSEC_MAY_NTLM))
1999 return false;
2000 break;
2001 case Kerberos:
2002 if (!(secFlags & CIFSSEC_MAY_KRB5))
2003 return false;
2004 break;
2005 case RawNTLMSSP:
2006 if (!(secFlags & CIFSSEC_MAY_NTLMSSP))
2007 return false;
2008 break;
2009 default:
2010 /* shouldn't happen */
2011 return false; 2000 return false;
2012 }
2013 2001
2014 /* now check if signing mode is acceptable */ 2002 /*
2015 if ((secFlags & CIFSSEC_MAY_SIGN) == 0 && 2003 * Now check if signing mode is acceptable. No need to check
2016 (server->sec_mode & SECMODE_SIGN_REQUIRED)) 2004 * global_secflags at this point since if MUST_SIGN is set then
2017 return false; 2005 * the server->sign had better be too.
2018 else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) && 2006 */
2019 (server->sec_mode & 2007 if (vol->sign && !server->sign)
2020 (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0) 2008 return false;
2021 return false;
2022 2009
2023 return true; 2010 return true;
2024} 2011}
@@ -2027,6 +2014,9 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
2027{ 2014{
2028 struct sockaddr *addr = (struct sockaddr *)&vol->dstaddr; 2015 struct sockaddr *addr = (struct sockaddr *)&vol->dstaddr;
2029 2016
2017 if (vol->nosharesock)
2018 return 0;
2019
2030 if ((server->vals != vol->vals) || (server->ops != vol->ops)) 2020 if ((server->vals != vol->vals) || (server->ops != vol->ops))
2031 return 0; 2021 return 0;
2032 2022
@@ -2216,7 +2206,11 @@ out_err:
2216 2206
2217static int match_session(struct cifs_ses *ses, struct smb_vol *vol) 2207static int match_session(struct cifs_ses *ses, struct smb_vol *vol)
2218{ 2208{
2219 switch (ses->server->secType) { 2209 if (vol->sectype != Unspecified &&
2210 vol->sectype != ses->sectype)
2211 return 0;
2212
2213 switch (ses->sectype) {
2220 case Kerberos: 2214 case Kerberos:
2221 if (!uid_eq(vol->cred_uid, ses->cred_uid)) 2215 if (!uid_eq(vol->cred_uid, ses->cred_uid))
2222 return 0; 2216 return 0;
@@ -2493,7 +2487,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
2493 ses->cred_uid = volume_info->cred_uid; 2487 ses->cred_uid = volume_info->cred_uid;
2494 ses->linux_uid = volume_info->linux_uid; 2488 ses->linux_uid = volume_info->linux_uid;
2495 2489
2496 ses->overrideSecFlg = volume_info->secFlg; 2490 ses->sectype = volume_info->sectype;
2491 ses->sign = volume_info->sign;
2497 2492
2498 mutex_lock(&ses->session_mutex); 2493 mutex_lock(&ses->session_mutex);
2499 rc = cifs_negotiate_protocol(xid, ses); 2494 rc = cifs_negotiate_protocol(xid, ses);
@@ -3656,7 +3651,7 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
3656 NTLMv2 password here) */ 3651 NTLMv2 password here) */
3657#ifdef CONFIG_CIFS_WEAK_PW_HASH 3652#ifdef CONFIG_CIFS_WEAK_PW_HASH
3658 if ((global_secflags & CIFSSEC_MAY_LANMAN) && 3653 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
3659 (ses->server->secType == LANMAN)) 3654 (ses->sectype == LANMAN))
3660 calc_lanman_hash(tcon->password, ses->server->cryptkey, 3655 calc_lanman_hash(tcon->password, ses->server->cryptkey,
3661 ses->server->sec_mode & 3656 ses->server->sec_mode &
3662 SECMODE_PW_ENCRYPT ? true : false, 3657 SECMODE_PW_ENCRYPT ? true : false,
@@ -3674,8 +3669,7 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
3674 } 3669 }
3675 } 3670 }
3676 3671
3677 if (ses->server->sec_mode & 3672 if (ses->server->sign)
3678 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3679 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 3673 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3680 3674
3681 if (ses->capabilities & CAP_STATUS32) { 3675 if (ses->capabilities & CAP_STATUS32) {
@@ -3738,7 +3732,7 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
3738 } 3732 }
3739 bcc_ptr += length + 1; 3733 bcc_ptr += length + 1;
3740 bytes_left -= (length + 1); 3734 bytes_left -= (length + 1);
3741 strncpy(tcon->treeName, tree, MAX_TREE_SIZE); 3735 strlcpy(tcon->treeName, tree, sizeof(tcon->treeName));
3742 3736
3743 /* mostly informational -- no need to fail on error here */ 3737 /* mostly informational -- no need to fail on error here */
3744 kfree(tcon->nativeFileSystem); 3738 kfree(tcon->nativeFileSystem);
@@ -3827,7 +3821,6 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
3827 int rc = -ENOSYS; 3821 int rc = -ENOSYS;
3828 struct TCP_Server_Info *server = ses->server; 3822 struct TCP_Server_Info *server = ses->server;
3829 3823
3830 ses->flags = 0;
3831 ses->capabilities = server->capabilities; 3824 ses->capabilities = server->capabilities;
3832 if (linuxExtEnabled == 0) 3825 if (linuxExtEnabled == 0)
3833 ses->capabilities &= (~server->vals->cap_unix); 3826 ses->capabilities &= (~server->vals->cap_unix);
@@ -3848,6 +3841,8 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
3848 server->sequence_number = 0x2; 3841 server->sequence_number = 0x2;
3849 server->session_estab = true; 3842 server->session_estab = true;
3850 ses->auth_key.response = NULL; 3843 ses->auth_key.response = NULL;
3844 if (server->ops->generate_signingkey)
3845 server->ops->generate_signingkey(server);
3851 } 3846 }
3852 mutex_unlock(&server->srv_mutex); 3847 mutex_unlock(&server->srv_mutex);
3853 3848
@@ -3870,23 +3865,11 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
3870static int 3865static int
3871cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses) 3866cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses)
3872{ 3867{
3873 switch (ses->server->secType) { 3868 vol->sectype = ses->sectype;
3874 case Kerberos: 3869
3875 vol->secFlg = CIFSSEC_MUST_KRB5; 3870 /* krb5 is special, since we don't need username or pw */
3871 if (vol->sectype == Kerberos)
3876 return 0; 3872 return 0;
3877 case NTLMv2:
3878 vol->secFlg = CIFSSEC_MUST_NTLMV2;
3879 break;
3880 case NTLM:
3881 vol->secFlg = CIFSSEC_MUST_NTLM;
3882 break;
3883 case RawNTLMSSP:
3884 vol->secFlg = CIFSSEC_MUST_NTLMSSP;
3885 break;
3886 case LANMAN:
3887 vol->secFlg = CIFSSEC_MUST_LANMAN;
3888 break;
3889 }
3890 3873
3891 return cifs_set_cifscreds(vol, ses); 3874 return cifs_set_cifscreds(vol, ses);
3892} 3875}
@@ -3912,6 +3895,8 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
3912 vol_info->nocase = master_tcon->nocase; 3895 vol_info->nocase = master_tcon->nocase;
3913 vol_info->local_lease = master_tcon->local_lease; 3896 vol_info->local_lease = master_tcon->local_lease;
3914 vol_info->no_linux_ext = !master_tcon->unix_ext; 3897 vol_info->no_linux_ext = !master_tcon->unix_ext;
3898 vol_info->sectype = master_tcon->ses->sectype;
3899 vol_info->sign = master_tcon->ses->sign;
3915 3900
3916 rc = cifs_set_vol_auth(vol_info, master_tcon->ses); 3901 rc = cifs_set_vol_auth(vol_info, master_tcon->ses);
3917 if (rc) { 3902 if (rc) {