]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
[CIFS] Support for older servers which require plaintext passwords
authorSteve French <sfrench@us.ibm.com>
Fri, 2 Jun 2006 22:57:13 +0000 (22:57 +0000)
committerSteve French <sfrench@us.ibm.com>
Fri, 2 Jun 2006 22:57:13 +0000 (22:57 +0000)
disabled by default, but can be enabled via proc for servers which
require such support.  Also includes support for setting security
flags for cifs.  See fs/cifs/README

Signed-off-by: Steve French <sfrench@us.ibm.com>
fs/cifs/cifs_debug.c
fs/cifs/cifsencrypt.c
fs/cifs/cifssmb.c

index 4e10e21c54fd43df8a1ae16ca869541432a85fed..7c0015a96959337d66097bee53a82d05908ce21b 100644 (file)
@@ -445,8 +445,8 @@ static read_proc_t traceSMB_read;
 static write_proc_t traceSMB_write;
 static read_proc_t multiuser_mount_read;
 static write_proc_t multiuser_mount_write;
-static read_proc_t extended_security_read;
-static write_proc_t extended_security_write;
+static read_proc_t security_flags_read;
+static write_proc_t security_flags_write;
 /* static read_proc_t ntlmv2_enabled_read;
 static write_proc_t ntlmv2_enabled_write;
 static read_proc_t packet_signing_enabled_read;
@@ -509,9 +509,9 @@ cifs_proc_init(void)
 
        pde =
            create_proc_read_entry("SecurityFlags", 0, proc_fs_cifs,
-                               extended_security_read, NULL);
+                               security_flags_read, NULL);
        if (pde)
-               pde->write_proc = extended_security_write;
+               pde->write_proc = security_flags_write;
 
        pde =
        create_proc_read_entry("LookupCacheEnabled", 0, proc_fs_cifs,
@@ -832,7 +832,7 @@ multiuser_mount_write(struct file *file, const char __user *buffer,
 }
 
 static int
-extended_security_read(char *page, char **start, off_t off,
+security_flags_read(char *page, char **start, off_t off,
                       int count, int *eof, void *data)
 {
        int len;
@@ -853,26 +853,50 @@ extended_security_read(char *page, char **start, off_t off,
        return len;
 }
 static int
-extended_security_write(struct file *file, const char __user *buffer,
+security_flags_write(struct file *file, const char __user *buffer,
                        unsigned long count, void *data)
 {
+       unsigned int flags;
+       char flags_string[12];
        char c;
-       int rc;
+
        cERROR(1,("size %ld",count)); /* BB removeme BB */
-       if((count < 2) || (count > 8))
+
+       if((count < 1) || (count > 11))
                return -EINVAL;
 
-       rc = get_user(c, buffer);
+       memset(flags_string, 0, 12);
 
-/* BB fixme need to parse more characters in order to handle CIFSSEC flags */ 
+       if(copy_from_user(flags_string, buffer, count))
+               return -EFAULT;
 
-       if (rc)
-               return rc;
-       if (c == '0' || c == 'n' || c == 'N')
-               extended_security = CIFSSEC_DEF; /* default */
-       else if (c == '1' || c == 'y' || c == 'Y')
-               extended_security = CIFSSEC_MAX;
+       if(count < 3) {
+               /* single char or single char followed by null */
+               c = flags_string[0];
+               if (c == '0' || c == 'n' || c == 'N')
+                       extended_security = CIFSSEC_DEF; /* default */
+               else if (c == '1' || c == 'y' || c == 'Y')
+                       extended_security = CIFSSEC_MAX;
+               return count;
+       }
+       /* else we have a number */
+
+       flags = simple_strtoul(flags_string, NULL, 0);
+
+       cERROR(1,("sec flags 0x%x", flags));  /* BB FIXME make cFYI */
+
+       if(flags <= 0)  {
+               cERROR(1,("invalid security flags %s",flags_string));
+               return -EINVAL;
+       }
 
+       if((flags & CIFSSEC_MASK) != CIFSSEC_MASK) {
+               cERROR(1,("attempt to set unsupported security flags 0x%d",
+                       flags & ~CIFSSEC_MASK));
+               return -EINVAL;
+       }
+       /* flags look ok - update the global security flags for cifs module */
+       extended_security = flags;
        return count;
 }
 
index e11d8c6bb2270484a2ed5651c838786c2d09f6bf..3ae964bbfdc3f61490d8faf805635f491daf7cda 100644 (file)
@@ -271,9 +271,18 @@ void calc_lanman_hash(struct cifsSesInfo * ses, char * lnm_session_key)
        int i;
        char password_with_pad[CIFS_ENCPWD_SIZE];
 
+       if(ses->server == NULL)
+               return;
+
        memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
        strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE);
 
+       if((ses->server->secMode & SECMODE_PW_ENCRYPT) == 0)
+               if(extended_security & CIFSSEC_MAY_PLNTXT) {
+                       memcpy(lnm_session_key, password_with_pad, CIFS_ENCPWD_SIZE); 
+                       return;
+               }
+
        /* calculate old style session key */
        /* calling toupper is less broken than repeatedly
        calling nls_toupper would be since that will never
index b8c236be4d85e6ab9b2e31db32b801609af28dce..77cca380946742a7fef62a42e7441576c064913f 100644 (file)
@@ -492,6 +492,13 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
                server->secMode = pSMBr->SecurityMode;
                if((server->secMode & SECMODE_USER) == 0)
                        cFYI(1,("share mode security"));
+
+               if((server->secMode & SECMODE_PW_ENCRYPT) == 0)
+#ifdef CONFIG_CIFS_WEAK_PW_HASH
+                       if ((extended_security & CIFSSEC_MAY_PLNTXT) == 0)
+#endif /* CIFS_WEAK_PW_HASH */
+                               cERROR(1,("Server requests plain text password"
+                                       " but client support disabled"));
                
                if(extended_security & CIFSSEC_MUST_NTLMV2)
                        server->secType = NTLMv2;