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 static bool rpc_setup_epmapper(struct tevent_context *ev_ctx,
77 struct messaging_context *msg_ctx)
79 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
82 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
83 status = rpc_epmapper_init(NULL);
84 if (!NT_STATUS_IS_OK(status)) {
92 static bool rpc_setup_winreg(struct tevent_context *ev_ctx,
93 struct messaging_context *msg_ctx,
94 const struct dcerpc_binding_vector *v)
96 const struct ndr_interface_table *t = &ndr_table_winreg;
97 const char *pipe_name = "winreg";
98 struct dcerpc_binding_vector *v2;
99 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
103 status = rpc_winreg_init(NULL);
104 if (!NT_STATUS_IS_OK(status)) {
108 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
109 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
114 status = dcerpc_binding_vector_replace_iface(t, v2);
115 if (!NT_STATUS_IS_OK(status)) {
119 status = dcerpc_binding_vector_add_np_default(t, v2);
120 if (!NT_STATUS_IS_OK(status)) {
124 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
132 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
133 if (!NT_STATUS_IS_OK(status)) {
137 status = rpc_ep_register(ev_ctx,
141 if (!NT_STATUS_IS_OK(status)) {
149 static bool rpc_setup_srvsvc(struct tevent_context *ev_ctx,
150 struct messaging_context *msg_ctx,
151 const struct dcerpc_binding_vector *v)
153 const struct ndr_interface_table *t = &ndr_table_srvsvc;
154 const char *pipe_name = "srvsvc";
155 struct dcerpc_binding_vector *v2;
156 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
160 status = rpc_srvsvc_init(NULL);
161 if (!NT_STATUS_IS_OK(status)) {
165 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
166 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
171 status = dcerpc_binding_vector_replace_iface(t, v2);
172 if (!NT_STATUS_IS_OK(status)) {
176 status = dcerpc_binding_vector_add_np_default(t, v2);
177 if (!NT_STATUS_IS_OK(status)) {
181 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
189 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
190 if (!NT_STATUS_IS_OK(status)) {
194 status = rpc_ep_register(ev_ctx,
198 if (!NT_STATUS_IS_OK(status)) {
206 static bool rpc_setup_lsarpc(struct tevent_context *ev_ctx,
207 struct messaging_context *msg_ctx,
208 const struct dcerpc_binding_vector *v)
210 const struct ndr_interface_table *t = &ndr_table_lsarpc;
211 const char *pipe_name = "lsarpc";
212 struct dcerpc_binding_vector *v2;
213 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
217 status = rpc_lsarpc_init(NULL);
218 if (!NT_STATUS_IS_OK(status)) {
222 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
223 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
228 status = dcerpc_binding_vector_replace_iface(t, v2);
229 if (!NT_STATUS_IS_OK(status)) {
233 status = dcerpc_binding_vector_add_np_default(t, v2);
234 if (!NT_STATUS_IS_OK(status)) {
238 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
246 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
247 if (!NT_STATUS_IS_OK(status)) {
251 status = rpc_ep_register(ev_ctx,
255 if (!NT_STATUS_IS_OK(status)) {
263 static bool rpc_setup_samr(struct tevent_context *ev_ctx,
264 struct messaging_context *msg_ctx,
265 const struct dcerpc_binding_vector *v)
267 const struct ndr_interface_table *t = &ndr_table_samr;
268 const char *pipe_name = "samr";
269 struct dcerpc_binding_vector *v2;
270 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
274 status = rpc_samr_init(NULL);
275 if (!NT_STATUS_IS_OK(status)) {
279 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
280 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
285 status = dcerpc_binding_vector_replace_iface(t, v2);
286 if (!NT_STATUS_IS_OK(status)) {
290 status = dcerpc_binding_vector_add_np_default(t, v2);
291 if (!NT_STATUS_IS_OK(status)) {
295 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
303 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
304 if (!NT_STATUS_IS_OK(status)) {
308 status = rpc_ep_register(ev_ctx,
312 if (!NT_STATUS_IS_OK(status)) {
320 static bool rpc_setup_netlogon(struct tevent_context *ev_ctx,
321 struct messaging_context *msg_ctx,
322 const struct dcerpc_binding_vector *v)
324 const struct ndr_interface_table *t = &ndr_table_netlogon;
325 const char *pipe_name = "netlogon";
326 struct dcerpc_binding_vector *v2;
327 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
331 status = rpc_netlogon_init(NULL);
332 if (!NT_STATUS_IS_OK(status)) {
336 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
337 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
342 status = dcerpc_binding_vector_replace_iface(t, v2);
343 if (!NT_STATUS_IS_OK(status)) {
347 status = dcerpc_binding_vector_add_np_default(t, v2);
348 if (!NT_STATUS_IS_OK(status)) {
352 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
360 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
361 if (!NT_STATUS_IS_OK(status)) {
365 status = rpc_ep_register(ev_ctx,
369 if (!NT_STATUS_IS_OK(status)) {
377 static bool rpc_setup_netdfs(struct tevent_context *ev_ctx,
378 struct messaging_context *msg_ctx,
379 const struct dcerpc_binding_vector *v)
381 const struct ndr_interface_table *t = &ndr_table_netdfs;
382 const char *pipe_name = "netdfs";
383 struct dcerpc_binding_vector *v2;
384 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
388 status = rpc_netdfs_init(NULL);
389 if (!NT_STATUS_IS_OK(status)) {
393 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
394 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
399 status = dcerpc_binding_vector_replace_iface(t, v2);
400 if (!NT_STATUS_IS_OK(status)) {
404 status = dcerpc_binding_vector_add_np_default(t, v2);
405 if (!NT_STATUS_IS_OK(status)) {
409 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
417 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
418 if (!NT_STATUS_IS_OK(status)) {
422 status = rpc_ep_register(ev_ctx,
426 if (!NT_STATUS_IS_OK(status)) {
435 static bool rpc_setup_rpcecho(struct tevent_context *ev_ctx,
436 struct messaging_context *msg_ctx,
437 const struct dcerpc_binding_vector *v)
439 const struct ndr_interface_table *t = &ndr_table_rpcecho;
440 const char *pipe_name = "rpcecho";
441 struct dcerpc_binding_vector *v2;
442 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
446 status = rpc_rpcecho_init(NULL);
447 if (!NT_STATUS_IS_OK(status)) {
451 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
452 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
457 status = dcerpc_binding_vector_replace_iface(t, v2);
458 if (!NT_STATUS_IS_OK(status)) {
462 status = dcerpc_binding_vector_add_np_default(t, v2);
463 if (!NT_STATUS_IS_OK(status)) {
467 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
475 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
476 if (!NT_STATUS_IS_OK(status)) {
480 status = rpc_ep_register(ev_ctx,
484 if (!NT_STATUS_IS_OK(status)) {
493 static bool rpc_setup_dssetup(struct tevent_context *ev_ctx,
494 struct messaging_context *msg_ctx,
495 const struct dcerpc_binding_vector *v)
497 const struct ndr_interface_table *t = &ndr_table_dssetup;
498 const char *pipe_name = "dssetup";
499 struct dcerpc_binding_vector *v2;
500 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
504 status = rpc_dssetup_init(NULL);
505 if (!NT_STATUS_IS_OK(status)) {
509 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
510 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
515 status = dcerpc_binding_vector_replace_iface(t, v2);
516 if (!NT_STATUS_IS_OK(status)) {
520 status = dcerpc_binding_vector_add_np_default(t, v2);
521 if (!NT_STATUS_IS_OK(status)) {
525 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
533 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
534 if (!NT_STATUS_IS_OK(status)) {
538 status = rpc_ep_register(ev_ctx,
542 if (!NT_STATUS_IS_OK(status)) {
550 static bool rpc_setup_wkssvc(struct tevent_context *ev_ctx,
551 struct messaging_context *msg_ctx,
552 const struct dcerpc_binding_vector *v)
554 const struct ndr_interface_table *t = &ndr_table_wkssvc;
555 const char *pipe_name = "wkssvc";
556 struct dcerpc_binding_vector *v2;
557 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
561 status = rpc_wkssvc_init(NULL);
562 if (!NT_STATUS_IS_OK(status)) {
566 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
567 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
572 status = dcerpc_binding_vector_replace_iface(t, v2);
573 if (!NT_STATUS_IS_OK(status)) {
577 status = dcerpc_binding_vector_add_np_default(t, v2);
578 if (!NT_STATUS_IS_OK(status)) {
582 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
590 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
591 if (!NT_STATUS_IS_OK(status)) {
595 status = rpc_ep_register(ev_ctx,
599 if (!NT_STATUS_IS_OK(status)) {
607 static bool spoolss_init_cb(void *ptr)
609 struct messaging_context *msg_ctx =
610 talloc_get_type_abort(ptr, struct messaging_context);
614 * Migrate the printers first.
616 ok = nt_printing_tdb_migrate(msg_ctx);
624 static bool spoolss_shutdown_cb(void *ptr)
626 srv_spoolss_cleanup();
631 static bool rpc_setup_spoolss(struct tevent_context *ev_ctx,
632 struct messaging_context *msg_ctx)
634 const struct ndr_interface_table *t = &ndr_table_spoolss;
635 struct rpc_srv_callbacks spoolss_cb;
636 const char *rpcsrv_type;
637 struct dcerpc_binding_vector *v;
640 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
645 if (strcasecmp_m(rpcsrv_type, "embedded") == 0) {
646 spoolss_cb.init = spoolss_init_cb;
647 spoolss_cb.shutdown = spoolss_shutdown_cb;
648 spoolss_cb.private_data = msg_ctx;
650 status = rpc_spoolss_init(&spoolss_cb);
651 } else if (strcasecmp_m(rpcsrv_type, "daemon") == 0 ||
652 strcasecmp_m(rpcsrv_type, "external") == 0) {
653 status = rpc_spoolss_init(NULL);
655 if (!NT_STATUS_IS_OK(status)) {
659 if (strcasecmp_m(rpcsrv_type, "embedded")) {
660 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
662 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
663 status = dcerpc_binding_vector_new(talloc_tos(), &v);
664 if (!NT_STATUS_IS_OK(status)) {
668 status = dcerpc_binding_vector_add_np_default(t, v);
669 if (!NT_STATUS_IS_OK(status)) {
673 status = rpc_ep_register(ev_ctx,
677 if (!NT_STATUS_IS_OK(status)) {
686 static bool svcctl_init_cb(void *ptr)
688 struct messaging_context *msg_ctx =
689 talloc_get_type_abort(ptr, struct messaging_context);
692 /* initialize the control hooks */
693 init_service_op_table();
695 ok = svcctl_init_winreg(msg_ctx);
703 static bool svcctl_shutdown_cb(void *ptr)
705 shutdown_service_op_table();
710 static bool rpc_setup_svcctl(struct tevent_context *ev_ctx,
711 struct messaging_context *msg_ctx)
713 const struct ndr_interface_table *t = &ndr_table_svcctl;
714 const char *pipe_name = "svcctl";
715 struct dcerpc_binding_vector *v;
716 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
717 struct rpc_srv_callbacks svcctl_cb;
721 svcctl_cb.init = svcctl_init_cb;
722 svcctl_cb.shutdown = svcctl_shutdown_cb;
723 svcctl_cb.private_data = msg_ctx;
725 status = rpc_svcctl_init(&svcctl_cb);
726 if (!NT_STATUS_IS_OK(status)) {
730 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
731 status = dcerpc_binding_vector_new(talloc_tos(), &v);
732 if (!NT_STATUS_IS_OK(status)) {
736 status = dcerpc_binding_vector_add_np_default(t, v);
737 if (!NT_STATUS_IS_OK(status)) {
741 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
749 status = dcerpc_binding_vector_add_unix(t, v, pipe_name);
750 if (!NT_STATUS_IS_OK(status)) {
754 status = rpc_ep_register(ev_ctx,
758 if (!NT_STATUS_IS_OK(status)) {
766 static bool rpc_setup_ntsvcs(struct tevent_context *ev_ctx,
767 struct messaging_context *msg_ctx)
769 const struct ndr_interface_table *t = &ndr_table_ntsvcs;
770 struct dcerpc_binding_vector *v;
771 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
774 status = rpc_ntsvcs_init(NULL);
775 if (!NT_STATUS_IS_OK(status)) {
779 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
780 status = dcerpc_binding_vector_new(talloc_tos(), &v);
781 if (!NT_STATUS_IS_OK(status)) {
785 status = dcerpc_binding_vector_add_np_default(t, v);
786 if (!NT_STATUS_IS_OK(status)) {
790 status = rpc_ep_register(ev_ctx,
794 if (!NT_STATUS_IS_OK(status)) {
802 static bool eventlog_init_cb(void *ptr)
804 struct messaging_context *msg_ctx =
805 talloc_get_type_abort(ptr, struct messaging_context);
808 ok = eventlog_init_winreg(msg_ctx);
816 static bool rpc_setup_eventlog(struct tevent_context *ev_ctx,
817 struct messaging_context *msg_ctx)
819 const struct ndr_interface_table *t = &ndr_table_eventlog;
820 struct rpc_srv_callbacks eventlog_cb;
821 struct dcerpc_binding_vector *v;
822 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
825 eventlog_cb.init = eventlog_init_cb;
826 eventlog_cb.shutdown = NULL;
827 eventlog_cb.private_data = msg_ctx;
829 status = rpc_eventlog_init(&eventlog_cb);
830 if (!NT_STATUS_IS_OK(status)) {
834 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
835 status = dcerpc_binding_vector_new(talloc_tos(), &v);
836 if (!NT_STATUS_IS_OK(status)) {
840 status = dcerpc_binding_vector_add_np_default(t, v);
841 if (!NT_STATUS_IS_OK(status)) {
845 status = rpc_ep_register(ev_ctx,
849 if (!NT_STATUS_IS_OK(status)) {
857 static bool rpc_setup_initshutdown(struct tevent_context *ev_ctx,
858 struct messaging_context *msg_ctx)
860 const struct ndr_interface_table *t = &ndr_table_initshutdown;
861 struct dcerpc_binding_vector *v;
862 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
865 status = rpc_initshutdown_init(NULL);
866 if (!NT_STATUS_IS_OK(status)) {
870 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
871 status = dcerpc_binding_vector_new(talloc_tos(), &v);
872 if (!NT_STATUS_IS_OK(status)) {
876 status = dcerpc_binding_vector_add_np_default(t, v);
877 if (!NT_STATUS_IS_OK(status)) {
881 status = rpc_ep_register(ev_ctx,
885 if (!NT_STATUS_IS_OK(status)) {
893 bool dcesrv_ep_setup(struct tevent_context *ev_ctx,
894 struct messaging_context *msg_ctx)
896 struct dcerpc_binding_vector *v;
897 const char *rpcsrv_type;
902 tmp_ctx = talloc_stackframe();
903 if (tmp_ctx == NULL) {
907 status = dcerpc_binding_vector_new(tmp_ctx,
909 if (!NT_STATUS_IS_OK(status)) {
914 ok = rpc_setup_epmapper(ev_ctx, msg_ctx);
919 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
924 if (strcasecmp_m(rpcsrv_type, "yes") == 0 ||
925 strcasecmp_m(rpcsrv_type, "true") == 0) {
926 status = rpc_setup_tcpip_sockets(ev_ctx,
931 if (!NT_STATUS_IS_OK(status)) {
937 ok = rpc_setup_winreg(ev_ctx, msg_ctx, v);
942 ok = rpc_setup_srvsvc(ev_ctx, msg_ctx, v);
947 ok = rpc_setup_lsarpc(ev_ctx, msg_ctx, v);
952 ok = rpc_setup_samr(ev_ctx, msg_ctx, v);
957 ok = rpc_setup_netlogon(ev_ctx, msg_ctx, v);
962 ok = rpc_setup_netdfs(ev_ctx, msg_ctx, v);
968 ok = rpc_setup_rpcecho(ev_ctx, msg_ctx, v);
974 ok = rpc_setup_dssetup(ev_ctx, msg_ctx, v);
979 ok = rpc_setup_wkssvc(ev_ctx, msg_ctx, v);
984 ok = rpc_setup_spoolss(ev_ctx, msg_ctx);
989 ok = rpc_setup_svcctl(ev_ctx, msg_ctx);
994 ok = rpc_setup_ntsvcs(ev_ctx, msg_ctx);
999 ok = rpc_setup_eventlog(ev_ctx, msg_ctx);
1004 ok = rpc_setup_initshutdown(ev_ctx, msg_ctx);
1010 talloc_free(tmp_ctx);
1014 /* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */