diff options
Diffstat (limited to 'source3/rpc_server/rpc_ncacn_np.c')
-rw-r--r-- | source3/rpc_server/rpc_ncacn_np.c | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c new file mode 100644 index 0000000..03618df --- /dev/null +++ b/source3/rpc_server/rpc_ncacn_np.c @@ -0,0 +1,217 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + */ + +#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_<name>. + * + * @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_<name>. + * + * @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; +} |