diff options
author | Samuel Cabrero <scabrero@samba.org> | 2019-09-06 15:16:01 +0200 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2019-12-12 00:35:31 +0000 |
commit | e24ce0023fa00a33d22f5f475e9280a8cad612c3 (patch) | |
tree | 0a026da32c67e7bac19789231a5f3a00969eec76 | |
parent | 79af978c815e6ad94797742c8755f4fe8142160e (diff) | |
download | samba-e24ce0023fa00a33d22f5f475e9280a8cad612c3.tar.gz |
pidl:NDR/Server: Allow to define endpoint server shutdown functions
The next commits will register legacy api_struct when the endpoint server
is initialized. This commit adds a shutdown function which will be used
to unregister the legacy api_struct.
The shutdown function will be also used to replace the rpc_srv_callbacks
struct shutdown member used, for example, by the spoolss service to
cleanup before exiting.
Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
-rw-r--r-- | librpc/rpc/dcesrv_core.c | 50 | ||||
-rw-r--r-- | librpc/rpc/dcesrv_core.h | 7 | ||||
-rw-r--r-- | pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm | 10 | ||||
-rw-r--r-- | source4/rpc_server/remote/dcesrv_remote.c | 7 | ||||
-rw-r--r-- | source4/torture/rpc/spoolss_notify.c | 7 |
5 files changed, 81 insertions, 0 deletions
diff --git a/librpc/rpc/dcesrv_core.c b/librpc/rpc/dcesrv_core.c index c1de3e62adf..4148c3f0f1a 100644 --- a/librpc/rpc/dcesrv_core.c +++ b/librpc/rpc/dcesrv_core.c @@ -2455,6 +2455,56 @@ _PUBLIC_ NTSTATUS dcesrv_init_ep_server(struct dcesrv_context *dce_ctx, return NT_STATUS_OK; } +_PUBLIC_ NTSTATUS dcesrv_shutdown_registered_ep_servers( + struct dcesrv_context *dce_ctx) +{ + NTSTATUS status; + int i; + + for (i = 0; i < num_ep_servers; i++) { + status = dcesrv_shutdown_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_shutdown_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; + } + + DBG_INFO("Shutting down DCE/RPC endpoint server '%s'\n", + ep_server_name); + + status = ep_server->shutdown_server(dce_ctx, ep_server); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("Failed to shutdown endpoint server '%s': %s\n", + ep_server_name, nt_errstr(status)); + return status; + } + + ep_server->initialized = false; + + return NT_STATUS_OK; +} + /* register a DCERPC endpoint server. diff --git a/librpc/rpc/dcesrv_core.h b/librpc/rpc/dcesrv_core.h index 4273176ea6f..74ce956032e 100644 --- a/librpc/rpc/dcesrv_core.h +++ b/librpc/rpc/dcesrv_core.h @@ -333,6 +333,10 @@ struct dcesrv_endpoint_server { */ NTSTATUS (*init_server)(struct dcesrv_context *, const struct dcesrv_endpoint_server *); + /* this function should cleanup endpoint server state and unregister + * the endpoint server from dcesrv_context */ + NTSTATUS (*shutdown_server)(struct dcesrv_context *, const struct dcesrv_endpoint_server *); + /* this function can be used by other endpoint servers to * ask for a dcesrv_interface implementation * - iface must be reference to an already existing struct ! @@ -450,8 +454,11 @@ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_serve 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_shutdown_registered_ep_servers(struct dcesrv_context *dce_ctx); NTSTATUS dcesrv_init_ep_server(struct dcesrv_context *dce_ctx, const char *ep_server_name); +NTSTATUS dcesrv_shutdown_ep_server(struct dcesrv_context *dce_ctx, + const char *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 68479893116..eed7d799c0e 100644 --- a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm +++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm @@ -240,6 +240,11 @@ static NTSTATUS $name\__op_init_server(struct dcesrv_context *dce_ctx, const str return NT_STATUS_OK; } +static NTSTATUS $name\__op_shutdown_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server) +{ + return NT_STATUS_OK; +} + static bool $name\__op_interface_by_uuid(struct dcesrv_interface *iface, const struct GUID *uuid, uint32_t if_version) { if (dcesrv_$name\_interface.syntax_id.if_version == if_version && @@ -277,6 +282,11 @@ NTSTATUS dcerpc_server_$name\_init(TALLOC_CTX *ctx) #else .init_server = $name\__op_init_server, #endif +#ifdef DCESRV_INTERFACE_$uname\_SHUTDOWN_SERVER + .shutdown_server = DCESRV_INTERFACE_$uname\_SHUTDOWN_SERVER, +#else + .shutdown_server = $name\__op_shutdown_server, +#endif .interface_by_uuid = $name\__op_interface_by_uuid, .interface_by_name = $name\__op_interface_by_name }; diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index e6e231f1e23..825c4cd9bd2 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -446,6 +446,12 @@ static NTSTATUS remote_op_init_server(struct dcesrv_context *dce_ctx, const stru return NT_STATUS_OK; } +static NTSTATUS remote_op_shutdown_server(struct dcesrv_context *dce_ctx, + const struct dcesrv_endpoint_server *ep_server) +{ + return NT_STATUS_OK; +} + static bool remote_fill_interface(struct dcesrv_interface *iface, const struct ndr_interface_table *if_tabl) { iface->name = if_tabl->name; @@ -500,6 +506,7 @@ NTSTATUS dcerpc_server_remote_init(TALLOC_CTX *ctx) /* fill in all the operations */ .init_server = remote_op_init_server, + .shutdown_server = remote_op_shutdown_server, .interface_by_uuid = remote_op_interface_by_uuid, .interface_by_name = remote_op_interface_by_name diff --git a/source4/torture/rpc/spoolss_notify.c b/source4/torture/rpc/spoolss_notify.c index 8d4a15f1569..8c17d76cd3c 100644 --- a/source4/torture/rpc/spoolss_notify.c +++ b/source4/torture/rpc/spoolss_notify.c @@ -262,6 +262,12 @@ static NTSTATUS spoolss__op_init_server(struct dcesrv_context *dce_ctx, const st return NT_STATUS_OK; } +static NTSTATUS spoolss__op_shutdown_server(struct dcesrv_context *dce_ctx, + const struct dcesrv_endpoint_server *ep_server) +{ + return NT_STATUS_OK; +} + static bool test_OpenPrinter(struct torture_context *tctx, struct dcerpc_pipe *p, struct policy_handle *handle, @@ -462,6 +468,7 @@ static bool test_start_dcerpc_server(struct torture_context *tctx, /* fill in all the operations */ ep_server.init_server = spoolss__op_init_server; + ep_server.shutdown_server = spoolss__op_shutdown_server; ep_server.interface_by_uuid = spoolss__op_interface_by_uuid; ep_server.interface_by_name = spoolss__op_interface_by_name; |