summaryrefslogtreecommitdiff
path: root/source3/rpc_client
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_client')
-rw-r--r--source3/rpc_client/rpc_transport_np.c419
-rw-r--r--source3/rpc_client/rpc_transport_tstream.c19
2 files changed, 38 insertions, 400 deletions
diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c
index 9d803aa9d4..a3f3a1735d 100644
--- a/source3/rpc_client/rpc_transport_np.c
+++ b/source3/rpc_client/rpc_transport_np.c
@@ -18,363 +18,13 @@
*/
#include "includes.h"
+#include "libsmb/cli_np_tstream.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_CLI
-struct rpc_transport_np_state {
- struct cli_state *cli;
- const char *pipe_name;
- uint16_t fnum;
-};
-
-static bool rpc_np_is_connected(void *priv)
-{
- struct rpc_transport_np_state *np_transport = talloc_get_type_abort(
- priv, struct rpc_transport_np_state);
- bool ok;
-
- if (np_transport->cli == NULL) {
- return false;
- }
-
- ok = cli_state_is_connected(np_transport->cli);
- if (!ok) {
- np_transport->cli = NULL;
- return false;
- }
-
- return true;
-}
-
-static unsigned int rpc_np_set_timeout(void *priv, unsigned int timeout)
-{
- struct rpc_transport_np_state *np_transport = talloc_get_type_abort(
- priv, struct rpc_transport_np_state);
- bool ok;
-
- if (np_transport->cli == NULL) {
- return false;
- }
-
- ok = rpc_np_is_connected(np_transport);
- if (!ok) {
- return 0;
- }
-
- return cli_set_timeout(np_transport->cli, timeout);
-}
-
-static int rpc_transport_np_state_destructor(struct rpc_transport_np_state *s)
-{
- if (!rpc_np_is_connected(s)) {
- DEBUG(10, ("socket was closed, no need to send close request.\n"));
- return 0;
- }
-
- /* TODO: do not use a sync call with a destructor!!! */
- if (!NT_STATUS_IS_OK(cli_close(s->cli, s->fnum))) {
- DEBUG(1, ("rpc_transport_np_state_destructor: cli_close "
- "failed on pipe %s. Error was %s\n", s->pipe_name,
- cli_errstr(s->cli)));
- }
- DEBUG(10, ("rpc_pipe_destructor: closed %s\n", s->pipe_name));
- /*
- * We can't do much on failure
- */
- return 0;
-}
-
-struct rpc_np_write_state {
- struct rpc_transport_np_state *np_transport;
- size_t size;
- size_t written;
-};
-
-static void rpc_np_write_done(struct tevent_req *subreq);
-
-static struct tevent_req *rpc_np_write_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- const uint8_t *data, size_t size,
- void *priv)
-{
- struct rpc_transport_np_state *np_transport = talloc_get_type_abort(
- priv, struct rpc_transport_np_state);
- struct tevent_req *req, *subreq;
- struct rpc_np_write_state *state;
- bool ok;
-
- req = tevent_req_create(mem_ctx, &state, struct rpc_np_write_state);
- if (req == NULL) {
- return NULL;
- }
-
- ok = rpc_np_is_connected(np_transport);
- if (!ok) {
- tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);
- return tevent_req_post(req, ev);
- }
-
- state->np_transport = np_transport;
- state->size = size;
-
-
- subreq = cli_write_andx_send(mem_ctx, ev, np_transport->cli,
- np_transport->fnum,
- 8, /* 8 means message mode. */
- data, 0, size);
- if (tevent_req_nomem(subreq, req)) {
- return tevent_req_post(req, ev);
- }
- tevent_req_set_callback(subreq, rpc_np_write_done, req);
- return req;
-}
-
-static void rpc_np_write_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct rpc_np_write_state *state = tevent_req_data(
- req, struct rpc_np_write_state);
- NTSTATUS status;
-
- status = cli_write_andx_recv(subreq, &state->written);
- TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status)) {
- state->np_transport->cli = NULL;
- tevent_req_nterror(req, status);
- return;
- }
- tevent_req_done(req);
-}
-
-static NTSTATUS rpc_np_write_recv(struct tevent_req *req, ssize_t *pwritten)
-{
- struct rpc_np_write_state *state = tevent_req_data(
- req, struct rpc_np_write_state);
- NTSTATUS status;
-
- if (tevent_req_is_nterror(req, &status)) {
- return status;
- }
- *pwritten = state->written;
- return NT_STATUS_OK;
-}
-
-struct rpc_np_read_state {
- struct rpc_transport_np_state *np_transport;
- uint8_t *data;
- size_t size;
- ssize_t received;
-};
-
-static void rpc_np_read_done(struct tevent_req *subreq);
-
-static struct tevent_req *rpc_np_read_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- uint8_t *data, size_t size,
- void *priv)
-{
- struct rpc_transport_np_state *np_transport = talloc_get_type_abort(
- priv, struct rpc_transport_np_state);
- struct tevent_req *req, *subreq;
- struct rpc_np_read_state *state;
- bool ok;
-
- req = tevent_req_create(mem_ctx, &state, struct rpc_np_read_state);
- if (req == NULL) {
- return NULL;
- }
-
- ok = rpc_np_is_connected(np_transport);
- if (!ok) {
- tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);
- return tevent_req_post(req, ev);
- }
-
- state->np_transport = np_transport;
- state->data = data;
- state->size = size;
-
- subreq = cli_read_andx_send(mem_ctx, ev, np_transport->cli,
- np_transport->fnum, 0, size);
- if (subreq == NULL) {
- goto fail;
- }
- tevent_req_set_callback(subreq, rpc_np_read_done, req);
- return req;
- fail:
- TALLOC_FREE(req);
- return NULL;
-}
-
-static void rpc_np_read_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct rpc_np_read_state *state = tevent_req_data(
- req, struct rpc_np_read_state);
- NTSTATUS status;
- uint8_t *rcvbuf;
-
- /* We must free subreq in this function as there is
- a timer event attached to it. */
-
- status = cli_read_andx_recv(subreq, &state->received, &rcvbuf);
- /*
- * We can't TALLOC_FREE(subreq) as usual here, as rcvbuf still is a
- * child of that.
- */
- if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {
- status = NT_STATUS_OK;
- }
- if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(subreq);
- state->np_transport->cli = NULL;
- tevent_req_nterror(req, status);
- return;
- }
-
- if (state->received > state->size) {
- TALLOC_FREE(subreq);
- state->np_transport->cli = NULL;
- tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
- return;
- }
-
- if (state->received == 0) {
- TALLOC_FREE(subreq);
- state->np_transport->cli = NULL;
- tevent_req_nterror(req, NT_STATUS_PIPE_BROKEN);
- return;
- }
-
- memcpy(state->data, rcvbuf, state->received);
- TALLOC_FREE(subreq);
- tevent_req_done(req);
-}
-
-static NTSTATUS rpc_np_read_recv(struct tevent_req *req, ssize_t *preceived)
-{
- struct rpc_np_read_state *state = tevent_req_data(
- req, struct rpc_np_read_state);
- NTSTATUS status;
-
- if (tevent_req_is_nterror(req, &status)) {
- return status;
- }
- *preceived = state->received;
- return NT_STATUS_OK;
-}
-
-struct rpc_np_trans_state {
- struct rpc_transport_np_state *np_transport;
- uint16_t setup[2];
- uint32_t max_rdata_len;
- uint8_t *rdata;
- uint32_t rdata_len;
-};
-
-static void rpc_np_trans_done(struct tevent_req *subreq);
-
-static struct tevent_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- uint8_t *data, size_t data_len,
- uint32_t max_rdata_len,
- void *priv)
-{
- struct rpc_transport_np_state *np_transport = talloc_get_type_abort(
- priv, struct rpc_transport_np_state);
- struct tevent_req *req, *subreq;
- struct rpc_np_trans_state *state;
- bool ok;
-
- req = tevent_req_create(mem_ctx, &state, struct rpc_np_trans_state);
- if (req == NULL) {
- return NULL;
- }
-
- ok = rpc_np_is_connected(np_transport);
- if (!ok) {
- tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);
- return tevent_req_post(req, ev);
- }
-
- state->np_transport = np_transport;
- state->max_rdata_len = max_rdata_len;
-
- SSVAL(state->setup+0, 0, TRANSACT_DCERPCCMD);
- SSVAL(state->setup+1, 0, np_transport->fnum);
-
- subreq = cli_trans_send(
- state, ev, np_transport->cli, SMBtrans,
- "\\PIPE\\", 0, 0, 0, state->setup, 2, 0,
- NULL, 0, 0, data, data_len, max_rdata_len);
- if (subreq == NULL) {
- goto fail;
- }
- tevent_req_set_callback(subreq, rpc_np_trans_done, req);
- return req;
-
- fail:
- TALLOC_FREE(req);
- return NULL;
-}
-
-static void rpc_np_trans_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct rpc_np_trans_state *state = tevent_req_data(
- req, struct rpc_np_trans_state);
- NTSTATUS status;
-
- status = cli_trans_recv(subreq, state, NULL, NULL, 0, NULL,
- NULL, 0, NULL,
- &state->rdata, 0, &state->rdata_len);
- TALLOC_FREE(subreq);
- if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {
- status = NT_STATUS_OK;
- }
- if (!NT_STATUS_IS_OK(status)) {
- state->np_transport->cli = NULL;
- tevent_req_nterror(req, status);
- return;
- }
-
- if (state->rdata_len > state->max_rdata_len) {
- state->np_transport->cli = NULL;
- tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
- return;
- }
-
- if (state->rdata_len == 0) {
- state->np_transport->cli = NULL;
- tevent_req_nterror(req, NT_STATUS_PIPE_BROKEN);
- return;
- }
-
- tevent_req_done(req);
-}
-
-static NTSTATUS rpc_np_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- uint8_t **prdata, uint32_t *prdata_len)
-{
- struct rpc_np_trans_state *state = tevent_req_data(
- req, struct rpc_np_trans_state);
- NTSTATUS status;
-
- if (tevent_req_is_nterror(req, &status)) {
- return status;
- }
- *prdata = talloc_move(mem_ctx, &state->rdata);
- *prdata_len = state->rdata_len;
- return NT_STATUS_OK;
-}
-
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 tevent_req *subreq);
@@ -384,9 +34,10 @@ struct tevent_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx,
struct cli_state *cli,
const struct ndr_syntax_id *abstract_syntax)
{
- struct tevent_req *req, *subreq;
+ struct tevent_req *req;
struct rpc_transport_np_init_state *state;
- bool ok;
+ const char *pipe_name;
+ struct tevent_req *subreq;
req = tevent_req_create(mem_ctx, &state,
struct rpc_transport_np_init_state);
@@ -394,36 +45,17 @@ struct tevent_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- ok = cli_state_is_connected(cli);
- if (!ok) {
- tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID);
- return tevent_req_post(req, ev);
- }
-
- state->transport = talloc(state, struct rpc_cli_transport);
- if (tevent_req_nomem(state->transport, req)) {
- return tevent_req_post(req, ev);
- }
- state->transport_np = talloc(state->transport,
- struct rpc_transport_np_state);
- if (tevent_req_nomem(state->transport_np, req)) {
+ pipe_name = get_pipe_name_from_syntax(state, abstract_syntax);
+ if (tevent_req_nomem(pipe_name, req)) {
return tevent_req_post(req, ev);
}
- state->transport->priv = state->transport_np;
- state->transport_np->pipe_name = get_pipe_name_from_syntax(
- state->transport_np, abstract_syntax);
- 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);
+ subreq = tstream_cli_np_open_send(state, ev, cli, pipe_name);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
- tevent_req_set_callback(subreq, rpc_transport_np_init_pipe_open,
- req);
+ tevent_req_set_callback(subreq, rpc_transport_np_init_pipe_open, req);
+
return req;
}
@@ -434,16 +66,23 @@ static void rpc_transport_np_init_pipe_open(struct tevent_req *subreq)
struct rpc_transport_np_init_state *state = tevent_req_data(
req, struct rpc_transport_np_init_state);
NTSTATUS status;
+ struct tstream_context *stream;
- status = cli_ntcreate_recv(subreq, &state->transport_np->fnum);
+ status = tstream_cli_np_open_recv(subreq, state, &stream);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return;
}
- talloc_set_destructor(state->transport_np,
- rpc_transport_np_state_destructor);
+ status = rpc_transport_tstream_init(state,
+ &stream,
+ &state->transport);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+
tevent_req_done(req);
}
@@ -459,15 +98,6 @@ NTSTATUS rpc_transport_np_init_recv(struct tevent_req *req,
return status;
}
- 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;
- state->transport->is_connected = rpc_np_is_connected;
- state->transport->set_timeout = rpc_np_set_timeout;
-
*presult = talloc_move(mem_ctx, &state->transport);
return NT_STATUS_OK;
}
@@ -503,14 +133,3 @@ NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli,
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(
- p->transport->priv, struct rpc_transport_np_state);
-
- if (state == NULL) {
- return NULL;
- }
- return state->cli;
-}
diff --git a/source3/rpc_client/rpc_transport_tstream.c b/source3/rpc_client/rpc_transport_tstream.c
index 6d8200e8b4..d414002035 100644
--- a/source3/rpc_client/rpc_transport_tstream.c
+++ b/source3/rpc_client/rpc_transport_tstream.c
@@ -559,3 +559,22 @@ NTSTATUS rpc_transport_tstream_init(TALLOC_CTX *mem_ctx,
*presult = result;
return NT_STATUS_OK;
}
+
+struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
+{
+ struct rpc_tstream_state *transp =
+ talloc_get_type_abort(p->transport->priv,
+ struct rpc_tstream_state);
+ bool ok;
+
+ ok = rpccli_is_connected(p);
+ if (!ok) {
+ return NULL;
+ }
+
+ if (!tstream_is_cli_np(transp->stream)) {
+ return NULL;
+ }
+
+ return tstream_cli_np_get_cli_state(transp->stream);
+}