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/rpc_config.h"
54 #include "rpc_server/rpc_modules.h"
55 #include "rpc_server/epmapper/srv_epmapper.h"
58 #define DBGC_CLASS DBGC_RPC_SRV
62 /* Common routine for embedded RPC servers */
63 NTSTATUS
rpc_setup_embedded(struct tevent_context
*ev_ctx
,
64 struct messaging_context
*msg_ctx
,
65 const struct ndr_interface_table
*t
,
66 const char *pipe_name
)
68 struct dcerpc_binding_vector
*v
;
69 enum rpc_service_mode_e epm_mode
= rpc_epmapper_mode();
72 /* Registration of ncacn_np services is problematic. The
73 * ev_ctx passed in here is passed down to all children of the
74 * smbd process, and if the end point mapper ever goes away,
75 * they will all attempt to re-register. But we want to test
76 * the code for now, so it is enabled in on environment in
78 if (epm_mode
!= RPC_SERVICE_MODE_DISABLED
&&
79 (lp_parm_bool(-1, "rpc_server", "register_embedded_np", false))) {
80 status
= dcerpc_binding_vector_new(talloc_tos(), &v
);
81 if (!NT_STATUS_IS_OK(status
)) {
85 status
= dcerpc_binding_vector_add_np_default(t
, v
);
86 if (!NT_STATUS_IS_OK(status
)) {
90 status
= rpc_ep_register(ev_ctx
,
94 if (!NT_STATUS_IS_OK(status
)) {
102 static NTSTATUS
rpc_setup_winreg(struct tevent_context
*ev_ctx
,
103 struct messaging_context
*msg_ctx
)
105 const struct ndr_interface_table
*t
= &ndr_table_winreg
;
106 const char *pipe_name
= "winreg";
108 enum rpc_service_mode_e service_mode
= rpc_service_mode(t
->name
);
110 if (service_mode
!= RPC_SERVICE_MODE_EMBEDDED
) {
114 status
= rpc_winreg_init(NULL
);
115 if (!NT_STATUS_IS_OK(status
)) {
119 status
= rpc_setup_embedded(ev_ctx
, msg_ctx
, t
, pipe_name
);
120 if (!NT_STATUS_IS_OK(status
)) {
127 static NTSTATUS
rpc_setup_srvsvc(struct tevent_context
*ev_ctx
,
128 struct messaging_context
*msg_ctx
)
130 const struct ndr_interface_table
*t
= &ndr_table_srvsvc
;
131 const char *pipe_name
= "srvsvc";
133 enum rpc_service_mode_e service_mode
= rpc_service_mode(t
->name
);
135 if (service_mode
!= RPC_SERVICE_MODE_EMBEDDED
) {
139 status
= rpc_srvsvc_init(NULL
);
140 if (!NT_STATUS_IS_OK(status
)) {
144 status
= rpc_setup_embedded(ev_ctx
, msg_ctx
, t
, pipe_name
);
145 if (!NT_STATUS_IS_OK(status
)) {
152 static NTSTATUS
rpc_setup_lsarpc(struct tevent_context
*ev_ctx
,
153 struct messaging_context
*msg_ctx
)
155 const struct ndr_interface_table
*t
= &ndr_table_lsarpc
;
156 const char *pipe_name
= "lsarpc";
157 enum rpc_daemon_type_e lsasd_type
= rpc_lsasd_daemon();
160 enum rpc_service_mode_e service_mode
= rpc_service_mode(t
->name
);
161 if (service_mode
!= RPC_SERVICE_MODE_EMBEDDED
||
162 lsasd_type
!= RPC_DAEMON_EMBEDDED
) {
166 status
= rpc_lsarpc_init(NULL
);
167 if (!NT_STATUS_IS_OK(status
)) {
171 status
= rpc_setup_embedded(ev_ctx
, msg_ctx
, t
, pipe_name
);
172 if (!NT_STATUS_IS_OK(status
)) {
179 static NTSTATUS
rpc_setup_samr(struct tevent_context
*ev_ctx
,
180 struct messaging_context
*msg_ctx
)
182 const struct ndr_interface_table
*t
= &ndr_table_samr
;
183 const char *pipe_name
= "samr";
184 enum rpc_daemon_type_e lsasd_type
= rpc_lsasd_daemon();
186 enum rpc_service_mode_e service_mode
= rpc_service_mode(t
->name
);
188 if (service_mode
!= RPC_SERVICE_MODE_EMBEDDED
||
189 lsasd_type
!= RPC_DAEMON_EMBEDDED
) {
193 status
= rpc_samr_init(NULL
);
194 if (!NT_STATUS_IS_OK(status
)) {
198 status
= rpc_setup_embedded(ev_ctx
, msg_ctx
, t
, pipe_name
);
199 if (!NT_STATUS_IS_OK(status
)) {
206 static NTSTATUS
rpc_setup_netlogon(struct tevent_context
*ev_ctx
,
207 struct messaging_context
*msg_ctx
)
209 const struct ndr_interface_table
*t
= &ndr_table_netlogon
;
210 const char *pipe_name
= "netlogon";
211 enum rpc_daemon_type_e lsasd_type
= rpc_lsasd_daemon();
213 enum rpc_service_mode_e service_mode
= rpc_service_mode(t
->name
);
215 if (service_mode
!= RPC_SERVICE_MODE_EMBEDDED
||
216 lsasd_type
!= RPC_DAEMON_EMBEDDED
) {
220 status
= rpc_netlogon_init(NULL
);
221 if (!NT_STATUS_IS_OK(status
)) {
225 status
= rpc_setup_embedded(ev_ctx
, msg_ctx
, t
, pipe_name
);
226 if (!NT_STATUS_IS_OK(status
)) {
233 static NTSTATUS
rpc_setup_netdfs(struct tevent_context
*ev_ctx
,
234 struct messaging_context
*msg_ctx
)
236 const struct ndr_interface_table
*t
= &ndr_table_netdfs
;
237 const char *pipe_name
= "netdfs";
239 enum rpc_service_mode_e service_mode
= rpc_service_mode(t
->name
);
241 if (service_mode
!= RPC_SERVICE_MODE_EMBEDDED
) {
245 status
= rpc_netdfs_init(NULL
);
246 if (!NT_STATUS_IS_OK(status
)) {
250 status
= rpc_setup_embedded(ev_ctx
, msg_ctx
, t
, pipe_name
);
251 if (!NT_STATUS_IS_OK(status
)) {
259 static NTSTATUS
rpc_setup_rpcecho(struct tevent_context
*ev_ctx
,
260 struct messaging_context
*msg_ctx
)
262 const struct ndr_interface_table
*t
= &ndr_table_rpcecho
;
263 const char *pipe_name
= "rpcecho";
265 enum rpc_service_mode_e service_mode
= rpc_service_mode(t
->name
);
267 if (service_mode
!= RPC_SERVICE_MODE_EMBEDDED
) {
271 status
= rpc_rpcecho_init(NULL
);
272 if (!NT_STATUS_IS_OK(status
)) {
276 status
= rpc_setup_embedded(ev_ctx
, msg_ctx
, t
, pipe_name
);
277 if (!NT_STATUS_IS_OK(status
)) {
285 static NTSTATUS
rpc_setup_dssetup(struct tevent_context
*ev_ctx
,
286 struct messaging_context
*msg_ctx
)
288 const struct ndr_interface_table
*t
= &ndr_table_dssetup
;
289 const char *pipe_name
= "dssetup";
291 enum rpc_service_mode_e service_mode
= rpc_service_mode(t
->name
);
293 if (service_mode
!= RPC_SERVICE_MODE_EMBEDDED
) {
297 status
= rpc_dssetup_init(NULL
);
298 if (!NT_STATUS_IS_OK(status
)) {
302 status
= rpc_setup_embedded(ev_ctx
, msg_ctx
, t
, pipe_name
);
303 if (!NT_STATUS_IS_OK(status
)) {
310 static NTSTATUS
rpc_setup_wkssvc(struct tevent_context
*ev_ctx
,
311 struct messaging_context
*msg_ctx
)
313 const struct ndr_interface_table
*t
= &ndr_table_wkssvc
;
314 const char *pipe_name
= "wkssvc";
316 enum rpc_service_mode_e service_mode
= rpc_service_mode(t
->name
);
318 if (service_mode
!= RPC_SERVICE_MODE_EMBEDDED
) {
322 status
= rpc_wkssvc_init(NULL
);
323 if (!NT_STATUS_IS_OK(status
)) {
327 status
= rpc_setup_embedded(ev_ctx
, msg_ctx
, t
, pipe_name
);
328 if (!NT_STATUS_IS_OK(status
)) {
335 static bool spoolss_init_cb(void *ptr
)
337 struct messaging_context
*msg_ctx
=
338 talloc_get_type_abort(ptr
, struct messaging_context
);
342 * Migrate the printers first.
344 ok
= nt_printing_tdb_migrate(msg_ctx
);
352 static bool spoolss_shutdown_cb(void *ptr
)
354 srv_spoolss_cleanup();
359 static NTSTATUS
rpc_setup_spoolss(struct tevent_context
*ev_ctx
,
360 struct messaging_context
*msg_ctx
)
362 const struct ndr_interface_table
*t
= &ndr_table_spoolss
;
363 struct rpc_srv_callbacks spoolss_cb
;
364 enum rpc_daemon_type_e spoolss_type
= rpc_spoolss_daemon();
365 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
366 enum rpc_service_mode_e service_mode
= rpc_service_mode(t
->name
);
368 if (lp__disable_spoolss()) {
372 if (service_mode
!= RPC_SERVICE_MODE_EMBEDDED
||
373 spoolss_type
!= RPC_DAEMON_EMBEDDED
) {
377 spoolss_cb
.init
= spoolss_init_cb
;
378 spoolss_cb
.shutdown
= spoolss_shutdown_cb
;
379 spoolss_cb
.private_data
= msg_ctx
;
381 status
= rpc_spoolss_init(&spoolss_cb
);
382 if (!NT_STATUS_IS_OK(status
)) {
386 status
= rpc_setup_embedded(ev_ctx
, msg_ctx
, t
, NULL
);
387 if (!NT_STATUS_IS_OK(status
)) {
394 static bool svcctl_init_cb(void *ptr
)
396 struct messaging_context
*msg_ctx
=
397 talloc_get_type_abort(ptr
, struct messaging_context
);
400 /* initialize the control hooks */
401 init_service_op_table();
403 ok
= svcctl_init_winreg(msg_ctx
);
411 static bool svcctl_shutdown_cb(void *ptr
)
413 shutdown_service_op_table();
418 static NTSTATUS
rpc_setup_svcctl(struct tevent_context
*ev_ctx
,
419 struct messaging_context
*msg_ctx
)
421 const struct ndr_interface_table
*t
= &ndr_table_svcctl
;
422 const char *pipe_name
= "svcctl";
423 struct rpc_srv_callbacks svcctl_cb
;
425 enum rpc_service_mode_e service_mode
= rpc_service_mode(t
->name
);
427 if (service_mode
!= RPC_SERVICE_MODE_EMBEDDED
) {
431 svcctl_cb
.init
= svcctl_init_cb
;
432 svcctl_cb
.shutdown
= svcctl_shutdown_cb
;
433 svcctl_cb
.private_data
= msg_ctx
;
435 status
= rpc_svcctl_init(&svcctl_cb
);
436 if (!NT_STATUS_IS_OK(status
)) {
440 status
= rpc_setup_embedded(ev_ctx
, msg_ctx
, t
, pipe_name
);
441 if (!NT_STATUS_IS_OK(status
)) {
448 static NTSTATUS
rpc_setup_ntsvcs(struct tevent_context
*ev_ctx
,
449 struct messaging_context
*msg_ctx
)
451 const struct ndr_interface_table
*t
= &ndr_table_ntsvcs
;
453 enum rpc_service_mode_e service_mode
= rpc_service_mode(t
->name
);
455 if (service_mode
!= RPC_SERVICE_MODE_EMBEDDED
) {
459 status
= rpc_ntsvcs_init(NULL
);
460 if (!NT_STATUS_IS_OK(status
)) {
464 status
= rpc_setup_embedded(ev_ctx
, msg_ctx
, t
, NULL
);
465 if (!NT_STATUS_IS_OK(status
)) {
472 static bool eventlog_init_cb(void *ptr
)
474 struct messaging_context
*msg_ctx
=
475 talloc_get_type_abort(ptr
, struct messaging_context
);
478 ok
= eventlog_init_winreg(msg_ctx
);
486 static NTSTATUS
rpc_setup_eventlog(struct tevent_context
*ev_ctx
,
487 struct messaging_context
*msg_ctx
)
489 const struct ndr_interface_table
*t
= &ndr_table_eventlog
;
490 struct rpc_srv_callbacks eventlog_cb
;
492 enum rpc_service_mode_e service_mode
= rpc_service_mode(t
->name
);
494 if (service_mode
!= RPC_SERVICE_MODE_EMBEDDED
) {
498 eventlog_cb
.init
= eventlog_init_cb
;
499 eventlog_cb
.shutdown
= NULL
;
500 eventlog_cb
.private_data
= msg_ctx
;
502 status
= rpc_eventlog_init(&eventlog_cb
);
503 if (!NT_STATUS_IS_OK(status
)) {
507 status
= rpc_setup_embedded(ev_ctx
, msg_ctx
, t
, NULL
);
508 if (!NT_STATUS_IS_OK(status
)) {
515 static NTSTATUS
rpc_setup_initshutdown(struct tevent_context
*ev_ctx
,
516 struct messaging_context
*msg_ctx
)
518 const struct ndr_interface_table
*t
= &ndr_table_initshutdown
;
520 enum rpc_service_mode_e service_mode
= rpc_service_mode(t
->name
);
522 if (service_mode
!= RPC_SERVICE_MODE_EMBEDDED
) {
526 status
= rpc_initshutdown_init(NULL
);
527 if (!NT_STATUS_IS_OK(status
)) {
531 status
= rpc_setup_embedded(ev_ctx
, msg_ctx
, t
, NULL
);
532 if (!NT_STATUS_IS_OK(status
)) {
539 NTSTATUS
dcesrv_ep_setup(struct tevent_context
*ev_ctx
,
540 struct messaging_context
*msg_ctx
)
544 init_module_fn
*mod_init_fns
= NULL
;
547 tmp_ctx
= talloc_stackframe();
548 if (tmp_ctx
== NULL
) {
549 return NT_STATUS_NO_MEMORY
;
552 status
= rpc_setup_winreg(ev_ctx
, msg_ctx
);
553 if (!NT_STATUS_IS_OK(status
)) {
557 status
= rpc_setup_srvsvc(ev_ctx
, msg_ctx
);
558 if (!NT_STATUS_IS_OK(status
)) {
562 status
= rpc_setup_lsarpc(ev_ctx
, msg_ctx
);
563 if (!NT_STATUS_IS_OK(status
)) {
567 status
= rpc_setup_samr(ev_ctx
, msg_ctx
);
568 if (!NT_STATUS_IS_OK(status
)) {
572 status
= rpc_setup_netlogon(ev_ctx
, msg_ctx
);
573 if (!NT_STATUS_IS_OK(status
)) {
577 status
= rpc_setup_netdfs(ev_ctx
, msg_ctx
);
578 if (!NT_STATUS_IS_OK(status
)) {
583 status
= rpc_setup_rpcecho(ev_ctx
, msg_ctx
);
584 if (!NT_STATUS_IS_OK(status
)) {
589 status
= rpc_setup_dssetup(ev_ctx
, msg_ctx
);
590 if (!NT_STATUS_IS_OK(status
)) {
594 status
= rpc_setup_wkssvc(ev_ctx
, msg_ctx
);
595 if (!NT_STATUS_IS_OK(status
)) {
599 status
= rpc_setup_spoolss(ev_ctx
, msg_ctx
);
600 if (!NT_STATUS_IS_OK(status
)) {
604 status
= rpc_setup_svcctl(ev_ctx
, msg_ctx
);
605 if (!NT_STATUS_IS_OK(status
)) {
609 status
= rpc_setup_ntsvcs(ev_ctx
, msg_ctx
);
610 if (!NT_STATUS_IS_OK(status
)) {
614 status
= rpc_setup_eventlog(ev_ctx
, msg_ctx
);
615 if (!NT_STATUS_IS_OK(status
)) {
619 status
= rpc_setup_initshutdown(ev_ctx
, msg_ctx
);
620 if (!NT_STATUS_IS_OK(status
)) {
624 DBG_INFO("Initializing DCE/RPC modules\n");
626 /* Initialize static subsystems */
627 static_init_rpc(NULL
);
629 /* Initialize shared modules */
630 mod_init_fns
= load_samba_modules(tmp_ctx
, "rpc");
631 if ((mod_init_fns
== NULL
) && (errno
!= ENOENT
)) {
633 * ENOENT means the directory doesn't exist which can happen if
634 * all modules are static. So ENOENT is ok, everything else is
637 DBG_ERR("Loading shared DCE/RPC modules failed [%s]\n",
639 status
= NT_STATUS_UNSUCCESSFUL
;
643 ok
= run_init_functions(NULL
, mod_init_fns
);
645 DBG_ERR("Initializing shared DCE/RPC modules failed\n");
646 status
= NT_STATUS_UNSUCCESSFUL
;
650 ok
= setup_rpc_modules(ev_ctx
, msg_ctx
);
652 DBG_ERR("Shared DCE/RPC modules setup failed\n");
653 status
= NT_STATUS_UNSUCCESSFUL
;
657 status
= NT_STATUS_OK
;
659 talloc_free(tmp_ctx
);
663 /* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */