Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 448

kernel-2.6.18-238.el5.src.rpm

From: Jeff Layton <jlayton@redhat.com>
Subject: [RHEL5.1 PATCH] CIFS: fix signing sec= mount options
Date: Mon, 9 Jul 2007 09:42:10 -0400
Bugzilla: 246595
Message-Id: <20070709094210.e8ec2d5c.jlayton@redhat.com>
Changelog: [CIFS] fix signing sec= mount options


The current code for CIFS sets the wrong variable when signing is
requested. If the client requests a signing sec= mount option (i.e.
ntlmi), the request is silently ignored. The upshot is that users will
think that everything worked, but the packets aren't actually being
signed.

The client also does not throw an error when signing is requested, but
the server doesn't support it (though it does printk a warning in this
situation).

diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 6017c46..a261954 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -895,90 +895,14 @@ security_flags_write(struct file *file, const char __user *buffer,
 	}
 	/* flags look ok - update the global security flags for cifs module */
 	extended_security = flags;
+	if (extended_security & CIFSSEC_MUST_SIGN) {
+		/* requiring signing implies signing is allowed */
+		extended_security |= CIFSSEC_MAY_SIGN;
+		cFYI(1,("packet signing now required"));
+	} else if ((extended_security & CIFSSEC_MAY_SIGN) == 0) {
+		cFYI(1,("packet signing disabled"));
+	}
+	/* BB should we turn on MAY flags for other MUST options? */
 	return count;
 }
-
-/* static int
-ntlmv2_enabled_read(char *page, char **start, off_t off,
-		       int count, int *eof, void *data)
-{
-	int len;
-
-	len = sprintf(page, "%d\n", ntlmv2_support);
-
-	len -= off;
-	*start = page + off;
-
-	if (len > count)
-		len = count;
-	else
-		*eof = 1;
-
-	if (len < 0)
-		len = 0;
-
-	return len;
-}
-static int
-ntlmv2_enabled_write(struct file *file, const char __user *buffer,
-			unsigned long count, void *data)
-{
-	char c;
-	int rc;
-
-	rc = get_user(c, buffer);
-	if (rc)
-		return rc;
-	if (c == '0' || c == 'n' || c == 'N')
-		ntlmv2_support = 0;
-	else if (c == '1' || c == 'y' || c == 'Y')
-		ntlmv2_support = 1;
-	else if (c == '2')
-		ntlmv2_support = 2;
-
-	return count;
-}
-
-static int
-packet_signing_enabled_read(char *page, char **start, off_t off,
-		       int count, int *eof, void *data)
-{
-	int len;
-
-	len = sprintf(page, "%d\n", sign_CIFS_PDUs);
-
-	len -= off;
-	*start = page + off;
-
-	if (len > count)
-		len = count;
-	else
-		*eof = 1;
-
-	if (len < 0)
-		len = 0;
-
-	return len;
-}
-static int
-packet_signing_enabled_write(struct file *file, const char __user *buffer,
-			unsigned long count, void *data)
-{
-	char c;
-	int rc;
-
-	rc = get_user(c, buffer);
-	if (rc)
-		return rc;
-	if (c == '0' || c == 'n' || c == 'N')
-		sign_CIFS_PDUs = 0;
-	else if (c == '1' || c == 'y' || c == 'Y')
-		sign_CIFS_PDUs = 1;
-	else if (c == '2')
-		sign_CIFS_PDUs = 2;
-
-	return count;
-} */
-
-
 #endif
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 2bb636c..7cafa38 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -1,7 +1,7 @@
 /*
  *   fs/cifs/cifsglob.h
  *
- *   Copyright (C) International Business Machines  Corp., 2002,2006
+ *   Copyright (C) International Business Machines  Corp., 2002,2007
  *   Author(s): Steve French (sfrench@us.ibm.com)
  *              Jeremy Allison (jra@samba.org)
  *
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 80fc491..b50718e 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -439,13 +439,17 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
 	if (rc)
 		return rc;
 
+#ifdef CONFIG_CIFS_DEBUG2
+	cFYI(1, ("security flags 0x%x override flags 0x%x",
+		extended_security, ses->overrideSecFlg)); 
+#endif
 	/* if any of auth flags (ie not sign or seal) are overriden use them */
 	if(ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
-		secFlags = ses->overrideSecFlg;
+		secFlags = ses->overrideSecFlg;  /* BB FIXME fix sign flags? */
 	else /* if override flags set only sign/seal OR them with global auth */
 		secFlags = extended_security | ses->overrideSecFlg;
 
-	cFYI(1,("secFlags 0x%x",secFlags));
+	cFYI(1, ("secFlags 0x%x", secFlags));
 
 	pSMB->hdr.Mid = GetNextMid(server);
 	pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
@@ -648,22 +652,32 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
 signing_check:
 #endif
-	if(sign_CIFS_PDUs == FALSE) {        
+	if((secFlags & CIFSSEC_MAY_SIGN) == 0) {
+		/* MUST_SIGN already includes the MAY_SIGN FLAG 
+		   so if this is zero it means that signing is disabled */
+		cFYI(1, ("Signing disabled"));
 		if(server->secMode & SECMODE_SIGN_REQUIRED)
-			cERROR(1,("Server requires "
-				 "/proc/fs/cifs/PacketSigningEnabled to be on"));
+			cERROR(1, ("Server requires "
+				   "/proc/fs/cifs/PacketSigningEnabled "
+				   "to be on"));
 		server->secMode &= 
 			~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
-	} else if(sign_CIFS_PDUs == 1) {
-		if((server->secMode & SECMODE_SIGN_REQUIRED) == 0)
-			server->secMode &= 
-				~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
-	} else if(sign_CIFS_PDUs == 2) {
+	} else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
+		/* signing required */
+		cFYI(1, ("Must sign - segFlags 0x%x", secFlags));
 		if((server->secMode & 
 			(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
 			cERROR(1,("signing required but server lacks support"));
-		}
+			rc = -EOPNOTSUPP;
+		} else 
+			server->secMode |= SECMODE_SIGN_REQUIRED;
+	} else {
+		/* signing optional ie CIFSSEC_MAY_SIGN */
+		if((server->secMode & SECMODE_SIGN_REQUIRED) == 0)
+			server->secMode &= 
+				~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
 	}
+	
 neg_err_exit:	
 	cifs_buf_release(pSMB);
 
-- 
1.5.2.2