From 90eb485cf9d8eaecfab31044e52e8f41b3a51452 Mon Sep 17 00:00:00 2001 From: Samuel Cabrero Date: Fri, 6 Sep 2019 14:38:29 +0200 Subject: [PATCH] librpc:core: Add public functions to initialize endpoint servers The dcesrv_init_registered_ep_servers() will be used by the S3 server to initialize all registered endpoint servers (for embedded services), and the dcesrv_init_ep_server() function will be used by the external daemons to initialize the required ones. As serveral S3 services may require to initialize another one before itself (svcctl and eventlog for example require winreg) a boolean flag is added to track the initialization status. Signed-off-by: Samuel Cabrero Reviewed-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett --- librpc/rpc/dcesrv_core.c | 61 +++++++++++++++++++---- librpc/rpc/dcesrv_core.h | 6 +++ pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm | 3 ++ source4/rpc_server/remote/dcesrv_remote.c | 2 + source4/torture/rpc/spoolss_notify.c | 2 + 5 files changed, 63 insertions(+), 11 deletions(-) diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c index 5e548a288d0..5ecb815b0ad 100644 --- a/librpc/rpc/dcesrv_core.c +++ b/librpc/rpc/dcesrv_core.c @@ -2361,18 +2361,10 @@ _PUBLIC_ NTSTATUS dcesrv_init_ep_servers(struct dcesrv_context *dce_ctx, } for (i=0;endpoint_servers[i];i++) { - const struct dcesrv_endpoint_server *ep_server; - - ep_server = dcesrv_ep_server_byname(endpoint_servers[i]); - if (!ep_server) { - DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i])); - return NT_STATUS_INTERNAL_ERROR; - } - - status = ep_server->init_server(dce_ctx, ep_server); + status = dcesrv_init_ep_server(dce_ctx, endpoint_servers[i]); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i], - nt_errstr(status))); + DBG_ERR("failed to init endpoint server = '%s': %s\n", + endpoint_servers[i], nt_errstr(status)); return status; } } @@ -2387,6 +2379,53 @@ static struct ep_server { } *ep_servers = NULL; static int num_ep_servers = 0; +_PUBLIC_ NTSTATUS dcesrv_init_registered_ep_servers( + struct dcesrv_context *dce_ctx) +{ + NTSTATUS status; + int i; + + for (i = 0; i < num_ep_servers; i++) { + status = dcesrv_init_ep_server(dce_ctx, + ep_servers[i].ep_server->name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + return NT_STATUS_OK; +} + +_PUBLIC_ NTSTATUS dcesrv_init_ep_server(struct dcesrv_context *dce_ctx, + const char *ep_server_name) +{ + struct dcesrv_endpoint_server *ep_server = NULL; + NTSTATUS status; + + ep_server = discard_const_p(struct dcesrv_endpoint_server, + dcesrv_ep_server_byname(ep_server_name)); + if (ep_server == NULL) { + DBG_ERR("Failed to find endpoint server '%s'\n", + ep_server_name); + return NT_STATUS_INTERNAL_ERROR; + } + + if (ep_server->initialized) { + return NT_STATUS_OK; + } + + status = ep_server->init_server(dce_ctx, ep_server); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("Failed to init endpoint server '%s': %s\n", + ep_server_name, nt_errstr(status)); + return status; + } + + ep_server->initialized = true; + + return NT_STATUS_OK; +} + /* register a DCERPC endpoint server. diff --git a/librpc/rpc/dcesrv_core.h b/librpc/rpc/dcesrv_core.h index e5ad652a4e2..81f9a8a1633 100644 --- a/librpc/rpc/dcesrv_core.h +++ b/librpc/rpc/dcesrv_core.h @@ -325,6 +325,9 @@ struct dcesrv_endpoint_server { /* this is the name of the endpoint server */ const char *name; + /* true if the endpoint server has been initialized */ + bool initialized; + /* this function should register endpoints and some other setup stuff, * it is called when the dcesrv_context gets initialized. */ @@ -446,6 +449,9 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server); NTSTATUS dcesrv_init_ep_servers(struct dcesrv_context *dce_ctx, const char **ep_servers); +NTSTATUS dcesrv_init_registered_ep_servers(struct dcesrv_context *dce_ctx); +NTSTATUS dcesrv_init_ep_server(struct dcesrv_context *dce_ctx, + const char *ep_server_name); const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name); NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm index 01974ed244b..68479893116 100644 --- a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm +++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm @@ -268,6 +268,9 @@ NTSTATUS dcerpc_server_$name\_init(TALLOC_CTX *ctx) /* fill in our name */ .name = \"$name\", + /* Initialization flag */ + .initialized = false, + /* fill in all the operations */ #ifdef DCESRV_INTERFACE_$uname\_INIT_SERVER .init_server = DCESRV_INTERFACE_$uname\_INIT_SERVER, diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index 8de9190e03e..e6e231f1e23 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -496,6 +496,8 @@ NTSTATUS dcerpc_server_remote_init(TALLOC_CTX *ctx) /* fill in our name */ .name = "remote", + .initialized = false, + /* fill in all the operations */ .init_server = remote_op_init_server, diff --git a/source4/torture/rpc/spoolss_notify.c b/source4/torture/rpc/spoolss_notify.c index 9b183ac49ae..8d4a15f1569 100644 --- a/source4/torture/rpc/spoolss_notify.c +++ b/source4/torture/rpc/spoolss_notify.c @@ -458,6 +458,8 @@ static bool test_start_dcerpc_server(struct torture_context *tctx, /* fill in our name */ ep_server.name = "spoolss"; + ep_server.initialized = false; + /* fill in all the operations */ ep_server.init_server = spoolss__op_init_server;