From: Samuel Cabrero Date: Mon, 28 Jan 2019 09:57:53 +0000 (+0100) Subject: s3:prefork: Allow to associate private data with listening socket X-Git-Tag: talloc-2.3.0~21 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6964348bbfc8781be76ebd6a9f931648843a22f9;p=thirdparty%2Fsamba.git s3:prefork: Allow to associate private data with listening socket Prepare for merger RPC server codebase, where it will be necessary to stablish an association between the listening socket and the dcesrv_endpoint that the socket is serving. Signed-off-by: Samuel Cabrero Reviewed-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- diff --git a/source3/lib/server_prefork.c b/source3/lib/server_prefork.c index 52c11ad12fe..d3fb8d1a8bc 100644 --- a/source3/lib/server_prefork.c +++ b/source3/lib/server_prefork.c @@ -29,9 +29,8 @@ #include "../lib/util/tevent_unix.h" struct prefork_pool { - int listen_fd_size; - int *listen_fds; + struct pf_listen_fd *listen_fds; prefork_main_fn_t *main_fn; void *private_data; @@ -57,7 +56,7 @@ static int prefork_pool_destructor(struct prefork_pool *pfp) bool prefork_create_pool(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, - int listen_fd_size, int *listen_fds, + int listen_fd_size, struct pf_listen_fd *listen_fds, int min_children, int max_children, prefork_main_fn_t *main_fn, void *private_data, struct prefork_pool **pf_pool) @@ -76,7 +75,8 @@ bool prefork_create_pool(TALLOC_CTX *mem_ctx, return false; } pfp->listen_fd_size = listen_fd_size; - pfp->listen_fds = talloc_array(pfp, int, listen_fd_size); + pfp->listen_fds = talloc_array(pfp, struct pf_listen_fd, + listen_fd_size); if (!pfp->listen_fds) { DEBUG(1, ("Out of memory!\n")); return false; @@ -84,7 +84,7 @@ bool prefork_create_pool(TALLOC_CTX *mem_ctx, for (i = 0; i < listen_fd_size; i++) { pfp->listen_fds[i] = listen_fds[i]; /* force sockets in non-blocking mode */ - set_blocking(listen_fds[i], false); + set_blocking(listen_fds[i].fd, false); } pfp->main_fn = main_fn; pfp->private_data = private_data; @@ -498,9 +498,9 @@ struct pf_listen_state { struct pf_worker_data *pf; int listen_fd_size; - int *listen_fds; + struct pf_listen_fd *listen_fds; - int accept_fd; + struct pf_listen_fd accept; struct tsocket_address *srv_addr; struct tsocket_address *cli_addr; @@ -512,6 +512,7 @@ struct pf_listen_ctx { TALLOC_CTX *fde_ctx; struct tevent_req *req; int listen_fd; + void *listen_fd_data; }; static void prefork_listen_accept_handler(struct tevent_context *ev, @@ -522,7 +523,7 @@ struct tevent_req *prefork_listen_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct pf_worker_data *pf, int listen_fd_size, - int *listen_fds) + struct pf_listen_fd *listen_fds) { struct tevent_req *req; struct pf_listen_state *state; @@ -540,7 +541,8 @@ struct tevent_req *prefork_listen_send(TALLOC_CTX *mem_ctx, state->pf = pf; state->listen_fd_size = listen_fd_size; state->listen_fds = listen_fds; - state->accept_fd = -1; + state->accept.fd = -1; + state->accept.fd_data = NULL; state->error = 0; fde_ctx = talloc_new(state); @@ -556,7 +558,8 @@ struct tevent_req *prefork_listen_send(TALLOC_CTX *mem_ctx, } ctx->fde_ctx = fde_ctx; ctx->req = req; - ctx->listen_fd = state->listen_fds[i]; + ctx->listen_fd = state->listen_fds[i].fd; + ctx->listen_fd_data = state->listen_fds[i].fd_data; fde = tevent_add_fd(state->ev, fde_ctx, ctx->listen_fd, TEVENT_FD_READ, @@ -622,7 +625,8 @@ static void prefork_listen_accept_handler(struct tevent_context *ev, } smb_set_close_on_exec(sd); - state->accept_fd = sd; + state->accept.fd = sd; + state->accept.fd_data = ctx->listen_fd_data; ret = tsocket_address_bsd_from_sockaddr(state, (struct sockaddr *)(void *)&addr, @@ -656,6 +660,7 @@ done: int prefork_listen_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, int *fd, + void **fd_data, struct tsocket_address **srv_addr, struct tsocket_address **cli_addr) { @@ -673,11 +678,14 @@ int prefork_listen_recv(struct tevent_req *req, } if (ret) { - if (state->accept_fd != -1) { - close(state->accept_fd); + if (state->accept.fd != -1) { + close(state->accept.fd); } } else { - *fd = state->accept_fd; + *fd = state->accept.fd; + if (fd_data != NULL) { + *fd_data = state->accept.fd_data; + } *srv_addr = talloc_move(mem_ctx, &state->srv_addr); *cli_addr = talloc_move(mem_ctx, &state->cli_addr); state->pf->num_clients++; diff --git a/source3/lib/server_prefork.h b/source3/lib/server_prefork.h index af112a91a3e..179bbc0dff0 100644 --- a/source3/lib/server_prefork.h +++ b/source3/lib/server_prefork.h @@ -39,6 +39,19 @@ enum pf_server_cmds { PF_SRV_MSG_EXIT }; +/** + * @brief This structure contains a socket listening for clients and a + * private pointer with any data associated to that particular + * socket. + */ +struct pf_listen_fd { + /* The socket to listen on */ + int fd; + + /* The socket associated data */ + void *fd_data; +}; + /** * @brief This structure is shared between the controlling parent and the * the child. The parent can only write to the 'cmds' and @@ -79,7 +92,7 @@ typedef int (prefork_main_fn_t)(struct tevent_context *ev, struct pf_worker_data *pf, int child_id, int listen_fd_size, - int *listen_fds, + struct pf_listen_fd *pf_listen_fds, void *private_data); /** @@ -119,7 +132,7 @@ typedef void (prefork_sigchld_fn_t)(struct tevent_context *ev_ctx, bool prefork_create_pool(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, - int listen_fd_size, int *listen_fds, + int listen_fd_size, struct pf_listen_fd *listen_fds, int min_children, int max_children, prefork_main_fn_t *main_fn, void *private_data, struct prefork_pool **pf_pool); @@ -278,7 +291,7 @@ struct tevent_req *prefork_listen_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct pf_worker_data *pf, int listen_fd_size, - int *listen_fds); + struct pf_listen_fd *listen_fds); /** * @brief Returns the file descriptor after the new client connection has * been accepted. @@ -292,7 +305,7 @@ struct tevent_req *prefork_listen_send(TALLOC_CTX *mem_ctx, * @return The error in case the operation failed. */ int prefork_listen_recv(struct tevent_req *req, - TALLOC_CTX *mem_ctx, int *fd, + TALLOC_CTX *mem_ctx, int *fd, void **fd_data, struct tsocket_address **srv_addr, struct tsocket_address **cli_addr); diff --git a/source3/printing/spoolssd.c b/source3/printing/spoolssd.c index eef10860d84..8bc5aed2bd5 100644 --- a/source3/printing/spoolssd.c +++ b/source3/printing/spoolssd.c @@ -317,7 +317,7 @@ struct spoolss_children_data { struct messaging_context *msg_ctx; struct pf_worker_data *pf; int listen_fd_size; - int *listen_fds; + struct pf_listen_fd *listen_fds; }; static void spoolss_next_client(void *pvt); @@ -327,7 +327,7 @@ static int spoolss_children_main(struct tevent_context *ev_ctx, struct pf_worker_data *pf, int child_id, int listen_fd_size, - int *listen_fds, + struct pf_listen_fd *listen_fds, void *private_data) { struct spoolss_children_data *data; @@ -427,7 +427,7 @@ static void spoolss_handle_client(struct tevent_req *req) client = tevent_req_callback_data(req, struct spoolss_new_client); data = client->data; - ret = prefork_listen_recv(req, client, &sd, + ret = prefork_listen_recv(req, client, &sd, NULL, &client->srv_addr, &client->cli_addr); /* this will free the request too */ @@ -604,7 +604,7 @@ pid_t start_spoolssd(struct tevent_context *ev_ctx, TALLOC_CTX *mem_ctx; pid_t pid; NTSTATUS status; - int listen_fd; + struct pf_listen_fd listen_fds[1]; int ret; bool ok; @@ -665,12 +665,14 @@ pid_t start_spoolssd(struct tevent_context *ev_ctx, /* the listening fd must be created before the children are actually * forked out. */ - status = dcesrv_create_ncacn_np_socket(SPOOLSS_PIPE_NAME, &listen_fd); + status = dcesrv_create_ncacn_np_socket(SPOOLSS_PIPE_NAME, + &listen_fds[0].fd); if (!NT_STATUS_IS_OK(status)) { exit(1); } + listen_fds[0].fd_data = NULL; - ret = listen(listen_fd, pf_spoolss_cfg.max_allowed_clients); + ret = listen(listen_fds[0].fd, pf_spoolss_cfg.max_allowed_clients); if (ret == -1) { DEBUG(0, ("Failed to listen on spoolss pipe - %s\n", strerror(errno))); @@ -680,7 +682,7 @@ pid_t start_spoolssd(struct tevent_context *ev_ctx, /* start children before any more initialization is done */ ok = prefork_create_pool(ev_ctx, /* mem_ctx */ ev_ctx, msg_ctx, - 1, &listen_fd, + 1, listen_fds, pf_spoolss_cfg.min_children, pf_spoolss_cfg.max_children, &spoolss_children_main, NULL, diff --git a/source3/rpc_server/lsasd.c b/source3/rpc_server/lsasd.c index eb738158c1d..5bc0b740fa2 100644 --- a/source3/rpc_server/lsasd.c +++ b/source3/rpc_server/lsasd.c @@ -295,7 +295,7 @@ struct lsasd_children_data { struct messaging_context *msg_ctx; struct pf_worker_data *pf; int listen_fd_size; - int *listen_fds; + struct pf_listen_fd *listen_fds; }; static void lsasd_next_client(void *pvt); @@ -305,7 +305,7 @@ static int lsasd_children_main(struct tevent_context *ev_ctx, struct pf_worker_data *pf, int child_id, int listen_fd_size, - int *listen_fds, + struct pf_listen_fd *listen_fds, void *private_data) { struct lsasd_children_data *data; @@ -417,6 +417,7 @@ static void lsasd_handle_client(struct tevent_req *req) rc = prefork_listen_recv(req, tmp_ctx, &sd, + NULL, &srv_addr, &cli_addr); @@ -594,7 +595,7 @@ static void lsasd_check_children(struct tevent_context *ev_ctx, static bool lsasd_create_sockets(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, - int *listen_fd, + struct pf_listen_fd *listen_fd, int *listen_fd_size) { struct dcerpc_binding_vector *v, *v_orig; @@ -627,7 +628,7 @@ static bool lsasd_create_sockets(struct tevent_context *ev_ctx, /* Start to listen on tcpip sockets */ for (i = 0; i < *listen_fd_size; i++) { - rc = listen(listen_fd[i], pf_lsasd_cfg.max_allowed_clients); + rc = listen(listen_fd[i].fd, pf_lsasd_cfg.max_allowed_clients); if (rc == -1) { DEBUG(0, ("Failed to listen on tcpip socket - %s\n", strerror(errno))); @@ -647,7 +648,8 @@ static bool lsasd_create_sockets(struct tevent_context *ev_ctx, strerror(errno))); goto done; } - listen_fd[*listen_fd_size] = fd; + listen_fd[*listen_fd_size].fd = fd; + listen_fd[*listen_fd_size].fd_data = NULL; (*listen_fd_size)++; status = dcesrv_create_ncacn_np_socket("lsass", &fd); @@ -661,7 +663,8 @@ static bool lsasd_create_sockets(struct tevent_context *ev_ctx, strerror(errno))); goto done; } - listen_fd[*listen_fd_size] = fd; + listen_fd[*listen_fd_size].fd = fd; + listen_fd[*listen_fd_size].fd_data = NULL; (*listen_fd_size)++; status = dcesrv_create_ncalrpc_socket("lsarpc", &fd); @@ -675,7 +678,8 @@ static bool lsasd_create_sockets(struct tevent_context *ev_ctx, strerror(errno))); goto done; } - listen_fd[*listen_fd_size] = fd; + listen_fd[*listen_fd_size].fd = fd; + listen_fd[*listen_fd_size].fd_data = NULL; (*listen_fd_size)++; fd = -1; @@ -716,7 +720,8 @@ static bool lsasd_create_sockets(struct tevent_context *ev_ctx, strerror(errno))); goto done; } - listen_fd[*listen_fd_size] = fd; + listen_fd[*listen_fd_size].fd = fd; + listen_fd[*listen_fd_size].fd_data = NULL; (*listen_fd_size)++; status = dcesrv_create_ncalrpc_socket("samr", &fd); @@ -730,7 +735,8 @@ static bool lsasd_create_sockets(struct tevent_context *ev_ctx, strerror(errno))); goto done; } - listen_fd[*listen_fd_size] = fd; + listen_fd[*listen_fd_size].fd = fd; + listen_fd[*listen_fd_size].fd_data = NULL; (*listen_fd_size)++; fd = -1; @@ -771,7 +777,8 @@ static bool lsasd_create_sockets(struct tevent_context *ev_ctx, strerror(errno))); goto done; } - listen_fd[*listen_fd_size] = fd; + listen_fd[*listen_fd_size].fd = fd; + listen_fd[*listen_fd_size].fd_data = NULL; (*listen_fd_size)++; status = dcesrv_create_ncalrpc_socket("netlogon", &fd); @@ -785,7 +792,8 @@ static bool lsasd_create_sockets(struct tevent_context *ev_ctx, strerror(errno))); goto done; } - listen_fd[*listen_fd_size] = fd; + listen_fd[*listen_fd_size].fd = fd; + listen_fd[*listen_fd_size].fd_data = NULL; (*listen_fd_size)++; fd = -1; @@ -827,7 +835,7 @@ void start_lsasd(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx) { NTSTATUS status; - int listen_fd[LSASD_MAX_SOCKETS]; + struct pf_listen_fd listen_fd[LSASD_MAX_SOCKETS]; int listen_fd_size = 0; pid_t pid; int rc; diff --git a/source3/rpc_server/mdssd.c b/source3/rpc_server/mdssd.c index aa305b52304..37200e996f7 100644 --- a/source3/rpc_server/mdssd.c +++ b/source3/rpc_server/mdssd.c @@ -238,7 +238,7 @@ struct mdssd_children_data { struct messaging_context *msg_ctx; struct pf_worker_data *pf; int listen_fd_size; - int *listen_fds; + struct pf_listen_fd *listen_fds; }; static void mdssd_next_client(void *pvt); @@ -248,7 +248,7 @@ static int mdssd_children_main(struct tevent_context *ev_ctx, struct pf_worker_data *pf, int child_id, int listen_fd_size, - int *listen_fds, + struct pf_listen_fd *listen_fds, void *private_data) { struct mdssd_children_data *data; @@ -360,6 +360,7 @@ static void mdssd_handle_client(struct tevent_req *req) rc = prefork_listen_recv(req, tmp_ctx, &sd, + NULL, &srv_addr, &cli_addr); @@ -536,7 +537,7 @@ static void mdssd_check_children(struct tevent_context *ev_ctx, static bool mdssd_create_sockets(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, - int *listen_fd, + struct pf_listen_fd *listen_fd, int *listen_fd_size) { struct dcerpc_binding_vector *v, *v_orig; @@ -566,7 +567,8 @@ static bool mdssd_create_sockets(struct tevent_context *ev_ctx, if (rc == -1) { goto done; } - listen_fd[*listen_fd_size] = fd; + listen_fd[*listen_fd_size].fd = fd; + listen_fd[*listen_fd_size].fd_data = NULL; (*listen_fd_size)++; status = dcesrv_create_ncalrpc_socket("mdssvc", &fd); @@ -578,7 +580,8 @@ static bool mdssd_create_sockets(struct tevent_context *ev_ctx, if (rc == -1) { goto done; } - listen_fd[*listen_fd_size] = fd; + listen_fd[*listen_fd_size].fd = fd; + listen_fd[*listen_fd_size].fd_data = NULL; (*listen_fd_size)++; fd = -1; @@ -615,7 +618,7 @@ void start_mdssd(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx) { NTSTATUS status; - int listen_fd[MDSSD_MAX_SOCKETS]; + struct pf_listen_fd listen_fd[MDSSD_MAX_SOCKETS]; int listen_fd_size = 0; pid_t pid; int rc; diff --git a/source3/rpc_server/rpc_sock_helper.c b/source3/rpc_server/rpc_sock_helper.c index 4ade35ec908..1a3b61ff149 100644 --- a/source3/rpc_server/rpc_sock_helper.c +++ b/source3/rpc_server/rpc_sock_helper.c @@ -26,12 +26,13 @@ #include "librpc/rpc/dcerpc_ep.h" #include "rpc_server/rpc_server.h" #include "rpc_server/rpc_sock_helper.h" +#include "lib/server_prefork.h" NTSTATUS dcesrv_create_ncacn_ip_tcp_sockets( const struct ndr_interface_table *iface, struct dcerpc_binding_vector *bvec, uint16_t port, - int *listen_fd, + struct pf_listen_fd *listen_fd, int *listen_fd_size) { uint32_t num_ifs = iface_count(); @@ -67,7 +68,8 @@ NTSTATUS dcesrv_create_ncacn_ip_tcp_sockets( if (!NT_STATUS_IS_OK(status)) { goto done; } - listen_fd[*listen_fd_size] = fd; + listen_fd[*listen_fd_size].fd = fd; + listen_fd[*listen_fd_size].fd_data = NULL; (*listen_fd_size)++; if (bvec != NULL) { @@ -129,7 +131,8 @@ NTSTATUS dcesrv_create_ncacn_ip_tcp_sockets( if (!NT_STATUS_IS_OK(status)) { goto done; } - listen_fd[*listen_fd_size] = fd; + listen_fd[*listen_fd_size].fd = fd; + listen_fd[*listen_fd_size].fd_data = NULL; (*listen_fd_size)++; if (bvec != NULL) { diff --git a/source3/rpc_server/rpc_sock_helper.h b/source3/rpc_server/rpc_sock_helper.h index 9fd1c40bd0f..4aca3411de6 100644 --- a/source3/rpc_server/rpc_sock_helper.h +++ b/source3/rpc_server/rpc_sock_helper.h @@ -23,11 +23,13 @@ #ifndef _RPC_SOCK_HELPER_H_ #define _RPC_SOCK_HELPER_H_ +struct pf_listen_fd; + NTSTATUS dcesrv_create_ncacn_ip_tcp_sockets( const struct ndr_interface_table *iface, struct dcerpc_binding_vector *bvec, uint16_t port, - int *listen_fd, + struct pf_listen_fd *listen_fd, int *listen_fd_size); NTSTATUS dcesrv_setup_ncacn_ip_tcp_sockets(struct tevent_context *ev_ctx,