s3-proto: move remaining spoolss protos to own header file.
[Samba.git] / source3 / rpc_server / rpc_ep_setup.c
blob6a48f8890df8ce60d477030bfe2099862ba3948c
1 /*
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/>.
22 #include "includes.h"
24 #include "../librpc/gen_ndr/ndr_epmapper_c.h"
25 #include "../librpc/gen_ndr/srv_epmapper.h"
26 #include "../librpc/gen_ndr/srv_srvsvc.h"
27 #include "../librpc/gen_ndr/srv_winreg.h"
28 #include "../librpc/gen_ndr/srv_dfs.h"
29 #include "../librpc/gen_ndr/srv_dssetup.h"
30 #include "../librpc/gen_ndr/srv_echo.h"
31 #include "../librpc/gen_ndr/srv_eventlog.h"
32 #include "../librpc/gen_ndr/srv_initshutdown.h"
33 #include "../librpc/gen_ndr/srv_lsa.h"
34 #include "../librpc/gen_ndr/srv_netlogon.h"
35 #include "../librpc/gen_ndr/srv_ntsvcs.h"
36 #include "../librpc/gen_ndr/srv_samr.h"
37 #include "../librpc/gen_ndr/srv_spoolss.h"
38 #include "../librpc/gen_ndr/srv_svcctl.h"
39 #include "../librpc/gen_ndr/srv_wkssvc.h"
41 #include "printing/nt_printing_migrate.h"
42 #include "rpc_server/eventlog/srv_eventlog_reg.h"
43 #include "rpc_server/svcctl/srv_svcctl_reg.h"
44 #include "rpc_server/spoolss/srv_spoolss_nt.h"
46 #include "librpc/rpc/dcerpc_ep.h"
48 #include "rpc_server/rpc_ep_setup.h"
49 #include "rpc_server/rpc_server.h"
50 #include "rpc_server/srv_pipe_register.h"
51 #include "rpc_server/epmapper/srv_epmapper.h"
53 struct dcesrv_ep_context {
54 struct tevent_context *ev_ctx;
55 struct messaging_context *msg_ctx;
58 static uint16_t _open_sockets(struct tevent_context *ev_ctx,
59 struct messaging_context *msg_ctx,
60 struct ndr_syntax_id syntax_id,
61 uint16_t port)
63 uint32_t num_ifs = iface_count();
64 uint32_t i;
65 uint16_t p = 0;
67 if (lp_interfaces() && lp_bind_interfaces_only()) {
69 * We have been given an interfaces line, and been told to only
70 * bind to those interfaces. Create a socket per interface and
71 * bind to only these.
74 /* Now open a listen socket for each of the interfaces. */
75 for(i = 0; i < num_ifs; i++) {
76 const struct sockaddr_storage *ifss =
77 iface_n_sockaddr_storage(i);
79 p = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
80 msg_ctx,
81 syntax_id,
82 ifss,
83 port);
84 if (p == 0) {
85 return 0;
87 port = p;
89 } else {
90 const char *sock_addr = lp_socket_address();
91 const char *sock_ptr;
92 char *sock_tok;
94 if (strequal(sock_addr, "0.0.0.0") ||
95 strequal(sock_addr, "::")) {
96 #if HAVE_IPV6
97 sock_addr = "::";
98 #else
99 sock_addr = "0.0.0.0";
100 #endif
103 for (sock_ptr = sock_addr;
104 next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,");
106 struct sockaddr_storage ss;
108 /* open an incoming socket */
109 if (!interpret_string_addr(&ss,
110 sock_tok,
111 AI_NUMERICHOST|AI_PASSIVE)) {
112 continue;
115 p = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
116 msg_ctx,
117 syntax_id,
118 &ss,
119 port);
120 if (p == 0) {
121 return 0;
123 port = p;
127 return p;
130 static void rpc_ep_setup_register_loop(struct tevent_req *subreq);
131 static NTSTATUS rpc_ep_setup_try_register(TALLOC_CTX *mem_ctx,
132 struct tevent_context *ev_ctx,
133 struct messaging_context *msg_ctx,
134 const struct ndr_interface_table *iface,
135 const char *name,
136 uint16_t port,
137 struct dcerpc_binding_handle **pbh);
139 struct rpc_ep_regsiter_state {
140 struct dcerpc_binding_handle *h;
142 TALLOC_CTX *mem_ctx;
143 struct tevent_context *ev_ctx;
144 struct messaging_context *msg_ctx;
146 const struct ndr_interface_table *iface;
148 const char *ncalrpc;
149 uint16_t port;
151 uint32_t wait_time;
154 NTSTATUS rpc_ep_setup_register(struct tevent_context *ev_ctx,
155 struct messaging_context *msg_ctx,
156 const struct ndr_interface_table *iface,
157 const char *ncalrpc,
158 uint16_t port)
160 struct rpc_ep_regsiter_state *state;
161 struct tevent_req *req;
163 state = talloc(ev_ctx, struct rpc_ep_regsiter_state);
164 if (state == NULL) {
165 return NT_STATUS_NO_MEMORY;
168 state->mem_ctx = talloc_named(state,
170 "ep %s %p",
171 iface->name, state);
172 if (state->mem_ctx == NULL) {
173 talloc_free(state);
174 return NT_STATUS_NO_MEMORY;
177 state->wait_time = 1;
178 state->ev_ctx = ev_ctx;
179 state->msg_ctx = msg_ctx;
180 state->iface = iface;
181 state->ncalrpc = talloc_strdup(state, ncalrpc);
182 state->port = port;
184 req = tevent_wakeup_send(state->mem_ctx,
185 state->ev_ctx,
186 timeval_current_ofs(1, 0));
187 if (tevent_req_nomem(state->mem_ctx, req)) {
188 talloc_free(state);
189 return NT_STATUS_NO_MEMORY;
192 tevent_req_set_callback(req, rpc_ep_setup_register_loop, state);
194 return NT_STATUS_OK;
197 #define MONITOR_WAIT_TIME 15
198 static void rpc_ep_setup_monitor_loop(struct tevent_req *subreq);
200 static void rpc_ep_setup_register_loop(struct tevent_req *subreq)
202 struct rpc_ep_regsiter_state *state =
203 tevent_req_callback_data(subreq, struct rpc_ep_regsiter_state);
204 NTSTATUS status;
205 bool ok;
207 ok = tevent_wakeup_recv(subreq);
208 TALLOC_FREE(subreq);
209 if (!ok) {
210 talloc_free(state);
211 return;
214 status = rpc_ep_setup_try_register(state->mem_ctx,
215 state->ev_ctx,
216 state->msg_ctx,
217 state->iface,
218 state->ncalrpc,
219 state->port,
220 &state->h);
221 if (NT_STATUS_IS_OK(status)) {
222 /* endpoint registered, monitor the connnection. */
223 subreq = tevent_wakeup_send(state->mem_ctx,
224 state->ev_ctx,
225 timeval_current_ofs(MONITOR_WAIT_TIME, 0));
226 if (tevent_req_nomem(state->mem_ctx, subreq)) {
227 talloc_free(state);
228 return;
231 tevent_req_set_callback(subreq, rpc_ep_setup_monitor_loop, state);
232 return;
235 state->wait_time = state->wait_time * 2;
236 if (state->wait_time > 16) {
237 DEBUG(0, ("Failed to register endpoint '%s'!\n",
238 state->iface->name));
239 state->wait_time = 16;
242 subreq = tevent_wakeup_send(state->mem_ctx,
243 state->ev_ctx,
244 timeval_current_ofs(state->wait_time, 0));
245 if (tevent_req_nomem(state->mem_ctx, subreq)) {
246 talloc_free(state);
247 return;
250 tevent_req_set_callback(subreq, rpc_ep_setup_register_loop, state);
251 return;
254 static NTSTATUS rpc_ep_setup_try_register(TALLOC_CTX *mem_ctx,
255 struct tevent_context *ev_ctx,
256 struct messaging_context *msg_ctx,
257 const struct ndr_interface_table *iface,
258 const char *name,
259 uint16_t port,
260 struct dcerpc_binding_handle **pbh)
262 struct dcerpc_binding_vector *v = NULL;
263 NTSTATUS status;
265 status = dcerpc_binding_vector_create(mem_ctx,
266 iface,
267 port,
268 name,
269 &v);
270 if (!NT_STATUS_IS_OK(status)) {
271 return status;
274 status = dcerpc_ep_register(mem_ctx,
275 iface,
277 &iface->syntax_id.uuid,
278 name,
279 pbh);
280 talloc_free(v);
281 if (!NT_STATUS_IS_OK(status)) {
282 return status;
285 return status;
289 * Monitor the connection to the endpoint mapper and if it goes away, try to
290 * register the endpoint.
292 static void rpc_ep_setup_monitor_loop(struct tevent_req *subreq)
294 struct rpc_ep_regsiter_state *state =
295 tevent_req_callback_data(subreq, struct rpc_ep_regsiter_state);
296 struct policy_handle entry_handle;
297 struct dcerpc_binding map_binding;
298 struct epm_twr_p_t towers[10];
299 struct epm_twr_t *map_tower;
300 uint32_t num_towers = 0;
301 struct GUID object;
302 NTSTATUS status;
303 uint32_t result = EPMAPPER_STATUS_CANT_PERFORM_OP;
304 TALLOC_CTX *tmp_ctx;
305 bool ok;
307 ZERO_STRUCT(object);
308 ZERO_STRUCT(entry_handle);
310 tmp_ctx = talloc_stackframe();
311 if (tmp_ctx == NULL) {
312 talloc_free(state);
313 return;
316 ok = tevent_wakeup_recv(subreq);
317 TALLOC_FREE(subreq);
318 if (!ok) {
319 talloc_free(state);
320 return;
323 /* Create map tower */
324 map_binding.transport = NCACN_NP;
325 map_binding.object = state->iface->syntax_id;
326 map_binding.host = "";
327 map_binding.endpoint = "";
329 map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
330 if (map_tower == NULL) {
331 talloc_free(tmp_ctx);
332 talloc_free(state);
333 return;
336 status = dcerpc_binding_build_tower(map_tower, &map_binding,
337 &map_tower->tower);
338 if (!NT_STATUS_IS_OK(status)) {
339 talloc_free(tmp_ctx);
340 talloc_free(state);
341 return;
344 ok = false;
345 status = dcerpc_epm_Map(state->h,
346 tmp_ctx,
347 &object,
348 map_tower,
349 &entry_handle,
351 &num_towers,
352 towers,
353 &result);
354 if (NT_STATUS_IS_OK(status)) {
355 ok = true;
357 if (result == EPMAPPER_STATUS_OK ||
358 result == EPMAPPER_STATUS_NO_MORE_ENTRIES) {
359 ok = true;
361 if (num_towers == 0) {
362 ok = false;
365 talloc_free(tmp_ctx);
367 subreq = tevent_wakeup_send(state->mem_ctx,
368 state->ev_ctx,
369 timeval_current_ofs(MONITOR_WAIT_TIME, 0));
370 if (tevent_req_nomem(state->mem_ctx, subreq)) {
371 talloc_free(state);
372 return;
375 if (ok) {
376 tevent_req_set_callback(subreq, rpc_ep_setup_monitor_loop, state);
377 } else {
378 TALLOC_FREE(state->h);
379 state->wait_time = 1;
381 tevent_req_set_callback(subreq, rpc_ep_setup_register_loop, state);
384 return;
387 static bool epmapper_init_cb(void *ptr)
389 struct dcesrv_ep_context *ep_ctx =
390 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
391 uint16_t port;
393 port = _open_sockets(ep_ctx->ev_ctx,
394 ep_ctx->msg_ctx,
395 ndr_table_epmapper.syntax_id,
396 135);
397 if (port == 135) {
398 return true;
401 return false;
404 static bool epmapper_shutdown_cb(void *ptr)
406 srv_epmapper_cleanup();
408 return true;
411 static bool winreg_init_cb(void *ptr)
413 struct dcesrv_ep_context *ep_ctx =
414 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
415 struct ndr_syntax_id abstract_syntax = ndr_table_winreg.syntax_id;
416 const char *pipe_name = "winreg";
417 const char *rpcsrv_type;
418 uint16_t port;
420 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
421 "rpc_server",
422 "epmapper",
423 "none");
425 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
426 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
427 NTSTATUS status;
428 bool ok;
430 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
431 ep_ctx->msg_ctx,
432 abstract_syntax,
433 pipe_name,
434 NULL);
435 if (!ok) {
436 return false;
438 port = _open_sockets(ep_ctx->ev_ctx,
439 ep_ctx->msg_ctx,
440 abstract_syntax,
442 if (port == 0) {
443 return false;
446 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
447 ep_ctx->msg_ctx,
448 &ndr_table_winreg,
449 pipe_name,
450 port);
451 if (!NT_STATUS_IS_OK(status)) {
452 return false;
456 return true;
459 static bool srvsvc_init_cb(void *ptr)
461 struct dcesrv_ep_context *ep_ctx =
462 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
463 struct ndr_syntax_id abstract_syntax = ndr_table_srvsvc.syntax_id;
464 const char *pipe_name = "srvsvc";
465 const char *rpcsrv_type;
466 uint16_t port;
468 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
469 "rpc_server",
470 "epmapper",
471 "none");
473 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
474 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
475 NTSTATUS status;
476 bool ok;
478 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
479 ep_ctx->msg_ctx,
480 abstract_syntax,
481 pipe_name,
482 NULL);
483 if (!ok) {
484 return false;
487 port = _open_sockets(ep_ctx->ev_ctx,
488 ep_ctx->msg_ctx,
489 abstract_syntax,
491 if (port == 0) {
492 return false;
495 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
496 ep_ctx->msg_ctx,
497 &ndr_table_srvsvc,
498 pipe_name,
499 port);
500 if (!NT_STATUS_IS_OK(status)) {
501 return false;
505 return true;
508 static bool lsarpc_init_cb(void *ptr)
510 struct dcesrv_ep_context *ep_ctx =
511 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
512 struct ndr_syntax_id abstract_syntax = ndr_table_lsarpc.syntax_id;
513 const char *pipe_name = "lsarpc";
514 const char *rpcsrv_type;
515 uint16_t port;
517 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
518 "rpc_server",
519 "epmapper",
520 "none");
522 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
523 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
524 NTSTATUS status;
525 bool ok;
527 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
528 ep_ctx->msg_ctx,
529 abstract_syntax,
530 pipe_name,
531 NULL);
532 if (!ok) {
533 return false;
536 port = _open_sockets(ep_ctx->ev_ctx,
537 ep_ctx->msg_ctx,
538 abstract_syntax,
540 if (port == 0) {
541 return false;
544 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
545 ep_ctx->msg_ctx,
546 &ndr_table_lsarpc,
547 pipe_name,
548 port);
549 if (!NT_STATUS_IS_OK(status)) {
550 return false;
554 return true;
557 static bool samr_init_cb(void *ptr)
559 struct dcesrv_ep_context *ep_ctx =
560 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
561 struct ndr_syntax_id abstract_syntax = ndr_table_samr.syntax_id;
562 const char *pipe_name = "samr";
563 const char *rpcsrv_type;
564 uint16_t port;
566 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
567 "rpc_server",
568 "epmapper",
569 "none");
571 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
572 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
573 NTSTATUS status;
574 bool ok;
576 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
577 ep_ctx->msg_ctx,
578 abstract_syntax,
579 pipe_name,
580 NULL);
581 if (!ok) {
582 return false;
585 port = _open_sockets(ep_ctx->ev_ctx,
586 ep_ctx->msg_ctx,
587 abstract_syntax,
589 if (port == 0) {
590 return false;
593 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
594 ep_ctx->msg_ctx,
595 &ndr_table_samr,
596 pipe_name,
597 port);
598 if (!NT_STATUS_IS_OK(status)) {
599 return false;
603 return true;
606 static bool netlogon_init_cb(void *ptr)
608 struct dcesrv_ep_context *ep_ctx =
609 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
610 struct ndr_syntax_id abstract_syntax = ndr_table_netlogon.syntax_id;
611 const char *pipe_name = "netlogon";
612 const char *rpcsrv_type;
613 uint16_t port;
615 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
616 "rpc_server",
617 "epmapper",
618 "none");
620 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
621 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
622 NTSTATUS status;
623 bool ok;
625 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
626 ep_ctx->msg_ctx,
627 abstract_syntax,
628 pipe_name,
629 NULL);
630 if (!ok) {
631 return false;
634 port = _open_sockets(ep_ctx->ev_ctx,
635 ep_ctx->msg_ctx,
636 abstract_syntax,
638 if (port == 0) {
639 return false;
642 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
643 ep_ctx->msg_ctx,
644 &ndr_table_netlogon,
645 pipe_name,
646 port);
647 if (!NT_STATUS_IS_OK(status)) {
648 return false;
652 return true;
655 static bool spoolss_init_cb(void *ptr)
657 struct dcesrv_ep_context *ep_ctx =
658 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
659 const char *rpcsrv_type;
660 bool ok;
662 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
663 "rpc_server",
664 "epmapper",
665 "none");
668 * Migrate the printers first.
670 ok = nt_printing_tdb_migrate(ep_ctx->msg_ctx);
671 if (!ok) {
672 return false;
675 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
676 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
677 NTSTATUS status;
679 status =rpc_ep_setup_register(ep_ctx->ev_ctx,
680 ep_ctx->msg_ctx,
681 &ndr_table_spoolss,
682 "spoolss",
684 if (!NT_STATUS_IS_OK(status)) {
685 return false;
689 return true;
692 static bool spoolss_shutdown_cb(void *ptr)
694 srv_spoolss_cleanup();
696 return true;
699 static bool svcctl_init_cb(void *ptr)
701 struct dcesrv_ep_context *ep_ctx =
702 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
703 const char *rpcsrv_type;
704 bool ok;
706 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
707 "rpc_server",
708 "epmapper",
709 "none");
711 ok = svcctl_init_winreg(ep_ctx->msg_ctx);
712 if (!ok) {
713 return false;
716 /* initialize the control hooks */
717 init_service_op_table();
719 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
720 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
721 NTSTATUS status;
723 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
724 ep_ctx->msg_ctx,
725 &ndr_table_svcctl,
726 "svcctl",
728 if (!NT_STATUS_IS_OK(status)) {
729 return false;
733 return true;
736 static bool svcctl_shutdown_cb(void *ptr)
738 shutdown_service_op_table();
740 return true;
743 static bool ntsvcs_init_cb(void *ptr)
745 struct dcesrv_ep_context *ep_ctx =
746 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
747 const char *rpcsrv_type;
749 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
750 "rpc_server",
751 "epmapper",
752 "none");
754 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
755 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
756 NTSTATUS status;
758 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
759 ep_ctx->msg_ctx,
760 &ndr_table_ntsvcs,
761 "ntsvcs",
763 if (!NT_STATUS_IS_OK(status)) {
764 return false;
768 return true;
771 static bool eventlog_init_cb(void *ptr)
773 struct dcesrv_ep_context *ep_ctx =
774 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
775 const char *rpcsrv_type;
776 bool ok;
778 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
779 "rpc_server",
780 "epmapper",
781 "none");
783 ok = eventlog_init_winreg(ep_ctx->msg_ctx);
784 if (!ok) {
785 return false;
788 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
789 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
790 NTSTATUS status;
792 status =rpc_ep_setup_register(ep_ctx->ev_ctx,
793 ep_ctx->msg_ctx,
794 &ndr_table_eventlog,
795 "eventlog",
797 if (!NT_STATUS_IS_OK(status)) {
798 return false;
802 return true;
805 static bool initshutdown_init_cb(void *ptr)
807 struct dcesrv_ep_context *ep_ctx =
808 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
809 const char *rpcsrv_type;
811 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
812 "rpc_server",
813 "epmapper",
814 "none");
816 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
817 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
818 NTSTATUS status;
820 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
821 ep_ctx->msg_ctx,
822 &ndr_table_initshutdown,
823 "initshutdown",
825 if (!NT_STATUS_IS_OK(status)) {
826 return false;
830 return true;
833 #ifdef DEVELOPER
834 static bool rpcecho_init_cb(void *ptr) {
835 struct dcesrv_ep_context *ep_ctx =
836 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
837 const char *rpcsrv_type;
838 uint16_t port;
840 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
841 "rpc_server",
842 "epmapper",
843 "none");
845 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
846 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
847 NTSTATUS status;
849 port = _open_sockets(ep_ctx->ev_ctx,
850 ep_ctx->msg_ctx,
851 ndr_table_rpcecho.syntax_id,
853 if (port == 0) {
854 return false;
857 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
858 ep_ctx->msg_ctx,
859 &ndr_table_rpcecho,
860 "rpcecho",
861 port);
862 if (!NT_STATUS_IS_OK(status)) {
863 return false;
867 return true;
870 #endif
872 static bool netdfs_init_cb(void *ptr)
874 struct dcesrv_ep_context *ep_ctx =
875 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
876 struct ndr_syntax_id abstract_syntax = ndr_table_netdfs.syntax_id;
877 const char *pipe_name = "netdfs";
878 const char *rpcsrv_type;
879 uint16_t port;
881 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
882 "rpc_server",
883 "epmapper",
884 "none");
885 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
886 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
887 NTSTATUS status;
888 bool ok;
890 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
891 ep_ctx->msg_ctx,
892 abstract_syntax,
893 pipe_name,
894 NULL);
895 if (!ok) {
896 return false;
899 port = _open_sockets(ep_ctx->ev_ctx,
900 ep_ctx->msg_ctx,
901 abstract_syntax,
903 if (port == 0) {
904 return false;
907 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
908 ep_ctx->msg_ctx,
909 &ndr_table_netdfs,
910 pipe_name,
911 port);
912 if (!NT_STATUS_IS_OK(status)) {
913 return false;
917 return true;
920 static bool dssetup_init_cb(void *ptr)
922 struct dcesrv_ep_context *ep_ctx =
923 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
924 struct ndr_syntax_id abstract_syntax = ndr_table_dssetup.syntax_id;
925 const char *pipe_name = "dssetup";
926 const char *rpcsrv_type;
927 uint16_t port;
929 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
930 "rpc_server",
931 "epmapper",
932 "none");
934 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
935 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
936 NTSTATUS status;
937 bool ok;
939 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
940 ep_ctx->msg_ctx,
941 abstract_syntax,
942 pipe_name,
943 NULL);
944 if (!ok) {
945 return false;
948 port = _open_sockets(ep_ctx->ev_ctx,
949 ep_ctx->msg_ctx,
950 abstract_syntax,
952 if (port == 0) {
953 return false;
956 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
957 ep_ctx->msg_ctx,
958 &ndr_table_dssetup,
959 "dssetup",
960 port);
961 if (!NT_STATUS_IS_OK(status)) {
962 return false;
966 return true;
969 static bool wkssvc_init_cb(void *ptr)
971 struct dcesrv_ep_context *ep_ctx =
972 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
973 struct ndr_syntax_id abstract_syntax = ndr_table_wkssvc.syntax_id;
974 const char *pipe_name = "wkssvc";
975 const char *rpcsrv_type;
976 uint16_t port;
978 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
979 "rpc_server",
980 "epmapper",
981 "none");
982 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
983 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
984 NTSTATUS status;
985 bool ok;
987 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
988 ep_ctx->msg_ctx,
989 abstract_syntax,
990 pipe_name,
991 NULL);
992 if (!ok) {
993 return false;
996 port = _open_sockets(ep_ctx->ev_ctx,
997 ep_ctx->msg_ctx,
998 abstract_syntax,
1000 if (port == 0) {
1001 return false;
1004 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
1005 ep_ctx->msg_ctx,
1006 &ndr_table_wkssvc,
1007 "wkssvc",
1008 port);
1009 if (!NT_STATUS_IS_OK(status)) {
1010 return false;
1014 return true;
1017 bool dcesrv_ep_setup(struct tevent_context *ev_ctx,
1018 struct messaging_context *msg_ctx)
1020 struct dcesrv_ep_context *ep_ctx;
1022 struct rpc_srv_callbacks epmapper_cb;
1024 struct rpc_srv_callbacks winreg_cb;
1025 struct rpc_srv_callbacks srvsvc_cb;
1027 struct rpc_srv_callbacks lsarpc_cb;
1028 struct rpc_srv_callbacks samr_cb;
1029 struct rpc_srv_callbacks netlogon_cb;
1031 struct rpc_srv_callbacks spoolss_cb;
1032 struct rpc_srv_callbacks svcctl_cb;
1033 struct rpc_srv_callbacks ntsvcs_cb;
1034 struct rpc_srv_callbacks eventlog_cb;
1035 struct rpc_srv_callbacks initshutdown_cb;
1036 struct rpc_srv_callbacks netdfs_cb;
1037 #ifdef DEVELOPER
1038 struct rpc_srv_callbacks rpcecho_cb;
1039 #endif
1040 struct rpc_srv_callbacks dssetup_cb;
1041 struct rpc_srv_callbacks wkssvc_cb;
1043 const char *rpcsrv_type;
1045 ep_ctx = talloc(ev_ctx, struct dcesrv_ep_context);
1046 if (ep_ctx == NULL) {
1047 return false;
1050 ep_ctx->ev_ctx = ev_ctx;
1051 ep_ctx->msg_ctx = msg_ctx;
1053 /* start endpoint mapper only if enabled */
1054 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1055 "rpc_server",
1056 "epmapper",
1057 "none");
1058 if (StrCaseCmp(rpcsrv_type, "embedded") == 0) {
1059 epmapper_cb.init = epmapper_init_cb;
1060 epmapper_cb.shutdown = epmapper_shutdown_cb;
1061 epmapper_cb.private_data = ep_ctx;
1063 if (!NT_STATUS_IS_OK(rpc_epmapper_init(&epmapper_cb))) {
1064 return false;
1066 } else if (StrCaseCmp(rpcsrv_type, "daemon") == 0) {
1067 if (!NT_STATUS_IS_OK(rpc_epmapper_init(NULL))) {
1068 return false;
1072 winreg_cb.init = winreg_init_cb;
1073 winreg_cb.shutdown = NULL;
1074 winreg_cb.private_data = ep_ctx;
1075 if (!NT_STATUS_IS_OK(rpc_winreg_init(&winreg_cb))) {
1076 return false;
1079 srvsvc_cb.init = srvsvc_init_cb;
1080 srvsvc_cb.shutdown = NULL;
1081 srvsvc_cb.private_data = ep_ctx;
1082 if (!NT_STATUS_IS_OK(rpc_srvsvc_init(&srvsvc_cb))) {
1083 return false;
1087 lsarpc_cb.init = lsarpc_init_cb;
1088 lsarpc_cb.shutdown = NULL;
1089 lsarpc_cb.private_data = ep_ctx;
1090 if (!NT_STATUS_IS_OK(rpc_lsarpc_init(&lsarpc_cb))) {
1091 return false;
1094 samr_cb.init = samr_init_cb;
1095 samr_cb.shutdown = NULL;
1096 samr_cb.private_data = ep_ctx;
1097 if (!NT_STATUS_IS_OK(rpc_samr_init(&samr_cb))) {
1098 return false;
1101 netlogon_cb.init = netlogon_init_cb;
1102 netlogon_cb.shutdown = NULL;
1103 netlogon_cb.private_data = ep_ctx;
1104 if (!NT_STATUS_IS_OK(rpc_netlogon_init(&netlogon_cb))) {
1105 return false;
1108 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1109 "rpc_server",
1110 "spoolss",
1111 "embedded");
1112 if (StrCaseCmp(rpcsrv_type, "embedded") == 0) {
1113 spoolss_cb.init = spoolss_init_cb;
1114 spoolss_cb.shutdown = spoolss_shutdown_cb;
1115 spoolss_cb.private_data = ep_ctx;
1116 if (!NT_STATUS_IS_OK(rpc_spoolss_init(&spoolss_cb))) {
1117 return false;
1119 } else if (StrCaseCmp(rpcsrv_type, "daemon") == 0 ||
1120 StrCaseCmp(rpcsrv_type, "external") == 0) {
1121 if (!NT_STATUS_IS_OK(rpc_spoolss_init(NULL))) {
1122 return false;
1126 svcctl_cb.init = svcctl_init_cb;
1127 svcctl_cb.shutdown = svcctl_shutdown_cb;
1128 svcctl_cb.private_data = ep_ctx;
1129 if (!NT_STATUS_IS_OK(rpc_svcctl_init(&svcctl_cb))) {
1130 return false;
1133 ntsvcs_cb.init = ntsvcs_init_cb;
1134 ntsvcs_cb.shutdown = NULL;
1135 ntsvcs_cb.private_data = ep_ctx;
1136 if (!NT_STATUS_IS_OK(rpc_ntsvcs_init(&ntsvcs_cb))) {
1137 return false;
1140 eventlog_cb.init = eventlog_init_cb;
1141 eventlog_cb.shutdown = NULL;
1142 eventlog_cb.private_data = ep_ctx;
1143 if (!NT_STATUS_IS_OK(rpc_eventlog_init(&eventlog_cb))) {
1144 return false;
1147 initshutdown_cb.init = initshutdown_init_cb;
1148 initshutdown_cb.shutdown = NULL;
1149 initshutdown_cb.private_data = ep_ctx;
1150 if (!NT_STATUS_IS_OK(rpc_initshutdown_init(&initshutdown_cb))) {
1151 return false;
1154 netdfs_cb.init = netdfs_init_cb;
1155 netdfs_cb.shutdown = NULL;
1156 netdfs_cb.private_data = ep_ctx;
1157 if (!NT_STATUS_IS_OK(rpc_netdfs_init(&netdfs_cb))) {
1158 return false;
1161 #ifdef DEVELOPER
1162 rpcecho_cb.init = rpcecho_init_cb;
1163 rpcecho_cb.shutdown = NULL;
1164 rpcecho_cb.private_data = ep_ctx;
1165 if (!NT_STATUS_IS_OK(rpc_rpcecho_init(&rpcecho_cb))) {
1166 return false;
1168 #endif
1170 dssetup_cb.init = dssetup_init_cb;
1171 dssetup_cb.shutdown = NULL;
1172 dssetup_cb.private_data = ep_ctx;
1173 if (!NT_STATUS_IS_OK(rpc_dssetup_init(&dssetup_cb))) {
1174 return false;
1177 wkssvc_cb.init = wkssvc_init_cb;
1178 wkssvc_cb.shutdown = NULL;
1179 wkssvc_cb.private_data = ep_ctx;
1180 if (!NT_STATUS_IS_OK(rpc_wkssvc_init(&wkssvc_cb))) {
1181 return false;
1184 return true;
1187 /* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */