librpc/rpc/binding_handle.c cleanups
authorStefan Metzmacher <metze@samba.org>
Sat, 21 Sep 2013 20:00:29 +0000 (22:00 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 4 Jun 2019 11:14:55 +0000 (13:14 +0200)
librpc/rpc/binding_handle.c

index 60b93770a8b4f5f422a0de3e0bfd3aa8f58abb83..c6d905137a3b366f851e22bffbcc81a296101b1d 100644 (file)
@@ -1113,6 +1113,19 @@ static struct tevent_req *dcerpc_binding_handle_call_params_pull_send(TALLOC_CTX
        state->chunk_ptr = chunk_ptr;
        state->is_last_chunk = true;
 
+       if (talloc_total_blocks(chunk_mem) != 1) {
+               /*
+                * As we typically only have autogenerated callers
+                * of this function, we can enforce that chunk_mem
+                * doesn't have any talloc children yet.
+                *
+                * This makes the error handling in the
+                * NDR_ERR_INCOMPLETE_BUFFER case simpler.
+                */
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER_MIX);
+               return tevent_req_post(req, ev);
+       }
+
        tevent_req_defer_callback(req, state->ev);
 
        talloc_set_destructor(state,
@@ -1139,10 +1152,8 @@ static void dcerpc_binding_handle_call_params_pull_notify(struct tevent_req *req
                tevent_req_data(pp->call_req,
                struct dcerpc_binding_handle_call_params_state);
        enum ndr_err_code ndr_err;
+       struct ndr_push *pipe_pull = NULL;
        const uint32_t *count = NULL;
-       uint32_t saved_offset;
-       size_t saved_ndr_blocks;
-       size_t saved_mem_blocks;
 
        if (call_state->pull == NULL) {
                return;
@@ -1152,49 +1163,44 @@ static void dcerpc_binding_handle_call_params_pull_notify(struct tevent_req *req
                return;
        }
 
-       /* pull the structure from the blob */
-       saved_offset = call_state->pull->offset;
-       saved_ndr_blocks = talloc_total_blocks(call_state->pull);
-       saved_mem_blocks = talloc_total_blocks(state->chunk_mem);
+       /*
+        * setup a shallow copy subcontext, which we might destroy
+        */
+       ndr_err = ndr_pull_subcontext_start(call_state->pull, &pipe_pull,
+                                           0xFFFFFFFF, 0);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               NTSTATUS error;
+               error = ndr_map_error2ntstatus(ndr_err);
+               tevent_req_nterror(req, error);
+               return;
+       }
 
-       call_state->pull->current_mem_ctx = state->chunk_mem;
-       ndr_err = call_state->call_pipe->ndr_pull(call_state->pull,
-                                                 NDR_SCALARS|NDR_BUFFERS,
-                                                 state->chunk_ptr);
+       /* pull the structure from the subcontext */
+       pipe_pull->current_mem_ctx = state->chunk_mem;
+       ndr_err = pipe_pull->ndr_pull(pipe_pull,
+                                     NDR_SCALARS|NDR_BUFFERS,
+                                     state->chunk_ptr);
        if (ndr_err == NDR_ERR_INCOMPLETE_BUFFER) {
-               SMB_ASSERT(saved_mem_blocks == 1);
-               SMB_ASSERT(saved_ndr_blocks == talloc_total_blocks(call_state->pull));
+               TALLOC_FREE(pipe_pull);
                talloc_free_children(state->chunk_mem);
-               call_state->pull->offset = saved_offset;
                return;
        }
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                NTSTATUS error;
                error = ndr_map_error2ntstatus(ndr_err);
-               //if (h->ops->ndr_pull_failed) {
-               //      h->ops->ndr_pull_failed(h, error,
-               //                              &state->response,
-               //                              state->call);
-               //}
                tevent_req_nterror(req, error);
                return;
        }
 
-       //if (h->ops->do_ndr_print) {
-       //      h->ops->do_ndr_print(h, NDR_OUT,
-       //                           state->params->r_ptr, state->call);
-       //}
-
-       //if (h->ops->ndr_validate_out) {
-       //      error = h->ops->ndr_validate_out(h,
-       //                                       state->pull,
-       //                                       state->params->r_ptr,
-       //                                       state->call);
-       //      if (!NT_STATUS_IS_OK(error)) {
-       //              tevent_req_nterror(req, error);
-       //              return;
-       //      }
-       //}
+       ndr_err = ndr_pull_subcontext_end(call_state->pull, pipe_pull,
+                                         0xFFFFFFFF, 0);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               NTSTATUS error;
+               error = ndr_map_error2ntstatus(ndr_err);
+               tevent_req_nterror(req, error);
+               return;
+       }
+       TALLOC_FREE(pipe_pull);
 
        ndr_err = ndr_pull_pop(call_state->pull);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {