From: Volker Lendecke Date: Mon, 8 Feb 2021 15:21:03 +0000 (+0100) Subject: rpcclient: Let rpc_pipe_open_ncalrpc() figure out the dst sock itself X-Git-Tag: tevent-0.11.0~1447 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0426f11bf0f719f4056704e309140d21b1bbf6a7;p=thirdparty%2Fsamba.git rpcclient: Let rpc_pipe_open_ncalrpc() figure out the dst sock itself Let the epmapper take care of this, with "EPMAPPER" being the default socket that is connected for registration from ep_register() Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- diff --git a/source3/librpc/rpc/dcerpc_ep.c b/source3/librpc/rpc/dcerpc_ep.c index fec5f6ca1b7..66b8b975d75 100644 --- a/source3/librpc/rpc/dcerpc_ep.c +++ b/source3/librpc/rpc/dcerpc_ep.c @@ -44,7 +44,6 @@ static NTSTATUS ep_register(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli = NULL; struct dcerpc_binding_handle *h; struct pipe_auth_data *auth; - const char *ncalrpc_sock; enum rpc_service_mode_e epmd_mode; struct epm_entry_t *entries = NULL; uint32_t i = 0; @@ -115,17 +114,7 @@ static NTSTATUS ep_register(TALLOC_CTX *mem_ctx, } } else if (epmd_mode == RPC_SERVICE_MODE_EXTERNAL) { /* Connect to the endpoint mapper locally */ - ncalrpc_sock = talloc_asprintf(tmp_ctx, - "%s/%s", - lp_ncalrpc_dir(), - "EPMAPPER"); - if (ncalrpc_sock == NULL) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - status = rpc_pipe_open_ncalrpc(tmp_ctx, - ncalrpc_sock, &ndr_table_epmapper, &cli); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 58d5001b4c3..f60dd846d1c 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2982,31 +2982,106 @@ NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const char *host, table, presult); } +static NTSTATUS rpc_pipe_get_ncalrpc_name( + const struct ndr_syntax_id *iface, + TALLOC_CTX *mem_ctx, + char **psocket_name) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct rpc_pipe_client *epm_pipe = NULL; + struct pipe_auth_data *auth = NULL; + NTSTATUS status = NT_STATUS_OK; + bool is_epm; + + is_epm = ndr_syntax_id_equal(iface, &ndr_table_epmapper.syntax_id); + if (is_epm) { + char *endpoint = talloc_strdup(mem_ctx, "EPMAPPER"); + if (endpoint == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + *psocket_name = endpoint; + goto done; + } + + status = rpc_pipe_open_ncalrpc( + frame, &ndr_table_epmapper, &epm_pipe); + if (!NT_STATUS_IS_OK(status)) { + DBG_DEBUG("rpc_pipe_open_ncalrpc failed: %s\n", + nt_errstr(status)); + goto done; + } + + status = rpccli_anon_bind_data(epm_pipe, &auth); + if (!NT_STATUS_IS_OK(status)) { + DBG_DEBUG("rpccli_anon_bind_data failed: %s\n", + nt_errstr(status)); + goto done; + } + + status = rpc_pipe_bind(epm_pipe, auth); + if (!NT_STATUS_IS_OK(status)) { + DBG_DEBUG("rpc_pipe_bind failed: %s\n", nt_errstr(status)); + goto done; + } + + status = rpccli_epm_map_interface( + epm_pipe->binding_handle, + NCALRPC, + iface, + mem_ctx, + psocket_name); + if (!NT_STATUS_IS_OK(status)) { + DBG_DEBUG("rpccli_epm_map_interface failed: %s\n", + nt_errstr(status)); + } + +done: + TALLOC_FREE(frame); + return status; +} + /******************************************************************** Create a rpc pipe client struct, connecting to a unix domain socket ********************************************************************/ -NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path, +NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, struct rpc_pipe_client **presult) { + char *socket_name = NULL; struct rpc_pipe_client *result; struct sockaddr_un addr = { .sun_family = AF_UNIX }; socklen_t salen = sizeof(addr); - size_t pathlen; + int pathlen; NTSTATUS status; int fd = -1; - pathlen = strlcpy(addr.sun_path, socket_path, sizeof(addr.sun_path)); - if (pathlen >= sizeof(addr.sun_path)) { - DBG_DEBUG("socket_path %s too long\n", socket_path); - return NT_STATUS_NAME_TOO_LONG; - } - result = talloc_zero(mem_ctx, struct rpc_pipe_client); if (result == NULL) { return NT_STATUS_NO_MEMORY; } + status = rpc_pipe_get_ncalrpc_name( + &table->syntax_id, result, &socket_name); + if (!NT_STATUS_IS_OK(status)) { + DBG_DEBUG("rpc_pipe_get_ncalrpc_name failed: %s\n", + nt_errstr(status)); + goto fail; + } + + pathlen = snprintf( + addr.sun_path, + sizeof(addr.sun_path), + "%s/%s", + lp_ncalrpc_dir(), + socket_name); + if ((pathlen < 0) || ((size_t)pathlen >= sizeof(addr.sun_path))) { + DBG_DEBUG("socket_path for %s too long\n", socket_name); + status = NT_STATUS_NAME_TOO_LONG; + goto fail; + } + TALLOC_FREE(socket_name); + result->abstract_syntax = table->syntax_id; result->transfer_syntax = ndr_transfer_syntax_ndr; @@ -3032,8 +3107,9 @@ NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path, } if (connect(fd, (struct sockaddr *)(void *)&addr, salen) == -1) { - DEBUG(0, ("connect(%s) failed: %s\n", socket_path, - strerror(errno))); + DBG_ERR("connect(%s) failed: %s\n", + addr.sun_path, + strerror(errno)); status = map_nt_error_from_unix(errno); goto fail; } diff --git a/source3/rpc_client/cli_pipe.h b/source3/rpc_client/cli_pipe.h index 636fc4c16d0..d7fed6bed88 100644 --- a/source3/rpc_client/cli_pipe.h +++ b/source3/rpc_client/cli_pipe.h @@ -55,7 +55,7 @@ NTSTATUS rpc_pipe_open_tcp(TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, struct rpc_pipe_client **presult); -NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const char *socket_path, +NTSTATUS rpc_pipe_open_ncalrpc(TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, struct rpc_pipe_client **presult);