Remove unused function parse_add_domuser().
[Samba.git] / source3 / rpc_server / rpc_ep_setup.c
blob3cf5af8cbe1d33dd1223ce913623d48cd22c47be
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.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/srv_pipe_register.h"
53 #include "rpc_server/epmapper/srv_epmapper.h"
55 struct dcesrv_ep_context {
56 struct tevent_context *ev_ctx;
57 struct messaging_context *msg_ctx;
60 static uint16_t _open_sockets(struct tevent_context *ev_ctx,
61 struct messaging_context *msg_ctx,
62 struct ndr_syntax_id syntax_id,
63 uint16_t port)
65 uint32_t num_ifs = iface_count();
66 uint32_t i;
67 uint16_t p = 0;
69 if (lp_interfaces() && lp_bind_interfaces_only()) {
71 * We have been given an interfaces line, and been told to only
72 * bind to those interfaces. Create a socket per interface and
73 * bind to only these.
76 /* Now open a listen socket for each of the interfaces. */
77 for(i = 0; i < num_ifs; i++) {
78 const struct sockaddr_storage *ifss =
79 iface_n_sockaddr_storage(i);
81 p = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
82 msg_ctx,
83 syntax_id,
84 ifss,
85 port);
86 if (p == 0) {
87 return 0;
89 port = p;
91 } else {
92 const char *sock_addr = lp_socket_address();
93 const char *sock_ptr;
94 char *sock_tok;
96 if (strequal(sock_addr, "0.0.0.0") ||
97 strequal(sock_addr, "::")) {
98 #if HAVE_IPV6
99 sock_addr = "::";
100 #else
101 sock_addr = "0.0.0.0";
102 #endif
105 for (sock_ptr = sock_addr;
106 next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,");
108 struct sockaddr_storage ss;
110 /* open an incoming socket */
111 if (!interpret_string_addr(&ss,
112 sock_tok,
113 AI_NUMERICHOST|AI_PASSIVE)) {
114 continue;
117 p = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
118 msg_ctx,
119 syntax_id,
120 &ss,
121 port);
122 if (p == 0) {
123 return 0;
125 port = p;
129 return p;
132 static void rpc_ep_setup_register_loop(struct tevent_req *subreq);
133 static NTSTATUS rpc_ep_setup_try_register(TALLOC_CTX *mem_ctx,
134 struct tevent_context *ev_ctx,
135 struct messaging_context *msg_ctx,
136 const struct ndr_interface_table *iface,
137 const char *name,
138 uint16_t port,
139 struct dcerpc_binding_handle **pbh);
141 struct rpc_ep_regsiter_state {
142 struct dcerpc_binding_handle *h;
144 TALLOC_CTX *mem_ctx;
145 struct tevent_context *ev_ctx;
146 struct messaging_context *msg_ctx;
148 const struct ndr_interface_table *iface;
150 const char *ncalrpc;
151 uint16_t port;
153 uint32_t wait_time;
156 NTSTATUS rpc_ep_setup_register(struct tevent_context *ev_ctx,
157 struct messaging_context *msg_ctx,
158 const struct ndr_interface_table *iface,
159 const char *ncalrpc,
160 uint16_t port)
162 struct rpc_ep_regsiter_state *state;
163 struct tevent_req *req;
165 state = talloc(ev_ctx, struct rpc_ep_regsiter_state);
166 if (state == NULL) {
167 return NT_STATUS_NO_MEMORY;
170 state->mem_ctx = talloc_named(state,
172 "ep %s %p",
173 iface->name, state);
174 if (state->mem_ctx == NULL) {
175 talloc_free(state);
176 return NT_STATUS_NO_MEMORY;
179 state->wait_time = 1;
180 state->ev_ctx = ev_ctx;
181 state->msg_ctx = msg_ctx;
182 state->iface = iface;
183 state->ncalrpc = talloc_strdup(state, ncalrpc);
184 state->port = port;
186 req = tevent_wakeup_send(state->mem_ctx,
187 state->ev_ctx,
188 timeval_current_ofs(1, 0));
189 if (tevent_req_nomem(state->mem_ctx, req)) {
190 talloc_free(state);
191 return NT_STATUS_NO_MEMORY;
194 tevent_req_set_callback(req, rpc_ep_setup_register_loop, state);
196 return NT_STATUS_OK;
199 #define MONITOR_WAIT_TIME 15
200 static void rpc_ep_setup_monitor_loop(struct tevent_req *subreq);
202 static void rpc_ep_setup_register_loop(struct tevent_req *subreq)
204 struct rpc_ep_regsiter_state *state =
205 tevent_req_callback_data(subreq, struct rpc_ep_regsiter_state);
206 NTSTATUS status;
207 bool ok;
209 ok = tevent_wakeup_recv(subreq);
210 TALLOC_FREE(subreq);
211 if (!ok) {
212 talloc_free(state);
213 return;
216 status = rpc_ep_setup_try_register(state->mem_ctx,
217 state->ev_ctx,
218 state->msg_ctx,
219 state->iface,
220 state->ncalrpc,
221 state->port,
222 &state->h);
223 if (NT_STATUS_IS_OK(status)) {
224 /* endpoint registered, monitor the connnection. */
225 subreq = tevent_wakeup_send(state->mem_ctx,
226 state->ev_ctx,
227 timeval_current_ofs(MONITOR_WAIT_TIME, 0));
228 if (tevent_req_nomem(state->mem_ctx, subreq)) {
229 talloc_free(state);
230 return;
233 tevent_req_set_callback(subreq, rpc_ep_setup_monitor_loop, state);
234 return;
237 state->wait_time = state->wait_time * 2;
238 if (state->wait_time > 16) {
239 DEBUG(0, ("Failed to register endpoint '%s'!\n",
240 state->iface->name));
241 state->wait_time = 16;
244 subreq = tevent_wakeup_send(state->mem_ctx,
245 state->ev_ctx,
246 timeval_current_ofs(state->wait_time, 0));
247 if (tevent_req_nomem(state->mem_ctx, subreq)) {
248 talloc_free(state);
249 return;
252 tevent_req_set_callback(subreq, rpc_ep_setup_register_loop, state);
253 return;
256 static NTSTATUS rpc_ep_setup_try_register(TALLOC_CTX *mem_ctx,
257 struct tevent_context *ev_ctx,
258 struct messaging_context *msg_ctx,
259 const struct ndr_interface_table *iface,
260 const char *name,
261 uint16_t port,
262 struct dcerpc_binding_handle **pbh)
264 struct dcerpc_binding_vector *v = NULL;
265 NTSTATUS status;
267 status = dcerpc_binding_vector_create(mem_ctx,
268 iface,
269 port,
270 name,
271 &v);
272 if (!NT_STATUS_IS_OK(status)) {
273 return status;
276 status = dcerpc_ep_register(mem_ctx,
277 iface,
279 &iface->syntax_id.uuid,
280 name,
281 pbh);
282 talloc_free(v);
283 if (!NT_STATUS_IS_OK(status)) {
284 return status;
287 return status;
291 * Monitor the connection to the endpoint mapper and if it goes away, try to
292 * register the endpoint.
294 static void rpc_ep_setup_monitor_loop(struct tevent_req *subreq)
296 struct rpc_ep_regsiter_state *state =
297 tevent_req_callback_data(subreq, struct rpc_ep_regsiter_state);
298 struct policy_handle entry_handle;
299 struct dcerpc_binding map_binding;
300 struct epm_twr_p_t towers[10];
301 struct epm_twr_t *map_tower;
302 uint32_t num_towers = 0;
303 struct GUID object;
304 NTSTATUS status;
305 uint32_t result = EPMAPPER_STATUS_CANT_PERFORM_OP;
306 TALLOC_CTX *tmp_ctx;
307 bool ok;
309 ZERO_STRUCT(object);
310 ZERO_STRUCT(entry_handle);
312 tmp_ctx = talloc_stackframe();
313 if (tmp_ctx == NULL) {
314 talloc_free(state);
315 return;
318 ok = tevent_wakeup_recv(subreq);
319 TALLOC_FREE(subreq);
320 if (!ok) {
321 talloc_free(state);
322 return;
325 /* Create map tower */
326 map_binding.transport = NCACN_NP;
327 map_binding.object = state->iface->syntax_id;
328 map_binding.host = "";
329 map_binding.endpoint = "";
331 map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
332 if (map_tower == NULL) {
333 talloc_free(tmp_ctx);
334 talloc_free(state);
335 return;
338 status = dcerpc_binding_build_tower(map_tower, &map_binding,
339 &map_tower->tower);
340 if (!NT_STATUS_IS_OK(status)) {
341 talloc_free(tmp_ctx);
342 talloc_free(state);
343 return;
346 ok = false;
347 status = dcerpc_epm_Map(state->h,
348 tmp_ctx,
349 &object,
350 map_tower,
351 &entry_handle,
353 &num_towers,
354 towers,
355 &result);
356 if (NT_STATUS_IS_OK(status)) {
357 ok = true;
359 if (result == EPMAPPER_STATUS_OK ||
360 result == EPMAPPER_STATUS_NO_MORE_ENTRIES) {
361 ok = true;
363 if (num_towers == 0) {
364 ok = false;
367 talloc_free(tmp_ctx);
369 subreq = tevent_wakeup_send(state->mem_ctx,
370 state->ev_ctx,
371 timeval_current_ofs(MONITOR_WAIT_TIME, 0));
372 if (tevent_req_nomem(state->mem_ctx, subreq)) {
373 talloc_free(state);
374 return;
377 if (ok) {
378 tevent_req_set_callback(subreq, rpc_ep_setup_monitor_loop, state);
379 } else {
380 TALLOC_FREE(state->h);
381 state->wait_time = 1;
383 tevent_req_set_callback(subreq, rpc_ep_setup_register_loop, state);
386 return;
389 static bool epmapper_init_cb(void *ptr)
391 struct dcesrv_ep_context *ep_ctx =
392 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
393 uint16_t port;
395 port = _open_sockets(ep_ctx->ev_ctx,
396 ep_ctx->msg_ctx,
397 ndr_table_epmapper.syntax_id,
398 135);
399 if (port == 135) {
400 return true;
403 return false;
406 static bool epmapper_shutdown_cb(void *ptr)
408 srv_epmapper_cleanup();
410 return true;
413 static bool winreg_init_cb(void *ptr)
415 struct dcesrv_ep_context *ep_ctx =
416 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
417 struct ndr_syntax_id abstract_syntax = ndr_table_winreg.syntax_id;
418 const char *pipe_name = "winreg";
419 const char *rpcsrv_type;
420 uint16_t port;
422 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
423 "rpc_server",
424 "epmapper",
425 "none");
427 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
428 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
429 NTSTATUS status;
430 bool ok;
432 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
433 ep_ctx->msg_ctx,
434 abstract_syntax,
435 pipe_name,
436 NULL);
437 if (!ok) {
438 return false;
440 port = _open_sockets(ep_ctx->ev_ctx,
441 ep_ctx->msg_ctx,
442 abstract_syntax,
444 if (port == 0) {
445 return false;
448 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
449 ep_ctx->msg_ctx,
450 &ndr_table_winreg,
451 pipe_name,
452 port);
453 if (!NT_STATUS_IS_OK(status)) {
454 return false;
458 return true;
461 static bool srvsvc_init_cb(void *ptr)
463 struct dcesrv_ep_context *ep_ctx =
464 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
465 struct ndr_syntax_id abstract_syntax = ndr_table_srvsvc.syntax_id;
466 const char *pipe_name = "srvsvc";
467 const char *rpcsrv_type;
468 uint16_t port;
470 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
471 "rpc_server",
472 "epmapper",
473 "none");
475 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
476 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
477 NTSTATUS status;
478 bool ok;
480 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
481 ep_ctx->msg_ctx,
482 abstract_syntax,
483 pipe_name,
484 NULL);
485 if (!ok) {
486 return false;
489 port = _open_sockets(ep_ctx->ev_ctx,
490 ep_ctx->msg_ctx,
491 abstract_syntax,
493 if (port == 0) {
494 return false;
497 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
498 ep_ctx->msg_ctx,
499 &ndr_table_srvsvc,
500 pipe_name,
501 port);
502 if (!NT_STATUS_IS_OK(status)) {
503 return false;
507 return true;
510 static bool lsarpc_init_cb(void *ptr)
512 struct dcesrv_ep_context *ep_ctx =
513 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
514 struct ndr_syntax_id abstract_syntax = ndr_table_lsarpc.syntax_id;
515 const char *pipe_name = "lsarpc";
516 const char *rpcsrv_type;
517 uint16_t port;
519 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
520 "rpc_server",
521 "epmapper",
522 "none");
524 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
525 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
526 NTSTATUS status;
527 bool ok;
529 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
530 ep_ctx->msg_ctx,
531 abstract_syntax,
532 pipe_name,
533 NULL);
534 if (!ok) {
535 return false;
538 port = _open_sockets(ep_ctx->ev_ctx,
539 ep_ctx->msg_ctx,
540 abstract_syntax,
542 if (port == 0) {
543 return false;
546 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
547 ep_ctx->msg_ctx,
548 &ndr_table_lsarpc,
549 pipe_name,
550 port);
551 if (!NT_STATUS_IS_OK(status)) {
552 return false;
556 return true;
559 static bool samr_init_cb(void *ptr)
561 struct dcesrv_ep_context *ep_ctx =
562 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
563 struct ndr_syntax_id abstract_syntax = ndr_table_samr.syntax_id;
564 const char *pipe_name = "samr";
565 const char *rpcsrv_type;
566 uint16_t port;
568 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
569 "rpc_server",
570 "epmapper",
571 "none");
573 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
574 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
575 NTSTATUS status;
576 bool ok;
578 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
579 ep_ctx->msg_ctx,
580 abstract_syntax,
581 pipe_name,
582 NULL);
583 if (!ok) {
584 return false;
587 port = _open_sockets(ep_ctx->ev_ctx,
588 ep_ctx->msg_ctx,
589 abstract_syntax,
591 if (port == 0) {
592 return false;
595 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
596 ep_ctx->msg_ctx,
597 &ndr_table_samr,
598 pipe_name,
599 port);
600 if (!NT_STATUS_IS_OK(status)) {
601 return false;
605 return true;
608 static bool netlogon_init_cb(void *ptr)
610 struct dcesrv_ep_context *ep_ctx =
611 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
612 struct ndr_syntax_id abstract_syntax = ndr_table_netlogon.syntax_id;
613 const char *pipe_name = "netlogon";
614 const char *rpcsrv_type;
615 uint16_t port;
617 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
618 "rpc_server",
619 "epmapper",
620 "none");
622 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
623 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
624 NTSTATUS status;
625 bool ok;
627 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
628 ep_ctx->msg_ctx,
629 abstract_syntax,
630 pipe_name,
631 NULL);
632 if (!ok) {
633 return false;
636 port = _open_sockets(ep_ctx->ev_ctx,
637 ep_ctx->msg_ctx,
638 abstract_syntax,
640 if (port == 0) {
641 return false;
644 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
645 ep_ctx->msg_ctx,
646 &ndr_table_netlogon,
647 pipe_name,
648 port);
649 if (!NT_STATUS_IS_OK(status)) {
650 return false;
654 return true;
657 static bool spoolss_init_cb(void *ptr)
659 struct dcesrv_ep_context *ep_ctx =
660 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
661 const char *rpcsrv_type;
662 bool ok;
664 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
665 "rpc_server",
666 "epmapper",
667 "none");
670 * Migrate the printers first.
672 ok = nt_printing_tdb_migrate(ep_ctx->msg_ctx);
673 if (!ok) {
674 return false;
677 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
678 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
679 NTSTATUS status;
681 status =rpc_ep_setup_register(ep_ctx->ev_ctx,
682 ep_ctx->msg_ctx,
683 &ndr_table_spoolss,
684 "spoolss",
686 if (!NT_STATUS_IS_OK(status)) {
687 return false;
691 return true;
694 static bool spoolss_shutdown_cb(void *ptr)
696 srv_spoolss_cleanup();
698 return true;
701 static bool svcctl_init_cb(void *ptr)
703 struct dcesrv_ep_context *ep_ctx =
704 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
705 const char *rpcsrv_type;
706 bool ok;
708 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
709 "rpc_server",
710 "epmapper",
711 "none");
713 ok = svcctl_init_winreg(ep_ctx->msg_ctx);
714 if (!ok) {
715 return false;
718 /* initialize the control hooks */
719 init_service_op_table();
721 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
722 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
723 NTSTATUS status;
725 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
726 ep_ctx->msg_ctx,
727 &ndr_table_svcctl,
728 "svcctl",
730 if (!NT_STATUS_IS_OK(status)) {
731 return false;
735 return true;
738 static bool svcctl_shutdown_cb(void *ptr)
740 shutdown_service_op_table();
742 return true;
745 static bool ntsvcs_init_cb(void *ptr)
747 struct dcesrv_ep_context *ep_ctx =
748 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
749 const char *rpcsrv_type;
751 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
752 "rpc_server",
753 "epmapper",
754 "none");
756 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
757 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
758 NTSTATUS status;
760 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
761 ep_ctx->msg_ctx,
762 &ndr_table_ntsvcs,
763 "ntsvcs",
765 if (!NT_STATUS_IS_OK(status)) {
766 return false;
770 return true;
773 static bool eventlog_init_cb(void *ptr)
775 struct dcesrv_ep_context *ep_ctx =
776 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
777 const char *rpcsrv_type;
778 bool ok;
780 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
781 "rpc_server",
782 "epmapper",
783 "none");
785 ok = eventlog_init_winreg(ep_ctx->msg_ctx);
786 if (!ok) {
787 return false;
790 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
791 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
792 NTSTATUS status;
794 status =rpc_ep_setup_register(ep_ctx->ev_ctx,
795 ep_ctx->msg_ctx,
796 &ndr_table_eventlog,
797 "eventlog",
799 if (!NT_STATUS_IS_OK(status)) {
800 return false;
804 return true;
807 static bool initshutdown_init_cb(void *ptr)
809 struct dcesrv_ep_context *ep_ctx =
810 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
811 const char *rpcsrv_type;
813 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
814 "rpc_server",
815 "epmapper",
816 "none");
818 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
819 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
820 NTSTATUS status;
822 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
823 ep_ctx->msg_ctx,
824 &ndr_table_initshutdown,
825 "initshutdown",
827 if (!NT_STATUS_IS_OK(status)) {
828 return false;
832 return true;
835 #ifdef DEVELOPER
836 static bool rpcecho_init_cb(void *ptr) {
837 struct dcesrv_ep_context *ep_ctx =
838 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
839 const char *rpcsrv_type;
840 uint16_t port;
842 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
843 "rpc_server",
844 "epmapper",
845 "none");
847 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
848 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
849 NTSTATUS status;
851 port = _open_sockets(ep_ctx->ev_ctx,
852 ep_ctx->msg_ctx,
853 ndr_table_rpcecho.syntax_id,
855 if (port == 0) {
856 return false;
859 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
860 ep_ctx->msg_ctx,
861 &ndr_table_rpcecho,
862 "rpcecho",
863 port);
864 if (!NT_STATUS_IS_OK(status)) {
865 return false;
869 return true;
872 #endif
874 static bool netdfs_init_cb(void *ptr)
876 struct dcesrv_ep_context *ep_ctx =
877 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
878 struct ndr_syntax_id abstract_syntax = ndr_table_netdfs.syntax_id;
879 const char *pipe_name = "netdfs";
880 const char *rpcsrv_type;
881 uint16_t port;
883 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
884 "rpc_server",
885 "epmapper",
886 "none");
887 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
888 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
889 NTSTATUS status;
890 bool ok;
892 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
893 ep_ctx->msg_ctx,
894 abstract_syntax,
895 pipe_name,
896 NULL);
897 if (!ok) {
898 return false;
901 port = _open_sockets(ep_ctx->ev_ctx,
902 ep_ctx->msg_ctx,
903 abstract_syntax,
905 if (port == 0) {
906 return false;
909 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
910 ep_ctx->msg_ctx,
911 &ndr_table_netdfs,
912 pipe_name,
913 port);
914 if (!NT_STATUS_IS_OK(status)) {
915 return false;
919 return true;
922 static bool dssetup_init_cb(void *ptr)
924 struct dcesrv_ep_context *ep_ctx =
925 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
926 struct ndr_syntax_id abstract_syntax = ndr_table_dssetup.syntax_id;
927 const char *pipe_name = "dssetup";
928 const char *rpcsrv_type;
929 uint16_t port;
931 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
932 "rpc_server",
933 "epmapper",
934 "none");
936 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
937 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
938 NTSTATUS status;
939 bool ok;
941 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
942 ep_ctx->msg_ctx,
943 abstract_syntax,
944 pipe_name,
945 NULL);
946 if (!ok) {
947 return false;
950 port = _open_sockets(ep_ctx->ev_ctx,
951 ep_ctx->msg_ctx,
952 abstract_syntax,
954 if (port == 0) {
955 return false;
958 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
959 ep_ctx->msg_ctx,
960 &ndr_table_dssetup,
961 "dssetup",
962 port);
963 if (!NT_STATUS_IS_OK(status)) {
964 return false;
968 return true;
971 static bool wkssvc_init_cb(void *ptr)
973 struct dcesrv_ep_context *ep_ctx =
974 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
975 struct ndr_syntax_id abstract_syntax = ndr_table_wkssvc.syntax_id;
976 const char *pipe_name = "wkssvc";
977 const char *rpcsrv_type;
978 uint16_t port;
980 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
981 "rpc_server",
982 "epmapper",
983 "none");
984 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
985 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
986 NTSTATUS status;
987 bool ok;
989 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
990 ep_ctx->msg_ctx,
991 abstract_syntax,
992 pipe_name,
993 NULL);
994 if (!ok) {
995 return false;
998 port = _open_sockets(ep_ctx->ev_ctx,
999 ep_ctx->msg_ctx,
1000 abstract_syntax,
1002 if (port == 0) {
1003 return false;
1006 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
1007 ep_ctx->msg_ctx,
1008 &ndr_table_wkssvc,
1009 "wkssvc",
1010 port);
1011 if (!NT_STATUS_IS_OK(status)) {
1012 return false;
1016 return true;
1019 bool dcesrv_ep_setup(struct tevent_context *ev_ctx,
1020 struct messaging_context *msg_ctx)
1022 struct dcesrv_ep_context *ep_ctx;
1024 struct rpc_srv_callbacks epmapper_cb;
1026 struct rpc_srv_callbacks winreg_cb;
1027 struct rpc_srv_callbacks srvsvc_cb;
1029 struct rpc_srv_callbacks lsarpc_cb;
1030 struct rpc_srv_callbacks samr_cb;
1031 struct rpc_srv_callbacks netlogon_cb;
1033 struct rpc_srv_callbacks spoolss_cb;
1034 struct rpc_srv_callbacks svcctl_cb;
1035 struct rpc_srv_callbacks ntsvcs_cb;
1036 struct rpc_srv_callbacks eventlog_cb;
1037 struct rpc_srv_callbacks initshutdown_cb;
1038 struct rpc_srv_callbacks netdfs_cb;
1039 #ifdef DEVELOPER
1040 struct rpc_srv_callbacks rpcecho_cb;
1041 #endif
1042 struct rpc_srv_callbacks dssetup_cb;
1043 struct rpc_srv_callbacks wkssvc_cb;
1045 const char *rpcsrv_type;
1047 ep_ctx = talloc(ev_ctx, struct dcesrv_ep_context);
1048 if (ep_ctx == NULL) {
1049 return false;
1052 ep_ctx->ev_ctx = ev_ctx;
1053 ep_ctx->msg_ctx = msg_ctx;
1055 /* start endpoint mapper only if enabled */
1056 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1057 "rpc_server",
1058 "epmapper",
1059 "none");
1060 if (StrCaseCmp(rpcsrv_type, "embedded") == 0) {
1061 epmapper_cb.init = epmapper_init_cb;
1062 epmapper_cb.shutdown = epmapper_shutdown_cb;
1063 epmapper_cb.private_data = ep_ctx;
1065 if (!NT_STATUS_IS_OK(rpc_epmapper_init(&epmapper_cb))) {
1066 return false;
1068 } else if (StrCaseCmp(rpcsrv_type, "daemon") == 0) {
1069 if (!NT_STATUS_IS_OK(rpc_epmapper_init(NULL))) {
1070 return false;
1074 winreg_cb.init = winreg_init_cb;
1075 winreg_cb.shutdown = NULL;
1076 winreg_cb.private_data = ep_ctx;
1077 if (!NT_STATUS_IS_OK(rpc_winreg_init(&winreg_cb))) {
1078 return false;
1081 srvsvc_cb.init = srvsvc_init_cb;
1082 srvsvc_cb.shutdown = NULL;
1083 srvsvc_cb.private_data = ep_ctx;
1084 if (!NT_STATUS_IS_OK(rpc_srvsvc_init(&srvsvc_cb))) {
1085 return false;
1089 lsarpc_cb.init = lsarpc_init_cb;
1090 lsarpc_cb.shutdown = NULL;
1091 lsarpc_cb.private_data = ep_ctx;
1092 if (!NT_STATUS_IS_OK(rpc_lsarpc_init(&lsarpc_cb))) {
1093 return false;
1096 samr_cb.init = samr_init_cb;
1097 samr_cb.shutdown = NULL;
1098 samr_cb.private_data = ep_ctx;
1099 if (!NT_STATUS_IS_OK(rpc_samr_init(&samr_cb))) {
1100 return false;
1103 netlogon_cb.init = netlogon_init_cb;
1104 netlogon_cb.shutdown = NULL;
1105 netlogon_cb.private_data = ep_ctx;
1106 if (!NT_STATUS_IS_OK(rpc_netlogon_init(&netlogon_cb))) {
1107 return false;
1110 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1111 "rpc_server",
1112 "spoolss",
1113 "embedded");
1114 if (StrCaseCmp(rpcsrv_type, "embedded") == 0) {
1115 spoolss_cb.init = spoolss_init_cb;
1116 spoolss_cb.shutdown = spoolss_shutdown_cb;
1117 spoolss_cb.private_data = ep_ctx;
1118 if (!NT_STATUS_IS_OK(rpc_spoolss_init(&spoolss_cb))) {
1119 return false;
1121 } else if (StrCaseCmp(rpcsrv_type, "daemon") == 0 ||
1122 StrCaseCmp(rpcsrv_type, "external") == 0) {
1123 if (!NT_STATUS_IS_OK(rpc_spoolss_init(NULL))) {
1124 return false;
1128 svcctl_cb.init = svcctl_init_cb;
1129 svcctl_cb.shutdown = svcctl_shutdown_cb;
1130 svcctl_cb.private_data = ep_ctx;
1131 if (!NT_STATUS_IS_OK(rpc_svcctl_init(&svcctl_cb))) {
1132 return false;
1135 ntsvcs_cb.init = ntsvcs_init_cb;
1136 ntsvcs_cb.shutdown = NULL;
1137 ntsvcs_cb.private_data = ep_ctx;
1138 if (!NT_STATUS_IS_OK(rpc_ntsvcs_init(&ntsvcs_cb))) {
1139 return false;
1142 eventlog_cb.init = eventlog_init_cb;
1143 eventlog_cb.shutdown = NULL;
1144 eventlog_cb.private_data = ep_ctx;
1145 if (!NT_STATUS_IS_OK(rpc_eventlog_init(&eventlog_cb))) {
1146 return false;
1149 initshutdown_cb.init = initshutdown_init_cb;
1150 initshutdown_cb.shutdown = NULL;
1151 initshutdown_cb.private_data = ep_ctx;
1152 if (!NT_STATUS_IS_OK(rpc_initshutdown_init(&initshutdown_cb))) {
1153 return false;
1156 netdfs_cb.init = netdfs_init_cb;
1157 netdfs_cb.shutdown = NULL;
1158 netdfs_cb.private_data = ep_ctx;
1159 if (!NT_STATUS_IS_OK(rpc_netdfs_init(&netdfs_cb))) {
1160 return false;
1163 #ifdef DEVELOPER
1164 rpcecho_cb.init = rpcecho_init_cb;
1165 rpcecho_cb.shutdown = NULL;
1166 rpcecho_cb.private_data = ep_ctx;
1167 if (!NT_STATUS_IS_OK(rpc_rpcecho_init(&rpcecho_cb))) {
1168 return false;
1170 #endif
1172 dssetup_cb.init = dssetup_init_cb;
1173 dssetup_cb.shutdown = NULL;
1174 dssetup_cb.private_data = ep_ctx;
1175 if (!NT_STATUS_IS_OK(rpc_dssetup_init(&dssetup_cb))) {
1176 return false;
1179 wkssvc_cb.init = wkssvc_init_cb;
1180 wkssvc_cb.shutdown = NULL;
1181 wkssvc_cb.private_data = ep_ctx;
1182 if (!NT_STATUS_IS_OK(rpc_wkssvc_init(&wkssvc_cb))) {
1183 return false;
1186 return true;
1189 /* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */