Fix bug 8429 - Compound SMB2 requests on an IPC connection can corrupt the reply...
authorJeremy Allison <jra@samba.org>
Wed, 31 Aug 2011 00:37:19 +0000 (17:37 -0700)
committerKarolin Seeger <kseeger@samba.org>
Thu, 15 Sep 2011 18:47:32 +0000 (20:47 +0200)
Autobuild-User: Jeremy Allison <jra@samba.org>
Autobuild-Date: Wed Aug 31 21:18:11 CEST 2011 on sn-devel-104
(cherry picked from commit 786fe9fab223723e4d2340f285592b2a44945d73)

source3/smbd/smb2_server.c

index d7a40ed16ecef5c438a889af644ed78173db5948..41ef607e4761c20df106231060f9adf3f499fa45 100644 (file)
@@ -901,7 +901,7 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
 
        /* Don't return an intermediate packet on a pipe read/write. */
        if (req->tcon && req->tcon->compat_conn && IS_IPC(req->tcon->compat_conn)) {
-               return NT_STATUS_OK;
+               goto ipc_out;
        }
 
        reqhdr = (uint8_t *)req->out.vector[i].iov_base;
@@ -990,6 +990,8 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
        /* Note we're going async with this request. */
        req->async = true;
 
+  ipc_out:
+
        /*
         * Now manipulate req so that the outstanding async request
         * is the only one left in the struct smbd_smb2_request.
@@ -1037,19 +1039,22 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
        smb2_setup_nbt_length(req->out.vector,
                req->out.vector_count);
 
-       /* Ensure our final reply matches the interim one. */
-       reqhdr = (uint8_t *)req->out.vector[1].iov_base;
-       SIVAL(reqhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
-       SBVAL(reqhdr, SMB2_HDR_PID, async_id);
+       if (req->async) {
+               /* Ensure our final reply matches the interim one. */
+               reqhdr = (uint8_t *)req->out.vector[1].iov_base;
+               SIVAL(reqhdr, SMB2_HDR_FLAGS, flags | SMB2_HDR_FLAG_ASYNC);
+               SBVAL(reqhdr, SMB2_HDR_PID, async_id);
 
-       {
-               const uint8_t *inhdr =
-                       (const uint8_t *)req->in.vector[1].iov_base;
-               DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
-                       "going async\n",
-                       smb2_opcode_name((uint16_t)IVAL(inhdr, SMB2_HDR_OPCODE)),
-                       (unsigned long long)async_id ));
+               {
+                       const uint8_t *inhdr =
+                               (const uint8_t *)req->in.vector[1].iov_base;
+                       DEBUG(10,("smbd_smb2_request_pending_queue: opcode[%s] mid %llu "
+                               "going async\n",
+                               smb2_opcode_name((uint16_t)IVAL(inhdr, SMB2_HDR_OPCODE)),
+                               (unsigned long long)async_id ));
+               }
        }
+
        return NT_STATUS_OK;
 }