smb2_create: simplify smbd_smb2_create_request_dispatch_immediate() logic
authorStefan Metzmacher <metze@samba.org>
Mon, 1 Mar 2021 12:58:30 +0000 (13:58 +0100)
committerStefan Metzmacher <metze@samba.org>
Wed, 8 Feb 2023 09:29:17 +0000 (10:29 +0100)
'state->im' should always be a talloc child of 'state', everthing else
is too complex. With that we can move tevent_req_set_callback(req, NULL, NULL)
right before smbd_smb2_request_dispatch().

It's simpler to allocate state->im early. Then we can rely on
tevent_schedule_immediate() to never fail and simplify it's usage.

tevent_schedule_immediate() with a NULL handler can deactivate the
event without doing a TALLOC_FREE().

Signed-off-by: Stefan Metzmacher <metze@samba.org>
source3/smbd/smb2_create.c

index 0f18d5594a46f6541ce3d36fe007a7e93ede15c4..beeca2ef1a2c7b6eb0dbf75345a976ed279ab2ce 100644 (file)
@@ -734,6 +734,11 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
                .in_create_disposition = in_create_disposition,
        };
 
+       state->im = tevent_create_immediate(state);
+       if (tevent_req_nomem(state->im, req)) {
+               return tevent_req_post(req, state->ev);
+       }
+
        smb1req = smbd_smb2_fake_smb_request(smb2req);
        if (tevent_req_nomem(smb1req, req)) {
                return tevent_req_post(req, state->ev);
@@ -1847,7 +1852,7 @@ static void remove_deferred_open_message_smb2_internal(struct smbd_smb2_request
 
        state->open_was_deferred = false;
        /* Ensure we don't have any outstanding immediate event. */
-       TALLOC_FREE(state->im);
+       tevent_schedule_immediate(state->im, state->ev, NULL, NULL);
        TALLOC_FREE(state->open_rec);
 }
 
@@ -1871,14 +1876,32 @@ static void smbd_smb2_create_request_dispatch_immediate(struct tevent_context *c
                                        struct tevent_immediate *im,
                                        void *private_data)
 {
-       struct smbd_smb2_request *smb2req = talloc_get_type_abort(private_data,
-                                       struct smbd_smb2_request);
+       struct tevent_req *req =
+               talloc_get_type_abort(private_data,
+               struct tevent_req);
+       struct smbd_smb2_create_state *state =
+               tevent_req_data(req,
+               struct smbd_smb2_create_state);
+       struct smbd_smb2_request *smb2req = state->smb2req;
        uint64_t mid = get_mid_from_smb2req(smb2req);
        NTSTATUS status;
 
-       DEBUG(10,("smbd_smb2_create_request_dispatch_immediate: "
-               "re-dispatching mid %llu\n",
-               (unsigned long long)mid ));
+       SMB_ASSERT(smb2req->subreq == req);
+
+       /*
+        * This is subtle. We must null out the callback
+        * before re-dispatching, else the first call to
+        * tevent_req_nterror() causes the _receive()
+        * function to be called, this causing tevent_req_post()
+        * to crash.
+        */
+       tevent_req_set_callback(req, NULL, NULL);
+       req = NULL;
+       state = NULL;
+
+       DBG_DEBUG("re-dispatching mid %llu on channel_id %llu\n",
+                 (unsigned long long)mid,
+                 (unsigned long long)smb2req->xconn->channel_id);
 
        status = smbd_smb2_request_dispatch(smb2req);
        if (!NT_STATUS_IS_OK(status)) {
@@ -1914,33 +1937,14 @@ bool schedule_deferred_open_message_smb2(
                return false;
        }
 
-       /* Ensure we don't have any outstanding immediate event. */
-       TALLOC_FREE(state->im);
-
-       /*
-        * This is subtle. We must null out the callback
-        * before rescheduling, else the first call to
-        * tevent_req_nterror() causes the _receive()
-        * function to be called, this causing tevent_req_post()
-        * to crash.
-        */
-       tevent_req_set_callback(smb2req->subreq, NULL, NULL);
-
-       state->im = tevent_create_immediate(smb2req);
-       if (!state->im) {
-               smbd_server_connection_terminate(smb2req->xconn,
-                       nt_errstr(NT_STATUS_NO_MEMORY));
-               return false;
-       }
-
-       DEBUG(10,("schedule_deferred_open_message_smb2: "
-               "re-processing mid %llu\n",
-               (unsigned long long)mid ));
+       DBG_DEBUG("re-dispatching mid %llu on channel_id %llu\n",
+                 (unsigned long long)mid,
+                 (unsigned long long)smb2req->xconn->channel_id);
 
        tevent_schedule_immediate(state->im,
-                       smb2req->sconn->ev_ctx,
-                       smbd_smb2_create_request_dispatch_immediate,
-                       smb2req);
+                                 state->ev,
+                                 smbd_smb2_create_request_dispatch_immediate,
+                                 smb2req->subreq);
 
        return true;
 }