summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2009-01-29 22:41:33 +0100
committerVolker Lendecke <vl@samba.org>2009-01-30 12:47:59 +0100
commitb873ede89d3155438f7f9938d9a027cb4e3791e7 (patch)
tree9826a5da6447216e5a937af3d4fb45498416e4bf
parenta0d52e7d54da450a734d7bc7f3827a2791e802b1 (diff)
downloadsamba-b873ede89d3155438f7f9938d9a027cb4e3791e7.tar.gz
samba-b873ede89d3155438f7f9938d9a027cb4e3791e7.tar.xz
samba-b873ede89d3155438f7f9938d9a027cb4e3791e7.zip
Make rpc_transport_np_init async
-rw-r--r--source3/include/proto.h7
-rw-r--r--source3/rpc_client/rpc_transport_np.c153
2 files changed, 128 insertions, 32 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 04740f5cae9..60e80bd87dd 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -5329,6 +5329,13 @@ NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
/* The following definitions come from rpc_client/rpc_transport_np.c */
+struct async_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const struct ndr_syntax_id *abstract_syntax);
+NTSTATUS rpc_transport_np_init_recv(struct async_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct rpc_cli_transport **presult);
NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli,
const struct ndr_syntax_id *abstract_syntax,
struct rpc_cli_transport **presult);
diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c
index e8a333e5092..68aae6a0cc6 100644
--- a/source3/rpc_client/rpc_transport_np.c
+++ b/source3/rpc_client/rpc_transport_np.c
@@ -272,51 +272,140 @@ static NTSTATUS rpc_np_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
-NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli,
- const struct ndr_syntax_id *abstract_syntax,
- struct rpc_cli_transport **presult)
+struct rpc_transport_np_init_state {
+ struct rpc_cli_transport *transport;
+ struct rpc_transport_np_state *transport_np;
+};
+
+static void rpc_transport_np_init_pipe_open(struct async_req *subreq);
+
+struct async_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const struct ndr_syntax_id *abstract_syntax)
{
- struct rpc_cli_transport *result;
- struct rpc_transport_np_state *state;
- int fnum;
+ struct async_req *result, *subreq;
+ struct rpc_transport_np_init_state *state;
+ NTSTATUS status;
- result = talloc(mem_ctx, struct rpc_cli_transport);
- if (result == NULL) {
- return NT_STATUS_NO_MEMORY;
+ if (!async_req_setup(mem_ctx, &result, &state,
+ struct rpc_transport_np_init_state)) {
+ return NULL;
}
- state = talloc(result, struct rpc_transport_np_state);
- if (state == NULL) {
- TALLOC_FREE(result);
- return NT_STATUS_NO_MEMORY;
+
+ state->transport = talloc(state, struct rpc_cli_transport);
+ if (state->transport == NULL) {
+ goto fail;
+ }
+ state->transport_np = talloc(state->transport,
+ struct rpc_transport_np_state);
+ if (state->transport_np == NULL) {
+ goto fail;
}
- result->priv = state;
+ state->transport->priv = state->transport_np;
- state->cli = cli;
- state->pipe_name = cli_get_pipe_name_from_iface(
+ state->transport_np->pipe_name = cli_get_pipe_name_from_iface(
state, abstract_syntax);
+ if (state->transport_np->pipe_name == NULL) {
+ status = NT_STATUS_PIPE_NOT_AVAILABLE;
+ goto post_status;
+ }
+ state->transport_np->cli = cli;
+
+ subreq = cli_ntcreate_send(
+ state, ev, cli, state->transport_np->pipe_name, 0,
+ DESIRED_ACCESS_PIPE, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
+ FILE_OPEN, 0, 0);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = rpc_transport_np_init_pipe_open;
+ subreq->async.priv = result;
+ return result;
+
+ post_status:
+ if (async_post_status(result, ev, status)) {
+ return result;
+ }
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void rpc_transport_np_init_pipe_open(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct rpc_transport_np_init_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_transport_np_init_state);
+ NTSTATUS status;
+
+ status = cli_ntcreate_recv(subreq, &state->transport_np->fnum);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_error(req, status);
+ return;
+ }
+
+ talloc_set_destructor(state->transport_np,
+ rpc_transport_np_state_destructor);
+ async_req_done(req);
+}
+
+NTSTATUS rpc_transport_np_init_recv(struct async_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct rpc_cli_transport **presult)
+{
+ struct rpc_transport_np_init_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_transport_np_init_state);
+ NTSTATUS status;
- fnum = cli_nt_create(cli, state->pipe_name, DESIRED_ACCESS_PIPE);
- if (fnum == -1) {
- DEBUG(3,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
- "to machine %s. Error was %s\n", state->pipe_name,
- cli->desthost, cli_errstr(cli)));
- TALLOC_FREE(result);
- return cli_get_nt_error(cli);
+ if (async_req_is_error(req, &status)) {
+ return status;
}
- state->fnum = fnum;
- talloc_set_destructor(state, rpc_transport_np_state_destructor);
- result->write_send = rpc_np_write_send;
- result->write_recv = rpc_np_write_recv;
- result->read_send = rpc_np_read_send;
- result->read_recv = rpc_np_read_recv;
- result->trans_send = rpc_np_trans_send;
- result->trans_recv = rpc_np_trans_recv;
+ state->transport->write_send = rpc_np_write_send;
+ state->transport->write_recv = rpc_np_write_recv;
+ state->transport->read_send = rpc_np_read_send;
+ state->transport->read_recv = rpc_np_read_recv;
+ state->transport->trans_send = rpc_np_trans_send;
+ state->transport->trans_recv = rpc_np_trans_recv;
- *presult = result;
+ *presult = talloc_move(mem_ctx, &state->transport);
return NT_STATUS_OK;
}
+NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli,
+ const struct ndr_syntax_id *abstract_syntax,
+ struct rpc_cli_transport **presult)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct async_req *req;
+ NTSTATUS status;
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = rpc_transport_np_init_send(frame, ev, cli, abstract_syntax);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ while (req->state < ASYNC_REQ_DONE) {
+ event_loop_once(ev);
+ }
+
+ status = rpc_transport_np_init_recv(req, mem_ctx, presult);
+ fail:
+ TALLOC_FREE(frame);
+ return status;
+}
+
struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
{
struct rpc_transport_np_state *state = talloc_get_type(