[CIFS] Allow raw ntlmssp code to be enabled with sec=ntlmssp
Steve French [Wed, 6 May 2009 04:16:04 +0000 (04:16 +0000)]
On mount, "sec=ntlmssp" can now be specified to allow
"rawntlmssp" security to be enabled during
CIFS session establishment/authentication (ntlmssp used to
require specifying krb5 which was counterintuitive).

Signed-off-by: Steve French <sfrench@us.ibm.com>

fs/cifs/README
fs/cifs/cifsglob.h
fs/cifs/cifssmb.c
fs/cifs/connect.c

index 0743418..db208dd 100644 (file)
@@ -651,7 +651,15 @@ Experimental            When set to 1 used to enable certain experimental
                        signing turned on in case buffer was modified
                        just before it was sent, also this flag will
                        be used to use the new experimental directory change 
-                       notification code).
+                       notification code).  When set to 2 enables
+                       an additional experimental feature, "raw ntlmssp"
+                       session establishment support (which allows
+                       specifying "sec=ntlmssp" on mount). The Linux cifs
+                       module will use ntlmv2 authentication encapsulated
+                       in "raw ntlmssp" (not using SPNEGO) when
+                       "sec=ntlmssp" is specified on mount.
+                       This support also requires building cifs with
+                       the CONFIG_CIFS_EXPERIMENTAL configuration flag.
 
 These experimental features and tracing can be enabled by changing flags in 
 /proc/fs/cifs (after the cifs module has been installed or built into the 
index df40ab6..a61ab77 100644 (file)
@@ -82,8 +82,8 @@ enum securityEnum {
        LANMAN,                 /* Legacy LANMAN auth */
        NTLM,                   /* Legacy NTLM012 auth with NTLM hash */
        NTLMv2,                 /* Legacy NTLM auth with NTLMv2 hash */
-       RawNTLMSSP,             /* NTLMSSP without SPNEGO */
-       NTLMSSP,                /* NTLMSSP via SPNEGO */
+       RawNTLMSSP,             /* NTLMSSP without SPNEGO, NTLMv2 hash */
+       NTLMSSP,                /* NTLMSSP via SPNEGO, NTLMv2 hash */
        Kerberos,               /* Kerberos via SPNEGO */
        MSKerberos,             /* MS Kerberos via SPNEGO */
 };
@@ -531,6 +531,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
 #define   CIFSSEC_MAY_PLNTXT    0
 #endif /* weak passwords */
 #define   CIFSSEC_MAY_SEAL     0x00040 /* not supported yet */
+#define   CIFSSEC_MAY_NTLMSSP  0x00080 /* raw ntlmssp with ntlmv2 */
 
 #define   CIFSSEC_MUST_SIGN    0x01001
 /* note that only one of the following can be set so the
@@ -543,22 +544,23 @@ require use of the stronger protocol */
 #define   CIFSSEC_MUST_LANMAN  0x10010
 #define   CIFSSEC_MUST_PLNTXT  0x20020
 #ifdef CONFIG_CIFS_UPCALL
-#define   CIFSSEC_MASK          0x3F03F /* allows weak security but also krb5 */
+#define   CIFSSEC_MASK          0xAF0AF /* allows weak security but also krb5 */
 #else
-#define   CIFSSEC_MASK          0x37037 /* current flags supported if weak */
+#define   CIFSSEC_MASK          0xA70A7 /* current flags supported if weak */
 #endif /* UPCALL */
 #else /* do not allow weak pw hash */
 #ifdef CONFIG_CIFS_UPCALL
-#define   CIFSSEC_MASK          0x0F00F /* flags supported if no weak allowed */
+#define   CIFSSEC_MASK          0x8F08F /* flags supported if no weak allowed */
 #else
-#define          CIFSSEC_MASK          0x07007 /* flags supported if no weak allowed */
+#define          CIFSSEC_MASK          0x87087 /* flags supported if no weak allowed */
 #endif /* UPCALL */
 #endif /* WEAK_PW_HASH */
 #define   CIFSSEC_MUST_SEAL    0x40040 /* not supported yet */
+#define   CIFSSEC_MUST_NTLMSSP 0x80080 /* raw ntlmssp with ntlmv2 */
 
 #define   CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2)
 #define   CIFSSEC_MAX (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2)
-#define   CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5)
+#define   CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP)
 /*
  *****************************************************************
  * All constants go here
index 4e10efd..75e6623 100644 (file)
@@ -449,6 +449,14 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                cFYI(1, ("Kerberos only mechanism, enable extended security"));
                pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
        }
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+       else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
+               pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
+       else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) {
+               cFYI(1, ("NTLMSSP only mechanism, enable extended security"));
+               pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
+       }
+#endif
 
        count = 0;
        for (i = 0; i < CIFS_NUM_PROT; i++) {
@@ -585,6 +593,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                server->secType = NTLMv2;
        else if (secFlags & CIFSSEC_MAY_KRB5)
                server->secType = Kerberos;
+       else if (secFlags & CIFSSEC_MAY_NTLMSSP)
+               server->secType = NTLMSSP;
        else if (secFlags & CIFSSEC_MAY_LANMAN)
                server->secType = LANMAN;
 /* #ifdef CONFIG_CIFS_EXPERIMENTAL
index 3a934dd..4aa81a5 100644 (file)
@@ -979,6 +979,13 @@ cifs_parse_mount_options(char *options, const char *devname,
                                return 1;
                        } else if (strnicmp(value, "krb5", 4) == 0) {
                                vol->secFlg |= CIFSSEC_MAY_KRB5;
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+                       } else if (strnicmp(value, "ntlmsspi", 8) == 0) {
+                               vol->secFlg |= CIFSSEC_MAY_NTLMSSP |
+                                       CIFSSEC_MUST_SIGN;
+                       } else if (strnicmp(value, "ntlmssp", 7) == 0) {
+                               vol->secFlg |= CIFSSEC_MAY_NTLMSSP;
+#endif
                        } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
                                vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
                                        CIFSSEC_MUST_SIGN;