s3:smbd: use PROTOCOL_SMB2_02 instead PROTOCOL_SMB2
[Samba/gebeck_regimport.git] / source3 / rpc_server / rpc_ep_setup.c
blob7dc23aae89d085e50dd86d73c2607565dff7f135
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 iface,
276 &iface->syntax_id.uuid,
277 iface->name,
278 pbh);
279 talloc_free(v);
280 if (!NT_STATUS_IS_OK(status)) {
281 return status;
284 return status;
288 * Monitor the connection to the endpoint mapper and if it goes away, try to
289 * register the endpoint.
291 static void rpc_ep_setup_monitor_loop(struct tevent_req *subreq)
293 struct rpc_ep_regsiter_state *state =
294 tevent_req_callback_data(subreq, struct rpc_ep_regsiter_state);
295 struct policy_handle entry_handle;
296 struct dcerpc_binding map_binding;
297 struct epm_twr_p_t towers[10];
298 struct epm_twr_t *map_tower;
299 uint32_t num_towers = 0;
300 struct GUID object;
301 NTSTATUS status;
302 uint32_t result = EPMAPPER_STATUS_CANT_PERFORM_OP;
303 TALLOC_CTX *tmp_ctx;
304 bool ok;
306 ZERO_STRUCT(object);
307 ZERO_STRUCT(entry_handle);
309 tmp_ctx = talloc_stackframe();
310 if (tmp_ctx == NULL) {
311 talloc_free(state);
312 return;
315 ok = tevent_wakeup_recv(subreq);
316 TALLOC_FREE(subreq);
317 if (!ok) {
318 talloc_free(state);
319 return;
322 /* Create map tower */
323 map_binding.transport = NCACN_NP;
324 map_binding.object = state->iface->syntax_id;
325 map_binding.host = "";
326 map_binding.endpoint = "";
328 map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
329 if (map_tower == NULL) {
330 talloc_free(tmp_ctx);
331 talloc_free(state);
332 return;
335 status = dcerpc_binding_build_tower(map_tower, &map_binding,
336 &map_tower->tower);
337 if (!NT_STATUS_IS_OK(status)) {
338 talloc_free(tmp_ctx);
339 talloc_free(state);
340 return;
343 ok = false;
344 status = dcerpc_epm_Map(state->h,
345 tmp_ctx,
346 &object,
347 map_tower,
348 &entry_handle,
350 &num_towers,
351 towers,
352 &result);
353 if (NT_STATUS_IS_OK(status)) {
354 ok = true;
356 if (result == EPMAPPER_STATUS_OK ||
357 result == EPMAPPER_STATUS_NO_MORE_ENTRIES) {
358 ok = true;
360 if (num_towers == 0) {
361 ok = false;
364 talloc_free(tmp_ctx);
366 subreq = tevent_wakeup_send(state->mem_ctx,
367 state->ev_ctx,
368 timeval_current_ofs(MONITOR_WAIT_TIME, 0));
369 if (tevent_req_nomem(state->mem_ctx, subreq)) {
370 talloc_free(state);
371 return;
374 if (ok) {
375 tevent_req_set_callback(subreq, rpc_ep_setup_monitor_loop, state);
376 } else {
377 TALLOC_FREE(state->h);
378 state->wait_time = 1;
380 tevent_req_set_callback(subreq, rpc_ep_setup_register_loop, state);
383 return;
386 static bool epmapper_init_cb(void *ptr)
388 struct dcesrv_ep_context *ep_ctx =
389 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
390 uint16_t port;
392 port = _open_sockets(ep_ctx->ev_ctx,
393 ep_ctx->msg_ctx,
394 ndr_table_epmapper.syntax_id,
395 135);
396 if (port == 135) {
397 return true;
400 return false;
403 static bool epmapper_shutdown_cb(void *ptr)
405 srv_epmapper_cleanup();
407 return true;
410 static bool winreg_init_cb(void *ptr)
412 struct dcesrv_ep_context *ep_ctx =
413 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
414 struct ndr_syntax_id abstract_syntax = ndr_table_winreg.syntax_id;
415 const char *pipe_name = "winreg";
416 const char *rpcsrv_type;
417 uint16_t port;
419 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
420 "rpc_server",
421 "epmapper",
422 "none");
424 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
425 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
426 NTSTATUS status;
427 bool ok;
429 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
430 ep_ctx->msg_ctx,
431 pipe_name,
432 NULL);
433 if (!ok) {
434 return false;
436 port = _open_sockets(ep_ctx->ev_ctx,
437 ep_ctx->msg_ctx,
438 abstract_syntax,
440 if (port == 0) {
441 return false;
444 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
445 ep_ctx->msg_ctx,
446 &ndr_table_winreg,
447 pipe_name,
448 port);
449 if (!NT_STATUS_IS_OK(status)) {
450 return false;
454 return true;
457 static bool srvsvc_init_cb(void *ptr)
459 struct dcesrv_ep_context *ep_ctx =
460 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
461 struct ndr_syntax_id abstract_syntax = ndr_table_srvsvc.syntax_id;
462 const char *pipe_name = "srvsvc";
463 const char *rpcsrv_type;
464 uint16_t port;
466 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
467 "rpc_server",
468 "epmapper",
469 "none");
471 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
472 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
473 NTSTATUS status;
474 bool ok;
476 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
477 ep_ctx->msg_ctx,
478 pipe_name,
479 NULL);
480 if (!ok) {
481 return false;
484 port = _open_sockets(ep_ctx->ev_ctx,
485 ep_ctx->msg_ctx,
486 abstract_syntax,
488 if (port == 0) {
489 return false;
492 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
493 ep_ctx->msg_ctx,
494 &ndr_table_srvsvc,
495 pipe_name,
496 port);
497 if (!NT_STATUS_IS_OK(status)) {
498 return false;
502 return true;
505 static bool lsarpc_init_cb(void *ptr)
507 struct dcesrv_ep_context *ep_ctx =
508 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
509 struct ndr_syntax_id abstract_syntax = ndr_table_lsarpc.syntax_id;
510 const char *pipe_name = "lsarpc";
511 const char *rpcsrv_type;
512 uint16_t port;
514 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
515 "rpc_server",
516 "epmapper",
517 "none");
519 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
520 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
521 NTSTATUS status;
522 bool ok;
524 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
525 ep_ctx->msg_ctx,
526 pipe_name,
527 NULL);
528 if (!ok) {
529 return false;
532 port = _open_sockets(ep_ctx->ev_ctx,
533 ep_ctx->msg_ctx,
534 abstract_syntax,
536 if (port == 0) {
537 return false;
540 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
541 ep_ctx->msg_ctx,
542 &ndr_table_lsarpc,
543 pipe_name,
544 port);
545 if (!NT_STATUS_IS_OK(status)) {
546 return false;
550 return true;
553 static bool samr_init_cb(void *ptr)
555 struct dcesrv_ep_context *ep_ctx =
556 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
557 struct ndr_syntax_id abstract_syntax = ndr_table_samr.syntax_id;
558 const char *pipe_name = "samr";
559 const char *rpcsrv_type;
560 uint16_t port;
562 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
563 "rpc_server",
564 "epmapper",
565 "none");
567 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
568 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
569 NTSTATUS status;
570 bool ok;
572 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
573 ep_ctx->msg_ctx,
574 pipe_name,
575 NULL);
576 if (!ok) {
577 return false;
580 port = _open_sockets(ep_ctx->ev_ctx,
581 ep_ctx->msg_ctx,
582 abstract_syntax,
584 if (port == 0) {
585 return false;
588 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
589 ep_ctx->msg_ctx,
590 &ndr_table_samr,
591 pipe_name,
592 port);
593 if (!NT_STATUS_IS_OK(status)) {
594 return false;
598 return true;
601 static bool netlogon_init_cb(void *ptr)
603 struct dcesrv_ep_context *ep_ctx =
604 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
605 struct ndr_syntax_id abstract_syntax = ndr_table_netlogon.syntax_id;
606 const char *pipe_name = "netlogon";
607 const char *rpcsrv_type;
608 uint16_t port;
610 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
611 "rpc_server",
612 "epmapper",
613 "none");
615 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
616 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
617 NTSTATUS status;
618 bool ok;
620 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
621 ep_ctx->msg_ctx,
622 pipe_name,
623 NULL);
624 if (!ok) {
625 return false;
628 port = _open_sockets(ep_ctx->ev_ctx,
629 ep_ctx->msg_ctx,
630 abstract_syntax,
632 if (port == 0) {
633 return false;
636 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
637 ep_ctx->msg_ctx,
638 &ndr_table_netlogon,
639 pipe_name,
640 port);
641 if (!NT_STATUS_IS_OK(status)) {
642 return false;
646 return true;
649 static bool spoolss_init_cb(void *ptr)
651 struct dcesrv_ep_context *ep_ctx =
652 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
653 const char *rpcsrv_type;
654 bool ok;
656 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
657 "rpc_server",
658 "epmapper",
659 "none");
662 * Migrate the printers first.
664 ok = nt_printing_tdb_migrate(ep_ctx->msg_ctx);
665 if (!ok) {
666 return false;
669 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
670 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
671 NTSTATUS status;
673 status =rpc_ep_setup_register(ep_ctx->ev_ctx,
674 ep_ctx->msg_ctx,
675 &ndr_table_spoolss,
676 "spoolss",
678 if (!NT_STATUS_IS_OK(status)) {
679 return false;
683 return true;
686 static bool spoolss_shutdown_cb(void *ptr)
688 srv_spoolss_cleanup();
690 return true;
693 static bool svcctl_init_cb(void *ptr)
695 struct dcesrv_ep_context *ep_ctx =
696 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
697 const char *rpcsrv_type;
698 bool ok;
700 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
701 "rpc_server",
702 "epmapper",
703 "none");
705 ok = svcctl_init_winreg(ep_ctx->msg_ctx);
706 if (!ok) {
707 return false;
710 /* initialize the control hooks */
711 init_service_op_table();
713 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
714 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
715 NTSTATUS status;
717 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
718 ep_ctx->msg_ctx,
719 &ndr_table_svcctl,
720 "svcctl",
722 if (!NT_STATUS_IS_OK(status)) {
723 return false;
727 return true;
730 static bool svcctl_shutdown_cb(void *ptr)
732 shutdown_service_op_table();
734 return true;
737 static bool ntsvcs_init_cb(void *ptr)
739 struct dcesrv_ep_context *ep_ctx =
740 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
741 const char *rpcsrv_type;
743 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
744 "rpc_server",
745 "epmapper",
746 "none");
748 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
749 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
750 NTSTATUS status;
752 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
753 ep_ctx->msg_ctx,
754 &ndr_table_ntsvcs,
755 "ntsvcs",
757 if (!NT_STATUS_IS_OK(status)) {
758 return false;
762 return true;
765 static bool eventlog_init_cb(void *ptr)
767 struct dcesrv_ep_context *ep_ctx =
768 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
769 const char *rpcsrv_type;
770 bool ok;
772 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
773 "rpc_server",
774 "epmapper",
775 "none");
777 ok = eventlog_init_winreg(ep_ctx->msg_ctx);
778 if (!ok) {
779 return false;
782 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
783 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
784 NTSTATUS status;
786 status =rpc_ep_setup_register(ep_ctx->ev_ctx,
787 ep_ctx->msg_ctx,
788 &ndr_table_eventlog,
789 "eventlog",
791 if (!NT_STATUS_IS_OK(status)) {
792 return false;
796 return true;
799 static bool initshutdown_init_cb(void *ptr)
801 struct dcesrv_ep_context *ep_ctx =
802 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
803 const char *rpcsrv_type;
805 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
806 "rpc_server",
807 "epmapper",
808 "none");
810 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
811 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
812 NTSTATUS status;
814 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
815 ep_ctx->msg_ctx,
816 &ndr_table_initshutdown,
817 "initshutdown",
819 if (!NT_STATUS_IS_OK(status)) {
820 return false;
824 return true;
827 #ifdef DEVELOPER
828 static bool rpcecho_init_cb(void *ptr) {
829 struct dcesrv_ep_context *ep_ctx =
830 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
831 const char *rpcsrv_type;
832 uint16_t port;
834 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
835 "rpc_server",
836 "epmapper",
837 "none");
839 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
840 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
841 NTSTATUS status;
843 port = _open_sockets(ep_ctx->ev_ctx,
844 ep_ctx->msg_ctx,
845 ndr_table_rpcecho.syntax_id,
847 if (port == 0) {
848 return false;
851 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
852 ep_ctx->msg_ctx,
853 &ndr_table_rpcecho,
854 "rpcecho",
855 port);
856 if (!NT_STATUS_IS_OK(status)) {
857 return false;
861 return true;
864 #endif
866 static bool netdfs_init_cb(void *ptr)
868 struct dcesrv_ep_context *ep_ctx =
869 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
870 struct ndr_syntax_id abstract_syntax = ndr_table_netdfs.syntax_id;
871 const char *pipe_name = "netdfs";
872 const char *rpcsrv_type;
873 uint16_t port;
875 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
876 "rpc_server",
877 "epmapper",
878 "none");
879 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
880 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
881 NTSTATUS status;
882 bool ok;
884 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
885 ep_ctx->msg_ctx,
886 pipe_name,
887 NULL);
888 if (!ok) {
889 return false;
892 port = _open_sockets(ep_ctx->ev_ctx,
893 ep_ctx->msg_ctx,
894 abstract_syntax,
896 if (port == 0) {
897 return false;
900 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
901 ep_ctx->msg_ctx,
902 &ndr_table_netdfs,
903 pipe_name,
904 port);
905 if (!NT_STATUS_IS_OK(status)) {
906 return false;
910 return true;
913 static bool dssetup_init_cb(void *ptr)
915 struct dcesrv_ep_context *ep_ctx =
916 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
917 struct ndr_syntax_id abstract_syntax = ndr_table_dssetup.syntax_id;
918 const char *pipe_name = "dssetup";
919 const char *rpcsrv_type;
920 uint16_t port;
922 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
923 "rpc_server",
924 "epmapper",
925 "none");
927 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
928 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
929 NTSTATUS status;
930 bool ok;
932 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
933 ep_ctx->msg_ctx,
934 pipe_name,
935 NULL);
936 if (!ok) {
937 return false;
940 port = _open_sockets(ep_ctx->ev_ctx,
941 ep_ctx->msg_ctx,
942 abstract_syntax,
944 if (port == 0) {
945 return false;
948 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
949 ep_ctx->msg_ctx,
950 &ndr_table_dssetup,
951 "dssetup",
952 port);
953 if (!NT_STATUS_IS_OK(status)) {
954 return false;
958 return true;
961 static bool wkssvc_init_cb(void *ptr)
963 struct dcesrv_ep_context *ep_ctx =
964 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
965 struct ndr_syntax_id abstract_syntax = ndr_table_wkssvc.syntax_id;
966 const char *pipe_name = "wkssvc";
967 const char *rpcsrv_type;
968 uint16_t port;
970 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
971 "rpc_server",
972 "epmapper",
973 "none");
974 if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
975 strcasecmp_m(rpcsrv_type, "daemon") == 0) {
976 NTSTATUS status;
977 bool ok;
979 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
980 ep_ctx->msg_ctx,
981 pipe_name,
982 NULL);
983 if (!ok) {
984 return false;
987 port = _open_sockets(ep_ctx->ev_ctx,
988 ep_ctx->msg_ctx,
989 abstract_syntax,
991 if (port == 0) {
992 return false;
995 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
996 ep_ctx->msg_ctx,
997 &ndr_table_wkssvc,
998 "wkssvc",
999 port);
1000 if (!NT_STATUS_IS_OK(status)) {
1001 return false;
1005 return true;
1008 bool dcesrv_ep_setup(struct tevent_context *ev_ctx,
1009 struct messaging_context *msg_ctx)
1011 struct dcesrv_ep_context *ep_ctx;
1013 struct rpc_srv_callbacks epmapper_cb;
1015 struct rpc_srv_callbacks winreg_cb;
1016 struct rpc_srv_callbacks srvsvc_cb;
1018 struct rpc_srv_callbacks lsarpc_cb;
1019 struct rpc_srv_callbacks samr_cb;
1020 struct rpc_srv_callbacks netlogon_cb;
1022 struct rpc_srv_callbacks spoolss_cb;
1023 struct rpc_srv_callbacks svcctl_cb;
1024 struct rpc_srv_callbacks ntsvcs_cb;
1025 struct rpc_srv_callbacks eventlog_cb;
1026 struct rpc_srv_callbacks initshutdown_cb;
1027 struct rpc_srv_callbacks netdfs_cb;
1028 #ifdef DEVELOPER
1029 struct rpc_srv_callbacks rpcecho_cb;
1030 #endif
1031 struct rpc_srv_callbacks dssetup_cb;
1032 struct rpc_srv_callbacks wkssvc_cb;
1034 const char *rpcsrv_type;
1036 ep_ctx = talloc(ev_ctx, struct dcesrv_ep_context);
1037 if (ep_ctx == NULL) {
1038 return false;
1041 ep_ctx->ev_ctx = ev_ctx;
1042 ep_ctx->msg_ctx = msg_ctx;
1044 /* start endpoint mapper only if enabled */
1045 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1046 "rpc_server",
1047 "epmapper",
1048 "none");
1049 if (strcasecmp_m(rpcsrv_type, "embedded") == 0) {
1050 epmapper_cb.init = epmapper_init_cb;
1051 epmapper_cb.shutdown = epmapper_shutdown_cb;
1052 epmapper_cb.private_data = ep_ctx;
1054 if (!NT_STATUS_IS_OK(rpc_epmapper_init(&epmapper_cb))) {
1055 return false;
1057 } else if (strcasecmp_m(rpcsrv_type, "daemon") == 0) {
1058 if (!NT_STATUS_IS_OK(rpc_epmapper_init(NULL))) {
1059 return false;
1063 winreg_cb.init = winreg_init_cb;
1064 winreg_cb.shutdown = NULL;
1065 winreg_cb.private_data = ep_ctx;
1066 if (!NT_STATUS_IS_OK(rpc_winreg_init(&winreg_cb))) {
1067 return false;
1070 srvsvc_cb.init = srvsvc_init_cb;
1071 srvsvc_cb.shutdown = NULL;
1072 srvsvc_cb.private_data = ep_ctx;
1073 if (!NT_STATUS_IS_OK(rpc_srvsvc_init(&srvsvc_cb))) {
1074 return false;
1078 lsarpc_cb.init = lsarpc_init_cb;
1079 lsarpc_cb.shutdown = NULL;
1080 lsarpc_cb.private_data = ep_ctx;
1081 if (!NT_STATUS_IS_OK(rpc_lsarpc_init(&lsarpc_cb))) {
1082 return false;
1085 samr_cb.init = samr_init_cb;
1086 samr_cb.shutdown = NULL;
1087 samr_cb.private_data = ep_ctx;
1088 if (!NT_STATUS_IS_OK(rpc_samr_init(&samr_cb))) {
1089 return false;
1092 netlogon_cb.init = netlogon_init_cb;
1093 netlogon_cb.shutdown = NULL;
1094 netlogon_cb.private_data = ep_ctx;
1095 if (!NT_STATUS_IS_OK(rpc_netlogon_init(&netlogon_cb))) {
1096 return false;
1099 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1100 "rpc_server",
1101 "spoolss",
1102 "embedded");
1103 if (strcasecmp_m(rpcsrv_type, "embedded") == 0) {
1104 spoolss_cb.init = spoolss_init_cb;
1105 spoolss_cb.shutdown = spoolss_shutdown_cb;
1106 spoolss_cb.private_data = ep_ctx;
1107 if (!NT_STATUS_IS_OK(rpc_spoolss_init(&spoolss_cb))) {
1108 return false;
1110 } else if (strcasecmp_m(rpcsrv_type, "daemon") == 0 ||
1111 strcasecmp_m(rpcsrv_type, "external") == 0) {
1112 if (!NT_STATUS_IS_OK(rpc_spoolss_init(NULL))) {
1113 return false;
1117 svcctl_cb.init = svcctl_init_cb;
1118 svcctl_cb.shutdown = svcctl_shutdown_cb;
1119 svcctl_cb.private_data = ep_ctx;
1120 if (!NT_STATUS_IS_OK(rpc_svcctl_init(&svcctl_cb))) {
1121 return false;
1124 ntsvcs_cb.init = ntsvcs_init_cb;
1125 ntsvcs_cb.shutdown = NULL;
1126 ntsvcs_cb.private_data = ep_ctx;
1127 if (!NT_STATUS_IS_OK(rpc_ntsvcs_init(&ntsvcs_cb))) {
1128 return false;
1131 eventlog_cb.init = eventlog_init_cb;
1132 eventlog_cb.shutdown = NULL;
1133 eventlog_cb.private_data = ep_ctx;
1134 if (!NT_STATUS_IS_OK(rpc_eventlog_init(&eventlog_cb))) {
1135 return false;
1138 initshutdown_cb.init = initshutdown_init_cb;
1139 initshutdown_cb.shutdown = NULL;
1140 initshutdown_cb.private_data = ep_ctx;
1141 if (!NT_STATUS_IS_OK(rpc_initshutdown_init(&initshutdown_cb))) {
1142 return false;
1145 netdfs_cb.init = netdfs_init_cb;
1146 netdfs_cb.shutdown = NULL;
1147 netdfs_cb.private_data = ep_ctx;
1148 if (!NT_STATUS_IS_OK(rpc_netdfs_init(&netdfs_cb))) {
1149 return false;
1152 #ifdef DEVELOPER
1153 rpcecho_cb.init = rpcecho_init_cb;
1154 rpcecho_cb.shutdown = NULL;
1155 rpcecho_cb.private_data = ep_ctx;
1156 if (!NT_STATUS_IS_OK(rpc_rpcecho_init(&rpcecho_cb))) {
1157 return false;
1159 #endif
1161 dssetup_cb.init = dssetup_init_cb;
1162 dssetup_cb.shutdown = NULL;
1163 dssetup_cb.private_data = ep_ctx;
1164 if (!NT_STATUS_IS_OK(rpc_dssetup_init(&dssetup_cb))) {
1165 return false;
1168 wkssvc_cb.init = wkssvc_init_cb;
1169 wkssvc_cb.shutdown = NULL;
1170 wkssvc_cb.private_data = ep_ctx;
1171 if (!NT_STATUS_IS_OK(rpc_wkssvc_init(&wkssvc_cb))) {
1172 return false;
1175 return true;
1178 /* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */