Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 12 Apr 2011 22:24:42 +0000 (15:24 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 12 Apr 2011 22:24:42 +0000 (15:24 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
  cifs: don't allow mmap'ed pages to be dirtied while under writeback (try #3)
  [CIFS] Warn on requesting default security (ntlm) on mount
  [CIFS] cifs: clarify the meaning of tcpStatus == CifsGood
  cifs: wrap received signature check in srv_mutex
  cifs: clean up various nits in unicode routines (try #2)
  cifs: clean up length checks in check2ndT2
  cifs: set ra_pages in backing_dev_info
  cifs: fix broken BCC check in is_valid_oplock_break
  cifs: always do is_path_accessible check in cifs_mount
  various endian fixes to cifs
  Elminate sparse __CHECK_ENDIAN__ warnings on port conversion
  Max share size is too small
  Allow user names longer than 32 bytes
  cifs: replace /proc/fs/cifs/Experimental with a module parm
  cifs: check for private_data before trying to put it

15 files changed:
fs/cifs/README
fs/cifs/cache.c
fs/cifs/cifs_debug.c
fs/cifs/cifs_spnego.c
fs/cifs/cifs_unicode.c
fs/cifs/cifs_unicode.h
fs/cifs/cifsencrypt.c
fs/cifs/cifsfs.c
fs/cifs/cifsglob.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/file.c
fs/cifs/link.c
fs/cifs/misc.c
fs/cifs/sess.c

index fe1683590828a0ed011fa4a2e6ca6cc157292dca..74ab165fc646aea64d873900b64696a2ef35f471 100644 (file)
@@ -685,22 +685,6 @@ LinuxExtensionsEnabled     If set to one then the client will attempt to
                        support and want to map the uid and gid fields 
                        to values supplied at mount (rather than the 
                        actual values, then set this to zero. (default 1)
-Experimental            When set to 1 used to enable certain experimental
-                       features (currently enables multipage writes
-                       when signing is enabled, the multipage write
-                       performance enhancement was disabled when
-                       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).  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 e654dfd092c3a8d0333af9771156898d1c9ed65e..53d57a3fe427c3d94218a7f54b4ab87df3d68031 100644 (file)
@@ -50,7 +50,7 @@ void cifs_fscache_unregister(void)
  */
 struct cifs_server_key {
        uint16_t        family;         /* address family */
-       uint16_t        port;           /* IP port */
+       __be16          port;           /* IP port */
        union {
                struct in_addr  ipv4_addr;
                struct in6_addr ipv6_addr;
index 65829d32128c253a661ecd61dc50f4893bc9f52d..30d01bc9085556bc810ce4d233f358728e6bea44 100644 (file)
@@ -423,7 +423,6 @@ static const struct file_operations cifs_lookup_cache_proc_fops;
 static const struct file_operations traceSMB_proc_fops;
 static const struct file_operations cifs_multiuser_mount_proc_fops;
 static const struct file_operations cifs_security_flags_proc_fops;
-static const struct file_operations cifs_experimental_proc_fops;
 static const struct file_operations cifs_linux_ext_proc_fops;
 
 void
@@ -441,8 +440,6 @@ cifs_proc_init(void)
        proc_create("cifsFYI", 0, proc_fs_cifs, &cifsFYI_proc_fops);
        proc_create("traceSMB", 0, proc_fs_cifs, &traceSMB_proc_fops);
        proc_create("OplockEnabled", 0, proc_fs_cifs, &cifs_oplock_proc_fops);
-       proc_create("Experimental", 0, proc_fs_cifs,
-                   &cifs_experimental_proc_fops);
        proc_create("LinuxExtensionsEnabled", 0, proc_fs_cifs,
                    &cifs_linux_ext_proc_fops);
        proc_create("MultiuserMount", 0, proc_fs_cifs,
@@ -469,7 +466,6 @@ cifs_proc_clean(void)
        remove_proc_entry("OplockEnabled", proc_fs_cifs);
        remove_proc_entry("SecurityFlags", proc_fs_cifs);
        remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs);
-       remove_proc_entry("Experimental", proc_fs_cifs);
        remove_proc_entry("LookupCacheEnabled", proc_fs_cifs);
        remove_proc_entry("fs/cifs", NULL);
 }
@@ -550,45 +546,6 @@ static const struct file_operations cifs_oplock_proc_fops = {
        .write          = cifs_oplock_proc_write,
 };
 
-static int cifs_experimental_proc_show(struct seq_file *m, void *v)
-{
-       seq_printf(m, "%d\n", experimEnabled);
-       return 0;
-}
-
-static int cifs_experimental_proc_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, cifs_experimental_proc_show, NULL);
-}
-
-static ssize_t cifs_experimental_proc_write(struct file *file,
-               const char __user *buffer, size_t count, loff_t *ppos)
-{
-       char c;
-       int rc;
-
-       rc = get_user(c, buffer);
-       if (rc)
-               return rc;
-       if (c == '0' || c == 'n' || c == 'N')
-               experimEnabled = 0;
-       else if (c == '1' || c == 'y' || c == 'Y')
-               experimEnabled = 1;
-       else if (c == '2')
-               experimEnabled = 2;
-
-       return count;
-}
-
-static const struct file_operations cifs_experimental_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = cifs_experimental_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = cifs_experimental_proc_write,
-};
-
 static int cifs_linux_ext_proc_show(struct seq_file *m, void *v)
 {
        seq_printf(m, "%d\n", linuxExtEnabled);
index 4dfba82831654910b3aab62a9803dc95855a52f1..33d221394acae068807adea4eeca47317a821888 100644 (file)
@@ -113,7 +113,7 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
                   MAX_MECH_STR_LEN +
                   UID_KEY_LEN + (sizeof(uid_t) * 2) +
                   CREDUID_KEY_LEN + (sizeof(uid_t) * 2) +
-                  USER_KEY_LEN + strlen(sesInfo->userName) +
+                  USER_KEY_LEN + strlen(sesInfo->user_name) +
                   PID_KEY_LEN + (sizeof(pid_t) * 2) + 1;
 
        spnego_key = ERR_PTR(-ENOMEM);
@@ -153,7 +153,7 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
        sprintf(dp, ";creduid=0x%x", sesInfo->cred_uid);
 
        dp = description + strlen(description);
-       sprintf(dp, ";user=%s", sesInfo->userName);
+       sprintf(dp, ";user=%s", sesInfo->user_name);
 
        dp = description + strlen(description);
        sprintf(dp, ";pid=0x%x", current->pid);
index fc0fd4fde306b989c1593ef11ce2611fd49dca54..23d43cde4306042407dcd3df76d78ab81b793db7 100644 (file)
@@ -90,7 +90,7 @@ cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp,
        case UNI_COLON:
                *target = ':';
                break;
-       case UNI_ASTERIK:
+       case UNI_ASTERISK:
                *target = '*';
                break;
        case UNI_QUESTION:
@@ -264,40 +264,40 @@ cifs_strndup_from_ucs(const char *src, const int maxlen, const bool is_unicode,
  * names are little endian 16 bit Unicode on the wire
  */
 int
-cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
+cifsConvertToUCS(__le16 *target, const char *source, int srclen,
                 const struct nls_table *cp, int mapChars)
 {
        int i, j, charlen;
-       int len_remaining = maxlen;
        char src_char;
-       __u16 temp;
+       __le16 dst_char;
+       wchar_t tmp;
 
        if (!mapChars)
                return cifs_strtoUCS(target, source, PATH_MAX, cp);
 
-       for (i = 0, j = 0; i < maxlen; j++) {
+       for (i = 0, j = 0; i < srclen; j++) {
                src_char = source[i];
                switch (src_char) {
                case 0:
-                       put_unaligned_le16(0, &target[j]);
+                       put_unaligned(0, &target[j]);
                        goto ctoUCS_out;
                case ':':
-                       temp = UNI_COLON;
+                       dst_char = cpu_to_le16(UNI_COLON);
                        break;
                case '*':
-                       temp = UNI_ASTERIK;
+                       dst_char = cpu_to_le16(UNI_ASTERISK);
                        break;
                case '?':
-                       temp = UNI_QUESTION;
+                       dst_char = cpu_to_le16(UNI_QUESTION);
                        break;
                case '<':
-                       temp = UNI_LESSTHAN;
+                       dst_char = cpu_to_le16(UNI_LESSTHAN);
                        break;
                case '>':
-                       temp = UNI_GRTRTHAN;
+                       dst_char = cpu_to_le16(UNI_GRTRTHAN);
                        break;
                case '|':
-                       temp = UNI_PIPE;
+                       dst_char = cpu_to_le16(UNI_PIPE);
                        break;
                /*
                 * FIXME: We can not handle remapping backslash (UNI_SLASH)
@@ -305,17 +305,17 @@ cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
                 * as they use backslash as separator.
                 */
                default:
-                       charlen = cp->char2uni(source+i, len_remaining,
-                                               &temp);
+                       charlen = cp->char2uni(source + i, srclen - i, &tmp);
+                       dst_char = cpu_to_le16(tmp);
+
                        /*
                         * if no match, use question mark, which at least in
                         * some cases serves as wild card
                         */
                        if (charlen < 1) {
-                               temp = 0x003f;
+                               dst_char = cpu_to_le16(0x003f);
                                charlen = 1;
                        }
-                       len_remaining -= charlen;
                        /*
                         * character may take more than one byte in the source
                         * string, but will take exactly two bytes in the
@@ -324,9 +324,8 @@ cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
                        i += charlen;
                        continue;
                }
-               put_unaligned_le16(temp, &target[j]);
+               put_unaligned(dst_char, &target[j]);
                i++; /* move to next char in source string */
-               len_remaining--;
        }
 
 ctoUCS_out:
index 7fe6b52df5076a2eb14a7ec563403795e2e4c041..644dd882a5604c5ed6f900aad2a47478bc31b49a 100644 (file)
@@ -44,7 +44,7 @@
  * reserved symbols (along with \ and /), otherwise illegal to store
  * in filenames in NTFS
  */
-#define UNI_ASTERI    (__u16) ('*' + 0xF000)
+#define UNI_ASTERISK    (__u16) ('*' + 0xF000)
 #define UNI_QUESTION    (__u16) ('?' + 0xF000)
 #define UNI_COLON       (__u16) (':' + 0xF000)
 #define UNI_GRTRTHAN    (__u16) ('>' + 0xF000)
index a51585f9852b4627735e318e83478cbf512c9fbc..d1a016be73ba75c7a70cb099cd5fdb55150926a9 100644 (file)
 #include <linux/ctype.h>
 #include <linux/random.h>
 
-/* Calculate and return the CIFS signature based on the mac key and SMB PDU */
-/* the 16 byte signature must be allocated by the caller  */
-/* Note we only use the 1st eight bytes */
-/* Note that the smb header signature field on input contains the
-       sequence number before this function is called */
-
+/*
+ * Calculate and return the CIFS signature based on the mac key and SMB PDU.
+ * The 16 byte signature must be allocated by the caller. Note we only use the
+ * 1st eight bytes and that the smb header signature field on input contains
+ * the sequence number before this function is called. Also, this function
+ * should be called with the server->srv_mutex held.
+ */
 static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
                                struct TCP_Server_Info *server, char *signature)
 {
@@ -209,8 +210,10 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
                                        cpu_to_le32(expected_sequence_number);
        cifs_pdu->Signature.Sequence.Reserved = 0;
 
+       mutex_lock(&server->srv_mutex);
        rc = cifs_calculate_signature(cifs_pdu, server,
                what_we_think_sig_should_be);
+       mutex_unlock(&server->srv_mutex);
 
        if (rc)
                return rc;
@@ -469,15 +472,15 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, char *ntlmv2_hash,
                return rc;
        }
 
-       /* convert ses->userName to unicode and uppercase */
-       len = strlen(ses->userName);
+       /* convert ses->user_name to unicode and uppercase */
+       len = strlen(ses->user_name);
        user = kmalloc(2 + (len * 2), GFP_KERNEL);
        if (user == NULL) {
                cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n");
                rc = -ENOMEM;
                goto calc_exit_2;
        }
-       len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp);
+       len = cifs_strtoUCS((__le16 *)user, ses->user_name, len, nls_cp);
        UniStrupr(user);
 
        crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
index f2970136d17d06c27e0654bbf4f13e302b3dc815..5c412b33cd7c3ba11d584befbcffd12c210e760c 100644 (file)
@@ -53,7 +53,6 @@ int cifsFYI = 0;
 int cifsERROR = 1;
 int traceSMB = 0;
 unsigned int oplockEnabled = 1;
-unsigned int experimEnabled = 0;
 unsigned int linuxExtEnabled = 1;
 unsigned int lookupCacheEnabled = 1;
 unsigned int multiuser_mount = 0;
@@ -127,6 +126,7 @@ cifs_read_super(struct super_block *sb, void *data,
                kfree(cifs_sb);
                return rc;
        }
+       cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages;
 
 #ifdef CONFIG_CIFS_DFS_UPCALL
        /* copy mount params to sb for use in submounts */
@@ -409,8 +409,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
 
        if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)
                seq_printf(s, ",multiuser");
-       else if (tcon->ses->userName)
-               seq_printf(s, ",username=%s", tcon->ses->userName);
+       else if (tcon->ses->user_name)
+               seq_printf(s, ",username=%s", tcon->ses->user_name);
 
        if (tcon->ses->domainName)
                seq_printf(s, ",domain=%s", tcon->ses->domainName);
index 17afb0fbcaed362b85935d43d12702f8e815efb5..a5d1106fcbde82ea8b5ab5f61de9a29dc72148d2 100644 (file)
 
 #define MAX_TREE_SIZE (2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1)
 #define MAX_SERVER_SIZE 15
-#define MAX_SHARE_SIZE  64     /* used to be 20, this should still be enough */
-#define MAX_USERNAME_SIZE 32   /* 32 is to allow for 15 char names + null
-                                  termination then *2 for unicode versions */
-#define MAX_PASSWORD_SIZE 512  /* max for windows seems to be 256 wide chars */
+#define MAX_SHARE_SIZE 80
+#define MAX_USERNAME_SIZE 256  /* reasonable maximum for current servers */
+#define MAX_PASSWORD_SIZE 512  /* max for windows seems to be 256 wide chars */
 
 #define CIFS_MIN_RCV_POOL 4
 
@@ -92,7 +91,8 @@ enum statusEnum {
        CifsNew = 0,
        CifsGood,
        CifsExiting,
-       CifsNeedReconnect
+       CifsNeedReconnect,
+       CifsNeedNegotiate
 };
 
 enum securityEnum {
@@ -274,7 +274,7 @@ struct cifsSesInfo {
        int capabilities;
        char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for
                                TCP names - will ipv6 and sctp addresses fit? */
-       char userName[MAX_USERNAME_SIZE + 1];
+       char *user_name;
        char *domainName;
        char *password;
        struct session_key auth_key;
@@ -817,7 +817,6 @@ GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions
                                have the uid/password or Kerberos credential
                                or equivalent for current user */
 GLOBAL_EXTERN unsigned int oplockEnabled;
-GLOBAL_EXTERN unsigned int experimEnabled;
 GLOBAL_EXTERN unsigned int lookupCacheEnabled;
 GLOBAL_EXTERN unsigned int global_secflags;    /* if on, session setup sent
                                with more secure ntlmssp2 challenge/resp */
index 2644a5d6cc67d91002810da3d7f05c3d4be11b5a..df959bae67281597a2c1b4ce643eb3893b0e6ee2 100644 (file)
@@ -142,9 +142,9 @@ cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
         */
        while (server->tcpStatus == CifsNeedReconnect) {
                wait_event_interruptible_timeout(server->response_q,
-                       (server->tcpStatus == CifsGood), 10 * HZ);
+                       (server->tcpStatus != CifsNeedReconnect), 10 * HZ);
 
-               /* is TCP session is reestablished now ?*/
+               /* are we still trying to reconnect? */
                if (server->tcpStatus != CifsNeedReconnect)
                        break;
 
@@ -729,7 +729,7 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
                return rc;
 
        /* set up echo request */
-       smb->hdr.Tid = cpu_to_le16(0xffff);
+       smb->hdr.Tid = 0xffff;
        smb->hdr.WordCount = 1;
        put_unaligned_le16(1, &smb->EchoCount);
        put_bcc_le(1, &smb->hdr);
@@ -1884,10 +1884,10 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
                                        __constant_cpu_to_le16(CIFS_WRLCK))
                                pLockData->fl_type = F_WRLCK;
 
-                       pLockData->fl_start = parm_data->start;
-                       pLockData->fl_end = parm_data->start +
-                                               parm_data->length - 1;
-                       pLockData->fl_pid = parm_data->pid;
+                       pLockData->fl_start = le64_to_cpu(parm_data->start);
+                       pLockData->fl_end = pLockData->fl_start +
+                                       le64_to_cpu(parm_data->length) - 1;
+                       pLockData->fl_pid = le32_to_cpu(parm_data->pid);
                }
        }
 
index 6e2b2addfc78a184ca6663fcc528c2f242e1056b..db9d55b507d0afe36b816889165975edd3a7198b 100644 (file)
@@ -199,8 +199,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
        }
        spin_unlock(&GlobalMid_Lock);
 
-       while ((server->tcpStatus != CifsExiting) &&
-              (server->tcpStatus != CifsGood)) {
+       while (server->tcpStatus == CifsNeedReconnect) {
                try_to_freeze();
 
                /* we should try only the port we connected to before */
@@ -212,7 +211,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
                        atomic_inc(&tcpSesReconnectCount);
                        spin_lock(&GlobalMid_Lock);
                        if (server->tcpStatus != CifsExiting)
-                               server->tcpStatus = CifsGood;
+                               server->tcpStatus = CifsNeedNegotiate;
                        spin_unlock(&GlobalMid_Lock);
                }
        }
@@ -248,24 +247,24 @@ static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
        total_data_size = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount);
        data_in_this_rsp = get_unaligned_le16(&pSMBt->t2_rsp.DataCount);
 
-       remaining = total_data_size - data_in_this_rsp;
-
-       if (remaining == 0)
+       if (total_data_size == data_in_this_rsp)
                return 0;
-       else if (remaining < 0) {
+       else if (total_data_size < data_in_this_rsp) {
                cFYI(1, "total data %d smaller than data in frame %d",
                        total_data_size, data_in_this_rsp);
                return -EINVAL;
-       } else {
-               cFYI(1, "missing %d bytes from transact2, check next response",
-                       remaining);
-               if (total_data_size > maxBufSize) {
-                       cERROR(1, "TotalDataSize %d is over maximum buffer %d",
-                               total_data_size, maxBufSize);
-                       return -EINVAL;
-               }
-               return remaining;
        }
+
+       remaining = total_data_size - data_in_this_rsp;
+
+       cFYI(1, "missing %d bytes from transact2, check next response",
+               remaining);
+       if (total_data_size > maxBufSize) {
+               cERROR(1, "TotalDataSize %d is over maximum buffer %d",
+                       total_data_size, maxBufSize);
+               return -EINVAL;
+       }
+       return remaining;
 }
 
 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
@@ -421,7 +420,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
                pdu_length = 4; /* enough to get RFC1001 header */
 
 incomplete_rcv:
-               if (echo_retries > 0 &&
+               if (echo_retries > 0 && server->tcpStatus == CifsGood &&
                    time_after(jiffies, server->lstrp +
                                        (echo_retries * SMB_ECHO_INTERVAL))) {
                        cERROR(1, "Server %s has not responded in %d seconds. "
@@ -881,7 +880,8 @@ cifs_parse_mount_options(char *options, const char *devname,
                                /* null user, ie anonymous, authentication */
                                vol->nullauth = 1;
                        }
-                       if (strnlen(value, 200) < 200) {
+                       if (strnlen(value, MAX_USERNAME_SIZE) <
+                                               MAX_USERNAME_SIZE) {
                                vol->username = value;
                        } else {
                                printk(KERN_WARNING "CIFS: username too long\n");
@@ -1472,7 +1472,7 @@ srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
 static bool
 match_port(struct TCP_Server_Info *server, struct sockaddr *addr)
 {
-       unsigned short int port, *sport;
+       __be16 port, *sport;
 
        switch (addr->sa_family) {
        case AF_INET:
@@ -1765,6 +1765,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
                module_put(THIS_MODULE);
                goto out_err_crypto_release;
        }
+       tcp_ses->tcpStatus = CifsNeedNegotiate;
 
        /* thread spawned, put it on the list */
        spin_lock(&cifs_tcp_ses_lock);
@@ -1808,7 +1809,9 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
                        break;
                default:
                        /* anything else takes username/password */
-                       if (strncmp(ses->userName, vol->username,
+                       if (ses->user_name == NULL)
+                               continue;
+                       if (strncmp(ses->user_name, vol->username,
                                    MAX_USERNAME_SIZE))
                                continue;
                        if (strlen(vol->username) != 0 &&
@@ -1851,6 +1854,8 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
        cifs_put_tcp_session(server);
 }
 
+static bool warned_on_ntlm;  /* globals init to false automatically */
+
 static struct cifsSesInfo *
 cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
 {
@@ -1906,9 +1911,11 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
        else
                sprintf(ses->serverName, "%pI4", &addr->sin_addr);
 
-       if (volume_info->username)
-               strncpy(ses->userName, volume_info->username,
-                       MAX_USERNAME_SIZE);
+       if (volume_info->username) {
+               ses->user_name = kstrdup(volume_info->username, GFP_KERNEL);
+               if (!ses->user_name)
+                       goto get_ses_fail;
+       }
 
        /* volume_info->password freed at unmount */
        if (volume_info->password) {
@@ -1923,6 +1930,15 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
        }
        ses->cred_uid = volume_info->cred_uid;
        ses->linux_uid = volume_info->linux_uid;
+
+       /* ntlmv2 is much stronger than ntlm security, and has been broadly
+       supported for many years, time to update default security mechanism */
+       if ((volume_info->secFlg == 0) && warned_on_ntlm == false) {
+               warned_on_ntlm = true;
+               cERROR(1, "default security mechanism requested.  The default "
+                       "security mechanism will be upgraded from ntlm to "
+                       "ntlmv2 in kernel release 2.6.41");
+       }
        ses->overrideSecFlg = volume_info->secFlg;
 
        mutex_lock(&ses->session_mutex);
@@ -2276,7 +2292,7 @@ static int
 generic_ip_connect(struct TCP_Server_Info *server)
 {
        int rc = 0;
-       unsigned short int sport;
+       __be16 sport;
        int slen, sfamily;
        struct socket *socket = server->ssocket;
        struct sockaddr *saddr;
@@ -2361,7 +2377,7 @@ generic_ip_connect(struct TCP_Server_Info *server)
 static int
 ip_connect(struct TCP_Server_Info *server)
 {
-       unsigned short int *sport;
+       __be16 *sport;
        struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
        struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
 
@@ -2826,7 +2842,7 @@ try_mount_again:
 
 remote_path_check:
        /* check if a whole path (including prepath) is not remote */
-       if (!rc && cifs_sb->prepathlen && tcon) {
+       if (!rc && tcon) {
                /* build_path_to_root works only when we have a valid tcon */
                full_path = cifs_build_path_to_root(cifs_sb, tcon);
                if (full_path == NULL) {
index c27d236738fc08ff80d32eceabc8f412140afbb2..faf59529e847a2adceb9728d10e739adc822f1f5 100644 (file)
@@ -575,8 +575,10 @@ reopen_error_exit:
 
 int cifs_close(struct inode *inode, struct file *file)
 {
-       cifsFileInfo_put(file->private_data);
-       file->private_data = NULL;
+       if (file->private_data != NULL) {
+               cifsFileInfo_put(file->private_data);
+               file->private_data = NULL;
+       }
 
        /* return code from the ->release op is always ignored */
        return 0;
@@ -970,6 +972,9 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
             total_written += bytes_written) {
                rc = -EAGAIN;
                while (rc == -EAGAIN) {
+                       struct kvec iov[2];
+                       unsigned int len;
+
                        if (open_file->invalidHandle) {
                                /* we could deadlock if we called
                                   filemap_fdatawait from here so tell
@@ -979,31 +984,14 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
                                if (rc != 0)
                                        break;
                        }
-                       if (experimEnabled || (pTcon->ses->server &&
-                               ((pTcon->ses->server->secMode &
-                               (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
-                               == 0))) {
-                               struct kvec iov[2];
-                               unsigned int len;
-
-                               len = min((size_t)cifs_sb->wsize,
-                                         write_size - total_written);
-                               /* iov[0] is reserved for smb header */
-                               iov[1].iov_base = (char *)write_data +
-                                                 total_written;
-                               iov[1].iov_len = len;
-                               rc = CIFSSMBWrite2(xid, pTcon,
-                                               open_file->netfid, len,
-                                               *poffset, &bytes_written,
-                                               iov, 1, 0);
-                       } else
-                               rc = CIFSSMBWrite(xid, pTcon,
-                                        open_file->netfid,
-                                        min_t(const int, cifs_sb->wsize,
-                                              write_size - total_written),
-                                        *poffset, &bytes_written,
-                                        write_data + total_written,
-                                        NULL, 0);
+
+                       len = min((size_t)cifs_sb->wsize,
+                                 write_size - total_written);
+                       /* iov[0] is reserved for smb header */
+                       iov[1].iov_base = (char *)write_data + total_written;
+                       iov[1].iov_len = len;
+                       rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, len,
+                                          *poffset, &bytes_written, iov, 1, 0);
                }
                if (rc || (bytes_written == 0)) {
                        if (total_written)
@@ -1240,12 +1228,6 @@ static int cifs_writepages(struct address_space *mapping,
        }
 
        tcon = tlink_tcon(open_file->tlink);
-       if (!experimEnabled && tcon->ses->server->secMode &
-                       (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
-               cifsFileInfo_put(open_file);
-               kfree(iov);
-               return generic_writepages(mapping, wbc);
-       }
        cifsFileInfo_put(open_file);
 
        xid = GetXid();
@@ -1980,6 +1962,24 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
        return total_read;
 }
 
+/*
+ * If the page is mmap'ed into a process' page tables, then we need to make
+ * sure that it doesn't change while being written back.
+ */
+static int
+cifs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+       struct page *page = vmf->page;
+
+       lock_page(page);
+       return VM_FAULT_LOCKED;
+}
+
+static struct vm_operations_struct cifs_file_vm_ops = {
+       .fault = filemap_fault,
+       .page_mkwrite = cifs_page_mkwrite,
+};
+
 int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma)
 {
        int rc, xid;
@@ -1991,6 +1991,8 @@ int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma)
                cifs_invalidate_mapping(inode);
 
        rc = generic_file_mmap(file, vma);
+       if (rc == 0)
+               vma->vm_ops = &cifs_file_vm_ops;
        FreeXid(xid);
        return rc;
 }
@@ -2007,6 +2009,8 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
                return rc;
        }
        rc = generic_file_mmap(file, vma);
+       if (rc == 0)
+               vma->vm_ops = &cifs_file_vm_ops;
        FreeXid(xid);
        return rc;
 }
index e8804d3734044f578da6d4427e4961431d61ae5a..ce417a9764a3fe5c3963e1e93fe5e5b17bf7390c 100644 (file)
@@ -239,7 +239,7 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
        if (rc != 0)
                return rc;
 
-       if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
+       if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
                CIFSSMBClose(xid, tcon, netfid);
                /* it's not a symlink */
                return -EINVAL;
@@ -316,7 +316,7 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
        if (rc != 0)
                goto out;
 
-       if (file_info.EndOfFile != CIFS_MF_SYMLINK_FILE_SIZE) {
+       if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
                CIFSSMBClose(xid, pTcon, netfid);
                /* it's not a symlink */
                goto out;
index 2a930a752a784faea9ee912211c3f7a88e1ce9d5..0c684ae4c07163140f4d9009b2d2ccd1f0c86dd2 100644 (file)
@@ -100,6 +100,7 @@ sesInfoFree(struct cifsSesInfo *buf_to_free)
                memset(buf_to_free->password, 0, strlen(buf_to_free->password));
                kfree(buf_to_free->password);
        }
+       kfree(buf_to_free->user_name);
        kfree(buf_to_free->domainName);
        kfree(buf_to_free);
 }
@@ -520,7 +521,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
                        (struct smb_com_transaction_change_notify_rsp *)buf;
                struct file_notify_information *pnotify;
                __u32 data_offset = 0;
-               if (pSMBr->ByteCount > sizeof(struct file_notify_information)) {
+               if (get_bcc_le(buf) > sizeof(struct file_notify_information)) {
                        data_offset = le32_to_cpu(pSMBr->DataOffset);
 
                        pnotify = (struct file_notify_information *)
index 16765703131be6288e41f0d22d6994ffe3d7685f..f6728eb6f4b94774431136a8700ce9e96b4d2940 100644 (file)
@@ -219,12 +219,12 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
                bcc_ptr++;
        } */
        /* copy user */
-       if (ses->userName == NULL) {
+       if (ses->user_name == NULL) {
                /* null user mount */
                *bcc_ptr = 0;
                *(bcc_ptr+1) = 0;
        } else {
-               bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,
+               bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->user_name,
                                          MAX_USERNAME_SIZE, nls_cp);
        }
        bcc_ptr += 2 * bytes_ret;
@@ -244,12 +244,11 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
        /* copy user */
        /* BB what about null user mounts - check that we do this BB */
        /* copy user */
-       if (ses->userName == NULL) {
-               /* BB what about null user mounts - check that we do this BB */
-       } else {
-               strncpy(bcc_ptr, ses->userName, MAX_USERNAME_SIZE);
-       }
-       bcc_ptr += strnlen(ses->userName, MAX_USERNAME_SIZE);
+       if (ses->user_name != NULL)
+               strncpy(bcc_ptr, ses->user_name, MAX_USERNAME_SIZE);
+       /* else null user mount */
+
+       bcc_ptr += strnlen(ses->user_name, MAX_USERNAME_SIZE);
        *bcc_ptr = 0;
        bcc_ptr++; /* account for null termination */
 
@@ -405,8 +404,8 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
        /* BB spec says that if AvId field of MsvAvTimestamp is populated then
                we must set the MIC field of the AUTHENTICATE_MESSAGE */
        ses->ntlmssp->server_flags = le32_to_cpu(pblob->NegotiateFlags);
-       tioffset = cpu_to_le16(pblob->TargetInfoArray.BufferOffset);
-       tilen = cpu_to_le16(pblob->TargetInfoArray.Length);
+       tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset);
+       tilen = le16_to_cpu(pblob->TargetInfoArray.Length);
        if (tilen) {
                ses->auth_key.response = kmalloc(tilen, GFP_KERNEL);
                if (!ses->auth_key.response) {
@@ -523,14 +522,14 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
                tmp += len;
        }
 
-       if (ses->userName == NULL) {
+       if (ses->user_name == NULL) {
                sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
                sec_blob->UserName.Length = 0;
                sec_blob->UserName.MaximumLength = 0;
                tmp += 2;
        } else {
                int len;
-               len = cifs_strtoUCS((__le16 *)tmp, ses->userName,
+               len = cifs_strtoUCS((__le16 *)tmp, ses->user_name,
                                    MAX_USERNAME_SIZE, nls_cp);
                len *= 2; /* unicode is 2 bytes each */
                sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
This page took 0.039936 seconds and 5 git commands to generate.