Fix bug #9572 - File corruption during SMB1 read by Mac OSX 10.8.2 clients.
authorJeremy Allison <jra@samba.org>
Wed, 23 Jan 2013 17:57:50 +0000 (09:57 -0800)
committerKarolin Seeger <kseeger@samba.org>
Mon, 28 Jan 2013 10:07:38 +0000 (11:07 +0100)
Accept a large read if we told the client we have UNIX extensions
and the client sent a non-zero upper 16-bit size.

Do the non-zero upper 16-bit size check first to save a function
call in what is a hot path.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Thu Jan 24 21:01:51 CET 2013 on sn-devel-104
(cherry picked from commit 996a10cdea4a1ea23bc86c8bc57c4ca02e285b17)

source3/smbd/reply.c

index e64ef13a360c2a088be7268a263f4868e59cfc31..e3c09cad742645525f238bc2713ff63ab527b4db 100644 (file)
@@ -3848,6 +3848,26 @@ nosendfile_read:
        return;
 }
 
+/****************************************************************************
+ MacOSX clients send large reads without telling us they are going to do that.
+ Bug #9572 - File corruption during SMB1 read by Mac OSX 10.8.2 clients
+ Allow this if we are talking to a Samba client, or if we told the client
+ we supported this.
+****************************************************************************/
+
+static bool server_will_accept_large_read(void)
+{
+       /* Samba client ? No problem. */
+       if (get_remote_arch() == RA_SAMBA) {
+               return true;
+       }
+       /* Need UNIX extensions. */
+       if (!lp_unix_extensions()) {
+               return false;
+       }
+       return true;
+}
+
 /****************************************************************************
  Reply to a read and X.
 ****************************************************************************/
@@ -3858,6 +3878,7 @@ void reply_read_and_X(struct smb_request *req)
        files_struct *fsp;
        off_t startpos;
        size_t smb_maxcnt;
+       size_t upper_size;
        bool big_readX = False;
 #if 0
        size_t smb_mincnt = SVAL(req->vwv+6, 0);
@@ -3892,8 +3913,15 @@ void reply_read_and_X(struct smb_request *req)
                return;
        }
 
-       if (global_client_caps & CAP_LARGE_READX) {
-               size_t upper_size = SVAL(req->vwv+7, 0);
+       upper_size = SVAL(req->vwv+7, 0);
+       if ((upper_size != 0) && server_will_accept_large_read()) {
+               /*
+                * This is Samba only behavior (up to Samba 3.6)!
+                *
+                * Windows 2008 R2 ignores the upper_size,
+                * so we do unless unix extentions are active
+                * or "smbclient" is talking to us.
+                */
                smb_maxcnt |= (upper_size<<16);
                if (upper_size > 1) {
                        /* Can't do this on a chained packet. */