The branch, master has been updated via 17a8fa6d242 rpc_server: Add CLOEXEC to the listening sockets via 585b093ce86 lib: Provide a meaningful errno if FD_CLOEXEC is missing via d4e46cae4c8 rpc_server: Consolidate transport-specific socket creation via 125c605ea5c rpc_server: Move socket creation to rpc_sock_helper.[ch] via 27987e313f9 rpc_server: Factor out e->ep_description in dcesrv_create_endpoint_sockets() via 1c889f4475e rpc_server: Pass dcerpc_binding to dcesrv_create_ncacn_np_socket() via e74d5208554 rpc_server: Pass dcerpc_binding to dcesrv_create_ncacn_ip_tcp_sockets() via cc456ac882a rpc_server: Pass dcerpc_binding to dcesrv_create_ncalrpc_socket() via f0aa39017b6 rpc_server: Remove an unused function parameter from da3b00f5511 vfs: Fix the FreeBSD build
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 17a8fa6d242ee9c898a1fdb5ab340223702fcced Author: Volker Lendecke <v...@samba.org> Date: Fri Jan 22 11:15:41 2021 +0100 rpc_server: Add CLOEXEC to the listening sockets We don't want to leak them into exec'ed processes. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Tue Jan 26 01:13:53 UTC 2021 on sn-devel-184 commit 585b093ce861bbf06d29237481e6a0a748be9156 Author: Volker Lendecke <v...@samba.org> Date: Fri Jan 22 11:13:53 2021 +0100 lib: Provide a meaningful errno if FD_CLOEXEC is missing Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit d4e46cae4c85151dde14f7fd1ad2bda065687cfc Author: Volker Lendecke <v...@samba.org> Date: Sat Jan 16 22:40:37 2021 +0100 rpc_server: Consolidate transport-specific socket creation We had the transport switch in two places, put them together into dcesrv_create_binding_sockets(). This makes the transport-specific socket creation functions static to rpc_sock_helper.c. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 125c605ea5cc5afa50b8e1d3a8f718a997b57569 Author: Volker Lendecke <v...@samba.org> Date: Sat Jan 16 22:24:05 2021 +0100 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 <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 27987e313f9c8feab3a1451cca380dc706c96203 Author: Volker Lendecke <v...@samba.org> Date: Sat Jan 16 21:32:19 2021 +0100 rpc_server: Factor out e->ep_description in dcesrv_create_endpoint_sockets() e->ep_description is used a lot in this function. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 1c889f4475efac2038f0c2ed7fe6c6dedb32b912 Author: Volker Lendecke <v...@samba.org> Date: Sat Jan 16 21:22:06 2021 +0100 rpc_server: Pass dcerpc_binding to dcesrv_create_ncacn_np_socket() It does not need a dcesrv_endpoint. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit e74d52085543eb0a5f2fe91ef5973f1eace84a5a Author: Volker Lendecke <v...@samba.org> Date: Sat Jan 16 20:32:38 2021 +0100 rpc_server: Pass dcerpc_binding to dcesrv_create_ncacn_ip_tcp_sockets() It does not need a dcesrv_endpoint. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit cc456ac882a59b134be34aced82c01d8fcce6d72 Author: Volker Lendecke <v...@samba.org> Date: Sat Jan 16 20:28:42 2021 +0100 rpc_server: Pass dcerpc_binding to dcesrv_create_ncalrpc_socket() It does not need a dcesrv_endpoint. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit f0aa39017b62d46a99e73aa62e8208281382d479 Author: Volker Lendecke <v...@samba.org> Date: Sat Jan 16 17:32:53 2021 +0100 rpc_server: Remove an unused function parameter dcesrv_create_endpoint_sockets() doesn't need dce_ctx. Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: lib/util/blocking.c | 2 + source3/rpc_server/rpc_server.c | 190 ------------------------ source3/rpc_server/rpc_server.h | 7 - source3/rpc_server/rpc_service_setup.c | 70 ++------- source3/rpc_server/rpc_service_setup.h | 1 - source3/rpc_server/rpc_sock_helper.c | 257 ++++++++++++++++++++++++++++++++- source3/rpc_server/rpc_sock_helper.h | 8 +- 7 files changed, 267 insertions(+), 268 deletions(-) Changeset truncated at 500 lines: diff --git a/lib/util/blocking.c b/lib/util/blocking.c index 0d845c0b2c4..6d7fc910676 100644 --- a/lib/util/blocking.c +++ b/lib/util/blocking.c @@ -69,6 +69,8 @@ _PUBLIC_ bool smb_set_close_on_exec(int fd) return true; } } +#else + errno = ENOSYS; #endif return false; } diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c index 20b727b64df..badb63ad84b 100644 --- a/source3/rpc_server/rpc_server.c +++ b/source3/rpc_server/rpc_server.c @@ -52,196 +52,6 @@ struct dcerpc_ncacn_listen_state { void *termination_data; }; -NTSTATUS dcesrv_create_ncacn_np_socket(struct dcesrv_endpoint *e, 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(e->ep_description, - "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 dcesrv_endpoint *e, int *out_fd) -{ - int fd = -1; - const char *endpoint = NULL; - NTSTATUS status; - - endpoint = dcerpc_binding_get_string_option(e->ep_description, - "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(e->ep_description, - "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 e4a18eb830a..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 dcesrv_endpoint *e, 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 dcesrv_endpoint *e, int *fd); struct dcerpc_ncacn_listen_state; int dcesrv_setup_ncacn_listener( diff --git a/source3/rpc_server/rpc_service_setup.c b/source3/rpc_server/rpc_service_setup.c index 94cf0de2c00..4d4af724126 100644 --- a/source3/rpc_server/rpc_service_setup.c +++ b/source3/rpc_server/rpc_service_setup.c @@ -87,57 +87,29 @@ NTSTATUS rpc_setup_embedded(struct tevent_context *ev_ctx, NTSTATUS dcesrv_create_endpoint_sockets(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e, TALLOC_CTX *mem_ctx, size_t *pnum_fds, int **pfds) { - enum dcerpc_transport_t transport = - dcerpc_binding_get_transport(e->ep_description); + struct dcerpc_binding *b = e->ep_description; char *binding = NULL; int *fds = NULL; size_t num_fds; NTSTATUS status; - binding = dcerpc_binding_string(mem_ctx, e->ep_description); + binding = dcerpc_binding_string(mem_ctx, b); if (binding == NULL) { return NT_STATUS_NO_MEMORY; } DBG_DEBUG("Creating endpoint '%s'\n", binding); TALLOC_FREE(binding); - fds = talloc(mem_ctx, int); - if (fds == NULL) { - return NT_STATUS_NO_MEMORY; - } - num_fds = 1; - - switch (transport) { - case NCALRPC: - status = dcesrv_create_ncalrpc_socket(e, fds); - break; - - case NCACN_IP_TCP: { - TALLOC_FREE(fds); - - status = dcesrv_create_ncacn_ip_tcp_sockets( - e, talloc_tos(), &num_fds, &fds); - break; - } - - case NCACN_NP: - status = dcesrv_create_ncacn_np_socket(e, fds); - break; - - default: - status = NT_STATUS_NOT_SUPPORTED; - break; - } + status = dcesrv_create_binding_sockets(b, mem_ctx, &num_fds, &fds); /* Build binding string again as the endpoint may have changed by * dcesrv_create_<transport>_socket functions */ - binding = dcerpc_binding_string(mem_ctx, e->ep_description); + binding = dcerpc_binding_string(mem_ctx, b); if (binding == NULL) { return NT_STATUS_NO_MEMORY; } @@ -188,7 +160,6 @@ NTSTATUS dcesrv_create_endpoint_list_pf_listen_fds( status = dcesrv_create_endpoint_sockets( ev_ctx, msg_ctx, - dce_ctx, e, mem_ctx, &num_ep_fds, @@ -252,46 +223,27 @@ NTSTATUS dcesrv_setup_endpoint_sockets(struct tevent_context *ev_ctx, void *term_data) { TALLOC_CTX *frame = talloc_stackframe(); - enum dcerpc_transport_t transport = - dcerpc_binding_get_transport(e->ep_description); + struct dcerpc_binding *b = e->ep_description; char *binding = NULL; NTSTATUS status = NT_STATUS_NO_MEMORY; struct dcesrv_if_list *iface = NULL; - int fd = -1; - int *fds = &fd; - size_t i, num_fds = 1; + int *fds = NULL; + size_t i, num_fds = 0; struct dcerpc_ncacn_listen_state **listen_states = NULL; - binding = dcerpc_binding_string(frame, e->ep_description); + binding = dcerpc_binding_string(frame, b); if (binding == NULL) { goto fail; } DBG_DEBUG("Setting up endpoint '%s'\n", binding); + TALLOC_FREE(binding); - switch (transport) { - case NCALRPC: - status = dcesrv_create_ncalrpc_socket(e, &fd); - break; - - case NCACN_IP_TCP: - status = dcesrv_create_ncacn_ip_tcp_sockets( - e, frame, &num_fds, &fds); - break; - - case NCACN_NP: - status = dcesrv_create_ncacn_np_socket(e, &fd); - break; - - default: - status = NT_STATUS_NOT_SUPPORTED; - break; - } + status = dcesrv_create_binding_sockets(b, frame, &num_fds, &fds); /* Build binding string again as the endpoint may have changed by * dcesrv_create_<transport>_socket functions */ - TALLOC_FREE(binding); - binding = dcerpc_binding_string(frame, e->ep_description); + binding = dcerpc_binding_string(frame, b); if (binding == NULL) { status = NT_STATUS_NO_MEMORY; goto fail; diff --git a/source3/rpc_server/rpc_service_setup.h b/source3/rpc_server/rpc_service_setup.h index 0288dab539a..668561794ff 100644 --- a/source3/rpc_server/rpc_service_setup.h +++ b/source3/rpc_server/rpc_service_setup.h @@ -40,7 +40,6 @@ NTSTATUS dcesrv_setup_endpoint_sockets(struct tevent_context *ev_ctx, NTSTATUS dcesrv_create_endpoint_sockets(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e, TALLOC_CTX *mem_ctx, size_t *pnum_fds, diff --git a/source3/rpc_server/rpc_sock_helper.c b/source3/rpc_server/rpc_sock_helper.c index 27d5cda9c4e..4b998962c8e 100644 --- a/source3/rpc_server/rpc_sock_helper.c +++ b/source3/rpc_server/rpc_sock_helper.c @@ -32,8 +32,129 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV -NTSTATUS dcesrv_create_ncacn_ip_tcp_sockets( - struct dcesrv_endpoint *e, +static 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; + -- Samba Shared Repository