diff options
Diffstat (limited to 'source3/rpc_client')
-rw-r--r-- | source3/rpc_client/rpc_transport_np.c | 153 |
1 files changed, 121 insertions, 32 deletions
diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c index e8a333e509..68aae6a0cc 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( |