diff options
author | Jeff Layton <jlayton@redhat.com> | 2013-06-12 20:52:14 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2013-06-24 02:56:44 -0400 |
commit | 3f618223dc0bdcbc8d510350e78ee2195ff93768 (patch) | |
tree | 07b910ab18112557f897f2192d073f97553e1055 /fs/cifs/connect.c | |
parent | 38d77c50b4f4e3ea1687e119871364f1c8d2f531 (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.c | 117 |
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, | |||
2003 | static bool | 1986 | static bool |
2004 | match_security(struct TCP_Server_Info *server, struct smb_vol *vol) | 1987 | match_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 | ||
2240 | static int match_session(struct cifs_ses *ses, struct smb_vol *vol) | 2202 | static 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, | |||
3893 | static int | 3858 | static int |
3894 | cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses) | 3859 | cifs_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 | } |