/* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1998, * Largely re-written : 2005 * Copyright (C) Jeremy Allison 1998 - 2005 * Copyright (C) Simo Sorce 2010 * Copyright (C) Andrew Bartlett 2011 * * 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 . */ #include "includes.h" #include "rpc_client/cli_pipe.h" #include "rpc_dce.h" #include "../libcli/named_pipe_auth/npa_tstream.h" #include "rpc_server/rpc_ncacn_np.h" #include "librpc/gen_ndr/netlogon.h" #include "librpc/gen_ndr/auth.h" #include "../auth/auth_sam_reply.h" #include "../auth/auth_util.h" #include "auth.h" #include "rpc_server/rpc_pipes.h" #include "../lib/tsocket/tsocket.h" #include "../lib/util/tevent_ntstatus.h" #include "rpc_server/rpc_config.h" #include "librpc/ndr/ndr_table.h" #include "rpc_server/rpc_server.h" #include "librpc/rpc/dcerpc_util.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV struct np_proxy_state { uint16_t file_type; uint16_t device_state; uint64_t allocation_size; struct tstream_context *npipe; struct tevent_queue *read_queue; struct tevent_queue *write_queue; }; struct npa_state *npa_state_init(TALLOC_CTX *mem_ctx) { struct npa_state *npa; npa = talloc_zero(mem_ctx, struct npa_state); if (npa == NULL) { return NULL; } npa->read_queue = tevent_queue_create(npa, "npa_cli_read"); if (npa->read_queue == NULL) { DEBUG(0, ("tevent_queue_create failed\n")); goto fail; } npa->write_queue = tevent_queue_create(npa, "npa_cli_write"); if (npa->write_queue == NULL) { DEBUG(0, ("tevent_queue_create failed\n")); goto fail; } return npa; fail: talloc_free(npa); return NULL; } /** * @brief Create a new DCERPC Binding Handle which uses a local dispatch function. * * @param[in] mem_ctx The memory context to use. * * @param[in] ndr_table Normally the ndr_table_. * * @param[in] remote_address The info about the connected client. * * @param[in] serversupplied_info The server supplied authentication function. * * @param[in] msg_ctx The messaging context that can be used by the server * * @param[out] binding_handle A pointer to store the connected * dcerpc_binding_handle * * @return NT_STATUS_OK on success, a corresponding NT status if an * error occurred. * * @code * struct dcerpc_binding_handle *winreg_binding; * NTSTATUS status; * * status = rpcint_binding_handle(tmp_ctx, * &ndr_table_winreg, * p->remote_address, * p->session_info, * p->msg_ctx * &winreg_binding); * @endcode */ NTSTATUS rpcint_binding_handle(TALLOC_CTX *mem_ctx, const struct ndr_interface_table *ndr_table, const struct tsocket_address *remote_address, const struct tsocket_address *local_address, const struct auth_session_info *session_info, struct messaging_context *msg_ctx, struct dcerpc_binding_handle **binding_handle) { struct rpc_pipe_client *rpccli = NULL; NTSTATUS status; status = rpc_pipe_open_local_np( mem_ctx, ndr_table, NULL, remote_address, NULL, local_address, session_info, &rpccli); if (!NT_STATUS_IS_OK(status)) { DBG_DEBUG("rpc_pipe_open_local_np failed: %s\n", nt_errstr(status)); goto fail; } *binding_handle = rpccli->binding_handle; return NT_STATUS_OK; fail: TALLOC_FREE(rpccli); return status; } /** * @brief Create a new RPC client context which uses a local dispatch function * or a remote transport, depending on rpc_server configuration for the * specific service. * * @param[in] mem_ctx The memory context to use. * * @param[in] abstract_syntax Normally the syntax_id of the autogenerated * ndr_table_. * * @param[in] serversupplied_info The server supplied authentication function. * * @param[in] remote_address The client address information. * * @param[in] msg_ctx The messaging context to use. * * @param[out] presult A pointer to store the connected rpc client pipe. * * @return NT_STATUS_OK on success, a corresponding NT status if an * error occurred. * * @code * struct rpc_pipe_client *winreg_pipe; * NTSTATUS status; * * status = rpc_pipe_open_interface(tmp_ctx, * &ndr_table_winreg.syntax_id, * p->session_info, * remote_address, * &winreg_pipe); * @endcode */ NTSTATUS rpc_pipe_open_interface(TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, const struct auth_session_info *session_info, const struct tsocket_address *remote_address, const struct tsocket_address *local_address, struct messaging_context *msg_ctx, struct rpc_pipe_client **cli_pipe) { struct rpc_pipe_client *cli = NULL; NTSTATUS status; if (cli_pipe != NULL) { if (rpccli_is_connected(*cli_pipe)) { return NT_STATUS_OK; } else { TALLOC_FREE(*cli_pipe); } } status = rpc_pipe_open_local_np( mem_ctx, table, NULL, remote_address, NULL, local_address, session_info, &cli); if (!NT_STATUS_IS_OK(status)) { DBG_ERR("Could not connect to %s pipe: %s\n", table->name, nt_errstr(status)); return status; } if (NT_STATUS_IS_OK(status) && cli_pipe != NULL) { *cli_pipe = cli; } return status; }