aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2007-10-04 16:05:09 -0400
committerSteve French <sfrench@us.ibm.com>2007-10-04 16:05:09 -0400
commita013689ddb2a4ba5f0452c053c0bf00bafb686f1 (patch)
treedaffe3644ed321b602a1f6a4e97dc6c6ef329dfb
parentd12fd121afd4f87cbc7675f8f6b651d649534f15 (diff)
[CIFS] Fix cifsd so shuts down when signing fails during mount
Fixes two problems: 1) we dropped down to negotiating lanman if we did not recognize the mechanism (krb5 e.g.) 2) we did not stop cifsd (thus will fail when doing rmod cifs with slab free errors) when we fail tcon but have a bad session (which is the case in which signing is required but we don't allow signing on the client) It also turns on extended security flag in the header when passing "sec=krb5" on mount command (although kerberos support is not done of course) Acked-by: Jeff Layton <jlayton@redhat.com> CC: Shaggy <shaggy@us.ibm.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
-rw-r--r--fs/cifs/cifs_debug.c11
-rw-r--r--fs/cifs/cifsglob.h4
-rw-r--r--fs/cifs/cifssmb.c23
-rw-r--r--fs/cifs/connect.c12
4 files changed, 42 insertions, 8 deletions
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 56c5d9126f50..73c4c419663c 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -879,11 +879,16 @@ security_flags_write(struct file *file, const char __user *buffer,
879 if (count < 3) { 879 if (count < 3) {
880 /* single char or single char followed by null */ 880 /* single char or single char followed by null */
881 c = flags_string[0]; 881 c = flags_string[0];
882 if (c == '0' || c == 'n' || c == 'N') 882 if (c == '0' || c == 'n' || c == 'N') {
883 extended_security = CIFSSEC_DEF; /* default */ 883 extended_security = CIFSSEC_DEF; /* default */
884 else if (c == '1' || c == 'y' || c == 'Y') 884 return count;
885 } else if (c == '1' || c == 'y' || c == 'Y') {
885 extended_security = CIFSSEC_MAX; 886 extended_security = CIFSSEC_MAX;
886 return count; 887 return count;
888 } else if (!isdigit(c)) {
889 cERROR(1, ("invalid flag %c", c));
890 return -EINVAL;
891 }
887 } 892 }
888 /* else we have a number */ 893 /* else we have a number */
889 894
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 3fb046be9c0b..fbde55c569fb 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -90,7 +90,8 @@ enum statusEnum {
90}; 90};
91 91
92enum securityEnum { 92enum securityEnum {
93 LANMAN = 0, /* Legacy LANMAN auth */ 93 PLAINTXT = 0, /* Legacy with Plaintext passwords */
94 LANMAN, /* Legacy LANMAN auth */
94 NTLM, /* Legacy NTLM012 auth with NTLM hash */ 95 NTLM, /* Legacy NTLM012 auth with NTLM hash */
95 NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */ 96 NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */
96 RawNTLMSSP, /* NTLMSSP without SPNEGO */ 97 RawNTLMSSP, /* NTLMSSP without SPNEGO */
@@ -499,6 +500,7 @@ require use of the stronger protocol */
499 500
500#define CIFSSEC_DEF CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 501#define CIFSSEC_DEF CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2
501#define CIFSSEC_MAX CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2 502#define CIFSSEC_MAX CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2
503#define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5)
502/* 504/*
503 ***************************************************************** 505 *****************************************************************
504 * All constants go here 506 * All constants go here
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 90b8f8d64d6e..fda8b2490263 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -438,8 +438,13 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
438 438
439 pSMB->hdr.Mid = GetNextMid(server); 439 pSMB->hdr.Mid = GetNextMid(server);
440 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS); 440 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
441
441 if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) 442 if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
442 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 443 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
444 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) {
445 cFYI(1, ("Kerberos only mechanism, enable extended security"));
446 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
447 }
443 448
444 count = 0; 449 count = 0;
445 for (i = 0; i < CIFS_NUM_PROT; i++) { 450 for (i = 0; i < CIFS_NUM_PROT; i++) {
@@ -573,7 +578,20 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
573 server->secType = NTLM; 578 server->secType = NTLM;
574 else if (secFlags & CIFSSEC_MAY_NTLMV2) 579 else if (secFlags & CIFSSEC_MAY_NTLMV2)
575 server->secType = NTLMv2; 580 server->secType = NTLMv2;
576 /* else krb5 ... any others ... */ 581 else if (secFlags & CIFSSEC_MAY_KRB5)
582 server->secType = Kerberos;
583 else if (secFlags & CIFSSEC_MAY_LANMAN)
584 server->secType = LANMAN;
585/* #ifdef CONFIG_CIFS_EXPERIMENTAL
586 else if (secFlags & CIFSSEC_MAY_PLNTXT)
587 server->secType = ??
588#endif */
589 else {
590 rc = -EOPNOTSUPP;
591 cERROR(1, ("Invalid security type"));
592 goto neg_err_exit;
593 }
594 /* else ... any others ...? */
577 595
578 /* one byte, so no need to convert this or EncryptionKeyLen from 596 /* one byte, so no need to convert this or EncryptionKeyLen from
579 little endian */ 597 little endian */
@@ -3089,8 +3107,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
3089 goto qsec_out; 3107 goto qsec_out;
3090 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base; 3108 pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
3091 3109
3092 cERROR(1, ("smb %p parm %p data %p", 3110 cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, psec_desc));
3093 pSMBr, parm, psec_desc)); /* BB removeme BB */
3094 3111
3095 if (le32_to_cpu(pSMBr->ParameterCount) != 4) { 3112 if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
3096 rc = -EIO; /* bad smb */ 3113 rc = -EIO; /* bad smb */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index fc3a851357fc..c0cd3ce56e9f 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2172,8 +2172,18 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2172 if (tsk) 2172 if (tsk)
2173 kthread_stop(tsk); 2173 kthread_stop(tsk);
2174 } 2174 }
2175 } else 2175 } else {
2176 cFYI(1, ("No session or bad tcon")); 2176 cFYI(1, ("No session or bad tcon"));
2177 if ((pSesInfo->server) &&
2178 (pSesInfo->server->tsk)) {
2179 struct task_struct *tsk;
2180 force_sig(SIGKILL,
2181 pSesInfo->server->tsk);
2182 tsk = pSesInfo->server->tsk;
2183 if (tsk)
2184 kthread_stop(tsk);
2185 }
2186 }
2177 sesInfoFree(pSesInfo); 2187 sesInfoFree(pSesInfo);
2178 /* pSesInfo = NULL; */ 2188 /* pSesInfo = NULL; */
2179 } 2189 }