2 * Unix SMB/CIFS implementation.
4 * SMBD RPC service callbacks
6 * Copyright (c) 2011 Andreas Schneider <asn@samba.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
25 #include "../librpc/gen_ndr/ndr_epmapper_c.h"
26 #include "../librpc/gen_ndr/srv_epmapper.h"
27 #include "../librpc/gen_ndr/srv_srvsvc.h"
28 #include "../librpc/gen_ndr/srv_winreg.h"
29 #include "../librpc/gen_ndr/srv_dfs.h"
30 #include "../librpc/gen_ndr/srv_dssetup.h"
31 #include "../librpc/gen_ndr/srv_echo.h"
32 #include "../librpc/gen_ndr/srv_eventlog.h"
33 #include "../librpc/gen_ndr/srv_initshutdown.h"
34 #include "../librpc/gen_ndr/srv_lsa.h"
35 #include "../librpc/gen_ndr/srv_netlogon.h"
36 #include "../librpc/gen_ndr/srv_ntsvcs.h"
37 #include "../librpc/gen_ndr/srv_samr.h"
38 #include "../librpc/gen_ndr/srv_spoolss.h"
39 #include "../librpc/gen_ndr/srv_svcctl.h"
40 #include "../librpc/gen_ndr/srv_wkssvc.h"
42 #include "printing/nt_printing_migrate_internal.h"
43 #include "rpc_server/eventlog/srv_eventlog_reg.h"
44 #include "rpc_server/svcctl/srv_svcctl_reg.h"
45 #include "rpc_server/spoolss/srv_spoolss_nt.h"
46 #include "rpc_server/svcctl/srv_svcctl_nt.h"
48 #include "librpc/rpc/dcerpc_ep.h"
49 #include "rpc_server/rpc_sock_helper.h"
50 #include "rpc_server/rpc_service_setup.h"
51 #include "rpc_server/rpc_ep_register.h"
52 #include "rpc_server/rpc_server.h"
53 #include "rpc_server/epmapper/srv_epmapper.h"
55 enum rpc_service_mode_e rpc_epmapper_mode(void)
57 const char *rpcsrv_type;
58 enum rpc_service_mode_e state;
60 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
65 if (strcasecmp_m(rpcsrv_type, "external") == 0) {
66 state = RPC_SERVICE_MODE_EXTERNAL;
67 } else if (strcasecmp_m(rpcsrv_type, "daemon") == 0) {
68 state = RPC_SERVICE_MODE_DAEMON;
70 state = RPC_SERVICE_MODE_DISABLED;
76 enum rpc_service_mode_e rpc_spoolss_mode(void)
78 const char *rpcsrv_type;
79 enum rpc_service_mode_e state;
81 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
86 if (strcasecmp_m(rpcsrv_type, "embedded") == 0) {
87 state = RPC_SERVICE_MODE_EMBEDDED;
88 } else if (strcasecmp_m(rpcsrv_type, "external") == 0) {
89 state = RPC_SERVICE_MODE_EXTERNAL;
90 } else if (strcasecmp_m(rpcsrv_type, "daemon") == 0) {
91 state = RPC_SERVICE_MODE_DAEMON;
93 state = RPC_SERVICE_MODE_DISABLED;
99 static bool rpc_setup_epmapper(struct tevent_context *ev_ctx,
100 struct messaging_context *msg_ctx)
102 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
105 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
106 status = rpc_epmapper_init(NULL);
107 if (!NT_STATUS_IS_OK(status)) {
115 static bool rpc_setup_winreg(struct tevent_context *ev_ctx,
116 struct messaging_context *msg_ctx,
117 const struct dcerpc_binding_vector *v)
119 const struct ndr_interface_table *t = &ndr_table_winreg;
120 const char *pipe_name = "winreg";
121 struct dcerpc_binding_vector *v2;
122 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
126 status = rpc_winreg_init(NULL);
127 if (!NT_STATUS_IS_OK(status)) {
131 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
132 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
137 status = dcerpc_binding_vector_replace_iface(t, v2);
138 if (!NT_STATUS_IS_OK(status)) {
142 status = dcerpc_binding_vector_add_np_default(t, v2);
143 if (!NT_STATUS_IS_OK(status)) {
147 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
155 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
156 if (!NT_STATUS_IS_OK(status)) {
160 status = rpc_ep_register(ev_ctx,
164 if (!NT_STATUS_IS_OK(status)) {
172 static bool rpc_setup_srvsvc(struct tevent_context *ev_ctx,
173 struct messaging_context *msg_ctx,
174 const struct dcerpc_binding_vector *v)
176 const struct ndr_interface_table *t = &ndr_table_srvsvc;
177 const char *pipe_name = "srvsvc";
178 struct dcerpc_binding_vector *v2;
179 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
183 status = rpc_srvsvc_init(NULL);
184 if (!NT_STATUS_IS_OK(status)) {
188 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
189 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
194 status = dcerpc_binding_vector_replace_iface(t, v2);
195 if (!NT_STATUS_IS_OK(status)) {
199 status = dcerpc_binding_vector_add_np_default(t, v2);
200 if (!NT_STATUS_IS_OK(status)) {
204 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
212 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
213 if (!NT_STATUS_IS_OK(status)) {
217 status = rpc_ep_register(ev_ctx,
221 if (!NT_STATUS_IS_OK(status)) {
229 static bool rpc_setup_lsarpc(struct tevent_context *ev_ctx,
230 struct messaging_context *msg_ctx,
231 const struct dcerpc_binding_vector *v)
233 const struct ndr_interface_table *t = &ndr_table_lsarpc;
234 const char *pipe_name = "lsarpc";
235 struct dcerpc_binding_vector *v2;
236 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
240 status = rpc_lsarpc_init(NULL);
241 if (!NT_STATUS_IS_OK(status)) {
245 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
246 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
251 status = dcerpc_binding_vector_replace_iface(t, v2);
252 if (!NT_STATUS_IS_OK(status)) {
256 status = dcerpc_binding_vector_add_np_default(t, v2);
257 if (!NT_STATUS_IS_OK(status)) {
261 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
269 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
270 if (!NT_STATUS_IS_OK(status)) {
274 status = rpc_ep_register(ev_ctx,
278 if (!NT_STATUS_IS_OK(status)) {
286 static bool rpc_setup_samr(struct tevent_context *ev_ctx,
287 struct messaging_context *msg_ctx,
288 const struct dcerpc_binding_vector *v)
290 const struct ndr_interface_table *t = &ndr_table_samr;
291 const char *pipe_name = "samr";
292 struct dcerpc_binding_vector *v2;
293 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
297 status = rpc_samr_init(NULL);
298 if (!NT_STATUS_IS_OK(status)) {
302 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
303 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
308 status = dcerpc_binding_vector_replace_iface(t, v2);
309 if (!NT_STATUS_IS_OK(status)) {
313 status = dcerpc_binding_vector_add_np_default(t, v2);
314 if (!NT_STATUS_IS_OK(status)) {
318 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
326 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
327 if (!NT_STATUS_IS_OK(status)) {
331 status = rpc_ep_register(ev_ctx,
335 if (!NT_STATUS_IS_OK(status)) {
343 static bool rpc_setup_netlogon(struct tevent_context *ev_ctx,
344 struct messaging_context *msg_ctx,
345 const struct dcerpc_binding_vector *v)
347 const struct ndr_interface_table *t = &ndr_table_netlogon;
348 const char *pipe_name = "netlogon";
349 struct dcerpc_binding_vector *v2;
350 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
354 status = rpc_netlogon_init(NULL);
355 if (!NT_STATUS_IS_OK(status)) {
359 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
360 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
365 status = dcerpc_binding_vector_replace_iface(t, v2);
366 if (!NT_STATUS_IS_OK(status)) {
370 status = dcerpc_binding_vector_add_np_default(t, v2);
371 if (!NT_STATUS_IS_OK(status)) {
375 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
383 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
384 if (!NT_STATUS_IS_OK(status)) {
388 status = rpc_ep_register(ev_ctx,
392 if (!NT_STATUS_IS_OK(status)) {
400 static bool rpc_setup_netdfs(struct tevent_context *ev_ctx,
401 struct messaging_context *msg_ctx,
402 const struct dcerpc_binding_vector *v)
404 const struct ndr_interface_table *t = &ndr_table_netdfs;
405 const char *pipe_name = "netdfs";
406 struct dcerpc_binding_vector *v2;
407 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
411 status = rpc_netdfs_init(NULL);
412 if (!NT_STATUS_IS_OK(status)) {
416 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
417 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
422 status = dcerpc_binding_vector_replace_iface(t, v2);
423 if (!NT_STATUS_IS_OK(status)) {
427 status = dcerpc_binding_vector_add_np_default(t, v2);
428 if (!NT_STATUS_IS_OK(status)) {
432 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
440 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
441 if (!NT_STATUS_IS_OK(status)) {
445 status = rpc_ep_register(ev_ctx,
449 if (!NT_STATUS_IS_OK(status)) {
458 static bool rpc_setup_rpcecho(struct tevent_context *ev_ctx,
459 struct messaging_context *msg_ctx,
460 const struct dcerpc_binding_vector *v)
462 const struct ndr_interface_table *t = &ndr_table_rpcecho;
463 const char *pipe_name = "rpcecho";
464 struct dcerpc_binding_vector *v2;
465 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
469 status = rpc_rpcecho_init(NULL);
470 if (!NT_STATUS_IS_OK(status)) {
474 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
475 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
480 status = dcerpc_binding_vector_replace_iface(t, v2);
481 if (!NT_STATUS_IS_OK(status)) {
485 status = dcerpc_binding_vector_add_np_default(t, v2);
486 if (!NT_STATUS_IS_OK(status)) {
490 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
498 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
499 if (!NT_STATUS_IS_OK(status)) {
503 status = rpc_ep_register(ev_ctx,
507 if (!NT_STATUS_IS_OK(status)) {
516 static bool rpc_setup_dssetup(struct tevent_context *ev_ctx,
517 struct messaging_context *msg_ctx,
518 const struct dcerpc_binding_vector *v)
520 const struct ndr_interface_table *t = &ndr_table_dssetup;
521 const char *pipe_name = "dssetup";
522 struct dcerpc_binding_vector *v2;
523 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
527 status = rpc_dssetup_init(NULL);
528 if (!NT_STATUS_IS_OK(status)) {
532 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
533 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
538 status = dcerpc_binding_vector_replace_iface(t, v2);
539 if (!NT_STATUS_IS_OK(status)) {
543 status = dcerpc_binding_vector_add_np_default(t, v2);
544 if (!NT_STATUS_IS_OK(status)) {
548 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
556 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
557 if (!NT_STATUS_IS_OK(status)) {
561 status = rpc_ep_register(ev_ctx,
565 if (!NT_STATUS_IS_OK(status)) {
573 static bool rpc_setup_wkssvc(struct tevent_context *ev_ctx,
574 struct messaging_context *msg_ctx,
575 const struct dcerpc_binding_vector *v)
577 const struct ndr_interface_table *t = &ndr_table_wkssvc;
578 const char *pipe_name = "wkssvc";
579 struct dcerpc_binding_vector *v2;
580 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
584 status = rpc_wkssvc_init(NULL);
585 if (!NT_STATUS_IS_OK(status)) {
589 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
590 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
595 status = dcerpc_binding_vector_replace_iface(t, v2);
596 if (!NT_STATUS_IS_OK(status)) {
600 status = dcerpc_binding_vector_add_np_default(t, v2);
601 if (!NT_STATUS_IS_OK(status)) {
605 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
613 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
614 if (!NT_STATUS_IS_OK(status)) {
618 status = rpc_ep_register(ev_ctx,
622 if (!NT_STATUS_IS_OK(status)) {
630 static bool spoolss_init_cb(void *ptr)
632 struct messaging_context *msg_ctx =
633 talloc_get_type_abort(ptr, struct messaging_context);
637 * Migrate the printers first.
639 ok = nt_printing_tdb_migrate(msg_ctx);
647 static bool spoolss_shutdown_cb(void *ptr)
649 srv_spoolss_cleanup();
654 static bool rpc_setup_spoolss(struct tevent_context *ev_ctx,
655 struct messaging_context *msg_ctx)
657 const struct ndr_interface_table *t = &ndr_table_spoolss;
658 struct rpc_srv_callbacks spoolss_cb;
659 struct dcerpc_binding_vector *v;
660 enum rpc_service_mode_e spoolss_mode = rpc_spoolss_mode();
663 if (_lp_disable_spoolss() ||
664 spoolss_mode == RPC_SERVICE_MODE_DISABLED) {
668 if (spoolss_mode == RPC_SERVICE_MODE_EMBEDDED) {
669 spoolss_cb.init = spoolss_init_cb;
670 spoolss_cb.shutdown = spoolss_shutdown_cb;
671 spoolss_cb.private_data = msg_ctx;
673 status = rpc_spoolss_init(&spoolss_cb);
674 } else if (spoolss_mode == RPC_SERVICE_MODE_EXTERNAL ||
675 spoolss_mode == RPC_SERVICE_MODE_DAEMON) {
676 status = rpc_spoolss_init(NULL);
678 if (!NT_STATUS_IS_OK(status)) {
682 if (spoolss_mode == RPC_SERVICE_MODE_EMBEDDED) {
683 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
685 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
686 status = dcerpc_binding_vector_new(talloc_tos(), &v);
687 if (!NT_STATUS_IS_OK(status)) {
691 status = dcerpc_binding_vector_add_np_default(t, v);
692 if (!NT_STATUS_IS_OK(status)) {
696 status = rpc_ep_register(ev_ctx,
700 if (!NT_STATUS_IS_OK(status)) {
709 static bool svcctl_init_cb(void *ptr)
711 struct messaging_context *msg_ctx =
712 talloc_get_type_abort(ptr, struct messaging_context);
715 /* initialize the control hooks */
716 init_service_op_table();
718 ok = svcctl_init_winreg(msg_ctx);
726 static bool svcctl_shutdown_cb(void *ptr)
728 shutdown_service_op_table();
733 static bool rpc_setup_svcctl(struct tevent_context *ev_ctx,
734 struct messaging_context *msg_ctx)
736 const struct ndr_interface_table *t = &ndr_table_svcctl;
737 const char *pipe_name = "svcctl";
738 struct dcerpc_binding_vector *v;
739 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
740 struct rpc_srv_callbacks svcctl_cb;
744 svcctl_cb.init = svcctl_init_cb;
745 svcctl_cb.shutdown = svcctl_shutdown_cb;
746 svcctl_cb.private_data = msg_ctx;
748 status = rpc_svcctl_init(&svcctl_cb);
749 if (!NT_STATUS_IS_OK(status)) {
753 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
754 status = dcerpc_binding_vector_new(talloc_tos(), &v);
755 if (!NT_STATUS_IS_OK(status)) {
759 status = dcerpc_binding_vector_add_np_default(t, v);
760 if (!NT_STATUS_IS_OK(status)) {
764 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
772 status = dcerpc_binding_vector_add_unix(t, v, pipe_name);
773 if (!NT_STATUS_IS_OK(status)) {
777 status = rpc_ep_register(ev_ctx,
781 if (!NT_STATUS_IS_OK(status)) {
789 static bool rpc_setup_ntsvcs(struct tevent_context *ev_ctx,
790 struct messaging_context *msg_ctx)
792 const struct ndr_interface_table *t = &ndr_table_ntsvcs;
793 struct dcerpc_binding_vector *v;
794 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
797 status = rpc_ntsvcs_init(NULL);
798 if (!NT_STATUS_IS_OK(status)) {
802 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
803 status = dcerpc_binding_vector_new(talloc_tos(), &v);
804 if (!NT_STATUS_IS_OK(status)) {
808 status = dcerpc_binding_vector_add_np_default(t, v);
809 if (!NT_STATUS_IS_OK(status)) {
813 status = rpc_ep_register(ev_ctx,
817 if (!NT_STATUS_IS_OK(status)) {
825 static bool eventlog_init_cb(void *ptr)
827 struct messaging_context *msg_ctx =
828 talloc_get_type_abort(ptr, struct messaging_context);
831 ok = eventlog_init_winreg(msg_ctx);
839 static bool rpc_setup_eventlog(struct tevent_context *ev_ctx,
840 struct messaging_context *msg_ctx)
842 const struct ndr_interface_table *t = &ndr_table_eventlog;
843 struct rpc_srv_callbacks eventlog_cb;
844 struct dcerpc_binding_vector *v;
845 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
848 eventlog_cb.init = eventlog_init_cb;
849 eventlog_cb.shutdown = NULL;
850 eventlog_cb.private_data = msg_ctx;
852 status = rpc_eventlog_init(&eventlog_cb);
853 if (!NT_STATUS_IS_OK(status)) {
857 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
858 status = dcerpc_binding_vector_new(talloc_tos(), &v);
859 if (!NT_STATUS_IS_OK(status)) {
863 status = dcerpc_binding_vector_add_np_default(t, v);
864 if (!NT_STATUS_IS_OK(status)) {
868 status = rpc_ep_register(ev_ctx,
872 if (!NT_STATUS_IS_OK(status)) {
880 static bool rpc_setup_initshutdown(struct tevent_context *ev_ctx,
881 struct messaging_context *msg_ctx)
883 const struct ndr_interface_table *t = &ndr_table_initshutdown;
884 struct dcerpc_binding_vector *v;
885 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
888 status = rpc_initshutdown_init(NULL);
889 if (!NT_STATUS_IS_OK(status)) {
893 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
894 status = dcerpc_binding_vector_new(talloc_tos(), &v);
895 if (!NT_STATUS_IS_OK(status)) {
899 status = dcerpc_binding_vector_add_np_default(t, v);
900 if (!NT_STATUS_IS_OK(status)) {
904 status = rpc_ep_register(ev_ctx,
908 if (!NT_STATUS_IS_OK(status)) {
916 bool dcesrv_ep_setup(struct tevent_context *ev_ctx,
917 struct messaging_context *msg_ctx)
919 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
920 struct dcerpc_binding_vector *v;
921 const char *rpcsrv_type;
926 tmp_ctx = talloc_stackframe();
927 if (tmp_ctx == NULL) {
931 status = dcerpc_binding_vector_new(tmp_ctx,
933 if (!NT_STATUS_IS_OK(status)) {
938 ok = rpc_setup_epmapper(ev_ctx, msg_ctx);
943 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
948 if ((strcasecmp_m(rpcsrv_type, "yes") == 0 ||
949 strcasecmp_m(rpcsrv_type, "true") == 0)
950 && epm_mode != RPC_SERVICE_MODE_DISABLED) {
951 status = rpc_setup_tcpip_sockets(ev_ctx,
956 if (!NT_STATUS_IS_OK(status)) {
962 ok = rpc_setup_winreg(ev_ctx, msg_ctx, v);
967 ok = rpc_setup_srvsvc(ev_ctx, msg_ctx, v);
972 ok = rpc_setup_lsarpc(ev_ctx, msg_ctx, v);
977 ok = rpc_setup_samr(ev_ctx, msg_ctx, v);
982 ok = rpc_setup_netlogon(ev_ctx, msg_ctx, v);
987 ok = rpc_setup_netdfs(ev_ctx, msg_ctx, v);
993 ok = rpc_setup_rpcecho(ev_ctx, msg_ctx, v);
999 ok = rpc_setup_dssetup(ev_ctx, msg_ctx, v);
1004 ok = rpc_setup_wkssvc(ev_ctx, msg_ctx, v);
1009 ok = rpc_setup_spoolss(ev_ctx, msg_ctx);
1014 ok = rpc_setup_svcctl(ev_ctx, msg_ctx);
1019 ok = rpc_setup_ntsvcs(ev_ctx, msg_ctx);
1024 ok = rpc_setup_eventlog(ev_ctx, msg_ctx);
1029 ok = rpc_setup_initshutdown(ev_ctx, msg_ctx);
1035 talloc_free(tmp_ctx);
1039 /* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */