From: Samuel Cabrero Date: Wed, 27 Feb 2019 17:58:15 +0000 (+0100) Subject: s3:rpc_server: Setup ncacn_np sockets through endpoint initialization X-Git-Tag: ldb-2.2.0~1327 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=64a70a96100d244ad0f266768ef5e5452a2771af;p=thirdparty%2Fsamba.git s3:rpc_server: Setup ncacn_np sockets through endpoint initialization Signed-off-by: Samuel Cabrero Reviewed-by: Andrew Bartlett --- diff --git a/source3/rpc_server/epmd.c b/source3/rpc_server/epmd.c index cdcd87c1e6f..2692276394d 100644 --- a/source3/rpc_server/epmd.c +++ b/source3/rpc_server/epmd.c @@ -238,12 +238,6 @@ void start_epmd(struct tevent_context *ev_ctx, } } - status = dcesrv_setup_ncacn_np_socket("epmapper", ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Failed to open epmd named pipe!\n")); - exit(1); - } - DEBUG(1, ("Endpoint Mapper Daemon Started (%u)\n", (unsigned int)getpid())); /* loop forever */ diff --git a/source3/rpc_server/fssd.c b/source3/rpc_server/fssd.c index 1a7fab16204..c625b45e10c 100644 --- a/source3/rpc_server/fssd.c +++ b/source3/rpc_server/fssd.c @@ -227,13 +227,6 @@ void start_fssd(struct tevent_context *ev_ctx, } } - /* case is normalized by smbd on connection */ - status = dcesrv_setup_ncacn_np_socket("fssagentrpc", ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Failed to open fssd named pipe!\n")); - exit(1); - } - DEBUG(1, ("File Server Shadow-copy Daemon Started (%d)\n", (int)getpid())); diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c index e96397302d1..d1d4e4f6f82 100644 --- a/source3/rpc_server/rpc_server.c +++ b/source3/rpc_server/rpc_server.c @@ -155,28 +155,58 @@ out: return status; } -NTSTATUS dcesrv_setup_ncacn_np_socket(const char *pipe_name, - struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) +NTSTATUS dcesrv_setup_ncacn_np_socket(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, + struct dcesrv_context *dce_ctx, + struct dcesrv_endpoint *e, + dcerpc_ncacn_termination_fn term_fn, + void *term_data) { struct dcerpc_ncacn_listen_state *state; struct tevent_fd *fde; int rc; NTSTATUS status; + const char *endpoint = NULL; + 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; + } - state = talloc_zero(ev_ctx, struct dcerpc_ncacn_listen_state); + /* Alloc in endpoint context. If the endpoint is freed (for example + * when forked daemons reinit the dcesrv_context, the tevent_fd + * listener will be stopped and the socket closed */ + state = talloc_zero(e, struct dcerpc_ncacn_listen_state); if (state == NULL) { DBG_ERR("Out of memory\n"); return NT_STATUS_NO_MEMORY; } state->fd = -1; - state->ep.name = talloc_strdup(state, pipe_name); - if (state->ep.name == NULL) { - DBG_ERR("Out of memory\n"); - status = NT_STATUS_NO_MEMORY; - goto out; - } - status = dcesrv_create_ncacn_np_socket(pipe_name, &state->fd); + state->ev_ctx = ev_ctx; + state->msg_ctx = msg_ctx; + state->endpoint = e; + state->dce_ctx = talloc_reference(state, dce_ctx); + state->termination_fn = term_fn; + state->termination_data = term_data; + + status = dcesrv_create_ncacn_np_socket(p, &state->fd); if (!NT_STATUS_IS_OK(status)) { goto out; } @@ -185,15 +215,12 @@ NTSTATUS dcesrv_setup_ncacn_np_socket(const char *pipe_name, if (rc < 0) { status = map_nt_error_from_unix_common(errno); DBG_ERR("Failed to listen on ncacn_np socket %s: %s\n", - pipe_name, strerror(errno)); + endpoint, strerror(errno)); goto out; } - state->ev_ctx = ev_ctx; - state->msg_ctx = msg_ctx; - DBG_DEBUG("Opened pipe socket fd %d for %s\n", - state->fd, pipe_name); + state->fd, endpoint); errno = 0; fde = tevent_add_fd(ev_ctx, @@ -210,12 +237,16 @@ NTSTATUS dcesrv_setup_ncacn_np_socket(const char *pipe_name, } tevent_fd_set_auto_close(fde); + + TALLOC_FREE(endpoint_normalized); + return NT_STATUS_OK; out: if (state->fd != -1) { close(state->fd); } + TALLOC_FREE(endpoint_normalized); TALLOC_FREE(state); return status; } @@ -232,6 +263,7 @@ static void dcesrv_ncacn_np_listener(struct tevent_context *ev, .sa_socklen = sizeof(struct sockaddr_un), }; int sd = -1; + const char *endpoint = NULL; /* TODO: should we have a limit to the number of clients ? */ @@ -246,13 +278,21 @@ static void dcesrv_ncacn_np_listener(struct tevent_context *ev, } smb_set_close_on_exec(sd); + endpoint = dcerpc_binding_get_string_option( + state->endpoint->ep_description, "endpoint"); + if (endpoint == NULL) { + DBG_ERR("Failed to get endpoint from binding description\n"); + close(sd); + return; + } + DBG_DEBUG("Accepted ncacn_np socket %s (fd: %d)\n", addr.u.un.sun_path, sd); dcerpc_ncacn_accept(state->ev_ctx, state->msg_ctx, NCACN_NP, - state->ep.name, + endpoint, NULL, /* remote client address */ NULL, /* local server address */ sd, diff --git a/source3/rpc_server/rpc_server.h b/source3/rpc_server/rpc_server.h index b7154ab28eb..6e81651f0e6 100644 --- a/source3/rpc_server/rpc_server.h +++ b/source3/rpc_server/rpc_server.h @@ -78,9 +78,12 @@ int make_server_pipes_struct(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(const char *pipe_name, int *out_fd); -NTSTATUS dcesrv_setup_ncacn_np_socket(const char *pipe_name, - struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx); +NTSTATUS dcesrv_setup_ncacn_np_socket(struct tevent_context *ev_ctx, + struct messaging_context *msg_ctx, + struct dcesrv_context *dce_ctx, + struct dcesrv_endpoint *e, + dcerpc_ncacn_termination_fn term_fn, + void *term_data); NTSTATUS dcesrv_create_ncacn_ip_tcp_socket(const struct sockaddr_storage *ifss, uint16_t *port, diff --git a/source3/rpc_server/rpc_service_setup.c b/source3/rpc_server/rpc_service_setup.c index fe8de1b0199..0e77237fd6f 100644 --- a/source3/rpc_server/rpc_service_setup.c +++ b/source3/rpc_server/rpc_service_setup.c @@ -235,8 +235,12 @@ NTSTATUS dcesrv_setup_endpoint_sockets(struct tevent_context *ev_ctx, break; case NCACN_NP: - /* TODO */ - status = NT_STATUS_OK; + status = dcesrv_setup_ncacn_np_socket(ev_ctx, + msg_ctx, + dce_ctx, + e, + term_fn, + term_data); break; default: