diff options
-rw-r--r-- | source3/Makefile.in | 3 | ||||
-rw-r--r-- | source3/include/proto.h | 4 | ||||
-rw-r--r-- | source3/rpc_client/cli_pipe.c | 65 | ||||
-rw-r--r-- | source3/rpc_client/rpc_transport_smbd.c | 767 |
4 files changed, 1 insertions, 838 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 755fdb2823..1a51b7c471 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -706,8 +706,7 @@ RPC_CLIENT_OBJ = rpc_client/cli_pipe.o \ librpc/rpc/dcerpc_spnego.o \ librpc/rpc/rpc_common.o \ rpc_client/rpc_transport_np.o \ - rpc_client/rpc_transport_sock.o \ - rpc_client/rpc_transport_smbd.o + rpc_client/rpc_transport_sock.o LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o diff --git a/source3/include/proto.h b/source3/include/proto.h index 80d23e5431..70a2102163 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -4614,10 +4614,6 @@ NTSTATUS cli_rpc_pipe_open_spnego_krb5(struct cli_state *cli, NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, DATA_BLOB *session_key); -NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx, - struct rpc_cli_smbd_conn *conn, - const struct ndr_syntax_id *syntax, - struct rpc_pipe_client **presult); /* The following definitions come from rpc_client/rpc_transport_np.c */ diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 18724a6fa8..6bfcad68e3 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2808,71 +2808,6 @@ static NTSTATUS rpc_pipe_open_np(struct cli_state *cli, return NT_STATUS_OK; } -NTSTATUS rpc_pipe_open_local(TALLOC_CTX *mem_ctx, - struct rpc_cli_smbd_conn *conn, - const struct ndr_syntax_id *syntax, - struct rpc_pipe_client **presult) -{ - struct rpc_pipe_client *result; - struct pipe_auth_data *auth; - NTSTATUS status; - - result = talloc(mem_ctx, struct rpc_pipe_client); - if (result == NULL) { - return NT_STATUS_NO_MEMORY; - } - result->abstract_syntax = *syntax; - result->transfer_syntax = ndr_transfer_syntax; - result->dispatch = cli_do_rpc_ndr; - result->dispatch_send = cli_do_rpc_ndr_send; - result->dispatch_recv = cli_do_rpc_ndr_recv; - result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; - result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN; - - result->desthost = talloc_strdup(result, global_myname()); - result->srv_name_slash = talloc_asprintf_strupper_m( - result, "\\\\%s", global_myname()); - if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) { - TALLOC_FREE(result); - return NT_STATUS_NO_MEMORY; - } - - status = rpc_transport_smbd_init(result, conn, syntax, - &result->transport); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("rpc_transport_smbd_init failed: %s\n", - nt_errstr(status))); - TALLOC_FREE(result); - return status; - } - - status = rpccli_anon_bind_data(result, &auth); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("rpccli_anon_bind_data failed: %s\n", - nt_errstr(status))); - TALLOC_FREE(result); - return status; - } - - status = rpc_pipe_bind(result, auth); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("rpc_pipe_bind failed: %s\n", nt_errstr(status))); - TALLOC_FREE(result); - return status; - } - - result->transport->transport = NCACN_INTERNAL; - - result->binding_handle = rpccli_bh_create(result); - if (result->binding_handle == NULL) { - TALLOC_FREE(result); - return NT_STATUS_NO_MEMORY; - } - - *presult = result; - return NT_STATUS_OK; -} - /**************************************************************************** Open a pipe to a remote server. ****************************************************************************/ diff --git a/source3/rpc_client/rpc_transport_smbd.c b/source3/rpc_client/rpc_transport_smbd.c deleted file mode 100644 index 57fac68b30..0000000000 --- a/source3/rpc_client/rpc_transport_smbd.c +++ /dev/null @@ -1,767 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC client transport over named pipes to a child smbd - * 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_CLI - -/** - * struct rpc_cli_smbd_conn represents a forked smbd. This structure should - * exist only once per process which does the rpc calls. - * - * RPC pipe handles can be attached to this smbd connection with - * rpc_pipe_open_local(). - * - * For this to work right, we can not use rpc_transport_np directly, because - * the child smbd wants to write its DEBUG output somewhere. We redirect the - * child's output to rpc_cli_smbd_conn->stdout_fd. While the RPC calls are - * active, we have an event context available and attach a fd event to the - * stdout_df. - */ - -struct rpc_cli_smbd_conn { - /** - * The smb connection to handle the named pipe traffic over - */ - struct cli_state *cli; - - /** - * Attached to stdout in the forked smbd, this is where smbd will - * print its DEBUG. - */ - int stdout_fd; - - /** - * Custom callback provided by the owner of the - * rpc_cli_smbd_conn. Here we send the smbd DEBUG output. Can be NULL. - */ - struct { - void (*fn)(char *buf, size_t len, void *priv); - void *priv; - } stdout_callback ; -}; - -/** - * Event handler to be called whenever the forked smbd prints debugging - * output. - */ - -static void rpc_cli_smbd_stdout_reader(struct event_context *ev, - struct fd_event *fde, - uint16_t flags, void *priv) -{ - struct rpc_cli_smbd_conn *conn = talloc_get_type_abort( - priv, struct rpc_cli_smbd_conn); - char buf[1024]; - ssize_t nread; - - if ((flags & EVENT_FD_READ) == 0) { - return; - } - - nread = read(conn->stdout_fd, buf, sizeof(buf)-1); - if (nread < 0) { - DEBUG(0, ("Could not read from smbd stdout: %s\n", - strerror(errno))); - TALLOC_FREE(fde); - return; - } - if (nread == 0) { - DEBUG(0, ("EOF from smbd stdout\n")); - TALLOC_FREE(fde); - return; - } - buf[nread] = '\0'; - - if (conn->stdout_callback.fn != NULL) { - conn->stdout_callback.fn(buf, nread, - conn->stdout_callback.priv); - } -} - -/** - * struct rpc_transport_smbd_state is the link from a struct rpc_pipe_client - * to the rpc_cli_smbd_conn. We use a named pipe transport as a subtransport. - */ - -struct rpc_transport_smbd_state { - struct rpc_cli_smbd_conn *conn; - struct rpc_cli_transport *sub_transp; -}; - -static int rpc_cli_smbd_conn_destructor(struct rpc_cli_smbd_conn *conn) -{ - if (conn->cli != NULL) { - cli_shutdown(conn->cli); - conn->cli = NULL; - } - if (conn->stdout_fd != -1) { - close(conn->stdout_fd); - conn->stdout_fd = -1; - } - return 0; -} - -/* - * Do the negprot/sesssetup/tcon to an anonymous ipc$ connection - */ - -struct get_anon_ipc_state { - struct event_context *ev; - struct cli_state *cli; -}; - -static void get_anon_ipc_negprot_done(struct tevent_req *subreq); -static void get_anon_ipc_sesssetup_done(struct tevent_req *subreq); -static void get_anon_ipc_tcon_done(struct tevent_req *subreq); - -static struct tevent_req *get_anon_ipc_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct cli_state *cli) -{ - struct tevent_req *req, *subreq; - struct get_anon_ipc_state *state; - - req = tevent_req_create(mem_ctx, &state, struct get_anon_ipc_state); - if (req == NULL) { - return NULL; - } - state->ev = ev; - state->cli = cli; - - subreq = cli_negprot_send(state, ev, cli); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, get_anon_ipc_negprot_done, req); - return req; -} - -static void get_anon_ipc_negprot_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct get_anon_ipc_state *state = tevent_req_data( - req, struct get_anon_ipc_state); - NTSTATUS status; - - status = cli_negprot_recv(subreq); - TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - return; - } - - subreq = cli_session_setup_guest_send(state, state->ev, state->cli); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, get_anon_ipc_sesssetup_done, req); -} - -static void get_anon_ipc_sesssetup_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct get_anon_ipc_state *state = tevent_req_data( - req, struct get_anon_ipc_state); - NTSTATUS status; - - status = cli_session_setup_guest_recv(subreq); - TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - return; - } - - subreq = cli_tcon_andx_send(state, state->ev, state->cli, - "IPC$", "IPC", NULL, 0); - if (tevent_req_nomem(subreq, req)) { - return; - } - tevent_req_set_callback(subreq, get_anon_ipc_tcon_done, req); -} - -static void get_anon_ipc_tcon_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - NTSTATUS status; - - status = cli_tcon_andx_recv(subreq); - TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - return; - } - tevent_req_done(req); -} - -static NTSTATUS get_anon_ipc_recv(struct tevent_req *req) -{ - return tevent_req_simple_recv_ntstatus(req); -} - -struct rpc_cli_smbd_conn_init_state { - struct event_context *ev; - struct rpc_cli_smbd_conn *conn; -}; - -static void rpc_cli_smbd_conn_init_done(struct tevent_req *subreq); - -struct tevent_req *rpc_cli_smbd_conn_init_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - void (*stdout_callback)(char *buf, - size_t len, - void *priv), - void *priv) -{ - struct tevent_req *req, *subreq; - struct rpc_cli_smbd_conn_init_state *state; - int smb_sock[2]; - int stdout_pipe[2]; - NTSTATUS status; - pid_t pid; - int ret; - - smb_sock[0] = smb_sock[1] = stdout_pipe[0] = stdout_pipe[1] = -1; - - req = tevent_req_create(mem_ctx, &state, - struct rpc_cli_smbd_conn_init_state); - if (req == NULL) { - return NULL; - } - state->ev = ev; - - state->conn = talloc(state, struct rpc_cli_smbd_conn); - if (tevent_req_nomem(state->conn, req)) { - return tevent_req_post(req, ev); - } - - state->conn->cli = cli_initialise(); - if (tevent_req_nomem(state->conn->cli, req)) { - return tevent_req_post(req, ev); - } - state->conn->stdout_fd = -1; - state->conn->stdout_callback.fn = stdout_callback; - state->conn->stdout_callback.priv = priv; - talloc_set_destructor(state->conn, rpc_cli_smbd_conn_destructor); - - ret = socketpair(AF_UNIX, SOCK_STREAM, 0, smb_sock); - if (ret == -1) { - status = map_nt_error_from_unix(errno); - goto post_status; - } - ret = pipe(stdout_pipe); - if (ret == -1) { - status = map_nt_error_from_unix(errno); - goto post_status; - } - - pid = sys_fork(); - if (pid == -1) { - status = map_nt_error_from_unix(errno); - goto post_status; - } - if (pid == 0) { - char *smbd_cmd; - - close(smb_sock[0]); - close(stdout_pipe[0]); - close(0); - if (dup(smb_sock[1]) == -1) { - exit(1); - } - close(smb_sock[1]); - close(1); - if (dup(stdout_pipe[1]) == -1) { - exit(1); - } - close(stdout_pipe[1]); - - smbd_cmd = getenv("SMB_PATH"); - - if ((smbd_cmd == NULL) - && (asprintf(&smbd_cmd, "%s/smbd", get_dyn_SBINDIR()) - == -1)) { - printf("no memory"); - exit(1); - } - if (asprintf(&smbd_cmd, "%s -F -S -d %d", smbd_cmd, - DEBUGLEVEL) == -1) { - printf("no memory"); - exit(1); - } - - exit(system(smbd_cmd)); - } - - state->conn->cli->fd = smb_sock[0]; - smb_sock[0] = -1; - close(smb_sock[1]); - smb_sock[1] = -1; - - state->conn->stdout_fd = stdout_pipe[0]; - stdout_pipe[0] = -1; - close(stdout_pipe[1]); - stdout_pipe[1] = -1; - - subreq = get_anon_ipc_send(state, ev, state->conn->cli); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - - if (event_add_fd(ev, state, state->conn->stdout_fd, EVENT_FD_READ, - rpc_cli_smbd_stdout_reader, state->conn) == NULL) { - status = NT_STATUS_NO_MEMORY; - goto post_status; - } - - tevent_req_set_callback(subreq, rpc_cli_smbd_conn_init_done, req); - return req; - - post_status: - if (smb_sock[0] != -1) { - close(smb_sock[0]); - } - if (smb_sock[1] != -1) { - close(smb_sock[1]); - } - if (stdout_pipe[0] != -1) { - close(stdout_pipe[0]); - } - if (stdout_pipe[1] != -1) { - close(stdout_pipe[1]); - } - tevent_req_nterror(req, status); - return tevent_req_post(req, ev); -} - -static void rpc_cli_smbd_conn_init_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - NTSTATUS status; - - status = get_anon_ipc_recv(subreq); - TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - return; - } - tevent_req_done(req); -} - -NTSTATUS rpc_cli_smbd_conn_init_recv(struct tevent_req *req, - TALLOC_CTX *mem_ctx, - struct rpc_cli_smbd_conn **pconn) -{ - struct rpc_cli_smbd_conn_init_state *state = tevent_req_data( - req, struct rpc_cli_smbd_conn_init_state); - NTSTATUS status; - - if (tevent_req_is_nterror(req, &status)) { - return status; - } - *pconn = talloc_move(mem_ctx, &state->conn); - return NT_STATUS_OK; -} - -NTSTATUS rpc_cli_smbd_conn_init(TALLOC_CTX *mem_ctx, - struct rpc_cli_smbd_conn **pconn, - void (*stdout_callback)(char *buf, - size_t len, - void *priv), - void *priv) -{ - TALLOC_CTX *frame = talloc_stackframe(); - struct event_context *ev; - struct tevent_req *req; - NTSTATUS status; - - ev = event_context_init(frame); - if (ev == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - - req = rpc_cli_smbd_conn_init_send(frame, ev, stdout_callback, priv); - 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_cli_smbd_conn_init_recv(req, mem_ctx, pconn); - fail: - TALLOC_FREE(frame); - return status; -} - -static void rpc_smbd_disconnect(struct rpc_transport_smbd_state *transp) -{ - if (transp == NULL) { - return; - } - - if (transp->conn == NULL) { - return; - } - - if (transp->conn->cli == NULL) { - return; - } - - if (transp->conn->cli->fd != -1) { - close(transp->conn->cli->fd); - transp->conn->cli->fd = -1; - } - - transp->conn = NULL; -} - -static bool rpc_smbd_is_connected(void *priv) -{ - struct rpc_transport_smbd_state *transp = talloc_get_type_abort( - priv, struct rpc_transport_smbd_state); - bool ok; - - if (transp->conn == NULL) { - return false; - } - - if (transp->sub_transp == NULL) { - return false; - } - - ok = transp->sub_transp->is_connected(transp->sub_transp->priv); - if (!ok) { - rpc_smbd_disconnect(transp); - return false; - } - - return true; -} - -static unsigned int rpc_smbd_set_timeout(void *priv, unsigned int timeout) -{ - struct rpc_transport_smbd_state *transp = talloc_get_type_abort( - priv, struct rpc_transport_smbd_state); - bool ok; - - ok = rpc_smbd_is_connected(transp); - if (!ok) { - return 0; - } - - if (transp->sub_transp->set_timeout == NULL) { - return 0; - } - - return transp->sub_transp->set_timeout(transp->sub_transp->priv, timeout); -} - -struct rpc_smbd_write_state { - struct rpc_transport_smbd_state *transp; - ssize_t written; -}; - -static void rpc_smbd_write_done(struct tevent_req *subreq); - -static struct tevent_req *rpc_smbd_write_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - const uint8_t *data, size_t size, - void *priv) -{ - struct rpc_transport_smbd_state *transp = talloc_get_type_abort( - priv, struct rpc_transport_smbd_state); - struct tevent_req *req, *subreq; - struct rpc_smbd_write_state *state; - bool ok; - - req = tevent_req_create(mem_ctx, &state, struct rpc_smbd_write_state); - if (req == NULL) { - return NULL; - } - - ok = rpc_smbd_is_connected(transp); - if (!ok) { - tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID); - return tevent_req_post(req, ev); - } - - state->transp = transp; - - subreq = transp->sub_transp->write_send(state, ev, data, size, - transp->sub_transp->priv); - if (subreq == NULL) { - goto fail; - } - - if (event_add_fd(ev, state, transp->conn->stdout_fd, EVENT_FD_READ, - rpc_cli_smbd_stdout_reader, transp->conn) == NULL) { - goto fail; - } - tevent_req_set_callback(subreq, rpc_smbd_write_done, req); - return req; - - fail: - TALLOC_FREE(req); - return NULL; -} - -static void rpc_smbd_write_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct rpc_smbd_write_state *state = tevent_req_data( - req, struct rpc_smbd_write_state); - NTSTATUS status; - - status = state->transp->sub_transp->write_recv(subreq, &state->written); - TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - rpc_smbd_disconnect(state->transp); - tevent_req_nterror(req, status); - return; - } - tevent_req_done(req); -} - -static NTSTATUS rpc_smbd_write_recv(struct tevent_req *req, ssize_t *pwritten) -{ - struct rpc_smbd_write_state *state = tevent_req_data( - req, struct rpc_smbd_write_state); - NTSTATUS status; - - if (tevent_req_is_nterror(req, &status)) { - return status; - } - *pwritten = state->written; - return NT_STATUS_OK; -} - -struct rpc_smbd_read_state { - struct rpc_transport_smbd_state *transp; - ssize_t received; -}; - -static void rpc_smbd_read_done(struct tevent_req *subreq); - -static struct tevent_req *rpc_smbd_read_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - uint8_t *data, size_t size, - void *priv) -{ - struct rpc_transport_smbd_state *transp = talloc_get_type_abort( - priv, struct rpc_transport_smbd_state); - struct tevent_req *req, *subreq; - struct rpc_smbd_read_state *state; - bool ok; - - req = tevent_req_create(mem_ctx, &state, struct rpc_smbd_read_state); - if (req == NULL) { - return NULL; - } - - ok = rpc_smbd_is_connected(transp); - if (!ok) { - tevent_req_nterror(req, NT_STATUS_CONNECTION_INVALID); - return tevent_req_post(req, ev); - } - - state->transp = transp; - - subreq = transp->sub_transp->read_send(state, ev, data, size, - transp->sub_transp->priv); - if (subreq == NULL) { - goto fail; - } - - if (event_add_fd(ev, state, transp->conn->stdout_fd, EVENT_FD_READ, - rpc_cli_smbd_stdout_reader, transp->conn) == NULL) { - goto fail; - } - tevent_req_set_callback(subreq, rpc_smbd_read_done, req); - return req; - fail: - TALLOC_FREE(req); - return NULL; -} - -static void rpc_smbd_read_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct rpc_smbd_read_state *state = tevent_req_data( - req, struct rpc_smbd_read_state); - NTSTATUS status; - - status = state->transp->sub_transp->read_recv(subreq, &state->received); - TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - rpc_smbd_disconnect(state->transp); - tevent_req_nterror(req, status); - return; - } - tevent_req_done(req); -} - -static NTSTATUS rpc_smbd_read_recv(struct tevent_req *req, ssize_t *preceived) -{ - struct rpc_smbd_read_state *state = tevent_req_data( - req, struct rpc_smbd_read_state); - NTSTATUS status; - - if (tevent_req_is_nterror(req, &status)) { - return status; - } - *preceived = state->received; - return NT_STATUS_OK; -} - -struct rpc_transport_smbd_init_state { - struct rpc_cli_transport *transport; - struct rpc_transport_smbd_state *transport_smbd; -}; - -static void rpc_transport_smbd_init_done(struct tevent_req *subreq); - -struct tevent_req *rpc_transport_smbd_init_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_cli_smbd_conn *conn, - const struct ndr_syntax_id *abstract_syntax) -{ - struct tevent_req *req, *subreq; - struct rpc_transport_smbd_init_state *state; - - req = tevent_req_create(mem_ctx, &state, - struct rpc_transport_smbd_init_state); - if (req == NULL) { - return NULL; - } - - state->transport = talloc(state, struct rpc_cli_transport); - if (tevent_req_nomem(state->transport, req)) { - return tevent_req_post(req, ev); - } - state->transport_smbd = talloc(state->transport, - struct rpc_transport_smbd_state); - if (tevent_req_nomem(state->transport_smbd, req)) { - return tevent_req_post(req, ev); - } - state->transport_smbd->conn = conn; - state->transport->priv = state->transport_smbd; - - if (event_add_fd(ev, state, conn->stdout_fd, EVENT_FD_READ, - rpc_cli_smbd_stdout_reader, conn) == NULL) { - tevent_req_nterror(req, NT_STATUS_NO_MEMORY); - return tevent_req_post(req, ev); - } - - subreq = rpc_transport_np_init_send(state, ev, conn->cli, - abstract_syntax); - if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); - } - tevent_req_set_callback(subreq, rpc_transport_smbd_init_done, req); - return req; -} - -static void rpc_transport_smbd_init_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - struct rpc_transport_smbd_init_state *state = tevent_req_data( - req, struct rpc_transport_smbd_init_state); - NTSTATUS status; - - status = rpc_transport_np_init_recv( - subreq, state->transport_smbd, - &state->transport_smbd->sub_transp); - TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - return; - } - tevent_req_done(req); -} - -NTSTATUS rpc_transport_smbd_init_recv(struct tevent_req *req, - TALLOC_CTX *mem_ctx, - struct rpc_cli_transport **presult) -{ - struct rpc_transport_smbd_init_state *state = tevent_req_data( - req, struct rpc_transport_smbd_init_state); - NTSTATUS status; - - if (tevent_req_is_nterror(req, &status)) { - return status; - } - - state->transport->write_send = rpc_smbd_write_send; - state->transport->write_recv = rpc_smbd_write_recv; - state->transport->read_send = rpc_smbd_read_send; - state->transport->read_recv = rpc_smbd_read_recv; - state->transport->trans_send = NULL; - state->transport->trans_recv = NULL; - state->transport->is_connected = rpc_smbd_is_connected; - state->transport->set_timeout = rpc_smbd_set_timeout; - - *presult = talloc_move(mem_ctx, &state->transport); - return NT_STATUS_OK; -} - -NTSTATUS rpc_transport_smbd_init(TALLOC_CTX *mem_ctx, - struct rpc_cli_smbd_conn *conn, - const struct ndr_syntax_id *abstract_syntax, - struct rpc_cli_transport **presult) -{ - TALLOC_CTX *frame = talloc_stackframe(); - struct event_context *ev; - struct tevent_req *req; - NTSTATUS status; - - ev = event_context_init(frame); - if (ev == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - - req = rpc_transport_smbd_init_send(frame, ev, conn, abstract_syntax); - 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_transport_smbd_init_recv(req, mem_ctx, presult); - fail: - TALLOC_FREE(frame); - return status; -} |