s3/smbd: enable processing SMB2 requests async internally
authorRalph Boehme <slow@samba.org>
Wed, 11 Jan 2017 14:00:24 +0000 (15:00 +0100)
committerJeremy Allison <jra@samba.org>
Tue, 18 Apr 2017 20:54:16 +0000 (22:54 +0200)
The idea is to allow the implementation of an SMB2 request to tell the
main SMB2 processing engine that it wants to handle a requests
asynchronously internally.

This has two use cases:

- it allows (internal) async processing of compound requests that would
  otherwise be rejected by the SMB2 processing engine

- it preserves sync semantics at the SMB layer, some clients might not
  expect arbitrary SMB2 requests going async

Not used for now, will be used in laters commit for async SMB2 FIND
requests.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
source3/smbd/globals.h
source3/smbd/smb2_server.c

index 22e364c71f7d95353a74f385a5f146d6badda7b9..ae5ecf40138910317037aa2bfae94956d3b4b349 100644 (file)
@@ -276,6 +276,9 @@ NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
 NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
                                        size_t expected_body_size);
 
+void smb2_request_set_async_internal(struct smbd_smb2_request *req,
+                                    bool async_internal);
+
 enum protocol_types smbd_smb2_protocol_dialect_match(const uint8_t *indyn,
                                                     const int dialect_count,
                                                     uint16_t *dialect);
@@ -707,6 +710,13 @@ struct smbd_smb2_request {
        struct tevent_timer *async_te;
        bool compound_related;
 
+       /*
+        * Give the implementation of an SMB2 req a way to tell the SMB2 request
+        * processing engine that the internal request is going async, while
+        * preserving synchronous SMB2 behaviour.
+        */
+       bool async_internal;
+
        /*
         * the encryption key for the whole
         * compound chain
index acaa0126dd8ad118ddc85f024fb93cf223df1b41..d95631f2ff4d56407f0a59450ea28bcdceb6ede9 100644 (file)
@@ -272,6 +272,12 @@ static int smbd_smb2_request_destructor(struct smbd_smb2_request *req)
        return 0;
 }
 
+void smb2_request_set_async_internal(struct smbd_smb2_request *req,
+                                    bool async_internal)
+{
+       req->async_internal = async_internal;
+}
+
 static struct smbd_smb2_request *smbd_smb2_request_allocate(TALLOC_CTX *mem_ctx)
 {
        TALLOC_CTX *mem_pool;
@@ -1365,6 +1371,17 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
                return NT_STATUS_OK;
        }
 
+       if (req->async_internal) {
+               /*
+                * An SMB2 request implementation wants to handle the request
+                * asynchronously "internally" while keeping synchronous
+                * behaviour for the SMB2 request. This means we don't send an
+                * interim response and we can allow processing of compound SMB2
+                * requests (cf the subsequent check) for all cases.
+                */
+               return NT_STATUS_OK;
+       }
+
        if (req->in.vector_count > req->current_idx + SMBD_SMB2_NUM_IOV_PER_REQ) {
                /*
                 * We're trying to go async in a compound request
@@ -2292,6 +2309,7 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
                encryption_required = x->global->encryption_flags & SMBXSRV_ENCRYPTION_REQUIRED;
        }
 
+       req->async_internal = false;
        req->do_signing = false;
        req->do_encryption = false;
        req->was_encrypted = false;