]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
pidl:NDR/Server: Allow to define endpoint server shutdown functions
authorSamuel Cabrero <scabrero@samba.org>
Fri, 6 Sep 2019 13:16:01 +0000 (15:16 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 12 Dec 2019 00:35:31 +0000 (00:35 +0000)
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>
librpc/rpc/dcesrv_core.c
librpc/rpc/dcesrv_core.h
pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm
source4/rpc_server/remote/dcesrv_remote.c
source4/torture/rpc/spoolss_notify.c

index c1de3e62adfb03aadb0be2e3255501b2d17de6ef..4148c3f0f1af8c7c3d46c1f4f1aadd1bea2e6bb4 100644 (file)
@@ -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.
 
index 4273176ea6fcaf8529d8eb15254e5fbce050618e..74ce956032e9dee9e1183613e02c92fb5a22b481 100644 (file)
@@ -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,
index 68479893116ef627f0f0b7e60fb0870ef4235ace..eed7d799c0eb48f777707ffa85794d89c385b7be 100644 (file)
@@ -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 &&
@@ -276,6 +281,11 @@ NTSTATUS dcerpc_server_$name\_init(TALLOC_CTX *ctx)
            .init_server = DCESRV_INTERFACE_$uname\_INIT_SERVER,
 #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
index e6e231f1e233d6382fb309f37e6978e38883750d..825c4cd9bd2d5d17070c86c5c74e583fb089348e 100644 (file)
@@ -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
index 8d4a15f15696e34816824418c801c3289469421a..8c17d76cd3c6c93a0066a58e79af80ec23b05df2 100644 (file)
@@ -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;