aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2013-06-12 20:52:14 -0400
committerSteve French <smfrench@gmail.com>2013-06-24 02:56:44 -0400
commit3f618223dc0bdcbc8d510350e78ee2195ff93768 (patch)
tree07b910ab18112557f897f2192d073f97553e1055 /fs/cifs/connect.c
parent38d77c50b4f4e3ea1687e119871364f1c8d2f531 (diff)
move sectype to the cifs_ses instead of TCP_Server_Info
Now that we track what sort of NEGOTIATE response was received, stop mandating that every session on a socket use the same type of auth. Push that decision out into the session setup code, and make the sectype a per-session property. This should allow us to mix multiple sectypes on a socket as long as they are compatible with the NEGOTIATE response. With this too, we can now eliminate the ses->secFlg field since that info is redundant and harder to work with than a securityEnum. Signed-off-by: Jeff Layton <jlayton@redhat.com> Acked-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c117
1 files changed, 33 insertions, 84 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index acbb255352af..c4c6aa99ee1c 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1033,56 +1033,40 @@ static int cifs_parse_security_flavors(char *value,
1033 vol->sign = false; 1033 vol->sign = false;
1034 1034
1035 switch (match_token(value, cifs_secflavor_tokens, args)) { 1035 switch (match_token(value, cifs_secflavor_tokens, args)) {
1036 case Opt_sec_krb5p:
1037 cifs_dbg(VFS, "sec=krb5p is not supported!\n");
1038 return 1;
1039 case Opt_sec_krb5i:
1040 vol->sign = true;
1041 /* Fallthrough */
1036 case Opt_sec_krb5: 1042 case Opt_sec_krb5:
1037 vol->sectype = Kerberos; 1043 vol->sectype = Kerberos;
1038 vol->secFlg |= CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_SIGN;
1039 break; 1044 break;
1040 case Opt_sec_krb5i: 1045 case Opt_sec_ntlmsspi:
1041 vol->sectype = Kerberos;
1042 vol->sign = true; 1046 vol->sign = true;
1043 vol->secFlg |= CIFSSEC_MAY_KRB5 | CIFSSEC_MUST_SIGN; 1047 /* Fallthrough */
1044 break;
1045 case Opt_sec_krb5p:
1046 /* vol->secFlg |= CIFSSEC_MUST_SEAL | CIFSSEC_MAY_KRB5; */
1047 cifs_dbg(VFS, "Krb5 cifs privacy not supported\n");
1048 break;
1049 case Opt_sec_ntlmssp: 1048 case Opt_sec_ntlmssp:
1050 vol->sectype = RawNTLMSSP; 1049 vol->sectype = RawNTLMSSP;
1051 vol->secFlg |= CIFSSEC_MAY_NTLMSSP;
1052 break; 1050 break;
1053 case Opt_sec_ntlmsspi: 1051 case Opt_sec_ntlmi:
1054 vol->sectype = RawNTLMSSP;
1055 vol->sign = true; 1052 vol->sign = true;
1056 vol->secFlg |= CIFSSEC_MAY_NTLMSSP | CIFSSEC_MUST_SIGN; 1053 /* Fallthrough */
1057 break;
1058 case Opt_ntlm: 1054 case Opt_ntlm:
1059 /* ntlm is default so can be turned off too */
1060 vol->sectype = NTLM; 1055 vol->sectype = NTLM;
1061 vol->secFlg |= CIFSSEC_MAY_NTLM;
1062 break; 1056 break;
1063 case Opt_sec_ntlmi: 1057 case Opt_sec_ntlmv2i:
1064 vol->sectype = NTLM;
1065 vol->sign = true; 1058 vol->sign = true;
1066 vol->secFlg |= CIFSSEC_MAY_NTLM | CIFSSEC_MUST_SIGN; 1059 /* Fallthrough */
1067 break;
1068 case Opt_sec_ntlmv2: 1060 case Opt_sec_ntlmv2:
1069 vol->sectype = NTLMv2; 1061 vol->sectype = NTLMv2;
1070 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
1071 break;
1072 case Opt_sec_ntlmv2i:
1073 vol->sectype = NTLMv2;
1074 vol->sign = true;
1075 vol->secFlg |= CIFSSEC_MAY_NTLMV2 | CIFSSEC_MUST_SIGN;
1076 break; 1062 break;
1077#ifdef CONFIG_CIFS_WEAK_PW_HASH 1063#ifdef CONFIG_CIFS_WEAK_PW_HASH
1078 case Opt_sec_lanman: 1064 case Opt_sec_lanman:
1079 vol->sectype = LANMAN; 1065 vol->sectype = LANMAN;
1080 vol->secFlg |= CIFSSEC_MAY_LANMAN;
1081 break; 1066 break;
1082#endif 1067#endif
1083 case Opt_sec_none: 1068 case Opt_sec_none:
1084 vol->nullauth = 1; 1069 vol->nullauth = 1;
1085 vol->secFlg |= CIFSSEC_MAY_NTLM;
1086 break; 1070 break;
1087 default: 1071 default:
1088 cifs_dbg(VFS, "bad security option: %s\n", value); 1072 cifs_dbg(VFS, "bad security option: %s\n", value);
@@ -1445,7 +1429,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1445 vol->local_lease = 1; 1429 vol->local_lease = 1;
1446 break; 1430 break;
1447 case Opt_sign: 1431 case Opt_sign:
1448 vol->secFlg |= CIFSSEC_MUST_SIGN;
1449 vol->sign = true; 1432 vol->sign = true;
1450 break; 1433 break;
1451 case Opt_seal: 1434 case Opt_seal:
@@ -2003,40 +1986,19 @@ match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
2003static bool 1986static bool
2004match_security(struct TCP_Server_Info *server, struct smb_vol *vol) 1987match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
2005{ 1988{
2006 unsigned int secFlags; 1989 /*
2007 1990 * The select_sectype function should either return the vol->sectype
2008 if (vol->secFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL))) 1991 * that was specified, or "Unspecified" if that sectype was not
2009 secFlags = vol->secFlg; 1992 * compatible with the given NEGOTIATE request.
2010 else 1993 */
2011 secFlags = global_secflags | vol->secFlg; 1994 if (select_sectype(server, vol->sectype) == Unspecified)
2012
2013 switch (server->secType) {
2014 case LANMAN:
2015 if (!(secFlags & (CIFSSEC_MAY_LANMAN|CIFSSEC_MAY_PLNTXT)))
2016 return false;
2017 break;
2018 case NTLMv2:
2019 if (!(secFlags & CIFSSEC_MAY_NTLMV2))
2020 return false;
2021 break;
2022 case NTLM:
2023 if (!(secFlags & CIFSSEC_MAY_NTLM))
2024 return false;
2025 break;
2026 case Kerberos:
2027 if (!(secFlags & CIFSSEC_MAY_KRB5))
2028 return false;
2029 break;
2030 case RawNTLMSSP:
2031 if (!(secFlags & CIFSSEC_MAY_NTLMSSP))
2032 return false;
2033 break;
2034 default:
2035 /* shouldn't happen */
2036 return false; 1995 return false;
2037 }
2038 1996
2039 /* now check if signing mode is acceptable */ 1997 /*
1998 * Now check if signing mode is acceptable. No need to check
1999 * global_secflags at this point since if MUST_SIGN is set then
2000 * the server->sign had better be too.
2001 */
2040 if (vol->sign && !server->sign) 2002 if (vol->sign && !server->sign)
2041 return false; 2003 return false;
2042 2004
@@ -2239,7 +2201,11 @@ out_err:
2239 2201
2240static int match_session(struct cifs_ses *ses, struct smb_vol *vol) 2202static int match_session(struct cifs_ses *ses, struct smb_vol *vol)
2241{ 2203{
2242 switch (ses->server->secType) { 2204 if (vol->sectype != Unspecified &&
2205 vol->sectype != ses->sectype)
2206 return 0;
2207
2208 switch (ses->sectype) {
2243 case Kerberos: 2209 case Kerberos:
2244 if (!uid_eq(vol->cred_uid, ses->cred_uid)) 2210 if (!uid_eq(vol->cred_uid, ses->cred_uid))
2245 return 0; 2211 return 0;
@@ -2516,7 +2482,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
2516 ses->cred_uid = volume_info->cred_uid; 2482 ses->cred_uid = volume_info->cred_uid;
2517 ses->linux_uid = volume_info->linux_uid; 2483 ses->linux_uid = volume_info->linux_uid;
2518 2484
2519 ses->overrideSecFlg = volume_info->secFlg;
2520 ses->sectype = volume_info->sectype; 2485 ses->sectype = volume_info->sectype;
2521 ses->sign = volume_info->sign; 2486 ses->sign = volume_info->sign;
2522 2487
@@ -3681,7 +3646,7 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
3681 NTLMv2 password here) */ 3646 NTLMv2 password here) */
3682#ifdef CONFIG_CIFS_WEAK_PW_HASH 3647#ifdef CONFIG_CIFS_WEAK_PW_HASH
3683 if ((global_secflags & CIFSSEC_MAY_LANMAN) && 3648 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
3684 (ses->server->secType == LANMAN)) 3649 (ses->sectype == LANMAN))
3685 calc_lanman_hash(tcon->password, ses->server->cryptkey, 3650 calc_lanman_hash(tcon->password, ses->server->cryptkey,
3686 ses->server->sec_mode & 3651 ses->server->sec_mode &
3687 SECMODE_PW_ENCRYPT ? true : false, 3652 SECMODE_PW_ENCRYPT ? true : false,
@@ -3893,27 +3858,11 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
3893static int 3858static int
3894cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses) 3859cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses)
3895{ 3860{
3896 switch (ses->server->secType) { 3861 vol->sectype = ses->sectype;
3897 case Kerberos: 3862
3898 vol->secFlg = CIFSSEC_MUST_KRB5; 3863 /* krb5 is special, since we don't need username or pw */
3864 if (vol->sectype == Kerberos)
3899 return 0; 3865 return 0;
3900 case NTLMv2:
3901 vol->secFlg = CIFSSEC_MUST_NTLMV2;
3902 break;
3903 case NTLM:
3904 vol->secFlg = CIFSSEC_MUST_NTLM;
3905 break;
3906 case RawNTLMSSP:
3907 vol->secFlg = CIFSSEC_MUST_NTLMSSP;
3908 break;
3909 case LANMAN:
3910 vol->secFlg = CIFSSEC_MUST_LANMAN;
3911 break;
3912 default:
3913 /* should never happen */
3914 vol->secFlg = 0;
3915 break;
3916 }
3917 3866
3918 return cifs_set_cifscreds(vol, ses); 3867 return cifs_set_cifscreds(vol, ses);
3919} 3868}