[PATCH] CIFS: CIFSSMBRead was returning an invalid pointer in buf on socket error
[sfrench/cifs-2.6.git] / fs / cifs / connect.c
index 45c9d726c0021b71abd5c16ab48e45d785d54042..ef5ae6f93c75daa4129128095a0cd0c490d949da 100644 (file)
@@ -76,6 +76,7 @@ struct smb_vol {
        unsigned setuids:1;
        unsigned noperm:1;
        unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
+       unsigned cifs_acl:1;
        unsigned no_xattr:1;   /* set if xattr (EA) support should be disabled*/
        unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
        unsigned direct_io:1;
@@ -1159,6 +1160,10 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
                        vol->server_ino = 1;
                } else if (strnicmp(data, "noserverino",9) == 0) {
                        vol->server_ino = 0;
+               } else if (strnicmp(data, "cifsacl",7) == 0) {
+                       vol->cifs_acl = 1;
+               } else if (strnicmp(data, "nocifsacl", 9) == 0) {
+                       vol->cifs_acl = 0;
                } else if (strnicmp(data, "acl",3) == 0) {
                        vol->no_psx_acl = 0;
                } else if (strnicmp(data, "noacl",5) == 0) {
@@ -1780,17 +1785,27 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                } else if(volume_info.wsize)
                        cifs_sb->wsize = volume_info.wsize;
                else
-                       cifs_sb->wsize = CIFSMaxBufSize; /* default */
-               if(cifs_sb->rsize < PAGE_CACHE_SIZE) {
-                       cifs_sb->rsize = PAGE_CACHE_SIZE; 
-                       /* Windows ME does this */
-                       cFYI(1,("Attempt to set readsize for mount to less than one page (4096)"));
+                       cifs_sb->wsize = 
+                               min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
+                                       127*1024);
+                       /* old default of CIFSMaxBufSize was too small now
+                          that SMB Write2 can send multiple pages in kvec.   
+                          RFC1001 does not describe what happens when frame
+                          bigger than 128K is sent so use that as max in
+                          conjunction with 52K kvec constraint on arch with 4K
+                          page size  */
+
+               if(cifs_sb->rsize < 2048) {
+                       cifs_sb->rsize = 2048; 
+                       /* Windows ME may prefer this */
+                       cFYI(1,("readsize set to minimum 2048"));
                }
                cifs_sb->mnt_uid = volume_info.linux_uid;
                cifs_sb->mnt_gid = volume_info.linux_gid;
                cifs_sb->mnt_file_mode = volume_info.file_mode;
                cifs_sb->mnt_dir_mode = volume_info.dir_mode;
-               cFYI(1,("file mode: 0x%x  dir mode: 0x%x",cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
+               cFYI(1,("file mode: 0x%x  dir mode: 0x%x",
+                       cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
 
                if(volume_info.noperm)
                        cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
@@ -1806,6 +1821,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
                        cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
                if(volume_info.nobrl)
                        cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
+               if(volume_info.cifs_acl)
+                       cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
 
                if(volume_info.direct_io) {
                        cFYI(1,("mounting share using direct i/o"));
@@ -1965,7 +1982,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
        __u32 capabilities;
        __u16 count;
 
-       cFYI(1, ("In sesssetup "));
+       cFYI(1, ("In sesssetup"));
        if(ses == NULL)
                return -EINVAL;
        user = ses->userName;
@@ -3241,9 +3258,26 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
 
        pSMB->AndXCommand = 0xFF;
        pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
-       pSMB->PasswordLength = cpu_to_le16(1);  /* minimum */
        bcc_ptr = &pSMB->Password[0];
-       bcc_ptr++;              /* skip password */
+       if((ses->server->secMode) & SECMODE_USER) {
+               pSMB->PasswordLength = cpu_to_le16(1);  /* minimum */
+               bcc_ptr++;              /* skip password */
+       } else {
+               pSMB->PasswordLength = cpu_to_le16(CIFS_SESSION_KEY_SIZE);
+               /* BB FIXME add code to fail this if NTLMv2 or Kerberos
+                  specified as required (when that support is added to
+                  the vfs in the future) as only NTLM or the much
+                  weaker LANMAN (which we do not send) is accepted
+                  by Samba (not sure whether other servers allow
+                  NTLMv2 password here) */
+               SMBNTencrypt(ses->password,
+                            ses->server->cryptKey,
+                            bcc_ptr);
+
+               bcc_ptr += CIFS_SESSION_KEY_SIZE;
+               *bcc_ptr = 0;
+               bcc_ptr++; /* align */
+       }
 
        if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
                smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
@@ -3261,7 +3295,6 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
                bcc_ptr += 2 * length;  /* convert num of 16 bit words to bytes */
                bcc_ptr += 2;   /* skip trailing null */
        } else {                /* ASCII */
-
                strcpy(bcc_ptr, tree);
                bcc_ptr += strlen(tree) + 1;
        }