]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:rpc_server: Register endpoint servers for embedded services
authorSamuel Cabrero <scabrero@samba.org>
Fri, 15 Nov 2019 13:26:28 +0000 (14:26 +0100)
committerSamuel Cabrero <scabrero@sn-devel-184>
Fri, 20 Mar 2020 15:36:31 +0000 (15:36 +0000)
Signed-off-by: Samuel Cabrero <scabrero@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source3/rpc_server/rpc_service_setup.c

index 4011ebe88233e42d1da4a8604eedb0354592ee66..0c8ee6bcf78d082b95bca20a3cd4f13fdfed2582 100644 (file)
 #include "../librpc/gen_ndr/srv_svcctl.h"
 #include "../librpc/gen_ndr/srv_wkssvc.h"
 
+#include "librpc/gen_ndr/ndr_winreg_scompat.h"
+#include "librpc/gen_ndr/ndr_srvsvc_scompat.h"
+#include "librpc/gen_ndr/ndr_lsa_scompat.h"
+#include "librpc/gen_ndr/ndr_samr_scompat.h"
+#include "librpc/gen_ndr/ndr_netlogon_scompat.h"
+#include "librpc/gen_ndr/ndr_dfs_scompat.h"
+#include "librpc/gen_ndr/ndr_echo_scompat.h"
+#include "librpc/gen_ndr/ndr_dssetup_scompat.h"
+#include "librpc/gen_ndr/ndr_wkssvc_scompat.h"
+#include "librpc/gen_ndr/ndr_spoolss_scompat.h"
+#include "librpc/gen_ndr/ndr_svcctl_scompat.h"
+#include "librpc/gen_ndr/ndr_ntsvcs_scompat.h"
+#include "librpc/gen_ndr/ndr_eventlog_scompat.h"
+#include "librpc/gen_ndr/ndr_initshutdown_scompat.h"
+
 #include "printing/nt_printing_migrate_internal.h"
 #include "rpc_server/eventlog/srv_eventlog_reg.h"
 #include "rpc_server/svcctl/srv_svcctl_reg.h"
 #include "rpc_server/spoolss/srv_spoolss_nt.h"
 #include "rpc_server/svcctl/srv_svcctl_nt.h"
 
+#include "librpc/rpc/dcesrv_core.h"
 #include "librpc/rpc/dcerpc_ep.h"
 #include "rpc_server/rpc_sock_helper.h"
 #include "rpc_server/rpc_service_setup.h"
@@ -105,12 +121,28 @@ static NTSTATUS rpc_setup_winreg(struct tevent_context *ev_ctx,
        const struct ndr_interface_table *t = &ndr_table_winreg;
        const char *pipe_name = "winreg";
        NTSTATUS status;
-       enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
+       enum rpc_service_mode_e service_mode;
+       const struct dcesrv_endpoint_server *ep_server = NULL;
+
+       /* Register the endpoint server in DCERPC core */
+       ep_server = winreg_get_ep_server();
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get 'winreg' endpoint server\n");
+               return NT_STATUS_UNSUCCESSFUL;
+       }
 
+       service_mode = rpc_service_mode(ep_server->name);
        if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
                return NT_STATUS_OK;
        }
 
+       status = dcerpc_register_ep_server(ep_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("Failed to register '%s' endpoint server: "
+                       "%s\n", ep_server->name, nt_errstr(status));
+               return status;
+       }
+
        status = rpc_winreg_init(NULL);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -130,12 +162,28 @@ static NTSTATUS rpc_setup_srvsvc(struct tevent_context *ev_ctx,
        const struct ndr_interface_table *t = &ndr_table_srvsvc;
        const char *pipe_name = "srvsvc";
        NTSTATUS status;
-       enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
+       enum rpc_service_mode_e service_mode;
+       const struct dcesrv_endpoint_server *ep_server = NULL;
+
+       /* Register the endpoint server in DCERPC core */
+       ep_server = srvsvc_get_ep_server();
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get 'srvsvc' endpoint server\n");
+               return NT_STATUS_UNSUCCESSFUL;
+       }
 
+       service_mode = rpc_service_mode(ep_server->name);
        if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
                return NT_STATUS_OK;
        }
 
+       status = dcerpc_register_ep_server(ep_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("Failed to register '%s' endpoint server: "
+                       "%s\n", ep_server->name, nt_errstr(status));
+               return status;
+       }
+
        status = rpc_srvsvc_init(NULL);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -156,13 +204,29 @@ static NTSTATUS rpc_setup_lsarpc(struct tevent_context *ev_ctx,
        const char *pipe_name = "lsarpc";
        enum rpc_daemon_type_e lsasd_type = rpc_lsasd_daemon();
        NTSTATUS status;
+       enum rpc_service_mode_e service_mode;
+       const struct dcesrv_endpoint_server *ep_server = NULL;
+
+       /* Register the endpoint server in DCERPC core */
+       ep_server = lsarpc_get_ep_server();
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get 'lsarpc' endpoint server\n");
+               return NT_STATUS_UNSUCCESSFUL;
+       }
 
-       enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
+       service_mode = rpc_service_mode(ep_server->name);
        if (service_mode != RPC_SERVICE_MODE_EMBEDDED ||
            lsasd_type != RPC_DAEMON_EMBEDDED) {
                return NT_STATUS_OK;
        }
 
+       status = dcerpc_register_ep_server(ep_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("Failed to register '%s' endpoint server: "
+                       "%s\n", ep_server->name, nt_errstr(status));
+               return status;
+       }
+
        status = rpc_lsarpc_init(NULL);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -183,13 +247,29 @@ static NTSTATUS rpc_setup_samr(struct tevent_context *ev_ctx,
        const char *pipe_name = "samr";
        enum rpc_daemon_type_e lsasd_type = rpc_lsasd_daemon();
        NTSTATUS status;
-       enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
+       enum rpc_service_mode_e service_mode;
+       const struct dcesrv_endpoint_server *ep_server = NULL;
 
+       /* Register the endpoint server in DCERPC core */
+       ep_server = samr_get_ep_server();
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get 'samr' endpoint server\n");
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       service_mode = rpc_service_mode(ep_server->name);
        if (service_mode != RPC_SERVICE_MODE_EMBEDDED ||
            lsasd_type != RPC_DAEMON_EMBEDDED) {
                return NT_STATUS_OK;
        }
 
+       status = dcerpc_register_ep_server(ep_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("Failed to register '%s' endpoint server: "
+                       "%s\n", ep_server->name, nt_errstr(status));
+               return status;
+       }
+
        status = rpc_samr_init(NULL);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -210,13 +290,29 @@ static NTSTATUS rpc_setup_netlogon(struct tevent_context *ev_ctx,
        const char *pipe_name = "netlogon";
        enum rpc_daemon_type_e lsasd_type = rpc_lsasd_daemon();
        NTSTATUS status;
-       enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
+       enum rpc_service_mode_e service_mode;
+       const struct dcesrv_endpoint_server *ep_server = NULL;
 
+       /* Register the endpoint server in DCERPC core */
+       ep_server = netlogon_get_ep_server();
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get 'netlogon' endpoint server\n");
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       service_mode = rpc_service_mode(ep_server->name);
        if (service_mode != RPC_SERVICE_MODE_EMBEDDED ||
            lsasd_type != RPC_DAEMON_EMBEDDED) {
                return NT_STATUS_OK;
        }
 
+       status = dcerpc_register_ep_server(ep_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("Failed to register '%s' endpoint server: "
+                       "%s\n", ep_server->name, nt_errstr(status));
+               return status;
+       }
+
        status = rpc_netlogon_init(NULL);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -236,12 +332,28 @@ static NTSTATUS rpc_setup_netdfs(struct tevent_context *ev_ctx,
        const struct ndr_interface_table *t = &ndr_table_netdfs;
        const char *pipe_name = "netdfs";
        NTSTATUS status;
-       enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
+       enum rpc_service_mode_e service_mode;
+       const struct dcesrv_endpoint_server *ep_server = NULL;
+
+       /* Register the endpoint server in DCERPC core */
+       ep_server = netdfs_get_ep_server();
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get 'netdfs' endpoint server\n");
+               return NT_STATUS_UNSUCCESSFUL;
+       }
 
+       service_mode = rpc_service_mode(ep_server->name);
        if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
                return NT_STATUS_OK;
        }
 
+       status = dcerpc_register_ep_server(ep_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("Failed to register '%s' endpoint server: "
+                       "%s\n", ep_server->name, nt_errstr(status));
+               return status;
+       }
+
        status = rpc_netdfs_init(NULL);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -262,12 +374,28 @@ static NTSTATUS rpc_setup_rpcecho(struct tevent_context *ev_ctx,
        const struct ndr_interface_table *t = &ndr_table_rpcecho;
        const char *pipe_name = "rpcecho";
        NTSTATUS status;
-       enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
+       enum rpc_service_mode_e service_mode;
+       const struct dcesrv_endpoint_server *ep_server = NULL;
+
+       /* Register the endpoint server in DCERPC core */
+       ep_server = rpcecho_get_ep_server();
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get 'rpcecho' endpoint server\n");
+               return NT_STATUS_UNSUCCESSFUL;
+       }
 
+       service_mode = rpc_service_mode(ep_server->name);
        if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
                return NT_STATUS_OK;
        }
 
+       status = dcerpc_register_ep_server(ep_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("Failed to register '%s' endpoint server: "
+                       "%s\n", ep_server->name, nt_errstr(status));
+               return status;
+       }
+
        status = rpc_rpcecho_init(NULL);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -288,12 +416,28 @@ static NTSTATUS rpc_setup_dssetup(struct tevent_context *ev_ctx,
        const struct ndr_interface_table *t = &ndr_table_dssetup;
        const char *pipe_name = "dssetup";
        NTSTATUS status;
-       enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
+       enum rpc_service_mode_e service_mode;
+       const struct dcesrv_endpoint_server *ep_server = NULL;
 
+       /* Register the endpoint server in DCERPC core */
+       ep_server = dssetup_get_ep_server();
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get 'dssetup' endpoint server\n");
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       service_mode = rpc_service_mode(ep_server->name);
        if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
                return NT_STATUS_OK;
        }
 
+       status = dcerpc_register_ep_server(ep_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("Failed to register '%s' endpoint server: "
+                       "%s\n", ep_server->name, nt_errstr(status));
+               return status;
+       }
+
        status = rpc_dssetup_init(NULL);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -313,12 +457,28 @@ static NTSTATUS rpc_setup_wkssvc(struct tevent_context *ev_ctx,
        const struct ndr_interface_table *t = &ndr_table_wkssvc;
        const char *pipe_name = "wkssvc";
        NTSTATUS status;
-       enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
+       enum rpc_service_mode_e service_mode;
+       const struct dcesrv_endpoint_server *ep_server = NULL;
 
+       /* Register the endpoint server in DCERPC core */
+       ep_server = wkssvc_get_ep_server();
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get 'wkssvc' endpoint server\n");
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       service_mode = rpc_service_mode(ep_server->name);
        if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
                return NT_STATUS_OK;
        }
 
+       status = dcerpc_register_ep_server(ep_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("Failed to register '%s' endpoint server: "
+                       "%s\n", ep_server->name, nt_errstr(status));
+               return status;
+       }
+
        status = rpc_wkssvc_init(NULL);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -363,17 +523,33 @@ static NTSTATUS rpc_setup_spoolss(struct tevent_context *ev_ctx,
        struct rpc_srv_callbacks spoolss_cb;
        enum rpc_daemon_type_e spoolss_type = rpc_spoolss_daemon();
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-       enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
+       enum rpc_service_mode_e service_mode;
+       const struct dcesrv_endpoint_server *ep_server = NULL;
 
        if (lp__disable_spoolss()) {
                return NT_STATUS_OK;
        }
 
+       /* Register the endpoint server in DCERPC core */
+       ep_server = spoolss_get_ep_server();
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get 'spoolss' endpoint server\n");
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       service_mode = rpc_service_mode(ep_server->name);
        if (service_mode != RPC_SERVICE_MODE_EMBEDDED ||
            spoolss_type != RPC_DAEMON_EMBEDDED) {
                return NT_STATUS_OK;
        }
 
+       status = dcerpc_register_ep_server(ep_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("Failed to register '%s' endpoint server"
+                       ": %s\n", ep_server->name, nt_errstr(status));
+               return status;
+       }
+
        spoolss_cb.init         = spoolss_init_cb;
        spoolss_cb.shutdown     = spoolss_shutdown_cb;
        spoolss_cb.private_data = msg_ctx;
@@ -422,12 +598,28 @@ static NTSTATUS rpc_setup_svcctl(struct tevent_context *ev_ctx,
        const char *pipe_name = "svcctl";
        struct rpc_srv_callbacks svcctl_cb;
        NTSTATUS status;
-       enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
+       enum rpc_service_mode_e service_mode;
+       const struct dcesrv_endpoint_server *ep_server = NULL;
+
+       /* Register the endpoint server in DCERPC core */
+       ep_server = svcctl_get_ep_server();
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get 'svcctl' endpoint server\n");
+               return NT_STATUS_UNSUCCESSFUL;
+       }
 
+       service_mode = rpc_service_mode(ep_server->name);
        if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
                return NT_STATUS_OK;
        }
 
+       status = dcerpc_register_ep_server(ep_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("Failed to register '%s' endpoint server"
+                       ": %s\n", ep_server->name, nt_errstr(status));
+               return status;
+       }
+
        svcctl_cb.init         = svcctl_init_cb;
        svcctl_cb.shutdown     = svcctl_shutdown_cb;
        svcctl_cb.private_data = msg_ctx;
@@ -450,12 +642,28 @@ static NTSTATUS rpc_setup_ntsvcs(struct tevent_context *ev_ctx,
 {
        const struct ndr_interface_table *t = &ndr_table_ntsvcs;
        NTSTATUS status;
-       enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
+       enum rpc_service_mode_e service_mode;
+       const struct dcesrv_endpoint_server *ep_server = NULL;
+
+       /* Register the endpoint server in DCERPC core */
+       ep_server = ntsvcs_get_ep_server();
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get 'ntsvcs' endpoint server\n");
+               return NT_STATUS_UNSUCCESSFUL;
+       }
 
+       service_mode = rpc_service_mode(ep_server->name);
        if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
                return NT_STATUS_OK;
        }
 
+       status = dcerpc_register_ep_server(ep_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("Failed to register '%s' endpoint server"
+                       ": %s\n", ep_server->name, nt_errstr(status));
+               return status;
+       }
+
        status = rpc_ntsvcs_init(NULL);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -489,12 +697,28 @@ static NTSTATUS rpc_setup_eventlog(struct tevent_context *ev_ctx,
        const struct ndr_interface_table *t = &ndr_table_eventlog;
        struct rpc_srv_callbacks eventlog_cb;
        NTSTATUS status;
-       enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
+       enum rpc_service_mode_e service_mode;
+       const struct dcesrv_endpoint_server *ep_server = NULL;
 
+       /* Register the endpoint server in DCERPC core */
+       ep_server = eventlog_get_ep_server();
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get 'eventlog' endpoint server\n");
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       service_mode = rpc_service_mode(ep_server->name);
        if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
                return NT_STATUS_OK;
        }
 
+       status = dcerpc_register_ep_server(ep_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("Failed to register '%s' endpoint server"
+                       ": %s\n", ep_server->name, nt_errstr(status));
+               return status;
+       }
+
        eventlog_cb.init         = eventlog_init_cb;
        eventlog_cb.shutdown     = NULL;
        eventlog_cb.private_data = msg_ctx;
@@ -517,12 +741,28 @@ static NTSTATUS rpc_setup_initshutdown(struct tevent_context *ev_ctx,
 {
        const struct ndr_interface_table *t = &ndr_table_initshutdown;
        NTSTATUS status;
-       enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
+       enum rpc_service_mode_e service_mode;
+       const struct dcesrv_endpoint_server *ep_server = NULL;
+
+       /* Register the endpoint server in DCERPC core */
+       ep_server = initshutdown_get_ep_server();
+       if (ep_server == NULL) {
+               DBG_ERR("Failed to get 'initshutdown' endpoint server\n");
+               return NT_STATUS_UNSUCCESSFUL;
+       }
 
+       service_mode = rpc_service_mode(ep_server->name);
        if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
                return NT_STATUS_OK;
        }
 
+       status = dcerpc_register_ep_server(ep_server);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("Failed to register '%s' endpoint "
+                       "server: %s\n", ep_server->name, nt_errstr(status));
+               return status;
+       }
+
        status = rpc_initshutdown_init(NULL);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -549,6 +789,8 @@ NTSTATUS dcesrv_ep_setup(struct tevent_context *ev_ctx,
                return NT_STATUS_NO_MEMORY;
        }
 
+       DBG_INFO("Registering DCE/RPC endpoint servers\n");
+
        status = rpc_setup_winreg(ev_ctx, msg_ctx);
        if (!NT_STATUS_IS_OK(status)) {
                goto done;
@@ -647,6 +889,7 @@ NTSTATUS dcesrv_ep_setup(struct tevent_context *ev_ctx,
                goto done;
        }
 
+       /* The RPC module setup function has to register the endpoint server */
        ok = setup_rpc_modules(ev_ctx, msg_ctx);
        if (!ok) {
                DBG_ERR("Shared DCE/RPC modules setup failed\n");