summaryrefslogtreecommitdiffstats
path: root/fs/cifs/sess.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2013-06-12 19:52:14 -0500
committerSteve French <smfrench@gmail.com>2013-06-24 01:56:44 -0500
commit3f618223dc0bdcbc8d510350e78ee2195ff93768 (patch)
tree07b910ab18112557f897f2192d073f97553e1055 /fs/cifs/sess.c
parent38d77c50b4f4e3ea1687e119871364f1c8d2f531 (diff)
downloadlinux-3f618223dc0bdcbc8d510350e78ee2195ff93768.tar.gz
linux-3f618223dc0bdcbc8d510350e78ee2195ff93768.tar.bz2
linux-3f618223dc0bdcbc8d510350e78ee2195ff93768.zip
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/sess.c')
-rw-r--r--fs/cifs/sess.c57
1 files changed, 56 insertions, 1 deletions
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 82b784a62c16..79358e341fd2 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -550,6 +550,56 @@ setup_ntlmv2_ret:
return rc;
}
+enum securityEnum
+select_sectype(struct TCP_Server_Info *server, enum securityEnum requested)
+{
+ switch (server->negflavor) {
+ case CIFS_NEGFLAVOR_EXTENDED:
+ switch (requested) {
+ case Kerberos:
+ case RawNTLMSSP:
+ return requested;
+ case Unspecified:
+ if (server->sec_ntlmssp &&
+ (global_secflags & CIFSSEC_MAY_NTLMSSP))
+ return RawNTLMSSP;
+ if ((server->sec_kerberos || server->sec_mskerberos) &&
+ (global_secflags & CIFSSEC_MAY_KRB5))
+ return Kerberos;
+ /* Fallthrough */
+ default:
+ return Unspecified;
+ }
+ case CIFS_NEGFLAVOR_UNENCAP:
+ switch (requested) {
+ case NTLM:
+ case NTLMv2:
+ return requested;
+ case Unspecified:
+ if (global_secflags & CIFSSEC_MAY_NTLMV2)
+ return NTLMv2;
+ if (global_secflags & CIFSSEC_MAY_NTLM)
+ return NTLM;
+ /* Fallthrough */
+ default:
+ return Unspecified;
+ }
+ case CIFS_NEGFLAVOR_LANMAN:
+ switch (requested) {
+ case LANMAN:
+ return requested;
+ case Unspecified:
+ if (global_secflags & CIFSSEC_MAY_LANMAN)
+ return LANMAN;
+ /* Fallthrough */
+ default:
+ return Unspecified;
+ }
+ default:
+ return Unspecified;
+ }
+}
+
int
CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
const struct nls_table *nls_cp)
@@ -576,8 +626,13 @@ CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
return -EINVAL;
}
- type = ses->server->secType;
+ type = select_sectype(ses->server, ses->sectype);
cifs_dbg(FYI, "sess setup type %d\n", type);
+ if (type == Unspecified) {
+ cifs_dbg(VFS, "Unable to select appropriate authentication method!");
+ return -EINVAL;
+ }
+
if (type == RawNTLMSSP) {
/* if memory allocation is successful, caller of this function
* frees it.