]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:rpc_server: Setup ncacn_np sockets through endpoint initialization
authorSamuel Cabrero <scabrero@suse.de>
Wed, 27 Feb 2019 17:58:15 +0000 (18:58 +0100)
committerSamuel Cabrero <scabrero@sn-devel-184>
Fri, 20 Mar 2020 15:36:34 +0000 (15:36 +0000)
Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source3/rpc_server/epmd.c
source3/rpc_server/fssd.c
source3/rpc_server/rpc_server.c
source3/rpc_server/rpc_server.h
source3/rpc_server/rpc_service_setup.c

index cdcd87c1e6f4d01ba47120204c00f527107398b4..2692276394d29039f076b7795405664fdfcf9abf 100644 (file)
@@ -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 */
index 1a7fab1620459ab41704679c760818dbbd4d6305..c625b45e10c6505e3063dedf7574c42667dc75dc 100644 (file)
@@ -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()));
 
index e96397302d1ed15a334951ea21c7e89b937b59de..d1d4e4f6f82f53388654826c8cc7c47523f39381 100644 (file)
@@ -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,
index b7154ab28eb8180580cf17a9ad5a53da14d8e513..6e81651f0e6ba7c7eb646f8333d34f32e3038082 100644 (file)
@@ -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,
index fe8de1b0199ff4d451aaf5fde34b3fbb24ef6ad3..0e77237fd6f05629d6dfd7982401a8781d652efb 100644 (file)
@@ -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: