diff options
Diffstat (limited to 'source3/rpc_server/rpc_ncacn_np.c')
-rw-r--r-- | source3/rpc_server/rpc_ncacn_np.c | 98 |
1 files changed, 62 insertions, 36 deletions
diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c index e89a366f9e..f14aae540d 100644 --- a/source3/rpc_server/rpc_ncacn_np.c +++ b/source3/rpc_server/rpc_ncacn_np.c @@ -31,12 +31,13 @@ #include "../auth/auth_sam_reply.h" #include "auth.h" #include "ntdomain.h" +#include "../lib/tsocket/tsocket.h" +#include "../lib/util/tevent_ntstatus.h" +#include "rpc_contexts.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV -static int pipes_open; - static struct pipes_struct *InternalPipes; /* TODO @@ -102,11 +103,11 @@ int close_internal_rpc_pipe_hnd(struct pipes_struct *p) TALLOC_FREE(p->auth.auth_ctx); - free_pipe_rpc_context_internal( p->contexts ); - /* Free the handles database. */ close_policy_by_pipe(p); + free_pipe_rpc_context_internal( p->contexts ); + DLIST_REMOVE(InternalPipes, p); ZERO_STRUCTP(p); @@ -125,11 +126,12 @@ struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx, struct messaging_context *msg_ctx) { struct pipes_struct *p; + struct pipe_rpc_fns *context_fns; DEBUG(4,("Create pipe requested %s\n", get_pipe_name_from_syntax(talloc_tos(), syntax))); - p = TALLOC_ZERO_P(mem_ctx, struct pipes_struct); + p = talloc_zero(mem_ctx, struct pipes_struct); if (!p) { DEBUG(0,("ERROR! no memory for pipes_struct!\n")); @@ -167,11 +169,25 @@ struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx, p->endian = RPC_LITTLE_ENDIAN; - p->syntax = *syntax; p->transport = NCALRPC; - DEBUG(4,("Created internal pipe %s (pipes_open=%d)\n", - get_pipe_name_from_syntax(talloc_tos(), syntax), pipes_open)); + context_fns = SMB_MALLOC_P(struct pipe_rpc_fns); + if (context_fns == NULL) { + DEBUG(0,("malloc() failed!\n")); + return False; + } + + context_fns->next = context_fns->prev = NULL; + context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(syntax); + context_fns->cmds = rpc_srv_get_pipe_cmds(syntax); + context_fns->context_id = 0; + context_fns->syntax = *syntax; + + /* add to the list of open contexts */ + DLIST_ADD(p->contexts, context_fns); + + DEBUG(4,("Created internal pipe %s\n", + get_pipe_name_from_syntax(talloc_tos(), syntax))); talloc_set_destructor(p, close_internal_rpc_pipe_hnd); @@ -184,8 +200,9 @@ static NTSTATUS rpcint_dispatch(struct pipes_struct *p, const DATA_BLOB *in_data, DATA_BLOB *out_data) { - uint32_t num_cmds = rpc_srv_get_pipe_num_cmds(&p->syntax); - const struct api_struct *cmds = rpc_srv_get_pipe_cmds(&p->syntax); + struct pipe_rpc_fns *fns = find_pipe_fns_by_context(p->contexts, 0); + uint32_t num_cmds = fns->n_cmds; + const struct api_struct *cmds = fns->cmds; uint32_t i; bool ok; @@ -517,7 +534,8 @@ NTSTATUS rpcint_binding_handle(TALLOC_CTX *mem_ctx, * @brief Create a new RPC client context which uses a local transport. * * This creates a local transport. It is a shortcut to directly call the server - * functions and avoid marschalling. + * functions and avoid marshalling. + * NOTE: this function should be used only by rpc_pipe_open_interface() * * @param[in] mem_ctx The memory context to use. * @@ -534,19 +552,8 @@ NTSTATUS rpcint_binding_handle(TALLOC_CTX *mem_ctx, * * @return NT_STATUS_OK on success, a corresponding NT status if an * error occured. - * - * @code - * struct rpc_pipe_client *winreg_pipe; - * NTSTATUS status; - * - * status = rpc_pipe_open_internal(tmp_ctx, - * &ndr_table_winreg.syntax_id, - * p->session_info, - * client_id, - * &winreg_pipe); - * @endcode */ -NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx, +static NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *abstract_syntax, const struct auth_serversupplied_info *serversupplied_info, struct client_address *client_id, @@ -556,7 +563,7 @@ NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *result; NTSTATUS status; - result = TALLOC_ZERO_P(mem_ctx, struct rpc_pipe_client); + result = talloc_zero(mem_ctx, struct rpc_pipe_client); if (result == NULL) { return NT_STATUS_NO_MEMORY; } @@ -831,17 +838,36 @@ done: } /** - * @brief Create a new RPC client context which uses a local dispatch function. + * @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 mem_ctx The memory context on which thje pipe will ultimately - * be allocated - * @param name The pipe name to connect to. - * @param session_info Credentials to use for the connection. - * @param pipe [in|out] Checks if a pipe is connected, and connects it - * if not + * @param[in] client_id The client address information. * - * @return NT_STATUS_OK on success, a corresponding NT status if - * an error occured. + * @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 occured. + * + * @code + * struct rpc_pipe_client *winreg_pipe; + * NTSTATUS status; + * + * status = rpc_pipe_open_interface(tmp_ctx, + * &ndr_table_winreg.syntax_id, + * p->session_info, + * client_id, + * &winreg_pipe); + * @endcode */ NTSTATUS rpc_pipe_open_interface(TALLOC_CTX *mem_ctx, @@ -884,7 +910,7 @@ NTSTATUS rpc_pipe_open_interface(TALLOC_CTX *mem_ctx, "rpc_server", pipe_name, "embedded"); - if (StrCaseCmp(server_type, "embedded") == 0) { + if (strcasecmp_m(server_type, "embedded") == 0) { status = rpc_pipe_open_internal(tmp_ctx, syntax, session_info, client_id, msg_ctx, @@ -892,8 +918,8 @@ NTSTATUS rpc_pipe_open_interface(TALLOC_CTX *mem_ctx, if (!NT_STATUS_IS_OK(status)) { goto done; } - } else if (StrCaseCmp(server_type, "daemon") == 0 || - StrCaseCmp(server_type, "external") == 0) { + } else if (strcasecmp_m(server_type, "daemon") == 0 || + strcasecmp_m(server_type, "external") == 0) { /* It would be nice to just use rpc_pipe_open_ncalrpc() but * for now we need to use the special proxy setup to connect * to spoolssd. */ |