Lift the event loop in rpc_api_pipe_req() one level into cli_do_rpc_ndr
authorVolker Lendecke <vl@samba.org>
Mon, 27 Jul 2009 12:28:52 +0000 (14:28 +0200)
committerVolker Lendecke <vl@samba.org>
Mon, 27 Jul 2009 14:15:54 +0000 (16:15 +0200)
source3/include/proto.h
source3/librpc/rpc/dcerpc.c
source3/rpc_client/cli_pipe.c
source3/rpc_client/ndr.c

index aed2c4c0f7143ab1c429e9bf2faa1de1d98a1c9c..3e9f5e8ae7c7a6805bf90f121ef671b5060e4c9f 100644 (file)
@@ -5262,10 +5262,6 @@ struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
                                         prs_struct *req_data);
 NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
                               prs_struct *reply_pdu);
-NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli,
-                       uint8 op_num,
-                       prs_struct *in_data,
-                       prs_struct *out_data);
 struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
                                      struct event_context *ev,
                                      struct rpc_pipe_client *cli,
@@ -5615,6 +5611,13 @@ void init_samr_CryptPassword(const char *pwd,
 
 /* The following definitions come from rpc_client/ndr.c  */
 
+struct tevent_req *cli_do_rpc_ndr_send(TALLOC_CTX *mem_ctx,
+                                      struct tevent_context *ev,
+                                      struct rpc_pipe_client *cli,
+                                      const struct ndr_interface_table *table,
+                                      uint32_t opnum,
+                                      void *r);
+NTSTATUS cli_do_rpc_ndr_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx);
 NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli,
                        TALLOC_CTX *mem_ctx,
                        const struct ndr_interface_table *table,
index 21a2004422c2c85bdbf42b4d2f9e7d824f01bdca..e6c4cb446b60abf4c5fd70ebe009a9e272bcf9a7 100644 (file)
@@ -69,6 +69,10 @@ struct rpc_request *dcerpc_ndr_request_send(struct dcerpc_pipe *p, const struct
        return ret;
 }
 
+#if 0
+
+Completely unfinished and unused -- vl :-)
+
 /**
  * Wait for a DCE/RPC request. 
  *
@@ -118,10 +122,6 @@ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req)
        return NT_STATUS_OK;
 }
 
-#if 0
-
-Completely unfinished and unused -- vl :-)
-
 /**
  * Connect to a DCE/RPC interface.
  * 
index 70660da8b205e0e62c40fd0e589ee496e5d99f8d..c9f17c65ade4168d5b7319e0bfae69b25eb40f68 100644 (file)
@@ -2284,39 +2284,6 @@ NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
-NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli,
-                       uint8 op_num,
-                       prs_struct *in_data,
-                       prs_struct *out_data)
-{
-       TALLOC_CTX *frame = talloc_stackframe();
-       struct event_context *ev;
-       struct tevent_req *req;
-       NTSTATUS status = NT_STATUS_OK;
-
-       ev = event_context_init(frame);
-       if (ev == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto fail;
-       }
-
-       req = rpc_api_pipe_req_send(frame, ev, cli, op_num, in_data);
-       if (req == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto fail;
-       }
-
-       if (!tevent_req_poll(req, ev)) {
-               status = map_nt_error_from_unix(errno);
-               goto fail;
-       }
-
-       status = rpc_api_pipe_req_recv(req, mem_ctx, out_data);
- fail:
-       TALLOC_FREE(frame);
-       return status;
-}
-
 #if 0
 /****************************************************************************
  Set the handle state.
index 6c40f09ab8f1840a3ae4dc38de9758d4153457b1..f9af2f5f7ad51b2706c08bced067bbc1924b508a 100644 (file)
@@ -4,6 +4,7 @@
    libndr interface
 
    Copyright (C) Jelmer Vernooij 2006
+   Copyright (C) Volker Lendecke 2009
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
 #include "includes.h"
 
+struct cli_do_rpc_ndr_state {
+       const struct ndr_interface_call *call;
+       prs_struct q_ps, r_ps;
+       void *r;
+};
 
-NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli,
-                       TALLOC_CTX *mem_ctx,
-                       const struct ndr_interface_table *table,
-                       uint32_t opnum, void *r)
+static void cli_do_rpc_ndr_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_do_rpc_ndr_send(TALLOC_CTX *mem_ctx,
+                                      struct tevent_context *ev,
+                                      struct rpc_pipe_client *cli,
+                                      const struct ndr_interface_table *table,
+                                      uint32_t opnum,
+                                      void *r)
 {
-       prs_struct q_ps, r_ps;
-       const struct ndr_interface_call *call;
-       struct ndr_pull *pull;
-       DATA_BLOB blob;
+       struct tevent_req *req, *subreq;
+       struct cli_do_rpc_ndr_state *state;
        struct ndr_push *push;
-       NTSTATUS status;
+       DATA_BLOB blob;
        enum ndr_err_code ndr_err;
+       bool ret;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct cli_do_rpc_ndr_state);
+       if (req == NULL) {
+               return NULL;
+       }
 
-       SMB_ASSERT(ndr_syntax_id_equal(&table->syntax_id,
-                                      &cli->abstract_syntax));
-       SMB_ASSERT(table->num_calls > opnum);
+       if (!ndr_syntax_id_equal(&table->syntax_id, &cli->abstract_syntax)
+           || (opnum >= table->num_calls)) {
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return tevent_req_post(req, ev);
+       }
 
-       call = &table->calls[opnum];
+       state->r = r;
+       state->call = &table->calls[opnum];
 
-       push = ndr_push_init_ctx(mem_ctx, NULL);
-       if (!push) {
-               return NT_STATUS_NO_MEMORY;
+       push = ndr_push_init_ctx(talloc_tos(), NULL);
+       if (tevent_req_nomem(push, req)) {
+               return tevent_req_post(req, ev);
        }
 
-       ndr_err = call->ndr_push(push, NDR_IN, r);
+       ndr_err = state->call->ndr_push(push, NDR_IN, r);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               return ndr_map_error2ntstatus(ndr_err);
+               tevent_req_nterror(req, ndr_map_error2ntstatus(ndr_err));
+               TALLOC_FREE(push);
+               return tevent_req_post(req, ev);
        }
 
        blob = ndr_push_blob(push);
+       ret = prs_init_data_blob(&state->q_ps, &blob, state);
+       TALLOC_FREE(push);
 
-       if (!prs_init_data_blob(&q_ps, &blob, mem_ctx)) {
-               return NT_STATUS_NO_MEMORY;
+       if (!ret) {
+               tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+               return tevent_req_post(req, ev);
        }
 
-       talloc_free(push);
-
-       status = rpc_api_pipe_req(mem_ctx, cli, opnum, &q_ps, &r_ps);
+       subreq = rpc_api_pipe_req_send(state, ev, cli, opnum, &state->q_ps);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, cli_do_rpc_ndr_done, req);
+       return req;
+}
 
-       prs_mem_free( &q_ps );
+static void cli_do_rpc_ndr_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct cli_do_rpc_ndr_state *state = tevent_req_data(
+               req, struct cli_do_rpc_ndr_state);
+       NTSTATUS status;
 
+       status = rpc_api_pipe_req_recv(subreq, state, &state->r_ps);
+       TALLOC_FREE(subreq);
+       prs_mem_free(&state->q_ps);
        if (!NT_STATUS_IS_OK(status)) {
-               prs_mem_free( &r_ps );
+               tevent_req_nterror(req, status);
+               return;
+       }
+       tevent_req_done(req);
+}
+
+NTSTATUS cli_do_rpc_ndr_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx)
+{
+       struct cli_do_rpc_ndr_state *state = tevent_req_data(
+               req, struct cli_do_rpc_ndr_state);
+       struct ndr_pull *pull;
+       enum ndr_err_code ndr_err;
+       NTSTATUS status;
+       DATA_BLOB blob;
+       bool ret;
+
+       if (tevent_req_is_nterror(req, &status)) {
                return status;
        }
 
-       if (!prs_data_blob(&r_ps, &blob, mem_ctx)) {
-               prs_mem_free( &r_ps );
+       ret = prs_data_blob(&state->r_ps, &blob, talloc_tos());
+       prs_mem_free(&state->r_ps);
+       if (!ret) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       prs_mem_free( &r_ps );
-
        pull = ndr_pull_init_blob(&blob, mem_ctx, NULL);
        if (pull == NULL) {
                return NT_STATUS_NO_MEMORY;
@@ -82,8 +133,8 @@ NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli,
 
        /* have the ndr parser alloc memory for us */
        pull->flags |= LIBNDR_FLAG_REF_ALLOC;
-       ndr_err = call->ndr_pull(pull, NDR_OUT, r);
-       talloc_free(pull);
+       ndr_err = state->call->ndr_pull(pull, NDR_OUT, state->r);
+       TALLOC_FREE(pull);
 
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                return ndr_map_error2ntstatus(ndr_err);
@@ -91,3 +142,36 @@ NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli,
 
        return NT_STATUS_OK;
 }
+
+NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli,
+                       TALLOC_CTX *mem_ctx,
+                       const struct ndr_interface_table *table,
+                       uint32_t opnum, void *r)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct event_context *ev;
+       struct tevent_req *req;
+       NTSTATUS status = NT_STATUS_OK;
+
+       ev = event_context_init(frame);
+       if (ev == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
+       }
+
+       req = cli_do_rpc_ndr_send(frame, ev, cli, table, opnum, r);
+       if (req == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
+       }
+
+       if (!tevent_req_poll(req, ev)) {
+               status = map_nt_error_from_unix(errno);
+               goto fail;
+       }
+
+       status = cli_do_rpc_ndr_recv(req, mem_ctx);
+ fail:
+       TALLOC_FREE(frame);
+       return status;
+}