librpc/rpc: add dcerpc_binding_handle_call_params*
authorStefan Metzmacher <metze@samba.org>
Fri, 1 Oct 2010 06:54:54 +0000 (08:54 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 4 Jun 2019 11:14:55 +0000 (13:14 +0200)
This function will allow to add dcerpc pipes support later.

metze

librpc/rpc/binding_handle.c
librpc/rpc/rpc_common.h

index bb5245772e1ca75fc578bf5d573582a44a7287c0..c42b4e9900cacee5013c55d756d81f5927a9925e 100644 (file)
@@ -344,35 +344,33 @@ NTSTATUS dcerpc_binding_handle_disconnect_recv(struct tevent_req *req)
        return NT_STATUS_OK;
 }
 
-struct dcerpc_binding_handle_call_state {
+struct dcerpc_binding_handle_call_params_state {
        struct dcerpc_binding_handle *h;
        const struct ndr_interface_call *call;
-       TALLOC_CTX *r_mem;
-       void *r_ptr;
+       struct dcerpc_binding_handle_call_params *params;
        struct ndr_push *push;
        DATA_BLOB request;
        DATA_BLOB response;
        struct ndr_pull *pull;
 };
 
-static void dcerpc_binding_handle_call_done(struct tevent_req *subreq);
+static void dcerpc_binding_handle_call_params_done(struct tevent_req *subreq);
 
-struct tevent_req *dcerpc_binding_handle_call_send(TALLOC_CTX *mem_ctx,
-                                       struct tevent_context *ev,
-                                       struct dcerpc_binding_handle *h,
-                                       const struct GUID *object,
-                                       const struct ndr_interface_table *table,
-                                       uint32_t opnum,
-                                       TALLOC_CTX *r_mem,
-                                       void *r_ptr)
+struct tevent_req *dcerpc_binding_handle_call_params_send(TALLOC_CTX *mem_ctx,
+                               struct tevent_context *ev,
+                               struct dcerpc_binding_handle *h,
+                               const struct GUID *object,
+                               const struct ndr_interface_table *table,
+                               uint32_t opnum,
+                               struct dcerpc_binding_handle_call_params *params)
 {
        struct tevent_req *req;
-       struct dcerpc_binding_handle_call_state *state;
+       struct dcerpc_binding_handle_call_params_state *state;
        struct tevent_req *subreq;
        enum ndr_err_code ndr_err;
 
        req = tevent_req_create(mem_ctx, &state,
-                               struct dcerpc_binding_handle_call_state);
+                               struct dcerpc_binding_handle_call_params_state);
        if (req == NULL) {
                return NULL;
        }
@@ -389,9 +387,27 @@ struct tevent_req *dcerpc_binding_handle_call_send(TALLOC_CTX *mem_ctx,
 
        state->h = h;
        state->call = &table->calls[opnum];
+       state->params = params;
+
+       if (params->in.num_pipes != state->call->in_pipes.num_pipes) {
+               tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+               return tevent_req_post(req, ev);
+       }
+
+       if (params->out.num_pipes != state->call->out_pipes.num_pipes) {
+               tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+               return tevent_req_post(req, ev);
+       }
 
-       state->r_mem = r_mem;
-       state->r_ptr = r_ptr;
+       if (params->in.num_pipes != 0) {
+               tevent_req_nterror(req, NT_STATUS_RPC_CANNOT_SUPPORT);
+               return tevent_req_post(req, ev);
+       }
+
+       if (params->out.num_pipes != 0) {
+               tevent_req_nterror(req, NT_STATUS_RPC_CANNOT_SUPPORT);
+               return tevent_req_post(req, ev);
+       }
 
        /* setup for a ndr_push_* call */
        state->push = ndr_push_init_ctx(state);
@@ -413,17 +429,17 @@ struct tevent_req *dcerpc_binding_handle_call_send(TALLOC_CTX *mem_ctx,
 
        if (h->ops->do_ndr_print) {
                h->ops->do_ndr_print(h, NDR_IN | NDR_SET_VALUES,
-                                    state->r_ptr, state->call);
+                                    state->params->r_ptr, state->call);
        }
 
        /* push the structure into a blob */
-       ndr_err = state->call->ndr_push(state->push, NDR_IN, state->r_ptr);
+       ndr_err = state->call->ndr_push(state->push, NDR_IN, state->params->r_ptr);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                NTSTATUS error;
                error = ndr_map_error2ntstatus(ndr_err);
                if (h->ops->ndr_push_failed) {
                        h->ops->ndr_push_failed(h, error,
-                                               state->r_ptr,
+                                               state->params->r_ptr,
                                                state->call);
                }
                tevent_req_nterror(req, error);
@@ -452,18 +468,18 @@ struct tevent_req *dcerpc_binding_handle_call_send(TALLOC_CTX *mem_ctx,
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
-       tevent_req_set_callback(subreq, dcerpc_binding_handle_call_done, req);
+       tevent_req_set_callback(subreq, dcerpc_binding_handle_call_params_done, req);
 
        return req;
 }
 
-static void dcerpc_binding_handle_call_done(struct tevent_req *subreq)
+static void dcerpc_binding_handle_call_params_done(struct tevent_req *subreq)
 {
        struct tevent_req *req = tevent_req_callback_data(subreq,
                                 struct tevent_req);
-       struct dcerpc_binding_handle_call_state *state =
+       struct dcerpc_binding_handle_call_params_state *state =
                tevent_req_data(req,
-               struct dcerpc_binding_handle_call_state);
+               struct dcerpc_binding_handle_call_params_state);
        struct dcerpc_binding_handle *h = state->h;
        NTSTATUS error;
        uint32_t out_flags = 0;
@@ -490,10 +506,11 @@ static void dcerpc_binding_handle_call_done(struct tevent_req *subreq)
                state->pull->flags &= ~LIBNDR_FLAG_BIGENDIAN;
        }
 
-       state->pull->current_mem_ctx = state->r_mem;
+       state->pull->current_mem_ctx = state->params->r_mem;
 
        /* pull the structure from the blob */
-       ndr_err = state->call->ndr_pull(state->pull, NDR_OUT, state->r_ptr);
+       ndr_err = state->call->ndr_pull(state->pull, NDR_OUT,
+                                       state->params->r_ptr);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                error = ndr_map_error2ntstatus(ndr_err);
                if (h->ops->ndr_pull_failed) {
@@ -507,13 +524,13 @@ static void dcerpc_binding_handle_call_done(struct tevent_req *subreq)
 
        if (h->ops->do_ndr_print) {
                h->ops->do_ndr_print(h, NDR_OUT,
-                                    state->r_ptr, state->call);
+                                    state->params->r_ptr, state->call);
        }
 
        if (h->ops->ndr_validate_out) {
                error = h->ops->ndr_validate_out(h,
                                                 state->pull,
-                                                state->r_ptr,
+                                                state->params->r_ptr,
                                                 state->call);
                if (!NT_STATUS_IS_OK(error)) {
                        tevent_req_nterror(req, error);
@@ -524,6 +541,65 @@ static void dcerpc_binding_handle_call_done(struct tevent_req *subreq)
        tevent_req_done(req);
 }
 
+NTSTATUS dcerpc_binding_handle_call_params_recv(struct tevent_req *req)
+{
+       return tevent_req_simple_recv_ntstatus(req);
+}
+
+struct dcerpc_binding_handle_call_state {
+       struct dcerpc_binding_handle_call_params params;
+};
+
+static void dcerpc_binding_handle_call_done(struct tevent_req *subreq);
+
+struct tevent_req *dcerpc_binding_handle_call_send(TALLOC_CTX *mem_ctx,
+                                       struct tevent_context *ev,
+                                       struct dcerpc_binding_handle *h,
+                                       const struct GUID *object,
+                                       const struct ndr_interface_table *table,
+                                       uint32_t opnum,
+                                       TALLOC_CTX *r_mem,
+                                       void *r_ptr)
+{
+       struct tevent_req *req;
+       struct dcerpc_binding_handle_call_state *state;
+       struct tevent_req *subreq;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct dcerpc_binding_handle_call_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       state->params.r_mem = r_mem;
+       state->params.r_ptr = r_ptr;
+
+       subreq = dcerpc_binding_handle_call_params_send(state, ev, h,
+                                                       object, table, opnum,
+                                                       &state->params);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, dcerpc_binding_handle_call_done, req);
+
+       return req;
+}
+
+static void dcerpc_binding_handle_call_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(subreq,
+                                struct tevent_req);
+       NTSTATUS error;
+
+       error = dcerpc_binding_handle_call_params_recv(subreq);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, error)) {
+               return;
+       }
+
+       tevent_req_done(req);
+}
+
 NTSTATUS dcerpc_binding_handle_call_recv(struct tevent_req *req)
 {
        return tevent_req_simple_recv_ntstatus(req);
@@ -539,6 +615,7 @@ NTSTATUS dcerpc_binding_handle_call(struct dcerpc_binding_handle *h,
        TALLOC_CTX *frame = talloc_stackframe();
        struct tevent_context *ev;
        struct tevent_req *subreq;
+       struct dcerpc_binding_handle_call_params params;
        NTSTATUS status = NT_STATUS_NO_MEMORY;
 
        /*
@@ -554,9 +631,13 @@ NTSTATUS dcerpc_binding_handle_call(struct dcerpc_binding_handle *h,
                goto fail;
        }
 
-       subreq = dcerpc_binding_handle_call_send(frame, ev,
-                                                h, object, table,
-                                                opnum, r_mem, r_ptr);
+       ZERO_STRUCT(params);
+       params.r_mem = r_mem;
+       params.r_ptr = r_ptr;
+
+       subreq = dcerpc_binding_handle_call_params_send(frame, ev, h,
+                                                       object, table, opnum,
+                                                       &params);
        if (subreq == NULL) {
                goto fail;
        }
@@ -565,7 +646,7 @@ NTSTATUS dcerpc_binding_handle_call(struct dcerpc_binding_handle *h,
                goto fail;
        }
 
-       status = dcerpc_binding_handle_call_recv(subreq);
+       status = dcerpc_binding_handle_call_params_recv(subreq);
 fail:
        TALLOC_FREE(frame);
        return status;
index e2ea739cf3d18a349c5cb36a95c34ef094473881..8a8d3be6c3ee263c5d7e06ece562a05561e2b17c 100644 (file)
@@ -366,6 +366,23 @@ struct tevent_req *dcerpc_binding_handle_disconnect_send(TALLOC_CTX *mem_ctx,
                                                struct dcerpc_binding_handle *h);
 NTSTATUS dcerpc_binding_handle_disconnect_recv(struct tevent_req *req);
 
+struct dcerpc_binding_handle_call_params {
+       TALLOC_CTX *r_mem;
+       void *r_ptr;
+       struct {
+               uint32_t num_pipes;
+               struct dcerpc_pipe_handle_connection **pipes;
+       } in, out;
+};
+
+struct tevent_req *dcerpc_binding_handle_call_params_send(TALLOC_CTX *mem_ctx,
+                               struct tevent_context *ev,
+                               struct dcerpc_binding_handle *h,
+                               const struct GUID *object,
+                               const struct ndr_interface_table *table,
+                               uint32_t opnum,
+                               struct dcerpc_binding_handle_call_params *params);
+NTSTATUS dcerpc_binding_handle_call_params_recv(struct tevent_req *req);
 struct tevent_req *dcerpc_binding_handle_call_send(TALLOC_CTX *mem_ctx,
                                        struct tevent_context *ev,
                                        struct dcerpc_binding_handle *h,