s3-utils/net_rpc_printer.c: print more info on write error
[Samba/gebeck_regimport.git] / source3 / rpc_server / rpc_ep_setup.c
blob7f40dda9197e995f180d0149ae15f87ccace197f
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"
23 #include "ntdomain.h"
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"
50 #include "rpc_server/rpc_ep_setup.h"
51 #include "rpc_server/rpc_server.h"
52 #include "rpc_server/epmapper/srv_epmapper.h"
54 struct dcesrv_ep_context {
55 struct tevent_context *ev_ctx;
56 struct messaging_context *msg_ctx;
59 static uint16_t _open_sockets(struct tevent_context *ev_ctx,
60 struct messaging_context *msg_ctx,
61 struct ndr_syntax_id syntax_id,
62 uint16_t port)
64 uint32_t num_ifs = iface_count();
65 uint32_t i;
66 uint16_t p = 0;
68 if (lp_interfaces() && lp_bind_interfaces_only()) {
70 * We have been given an interfaces line, and been told to only
71 * bind to those interfaces. Create a socket per interface and
72 * bind to only these.
75 /* Now open a listen socket for each of the interfaces. */
76 for(i = 0; i < num_ifs; i++) {
77 const struct sockaddr_storage *ifss =
78 iface_n_sockaddr_storage(i);
80 p = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
81 msg_ctx,
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 = "::,0.0.0.0";
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 &ss,
118 port);
119 if (p == 0) {
120 return 0;
122 port = p;
126 return p;
129 static void rpc_ep_setup_register_loop(struct tevent_req *subreq);
130 static NTSTATUS rpc_ep_setup_try_register(TALLOC_CTX *mem_ctx,
131 struct tevent_context *ev_ctx,
132 struct messaging_context *msg_ctx,
133 const struct ndr_interface_table *iface,
134 const char *ncalrpc,
135 uint16_t port,
136 struct dcerpc_binding_handle **pbh);
138 struct rpc_ep_regsiter_state {
139 struct dcerpc_binding_handle *h;
141 TALLOC_CTX *mem_ctx;
142 struct tevent_context *ev_ctx;
143 struct messaging_context *msg_ctx;
145 const struct ndr_interface_table *iface;
147 const char *ncalrpc;
148 uint16_t port;
150 uint32_t wait_time;
153 NTSTATUS rpc_ep_setup_register(struct tevent_context *ev_ctx,
154 struct messaging_context *msg_ctx,
155 const struct ndr_interface_table *iface,
156 const char *ncalrpc,
157 uint16_t port)
159 struct rpc_ep_regsiter_state *state;
160 struct tevent_req *req;
162 state = talloc(ev_ctx, struct rpc_ep_regsiter_state);
163 if (state == NULL) {
164 return NT_STATUS_NO_MEMORY;
167 state->mem_ctx = talloc_named(state,
169 "ep %s %p",
170 iface->name, state);
171 if (state->mem_ctx == NULL) {
172 talloc_free(state);
173 return NT_STATUS_NO_MEMORY;
176 state->wait_time = 1;
177 state->ev_ctx = ev_ctx;
178 state->msg_ctx = msg_ctx;
179 state->iface = iface;
180 state->ncalrpc = talloc_strdup(state, ncalrpc);
181 state->port = port;
183 req = tevent_wakeup_send(state->mem_ctx,
184 state->ev_ctx,
185 timeval_current_ofs(1, 0));
186 if (tevent_req_nomem(state->mem_ctx, req)) {
187 talloc_free(state);
188 return NT_STATUS_NO_MEMORY;
191 tevent_req_set_callback(req, rpc_ep_setup_register_loop, state);
193 return NT_STATUS_OK;
196 #define MONITOR_WAIT_TIME 15
197 static void rpc_ep_setup_monitor_loop(struct tevent_req *subreq);
199 static void rpc_ep_setup_register_loop(struct tevent_req *subreq)
201 struct rpc_ep_regsiter_state *state =
202 tevent_req_callback_data(subreq, struct rpc_ep_regsiter_state);
203 NTSTATUS status;
204 bool ok;
206 ok = tevent_wakeup_recv(subreq);
207 TALLOC_FREE(subreq);
208 if (!ok) {
209 talloc_free(state);
210 return;
213 status = rpc_ep_setup_try_register(state->mem_ctx,
214 state->ev_ctx,
215 state->msg_ctx,
216 state->iface,
217 state->ncalrpc,
218 state->port,
219 &state->h);
220 if (NT_STATUS_IS_OK(status)) {
221 /* endpoint registered, monitor the connnection. */
222 subreq = tevent_wakeup_send(state->mem_ctx,
223 state->ev_ctx,
224 timeval_current_ofs(MONITOR_WAIT_TIME, 0));
225 if (tevent_req_nomem(state->mem_ctx, subreq)) {
226 talloc_free(state);
227 return;
230 tevent_req_set_callback(subreq, rpc_ep_setup_monitor_loop, state);
231 return;
234 state->wait_time = state->wait_time * 2;
235 if (state->wait_time > 16) {
236 DEBUG(0, ("Failed to register endpoint '%s'!\n",
237 state->iface->name));
238 state->wait_time = 16;
241 subreq = tevent_wakeup_send(state->mem_ctx,
242 state->ev_ctx,
243 timeval_current_ofs(state->wait_time, 0));
244 if (tevent_req_nomem(state->mem_ctx, subreq)) {
245 talloc_free(state);
246 return;
249 tevent_req_set_callback(subreq, rpc_ep_setup_register_loop, state);
250 return;
253 static NTSTATUS rpc_ep_setup_try_register(TALLOC_CTX *mem_ctx,
254 struct tevent_context *ev_ctx,
255 struct messaging_context *msg_ctx,
256 const struct ndr_interface_table *iface,
257 const char *ncalrpc,
258 uint16_t port,
259 struct dcerpc_binding_handle **pbh)
261 struct dcerpc_binding_vector *v = NULL;
262 NTSTATUS status;
264 status = dcerpc_binding_vector_create(mem_ctx,
265 iface,
266 port,
267 ncalrpc,
268 &v);
269 if (!NT_STATUS_IS_OK(status)) {
270 return status;
273 status = dcerpc_ep_register(mem_ctx,
274 msg_ctx,
275 iface,
277 &iface->syntax_id.uuid,
278 iface->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_m(rpcsrv_type, "embedded") == 0 ||
426 strcasecmp_m(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 pipe_name,
433 NULL);
434 if (!ok) {
435 return false;
437 port = _open_sockets(ep_ctx->ev_ctx,
438 ep_ctx->msg_ctx,
439 abstract_syntax,
441 if (port == 0) {
442 return false;
445 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
446 ep_ctx->msg_ctx,
447 &ndr_table_winreg,
448 pipe_name,
449 port);
450 if (!NT_STATUS_IS_OK(status)) {
451 return false;
455 return true;
458 static bool srvsvc_init_cb(void *ptr)
460 struct dcesrv_ep_context *ep_ctx =
461 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
462 struct ndr_syntax_id abstract_syntax = ndr_table_srvsvc.syntax_id;
463 const char *pipe_name = "srvsvc";
464 const char *rpcsrv_type;
465 uint16_t port;
467 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
468 "rpc_server",
469 "epmapper",
470 "none");
472 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
473 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
474 NTSTATUS status;
475 bool ok;
477 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
478 ep_ctx->msg_ctx,
479 pipe_name,
480 NULL);
481 if (!ok) {
482 return false;
485 port = _open_sockets(ep_ctx->ev_ctx,
486 ep_ctx->msg_ctx,
487 abstract_syntax,
489 if (port == 0) {
490 return false;
493 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
494 ep_ctx->msg_ctx,
495 &ndr_table_srvsvc,
496 pipe_name,
497 port);
498 if (!NT_STATUS_IS_OK(status)) {
499 return false;
503 return true;
506 static bool lsarpc_init_cb(void *ptr)
508 struct dcesrv_ep_context *ep_ctx =
509 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
510 struct ndr_syntax_id abstract_syntax = ndr_table_lsarpc.syntax_id;
511 const char *pipe_name = "lsarpc";
512 const char *rpcsrv_type;
513 uint16_t port;
515 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
516 "rpc_server",
517 "epmapper",
518 "none");
520 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
521 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
522 NTSTATUS status;
523 bool ok;
525 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
526 ep_ctx->msg_ctx,
527 pipe_name,
528 NULL);
529 if (!ok) {
530 return false;
533 port = _open_sockets(ep_ctx->ev_ctx,
534 ep_ctx->msg_ctx,
535 abstract_syntax,
537 if (port == 0) {
538 return false;
541 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
542 ep_ctx->msg_ctx,
543 &ndr_table_lsarpc,
544 pipe_name,
545 port);
546 if (!NT_STATUS_IS_OK(status)) {
547 return false;
551 return true;
554 static bool samr_init_cb(void *ptr)
556 struct dcesrv_ep_context *ep_ctx =
557 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
558 struct ndr_syntax_id abstract_syntax = ndr_table_samr.syntax_id;
559 const char *pipe_name = "samr";
560 const char *rpcsrv_type;
561 uint16_t port;
563 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
564 "rpc_server",
565 "epmapper",
566 "none");
568 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
569 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
570 NTSTATUS status;
571 bool ok;
573 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
574 ep_ctx->msg_ctx,
575 pipe_name,
576 NULL);
577 if (!ok) {
578 return false;
581 port = _open_sockets(ep_ctx->ev_ctx,
582 ep_ctx->msg_ctx,
583 abstract_syntax,
585 if (port == 0) {
586 return false;
589 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
590 ep_ctx->msg_ctx,
591 &ndr_table_samr,
592 pipe_name,
593 port);
594 if (!NT_STATUS_IS_OK(status)) {
595 return false;
599 return true;
602 static bool netlogon_init_cb(void *ptr)
604 struct dcesrv_ep_context *ep_ctx =
605 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
606 struct ndr_syntax_id abstract_syntax = ndr_table_netlogon.syntax_id;
607 const char *pipe_name = "netlogon";
608 const char *rpcsrv_type;
609 uint16_t port;
611 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
612 "rpc_server",
613 "epmapper",
614 "none");
616 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
617 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
618 NTSTATUS status;
619 bool ok;
621 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
622 ep_ctx->msg_ctx,
623 pipe_name,
624 NULL);
625 if (!ok) {
626 return false;
629 port = _open_sockets(ep_ctx->ev_ctx,
630 ep_ctx->msg_ctx,
631 abstract_syntax,
633 if (port == 0) {
634 return false;
637 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
638 ep_ctx->msg_ctx,
639 &ndr_table_netlogon,
640 pipe_name,
641 port);
642 if (!NT_STATUS_IS_OK(status)) {
643 return false;
647 return true;
650 static bool spoolss_init_cb(void *ptr)
652 struct dcesrv_ep_context *ep_ctx =
653 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
654 const char *rpcsrv_type;
655 bool ok;
657 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
658 "rpc_server",
659 "epmapper",
660 "none");
663 * Migrate the printers first.
665 ok = nt_printing_tdb_migrate(ep_ctx->msg_ctx);
666 if (!ok) {
667 return false;
670 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
671 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
672 NTSTATUS status;
674 status =rpc_ep_setup_register(ep_ctx->ev_ctx,
675 ep_ctx->msg_ctx,
676 &ndr_table_spoolss,
677 "spoolss",
679 if (!NT_STATUS_IS_OK(status)) {
680 return false;
684 return true;
687 static bool spoolss_shutdown_cb(void *ptr)
689 srv_spoolss_cleanup();
691 return true;
694 static bool svcctl_init_cb(void *ptr)
696 struct dcesrv_ep_context *ep_ctx =
697 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
698 const char *rpcsrv_type;
699 bool ok;
701 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
702 "rpc_server",
703 "epmapper",
704 "none");
706 ok = svcctl_init_winreg(ep_ctx->msg_ctx);
707 if (!ok) {
708 return false;
711 /* initialize the control hooks */
712 init_service_op_table();
714 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
715 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
716 NTSTATUS status;
718 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
719 ep_ctx->msg_ctx,
720 &ndr_table_svcctl,
721 "svcctl",
723 if (!NT_STATUS_IS_OK(status)) {
724 return false;
728 return true;
731 static bool svcctl_shutdown_cb(void *ptr)
733 shutdown_service_op_table();
735 return true;
738 static bool ntsvcs_init_cb(void *ptr)
740 struct dcesrv_ep_context *ep_ctx =
741 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
742 const char *rpcsrv_type;
744 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
745 "rpc_server",
746 "epmapper",
747 "none");
749 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
750 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
751 NTSTATUS status;
753 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
754 ep_ctx->msg_ctx,
755 &ndr_table_ntsvcs,
756 "ntsvcs",
758 if (!NT_STATUS_IS_OK(status)) {
759 return false;
763 return true;
766 static bool eventlog_init_cb(void *ptr)
768 struct dcesrv_ep_context *ep_ctx =
769 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
770 const char *rpcsrv_type;
771 bool ok;
773 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
774 "rpc_server",
775 "epmapper",
776 "none");
778 ok = eventlog_init_winreg(ep_ctx->msg_ctx);
779 if (!ok) {
780 return false;
783 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
784 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
785 NTSTATUS status;
787 status =rpc_ep_setup_register(ep_ctx->ev_ctx,
788 ep_ctx->msg_ctx,
789 &ndr_table_eventlog,
790 "eventlog",
792 if (!NT_STATUS_IS_OK(status)) {
793 return false;
797 return true;
800 static bool initshutdown_init_cb(void *ptr)
802 struct dcesrv_ep_context *ep_ctx =
803 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
804 const char *rpcsrv_type;
806 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
807 "rpc_server",
808 "epmapper",
809 "none");
811 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
812 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
813 NTSTATUS status;
815 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
816 ep_ctx->msg_ctx,
817 &ndr_table_initshutdown,
818 "initshutdown",
820 if (!NT_STATUS_IS_OK(status)) {
821 return false;
825 return true;
828 #ifdef DEVELOPER
829 static bool rpcecho_init_cb(void *ptr) {
830 struct dcesrv_ep_context *ep_ctx =
831 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
832 const char *rpcsrv_type;
833 uint16_t port;
835 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
836 "rpc_server",
837 "epmapper",
838 "none");
840 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
841 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
842 NTSTATUS status;
844 port = _open_sockets(ep_ctx->ev_ctx,
845 ep_ctx->msg_ctx,
846 ndr_table_rpcecho.syntax_id,
848 if (port == 0) {
849 return false;
852 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
853 ep_ctx->msg_ctx,
854 &ndr_table_rpcecho,
855 "rpcecho",
856 port);
857 if (!NT_STATUS_IS_OK(status)) {
858 return false;
862 return true;
865 #endif
867 static bool netdfs_init_cb(void *ptr)
869 struct dcesrv_ep_context *ep_ctx =
870 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
871 struct ndr_syntax_id abstract_syntax = ndr_table_netdfs.syntax_id;
872 const char *pipe_name = "netdfs";
873 const char *rpcsrv_type;
874 uint16_t port;
876 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
877 "rpc_server",
878 "epmapper",
879 "none");
880 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
881 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
882 NTSTATUS status;
883 bool ok;
885 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
886 ep_ctx->msg_ctx,
887 pipe_name,
888 NULL);
889 if (!ok) {
890 return false;
893 port = _open_sockets(ep_ctx->ev_ctx,
894 ep_ctx->msg_ctx,
895 abstract_syntax,
897 if (port == 0) {
898 return false;
901 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
902 ep_ctx->msg_ctx,
903 &ndr_table_netdfs,
904 pipe_name,
905 port);
906 if (!NT_STATUS_IS_OK(status)) {
907 return false;
911 return true;
914 static bool dssetup_init_cb(void *ptr)
916 struct dcesrv_ep_context *ep_ctx =
917 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
918 struct ndr_syntax_id abstract_syntax = ndr_table_dssetup.syntax_id;
919 const char *pipe_name = "dssetup";
920 const char *rpcsrv_type;
921 uint16_t port;
923 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
924 "rpc_server",
925 "epmapper",
926 "none");
928 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
929 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
930 NTSTATUS status;
931 bool ok;
933 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
934 ep_ctx->msg_ctx,
935 pipe_name,
936 NULL);
937 if (!ok) {
938 return false;
941 port = _open_sockets(ep_ctx->ev_ctx,
942 ep_ctx->msg_ctx,
943 abstract_syntax,
945 if (port == 0) {
946 return false;
949 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
950 ep_ctx->msg_ctx,
951 &ndr_table_dssetup,
952 "dssetup",
953 port);
954 if (!NT_STATUS_IS_OK(status)) {
955 return false;
959 return true;
962 static bool wkssvc_init_cb(void *ptr)
964 struct dcesrv_ep_context *ep_ctx =
965 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
966 struct ndr_syntax_id abstract_syntax = ndr_table_wkssvc.syntax_id;
967 const char *pipe_name = "wkssvc";
968 const char *rpcsrv_type;
969 uint16_t port;
971 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
972 "rpc_server",
973 "epmapper",
974 "none");
975 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
976 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
977 NTSTATUS status;
978 bool ok;
980 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
981 ep_ctx->msg_ctx,
982 pipe_name,
983 NULL);
984 if (!ok) {
985 return false;
988 port = _open_sockets(ep_ctx->ev_ctx,
989 ep_ctx->msg_ctx,
990 abstract_syntax,
992 if (port == 0) {
993 return false;
996 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
997 ep_ctx->msg_ctx,
998 &ndr_table_wkssvc,
999 "wkssvc",
1000 port);
1001 if (!NT_STATUS_IS_OK(status)) {
1002 return false;
1006 return true;
1009 bool dcesrv_ep_setup(struct tevent_context *ev_ctx,
1010 struct messaging_context *msg_ctx)
1012 struct dcesrv_ep_context *ep_ctx;
1014 struct rpc_srv_callbacks epmapper_cb;
1016 struct rpc_srv_callbacks winreg_cb;
1017 struct rpc_srv_callbacks srvsvc_cb;
1019 struct rpc_srv_callbacks lsarpc_cb;
1020 struct rpc_srv_callbacks samr_cb;
1021 struct rpc_srv_callbacks netlogon_cb;
1023 struct rpc_srv_callbacks spoolss_cb;
1024 struct rpc_srv_callbacks svcctl_cb;
1025 struct rpc_srv_callbacks ntsvcs_cb;
1026 struct rpc_srv_callbacks eventlog_cb;
1027 struct rpc_srv_callbacks initshutdown_cb;
1028 struct rpc_srv_callbacks netdfs_cb;
1029 #ifdef DEVELOPER
1030 struct rpc_srv_callbacks rpcecho_cb;
1031 #endif
1032 struct rpc_srv_callbacks dssetup_cb;
1033 struct rpc_srv_callbacks wkssvc_cb;
1035 const char *rpcsrv_type;
1037 ep_ctx = talloc(ev_ctx, struct dcesrv_ep_context);
1038 if (ep_ctx == NULL) {
1039 return false;
1042 ep_ctx->ev_ctx = ev_ctx;
1043 ep_ctx->msg_ctx = msg_ctx;
1045 /* start endpoint mapper only if enabled */
1046 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1047 "rpc_server",
1048 "epmapper",
1049 "none");
1050 if (strcasecmp_m(rpcsrv_type, "embedded") == 0) {
1051 epmapper_cb.init = epmapper_init_cb;
1052 epmapper_cb.shutdown = epmapper_shutdown_cb;
1053 epmapper_cb.private_data = ep_ctx;
1055 if (!NT_STATUS_IS_OK(rpc_epmapper_init(&epmapper_cb))) {
1056 return false;
1058 } else if (strcasecmp_m(rpcsrv_type, "daemon") == 0) {
1059 if (!NT_STATUS_IS_OK(rpc_epmapper_init(NULL))) {
1060 return false;
1064 winreg_cb.init = winreg_init_cb;
1065 winreg_cb.shutdown = NULL;
1066 winreg_cb.private_data = ep_ctx;
1067 if (!NT_STATUS_IS_OK(rpc_winreg_init(&winreg_cb))) {
1068 return false;
1071 srvsvc_cb.init = srvsvc_init_cb;
1072 srvsvc_cb.shutdown = NULL;
1073 srvsvc_cb.private_data = ep_ctx;
1074 if (!NT_STATUS_IS_OK(rpc_srvsvc_init(&srvsvc_cb))) {
1075 return false;
1079 lsarpc_cb.init = lsarpc_init_cb;
1080 lsarpc_cb.shutdown = NULL;
1081 lsarpc_cb.private_data = ep_ctx;
1082 if (!NT_STATUS_IS_OK(rpc_lsarpc_init(&lsarpc_cb))) {
1083 return false;
1086 samr_cb.init = samr_init_cb;
1087 samr_cb.shutdown = NULL;
1088 samr_cb.private_data = ep_ctx;
1089 if (!NT_STATUS_IS_OK(rpc_samr_init(&samr_cb))) {
1090 return false;
1093 netlogon_cb.init = netlogon_init_cb;
1094 netlogon_cb.shutdown = NULL;
1095 netlogon_cb.private_data = ep_ctx;
1096 if (!NT_STATUS_IS_OK(rpc_netlogon_init(&netlogon_cb))) {
1097 return false;
1100 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1101 "rpc_server",
1102 "spoolss",
1103 "embedded");
1104 if (strcasecmp_m(rpcsrv_type, "embedded") == 0) {
1105 spoolss_cb.init = spoolss_init_cb;
1106 spoolss_cb.shutdown = spoolss_shutdown_cb;
1107 spoolss_cb.private_data = ep_ctx;
1108 if (!NT_STATUS_IS_OK(rpc_spoolss_init(&spoolss_cb))) {
1109 return false;
1111 } else if (strcasecmp_m(rpcsrv_type, "daemon") == 0 ||
1112 strcasecmp_m(rpcsrv_type, "external") == 0) {
1113 if (!NT_STATUS_IS_OK(rpc_spoolss_init(NULL))) {
1114 return false;
1118 svcctl_cb.init = svcctl_init_cb;
1119 svcctl_cb.shutdown = svcctl_shutdown_cb;
1120 svcctl_cb.private_data = ep_ctx;
1121 if (!NT_STATUS_IS_OK(rpc_svcctl_init(&svcctl_cb))) {
1122 return false;
1125 ntsvcs_cb.init = ntsvcs_init_cb;
1126 ntsvcs_cb.shutdown = NULL;
1127 ntsvcs_cb.private_data = ep_ctx;
1128 if (!NT_STATUS_IS_OK(rpc_ntsvcs_init(&ntsvcs_cb))) {
1129 return false;
1132 eventlog_cb.init = eventlog_init_cb;
1133 eventlog_cb.shutdown = NULL;
1134 eventlog_cb.private_data = ep_ctx;
1135 if (!NT_STATUS_IS_OK(rpc_eventlog_init(&eventlog_cb))) {
1136 return false;
1139 initshutdown_cb.init = initshutdown_init_cb;
1140 initshutdown_cb.shutdown = NULL;
1141 initshutdown_cb.private_data = ep_ctx;
1142 if (!NT_STATUS_IS_OK(rpc_initshutdown_init(&initshutdown_cb))) {
1143 return false;
1146 netdfs_cb.init = netdfs_init_cb;
1147 netdfs_cb.shutdown = NULL;
1148 netdfs_cb.private_data = ep_ctx;
1149 if (!NT_STATUS_IS_OK(rpc_netdfs_init(&netdfs_cb))) {
1150 return false;
1153 #ifdef DEVELOPER
1154 rpcecho_cb.init = rpcecho_init_cb;
1155 rpcecho_cb.shutdown = NULL;
1156 rpcecho_cb.private_data = ep_ctx;
1157 if (!NT_STATUS_IS_OK(rpc_rpcecho_init(&rpcecho_cb))) {
1158 return false;
1160 #endif
1162 dssetup_cb.init = dssetup_init_cb;
1163 dssetup_cb.shutdown = NULL;
1164 dssetup_cb.private_data = ep_ctx;
1165 if (!NT_STATUS_IS_OK(rpc_dssetup_init(&dssetup_cb))) {
1166 return false;
1169 wkssvc_cb.init = wkssvc_init_cb;
1170 wkssvc_cb.shutdown = NULL;
1171 wkssvc_cb.private_data = ep_ctx;
1172 if (!NT_STATUS_IS_OK(rpc_wkssvc_init(&wkssvc_cb))) {
1173 return false;
1176 return true;
1179 /* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */