From: Volker Lendecke Date: Sat, 16 Jan 2021 21:24:05 +0000 (+0100) Subject: rpc_server: Move socket creation to rpc_sock_helper.[ch] X-Git-Tag: tevent-0.11.0~1985 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=125c605ea5cc5afa50b8e1d3a8f718a997b57569;p=thirdparty%2Fsamba.git rpc_server: Move socket creation to rpc_sock_helper.[ch] dcesrv_create_ncacn_ip_tcp_sockets() already was there, move the rest as well. This makes dcesrv_create_ncacn_np_socket() static to rpc_sock_helper.c. Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison --- diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c index 9820be3216f..badb63ad84b 100644 --- a/source3/rpc_server/rpc_server.c +++ b/source3/rpc_server/rpc_server.c @@ -52,193 +52,6 @@ struct dcerpc_ncacn_listen_state { void *termination_data; }; -NTSTATUS dcesrv_create_ncacn_np_socket(struct dcerpc_binding *b, int *out_fd) -{ - char *np_dir = NULL; - int fd = -1; - NTSTATUS status; - const char *endpoint; - char *endpoint_normalized = NULL; - char *p = NULL; - - endpoint = dcerpc_binding_get_string_option(b, "endpoint"); - if (endpoint == NULL) { - DBG_ERR("Endpoint mandatory for named pipes\n"); - return NT_STATUS_INVALID_PARAMETER; - } - - /* The endpoint string from IDL can be mixed uppercase and case is - * normalized by smbd on connection */ - endpoint_normalized = strlower_talloc(talloc_tos(), endpoint); - if (endpoint_normalized == NULL) { - return NT_STATUS_NO_MEMORY; - } - - /* The endpoint string from IDL can be prefixed by \pipe\ */ - p = endpoint_normalized; - if (strncmp(p, "\\pipe\\", 6) == 0) { - p += 6; - } - - /* - * As lp_ncalrpc_dir() should have 0755, but - * lp_ncalrpc_dir()/np should have 0700, we need to - * create lp_ncalrpc_dir() first. - */ - if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) { - status = map_nt_error_from_unix_common(errno); - DBG_ERR("Failed to create pipe directory %s - %s\n", - lp_ncalrpc_dir(), strerror(errno)); - goto out; - } - - np_dir = talloc_asprintf(talloc_tos(), "%s/np", lp_ncalrpc_dir()); - if (!np_dir) { - status = NT_STATUS_NO_MEMORY; - DBG_ERR("Out of memory\n"); - goto out; - } - - if (!directory_create_or_exist_strict(np_dir, geteuid(), 0700)) { - status = map_nt_error_from_unix_common(errno); - DBG_ERR("Failed to create pipe directory %s - %s\n", - np_dir, strerror(errno)); - goto out; - } - - fd = create_pipe_sock(np_dir, p, 0700); - if (fd == -1) { - status = map_nt_error_from_unix_common(errno); - DBG_ERR("Failed to create ncacn_np socket! '%s/%s': %s\n", - np_dir, p, strerror(errno)); - goto out; - } - - DBG_DEBUG("Opened pipe socket fd %d for %s\n", fd, p); - - *out_fd = fd; - - status = NT_STATUS_OK; - -out: - TALLOC_FREE(endpoint_normalized); - TALLOC_FREE(np_dir); - return status; -} - -/******************************************************************** - * Start listening on the tcp/ip socket - ********************************************************************/ - -NTSTATUS dcesrv_create_ncacn_ip_tcp_socket(const struct sockaddr_storage *ifss, - uint16_t *port, - int *out_fd) -{ - int fd = -1; - - if (*port == 0) { - uint16_t i; - - for (i = lp_rpc_low_port(); i <= lp_rpc_high_port(); i++) { - fd = open_socket_in(SOCK_STREAM, - i, - 0, - ifss, - false); - if (fd >= 0) { - *port = i; - break; - } - } - } else { - fd = open_socket_in(SOCK_STREAM, - *port, - 0, - ifss, - true); - } - if (fd == -1) { - DBG_ERR("Failed to create socket on port %u!\n", *port); - return NT_STATUS_UNSUCCESSFUL; - } - - /* ready to listen */ - set_socket_options(fd, "SO_KEEPALIVE"); - set_socket_options(fd, lp_socket_options()); - - DBG_DEBUG("Opened ncacn_ip_tcp socket fd %d for port %u\n", fd, *port); - - *out_fd = fd; - - return NT_STATUS_OK; -} - -/******************************************************************** - * Start listening on the ncalrpc socket - ********************************************************************/ - -NTSTATUS dcesrv_create_ncalrpc_socket(struct dcerpc_binding *b, int *out_fd) -{ - int fd = -1; - const char *endpoint = NULL; - NTSTATUS status; - - endpoint = dcerpc_binding_get_string_option(b, "endpoint"); - if (endpoint == NULL) { - /* - * No identifier specified: use DEFAULT or SMBD. - * - * When role is AD DC we run two rpc server instances, the one - * started by 'samba' and the one embedded in 'smbd'. - * Avoid listening in DEFAULT socket for NCALRPC as both - * servers will race to accept connections. In this case smbd - * will listen in SMBD socket and rpcint binding handle - * implementation will pick the right socket to use. - * - * TODO: DO NOT hardcode this value anywhere else. Rather, - * specify no endpoint and let the epmapper worry about it. - */ - if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) { - endpoint = "SMBD"; - } else { - endpoint = "DEFAULT"; - } - status = dcerpc_binding_set_string_option( - b, "endpoint", endpoint); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to set ncalrpc 'endpoint' binding " - "string option to '%s': %s\n", - endpoint, nt_errstr(status)); - return status; - } - } - - if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) { - status = map_nt_error_from_unix_common(errno); - DBG_ERR("Failed to create ncalrpc directory '%s': %s\n", - lp_ncalrpc_dir(), strerror(errno)); - goto out; - } - - fd = create_pipe_sock(lp_ncalrpc_dir(), endpoint, 0755); - if (fd == -1) { - status = map_nt_error_from_unix_common(errno); - DBG_ERR("Failed to create ncalrpc socket '%s/%s': %s\n", - lp_ncalrpc_dir(), endpoint, strerror(errno)); - goto out; - } - - DBG_DEBUG("Opened ncalrpc socket fd '%d' for '%s/%s'\n", - fd, lp_ncalrpc_dir(), endpoint); - - *out_fd = fd; - - return NT_STATUS_OK; - -out: - return status; -} - static void dcesrv_ncacn_listener( struct tevent_context *ev, struct tevent_fd *fde, diff --git a/source3/rpc_server/rpc_server.h b/source3/rpc_server/rpc_server.h index 4365b0460c4..f735c394e83 100644 --- a/source3/rpc_server/rpc_server.h +++ b/source3/rpc_server/rpc_server.h @@ -67,13 +67,6 @@ NTSTATUS dcerpc_ncacn_conn_init(TALLOC_CTX *mem_ctx, void set_incoming_fault(struct pipes_struct *p); void process_complete_pdu(struct pipes_struct *p, struct ncacn_packet *pkt); -NTSTATUS dcesrv_create_ncacn_np_socket(struct dcerpc_binding *b, int *out_fd); - -NTSTATUS dcesrv_create_ncacn_ip_tcp_socket(const struct sockaddr_storage *ifss, - uint16_t *port, - int *out_fd); - -NTSTATUS dcesrv_create_ncalrpc_socket(struct dcerpc_binding *b, int *fd); struct dcerpc_ncacn_listen_state; int dcesrv_setup_ncacn_listener( diff --git a/source3/rpc_server/rpc_sock_helper.c b/source3/rpc_server/rpc_sock_helper.c index 75a432fb15b..852c87498ce 100644 --- a/source3/rpc_server/rpc_sock_helper.c +++ b/source3/rpc_server/rpc_sock_helper.c @@ -32,6 +32,126 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV +NTSTATUS dcesrv_create_ncacn_np_socket(struct dcerpc_binding *b, int *out_fd) +{ + char *np_dir = NULL; + int fd = -1; + NTSTATUS status; + const char *endpoint; + char *endpoint_normalized = NULL; + char *p = NULL; + + endpoint = dcerpc_binding_get_string_option(b, "endpoint"); + if (endpoint == NULL) { + DBG_ERR("Endpoint mandatory for named pipes\n"); + return NT_STATUS_INVALID_PARAMETER; + } + + /* The endpoint string from IDL can be mixed uppercase and case is + * normalized by smbd on connection */ + endpoint_normalized = strlower_talloc(talloc_tos(), endpoint); + if (endpoint_normalized == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* The endpoint string from IDL can be prefixed by \pipe\ */ + p = endpoint_normalized; + if (strncmp(p, "\\pipe\\", 6) == 0) { + p += 6; + } + + /* + * As lp_ncalrpc_dir() should have 0755, but + * lp_ncalrpc_dir()/np should have 0700, we need to + * create lp_ncalrpc_dir() first. + */ + if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) { + status = map_nt_error_from_unix_common(errno); + DBG_ERR("Failed to create pipe directory %s - %s\n", + lp_ncalrpc_dir(), strerror(errno)); + goto out; + } + + np_dir = talloc_asprintf(talloc_tos(), "%s/np", lp_ncalrpc_dir()); + if (!np_dir) { + status = NT_STATUS_NO_MEMORY; + DBG_ERR("Out of memory\n"); + goto out; + } + + if (!directory_create_or_exist_strict(np_dir, geteuid(), 0700)) { + status = map_nt_error_from_unix_common(errno); + DBG_ERR("Failed to create pipe directory %s - %s\n", + np_dir, strerror(errno)); + goto out; + } + + fd = create_pipe_sock(np_dir, p, 0700); + if (fd == -1) { + status = map_nt_error_from_unix_common(errno); + DBG_ERR("Failed to create ncacn_np socket! '%s/%s': %s\n", + np_dir, p, strerror(errno)); + goto out; + } + + DBG_DEBUG("Opened pipe socket fd %d for %s\n", fd, p); + + *out_fd = fd; + + status = NT_STATUS_OK; + +out: + TALLOC_FREE(endpoint_normalized); + TALLOC_FREE(np_dir); + return status; +} + +/******************************************************************** + * Start listening on the tcp/ip socket + ********************************************************************/ + +static NTSTATUS dcesrv_create_ncacn_ip_tcp_socket( + const struct sockaddr_storage *ifss, uint16_t *port, int *out_fd) +{ + int fd = -1; + + if (*port == 0) { + uint16_t i; + + for (i = lp_rpc_low_port(); i <= lp_rpc_high_port(); i++) { + fd = open_socket_in(SOCK_STREAM, + i, + 0, + ifss, + false); + if (fd >= 0) { + *port = i; + break; + } + } + } else { + fd = open_socket_in(SOCK_STREAM, + *port, + 0, + ifss, + true); + } + if (fd == -1) { + DBG_ERR("Failed to create socket on port %u!\n", *port); + return NT_STATUS_UNSUCCESSFUL; + } + + /* ready to listen */ + set_socket_options(fd, "SO_KEEPALIVE"); + set_socket_options(fd, lp_socket_options()); + + DBG_DEBUG("Opened ncacn_ip_tcp socket fd %d for port %u\n", fd, *port); + + *out_fd = fd; + + return NT_STATUS_OK; +} + NTSTATUS dcesrv_create_ncacn_ip_tcp_sockets( struct dcerpc_binding *b, TALLOC_CTX *mem_ctx, @@ -152,4 +272,70 @@ fail: return status; } +/******************************************************************** + * Start listening on the ncalrpc socket + ********************************************************************/ + +NTSTATUS dcesrv_create_ncalrpc_socket(struct dcerpc_binding *b, int *out_fd) +{ + int fd = -1; + const char *endpoint = NULL; + NTSTATUS status; + + endpoint = dcerpc_binding_get_string_option(b, "endpoint"); + if (endpoint == NULL) { + /* + * No identifier specified: use DEFAULT or SMBD. + * + * When role is AD DC we run two rpc server instances, the one + * started by 'samba' and the one embedded in 'smbd'. + * Avoid listening in DEFAULT socket for NCALRPC as both + * servers will race to accept connections. In this case smbd + * will listen in SMBD socket and rpcint binding handle + * implementation will pick the right socket to use. + * + * TODO: DO NOT hardcode this value anywhere else. Rather, + * specify no endpoint and let the epmapper worry about it. + */ + if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) { + endpoint = "SMBD"; + } else { + endpoint = "DEFAULT"; + } + status = dcerpc_binding_set_string_option( + b, "endpoint", endpoint); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("Failed to set ncalrpc 'endpoint' binding " + "string option to '%s': %s\n", + endpoint, nt_errstr(status)); + return status; + } + } + + if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) { + status = map_nt_error_from_unix_common(errno); + DBG_ERR("Failed to create ncalrpc directory '%s': %s\n", + lp_ncalrpc_dir(), strerror(errno)); + goto out; + } + + fd = create_pipe_sock(lp_ncalrpc_dir(), endpoint, 0755); + if (fd == -1) { + status = map_nt_error_from_unix_common(errno); + DBG_ERR("Failed to create ncalrpc socket '%s/%s': %s\n", + lp_ncalrpc_dir(), endpoint, strerror(errno)); + goto out; + } + + DBG_DEBUG("Opened ncalrpc socket fd '%d' for '%s/%s'\n", + fd, lp_ncalrpc_dir(), endpoint); + + *out_fd = fd; + + return NT_STATUS_OK; + +out: + return status; +} + /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */ diff --git a/source3/rpc_server/rpc_sock_helper.h b/source3/rpc_server/rpc_sock_helper.h index 0d673eb4959..0404a0e8d6c 100644 --- a/source3/rpc_server/rpc_sock_helper.h +++ b/source3/rpc_server/rpc_sock_helper.h @@ -27,6 +27,8 @@ struct pf_listen_fd; +NTSTATUS dcesrv_create_ncacn_np_socket(struct dcerpc_binding *b, int *out_fd); +NTSTATUS dcesrv_create_ncalrpc_socket(struct dcerpc_binding *b, int *fd); NTSTATUS dcesrv_create_ncacn_ip_tcp_sockets( struct dcerpc_binding *b, TALLOC_CTX *mem_ctx,