source: trunk/server/source3/rpc_server/rpc_ep_setup.c@ 953

Last change on this file since 953 was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 27.6 KB
Line 
1/*
2 * Unix SMB/CIFS implementation.
3 *
4 * SMBD RPC service callbacks
5 *
6 * Copyright (c) 2011 Andreas Schneider <[email protected]>
7 *
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.
12 *
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.
17 *
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/>.
20 */
21
22#include "includes.h"
23#include "ntdomain.h"
24
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"
41
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"
47
48#include "librpc/rpc/dcerpc_ep.h"
49
50#include "rpc_server/rpc_ep_setup.h"
51#include "rpc_server/rpc_server.h"
52#include "rpc_server/epmapper/srv_epmapper.h"
53
54struct dcesrv_ep_context {
55 struct tevent_context *ev_ctx;
56 struct messaging_context *msg_ctx;
57};
58
59static 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)
63{
64 uint32_t num_ifs = iface_count();
65 uint32_t i;
66 uint16_t p = 0;
67
68 if (lp_interfaces() && lp_bind_interfaces_only()) {
69 /*
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.
73 */
74
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);
79
80 p = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
81 msg_ctx,
82 syntax_id,
83 ifss,
84 port);
85 if (p == 0) {
86 return 0;
87 }
88 port = p;
89 }
90 } else {
91 const char *sock_addr = lp_socket_address();
92 const char *sock_ptr;
93 char *sock_tok;
94
95 if (strequal(sock_addr, "0.0.0.0") ||
96 strequal(sock_addr, "::")) {
97#if HAVE_IPV6
98 sock_addr = "::";
99#else
100 sock_addr = "0.0.0.0";
101#endif
102 }
103
104 for (sock_ptr = sock_addr;
105 next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,");
106 ) {
107 struct sockaddr_storage ss;
108
109 /* open an incoming socket */
110 if (!interpret_string_addr(&ss,
111 sock_tok,
112 AI_NUMERICHOST|AI_PASSIVE)) {
113 continue;
114 }
115
116 p = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
117 msg_ctx,
118 syntax_id,
119 &ss,
120 port);
121 if (p == 0) {
122 return 0;
123 }
124 port = p;
125 }
126 }
127
128 return p;
129}
130
131static void rpc_ep_setup_register_loop(struct tevent_req *subreq);
132static NTSTATUS rpc_ep_setup_try_register(TALLOC_CTX *mem_ctx,
133 struct tevent_context *ev_ctx,
134 struct messaging_context *msg_ctx,
135 const struct ndr_interface_table *iface,
136 const char *ncalrpc,
137 uint16_t port,
138 struct dcerpc_binding_handle **pbh);
139
140struct rpc_ep_regsiter_state {
141 struct dcerpc_binding_handle *h;
142
143 TALLOC_CTX *mem_ctx;
144 struct tevent_context *ev_ctx;
145 struct messaging_context *msg_ctx;
146
147 const struct ndr_interface_table *iface;
148
149 const char *ncalrpc;
150 uint16_t port;
151
152 uint32_t wait_time;
153};
154
155NTSTATUS rpc_ep_setup_register(struct tevent_context *ev_ctx,
156 struct messaging_context *msg_ctx,
157 const struct ndr_interface_table *iface,
158 const char *ncalrpc,
159 uint16_t port)
160{
161 struct rpc_ep_regsiter_state *state;
162 struct tevent_req *req;
163
164 state = talloc(ev_ctx, struct rpc_ep_regsiter_state);
165 if (state == NULL) {
166 return NT_STATUS_NO_MEMORY;
167 }
168
169 state->mem_ctx = talloc_named(state,
170 0,
171 "ep %s %p",
172 iface->name, state);
173 if (state->mem_ctx == NULL) {
174 talloc_free(state);
175 return NT_STATUS_NO_MEMORY;
176 }
177
178 state->wait_time = 1;
179 state->ev_ctx = ev_ctx;
180 state->msg_ctx = msg_ctx;
181 state->iface = iface;
182 state->ncalrpc = talloc_strdup(state, ncalrpc);
183 state->port = port;
184
185 req = tevent_wakeup_send(state->mem_ctx,
186 state->ev_ctx,
187 timeval_current_ofs(1, 0));
188 if (tevent_req_nomem(state->mem_ctx, req)) {
189 talloc_free(state);
190 return NT_STATUS_NO_MEMORY;
191 }
192
193 tevent_req_set_callback(req, rpc_ep_setup_register_loop, state);
194
195 return NT_STATUS_OK;
196}
197
198#define MONITOR_WAIT_TIME 15
199static void rpc_ep_setup_monitor_loop(struct tevent_req *subreq);
200
201static void rpc_ep_setup_register_loop(struct tevent_req *subreq)
202{
203 struct rpc_ep_regsiter_state *state =
204 tevent_req_callback_data(subreq, struct rpc_ep_regsiter_state);
205 NTSTATUS status;
206 bool ok;
207
208 ok = tevent_wakeup_recv(subreq);
209 TALLOC_FREE(subreq);
210 if (!ok) {
211 talloc_free(state);
212 return;
213 }
214
215 status = rpc_ep_setup_try_register(state->mem_ctx,
216 state->ev_ctx,
217 state->msg_ctx,
218 state->iface,
219 state->ncalrpc,
220 state->port,
221 &state->h);
222 if (NT_STATUS_IS_OK(status)) {
223 /* endpoint registered, monitor the connnection. */
224 subreq = tevent_wakeup_send(state->mem_ctx,
225 state->ev_ctx,
226 timeval_current_ofs(MONITOR_WAIT_TIME, 0));
227 if (tevent_req_nomem(state->mem_ctx, subreq)) {
228 talloc_free(state);
229 return;
230 }
231
232 tevent_req_set_callback(subreq, rpc_ep_setup_monitor_loop, state);
233 return;
234 }
235
236 state->wait_time = state->wait_time * 2;
237 if (state->wait_time > 16) {
238 DEBUG(0, ("Failed to register endpoint '%s'!\n",
239 state->iface->name));
240 state->wait_time = 16;
241 }
242
243 subreq = tevent_wakeup_send(state->mem_ctx,
244 state->ev_ctx,
245 timeval_current_ofs(state->wait_time, 0));
246 if (tevent_req_nomem(state->mem_ctx, subreq)) {
247 talloc_free(state);
248 return;
249 }
250
251 tevent_req_set_callback(subreq, rpc_ep_setup_register_loop, state);
252 return;
253}
254
255static NTSTATUS rpc_ep_setup_try_register(TALLOC_CTX *mem_ctx,
256 struct tevent_context *ev_ctx,
257 struct messaging_context *msg_ctx,
258 const struct ndr_interface_table *iface,
259 const char *ncalrpc,
260 uint16_t port,
261 struct dcerpc_binding_handle **pbh)
262{
263 struct dcerpc_binding_vector *v = NULL;
264 NTSTATUS status;
265
266 status = dcerpc_binding_vector_create(mem_ctx,
267 iface,
268 port,
269 ncalrpc,
270 &v);
271 if (!NT_STATUS_IS_OK(status)) {
272 return status;
273 }
274
275 status = dcerpc_ep_register(mem_ctx,
276 iface,
277 v,
278 &iface->syntax_id.uuid,
279 iface->name,
280 pbh);
281 talloc_free(v);
282 if (!NT_STATUS_IS_OK(status)) {
283 return status;
284 }
285
286 return status;
287}
288
289/*
290 * Monitor the connection to the endpoint mapper and if it goes away, try to
291 * register the endpoint.
292 */
293static void rpc_ep_setup_monitor_loop(struct tevent_req *subreq)
294{
295 struct rpc_ep_regsiter_state *state =
296 tevent_req_callback_data(subreq, struct rpc_ep_regsiter_state);
297 struct policy_handle entry_handle;
298 struct dcerpc_binding map_binding;
299 struct epm_twr_p_t towers[10];
300 struct epm_twr_t *map_tower;
301 uint32_t num_towers = 0;
302 struct GUID object;
303 NTSTATUS status;
304 uint32_t result = EPMAPPER_STATUS_CANT_PERFORM_OP;
305 TALLOC_CTX *tmp_ctx;
306 bool ok;
307
308 ZERO_STRUCT(object);
309 ZERO_STRUCT(entry_handle);
310
311 tmp_ctx = talloc_stackframe();
312 if (tmp_ctx == NULL) {
313 talloc_free(state);
314 return;
315 }
316
317 ok = tevent_wakeup_recv(subreq);
318 TALLOC_FREE(subreq);
319 if (!ok) {
320 talloc_free(state);
321 return;
322 }
323
324 /* Create map tower */
325 map_binding.transport = NCACN_NP;
326 map_binding.object = state->iface->syntax_id;
327 map_binding.host = "";
328 map_binding.endpoint = "";
329
330 map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
331 if (map_tower == NULL) {
332 talloc_free(tmp_ctx);
333 talloc_free(state);
334 return;
335 }
336
337 status = dcerpc_binding_build_tower(map_tower, &map_binding,
338 &map_tower->tower);
339 if (!NT_STATUS_IS_OK(status)) {
340 talloc_free(tmp_ctx);
341 talloc_free(state);
342 return;
343 }
344
345 ok = false;
346 status = dcerpc_epm_Map(state->h,
347 tmp_ctx,
348 &object,
349 map_tower,
350 &entry_handle,
351 10,
352 &num_towers,
353 towers,
354 &result);
355 if (NT_STATUS_IS_OK(status)) {
356 ok = true;
357 }
358 if (result == EPMAPPER_STATUS_OK ||
359 result == EPMAPPER_STATUS_NO_MORE_ENTRIES) {
360 ok = true;
361 }
362 if (num_towers == 0) {
363 ok = false;
364 }
365
366 talloc_free(tmp_ctx);
367
368 subreq = tevent_wakeup_send(state->mem_ctx,
369 state->ev_ctx,
370 timeval_current_ofs(MONITOR_WAIT_TIME, 0));
371 if (tevent_req_nomem(state->mem_ctx, subreq)) {
372 talloc_free(state);
373 return;
374 }
375
376 if (ok) {
377 tevent_req_set_callback(subreq, rpc_ep_setup_monitor_loop, state);
378 } else {
379 TALLOC_FREE(state->h);
380 state->wait_time = 1;
381
382 tevent_req_set_callback(subreq, rpc_ep_setup_register_loop, state);
383 }
384
385 return;
386}
387
388static bool epmapper_init_cb(void *ptr)
389{
390 struct dcesrv_ep_context *ep_ctx =
391 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
392 uint16_t port;
393
394 port = _open_sockets(ep_ctx->ev_ctx,
395 ep_ctx->msg_ctx,
396 ndr_table_epmapper.syntax_id,
397 135);
398 if (port == 135) {
399 return true;
400 }
401
402 return false;
403}
404
405static bool epmapper_shutdown_cb(void *ptr)
406{
407 srv_epmapper_cleanup();
408
409 return true;
410}
411
412static bool winreg_init_cb(void *ptr)
413{
414 struct dcesrv_ep_context *ep_ctx =
415 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
416 struct ndr_syntax_id abstract_syntax = ndr_table_winreg.syntax_id;
417 const char *pipe_name = "winreg";
418 const char *rpcsrv_type;
419 uint16_t port;
420
421 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
422 "rpc_server",
423 "epmapper",
424 "none");
425
426 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
427 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
428 NTSTATUS status;
429 bool ok;
430
431 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
432 ep_ctx->msg_ctx,
433 abstract_syntax,
434 pipe_name,
435 NULL);
436 if (!ok) {
437 return false;
438 }
439 port = _open_sockets(ep_ctx->ev_ctx,
440 ep_ctx->msg_ctx,
441 abstract_syntax,
442 0);
443 if (port == 0) {
444 return false;
445 }
446
447 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
448 ep_ctx->msg_ctx,
449 &ndr_table_winreg,
450 pipe_name,
451 port);
452 if (!NT_STATUS_IS_OK(status)) {
453 return false;
454 }
455 }
456
457 return true;
458}
459
460static bool srvsvc_init_cb(void *ptr)
461{
462 struct dcesrv_ep_context *ep_ctx =
463 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
464 struct ndr_syntax_id abstract_syntax = ndr_table_srvsvc.syntax_id;
465 const char *pipe_name = "srvsvc";
466 const char *rpcsrv_type;
467 uint16_t port;
468
469 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
470 "rpc_server",
471 "epmapper",
472 "none");
473
474 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
475 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
476 NTSTATUS status;
477 bool ok;
478
479 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
480 ep_ctx->msg_ctx,
481 abstract_syntax,
482 pipe_name,
483 NULL);
484 if (!ok) {
485 return false;
486 }
487
488 port = _open_sockets(ep_ctx->ev_ctx,
489 ep_ctx->msg_ctx,
490 abstract_syntax,
491 0);
492 if (port == 0) {
493 return false;
494 }
495
496 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
497 ep_ctx->msg_ctx,
498 &ndr_table_srvsvc,
499 pipe_name,
500 port);
501 if (!NT_STATUS_IS_OK(status)) {
502 return false;
503 }
504 }
505
506 return true;
507}
508
509static bool lsarpc_init_cb(void *ptr)
510{
511 struct dcesrv_ep_context *ep_ctx =
512 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
513 struct ndr_syntax_id abstract_syntax = ndr_table_lsarpc.syntax_id;
514 const char *pipe_name = "lsarpc";
515 const char *rpcsrv_type;
516 uint16_t port;
517
518 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
519 "rpc_server",
520 "epmapper",
521 "none");
522
523 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
524 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
525 NTSTATUS status;
526 bool ok;
527
528 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
529 ep_ctx->msg_ctx,
530 abstract_syntax,
531 pipe_name,
532 NULL);
533 if (!ok) {
534 return false;
535 }
536
537 port = _open_sockets(ep_ctx->ev_ctx,
538 ep_ctx->msg_ctx,
539 abstract_syntax,
540 0);
541 if (port == 0) {
542 return false;
543 }
544
545 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
546 ep_ctx->msg_ctx,
547 &ndr_table_lsarpc,
548 pipe_name,
549 port);
550 if (!NT_STATUS_IS_OK(status)) {
551 return false;
552 }
553 }
554
555 return true;
556}
557
558static bool samr_init_cb(void *ptr)
559{
560 struct dcesrv_ep_context *ep_ctx =
561 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
562 struct ndr_syntax_id abstract_syntax = ndr_table_samr.syntax_id;
563 const char *pipe_name = "samr";
564 const char *rpcsrv_type;
565 uint16_t port;
566
567 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
568 "rpc_server",
569 "epmapper",
570 "none");
571
572 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
573 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
574 NTSTATUS status;
575 bool ok;
576
577 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
578 ep_ctx->msg_ctx,
579 abstract_syntax,
580 pipe_name,
581 NULL);
582 if (!ok) {
583 return false;
584 }
585
586 port = _open_sockets(ep_ctx->ev_ctx,
587 ep_ctx->msg_ctx,
588 abstract_syntax,
589 0);
590 if (port == 0) {
591 return false;
592 }
593
594 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
595 ep_ctx->msg_ctx,
596 &ndr_table_samr,
597 pipe_name,
598 port);
599 if (!NT_STATUS_IS_OK(status)) {
600 return false;
601 }
602 }
603
604 return true;
605}
606
607static bool netlogon_init_cb(void *ptr)
608{
609 struct dcesrv_ep_context *ep_ctx =
610 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
611 struct ndr_syntax_id abstract_syntax = ndr_table_netlogon.syntax_id;
612 const char *pipe_name = "netlogon";
613 const char *rpcsrv_type;
614 uint16_t port;
615
616 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
617 "rpc_server",
618 "epmapper",
619 "none");
620
621 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
622 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
623 NTSTATUS status;
624 bool ok;
625
626 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
627 ep_ctx->msg_ctx,
628 abstract_syntax,
629 pipe_name,
630 NULL);
631 if (!ok) {
632 return false;
633 }
634
635 port = _open_sockets(ep_ctx->ev_ctx,
636 ep_ctx->msg_ctx,
637 abstract_syntax,
638 0);
639 if (port == 0) {
640 return false;
641 }
642
643 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
644 ep_ctx->msg_ctx,
645 &ndr_table_netlogon,
646 pipe_name,
647 port);
648 if (!NT_STATUS_IS_OK(status)) {
649 return false;
650 }
651 }
652
653 return true;
654}
655
656static bool spoolss_init_cb(void *ptr)
657{
658 struct dcesrv_ep_context *ep_ctx =
659 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
660 const char *rpcsrv_type;
661 bool ok;
662
663 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
664 "rpc_server",
665 "epmapper",
666 "none");
667
668 /*
669 * Migrate the printers first.
670 */
671 ok = nt_printing_tdb_migrate(ep_ctx->msg_ctx);
672 if (!ok) {
673 return false;
674 }
675
676 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
677 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
678 NTSTATUS status;
679
680 status =rpc_ep_setup_register(ep_ctx->ev_ctx,
681 ep_ctx->msg_ctx,
682 &ndr_table_spoolss,
683 "spoolss",
684 0);
685 if (!NT_STATUS_IS_OK(status)) {
686 return false;
687 }
688 }
689
690 return true;
691}
692
693static bool spoolss_shutdown_cb(void *ptr)
694{
695 srv_spoolss_cleanup();
696
697 return true;
698}
699
700static bool svcctl_init_cb(void *ptr)
701{
702 struct dcesrv_ep_context *ep_ctx =
703 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
704 const char *rpcsrv_type;
705 bool ok;
706
707 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
708 "rpc_server",
709 "epmapper",
710 "none");
711
712 ok = svcctl_init_winreg(ep_ctx->msg_ctx);
713 if (!ok) {
714 return false;
715 }
716
717 /* initialize the control hooks */
718 init_service_op_table();
719
720 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
721 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
722 NTSTATUS status;
723
724 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
725 ep_ctx->msg_ctx,
726 &ndr_table_svcctl,
727 "svcctl",
728 0);
729 if (!NT_STATUS_IS_OK(status)) {
730 return false;
731 }
732 }
733
734 return true;
735}
736
737static bool svcctl_shutdown_cb(void *ptr)
738{
739 shutdown_service_op_table();
740
741 return true;
742}
743
744static bool ntsvcs_init_cb(void *ptr)
745{
746 struct dcesrv_ep_context *ep_ctx =
747 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
748 const char *rpcsrv_type;
749
750 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
751 "rpc_server",
752 "epmapper",
753 "none");
754
755 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
756 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
757 NTSTATUS status;
758
759 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
760 ep_ctx->msg_ctx,
761 &ndr_table_ntsvcs,
762 "ntsvcs",
763 0);
764 if (!NT_STATUS_IS_OK(status)) {
765 return false;
766 }
767 }
768
769 return true;
770}
771
772static bool eventlog_init_cb(void *ptr)
773{
774 struct dcesrv_ep_context *ep_ctx =
775 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
776 const char *rpcsrv_type;
777 bool ok;
778
779 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
780 "rpc_server",
781 "epmapper",
782 "none");
783
784 ok = eventlog_init_winreg(ep_ctx->msg_ctx);
785 if (!ok) {
786 return false;
787 }
788
789 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
790 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
791 NTSTATUS status;
792
793 status =rpc_ep_setup_register(ep_ctx->ev_ctx,
794 ep_ctx->msg_ctx,
795 &ndr_table_eventlog,
796 "eventlog",
797 0);
798 if (!NT_STATUS_IS_OK(status)) {
799 return false;
800 }
801 }
802
803 return true;
804}
805
806static bool initshutdown_init_cb(void *ptr)
807{
808 struct dcesrv_ep_context *ep_ctx =
809 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
810 const char *rpcsrv_type;
811
812 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
813 "rpc_server",
814 "epmapper",
815 "none");
816
817 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
818 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
819 NTSTATUS status;
820
821 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
822 ep_ctx->msg_ctx,
823 &ndr_table_initshutdown,
824 "initshutdown",
825 0);
826 if (!NT_STATUS_IS_OK(status)) {
827 return false;
828 }
829 }
830
831 return true;
832}
833
834#ifdef DEVELOPER
835static bool rpcecho_init_cb(void *ptr) {
836 struct dcesrv_ep_context *ep_ctx =
837 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
838 const char *rpcsrv_type;
839 uint16_t port;
840
841 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
842 "rpc_server",
843 "epmapper",
844 "none");
845
846 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
847 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
848 NTSTATUS status;
849
850 port = _open_sockets(ep_ctx->ev_ctx,
851 ep_ctx->msg_ctx,
852 ndr_table_rpcecho.syntax_id,
853 0);
854 if (port == 0) {
855 return false;
856 }
857
858 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
859 ep_ctx->msg_ctx,
860 &ndr_table_rpcecho,
861 "rpcecho",
862 port);
863 if (!NT_STATUS_IS_OK(status)) {
864 return false;
865 }
866 }
867
868 return true;
869}
870
871#endif
872
873static bool netdfs_init_cb(void *ptr)
874{
875 struct dcesrv_ep_context *ep_ctx =
876 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
877 struct ndr_syntax_id abstract_syntax = ndr_table_netdfs.syntax_id;
878 const char *pipe_name = "netdfs";
879 const char *rpcsrv_type;
880 uint16_t port;
881
882 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
883 "rpc_server",
884 "epmapper",
885 "none");
886 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
887 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
888 NTSTATUS status;
889 bool ok;
890
891 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
892 ep_ctx->msg_ctx,
893 abstract_syntax,
894 pipe_name,
895 NULL);
896 if (!ok) {
897 return false;
898 }
899
900 port = _open_sockets(ep_ctx->ev_ctx,
901 ep_ctx->msg_ctx,
902 abstract_syntax,
903 0);
904 if (port == 0) {
905 return false;
906 }
907
908 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
909 ep_ctx->msg_ctx,
910 &ndr_table_netdfs,
911 pipe_name,
912 port);
913 if (!NT_STATUS_IS_OK(status)) {
914 return false;
915 }
916 }
917
918 return true;
919}
920
921static bool dssetup_init_cb(void *ptr)
922{
923 struct dcesrv_ep_context *ep_ctx =
924 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
925 struct ndr_syntax_id abstract_syntax = ndr_table_dssetup.syntax_id;
926 const char *pipe_name = "dssetup";
927 const char *rpcsrv_type;
928 uint16_t port;
929
930 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
931 "rpc_server",
932 "epmapper",
933 "none");
934
935 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
936 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
937 NTSTATUS status;
938 bool ok;
939
940 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
941 ep_ctx->msg_ctx,
942 abstract_syntax,
943 pipe_name,
944 NULL);
945 if (!ok) {
946 return false;
947 }
948
949 port = _open_sockets(ep_ctx->ev_ctx,
950 ep_ctx->msg_ctx,
951 abstract_syntax,
952 0);
953 if (port == 0) {
954 return false;
955 }
956
957 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
958 ep_ctx->msg_ctx,
959 &ndr_table_dssetup,
960 "dssetup",
961 port);
962 if (!NT_STATUS_IS_OK(status)) {
963 return false;
964 }
965 }
966
967 return true;
968}
969
970static bool wkssvc_init_cb(void *ptr)
971{
972 struct dcesrv_ep_context *ep_ctx =
973 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
974 struct ndr_syntax_id abstract_syntax = ndr_table_wkssvc.syntax_id;
975 const char *pipe_name = "wkssvc";
976 const char *rpcsrv_type;
977 uint16_t port;
978
979 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
980 "rpc_server",
981 "epmapper",
982 "none");
983 if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
984 StrCaseCmp(rpcsrv_type, "daemon") == 0) {
985 NTSTATUS status;
986 bool ok;
987
988 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
989 ep_ctx->msg_ctx,
990 abstract_syntax,
991 pipe_name,
992 NULL);
993 if (!ok) {
994 return false;
995 }
996
997 port = _open_sockets(ep_ctx->ev_ctx,
998 ep_ctx->msg_ctx,
999 abstract_syntax,
1000 0);
1001 if (port == 0) {
1002 return false;
1003 }
1004
1005 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
1006 ep_ctx->msg_ctx,
1007 &ndr_table_wkssvc,
1008 "wkssvc",
1009 port);
1010 if (!NT_STATUS_IS_OK(status)) {
1011 return false;
1012 }
1013 }
1014
1015 return true;
1016}
1017
1018bool dcesrv_ep_setup(struct tevent_context *ev_ctx,
1019 struct messaging_context *msg_ctx)
1020{
1021 struct dcesrv_ep_context *ep_ctx;
1022
1023 struct rpc_srv_callbacks epmapper_cb;
1024
1025 struct rpc_srv_callbacks winreg_cb;
1026 struct rpc_srv_callbacks srvsvc_cb;
1027
1028 struct rpc_srv_callbacks lsarpc_cb;
1029 struct rpc_srv_callbacks samr_cb;
1030 struct rpc_srv_callbacks netlogon_cb;
1031
1032 struct rpc_srv_callbacks spoolss_cb;
1033 struct rpc_srv_callbacks svcctl_cb;
1034 struct rpc_srv_callbacks ntsvcs_cb;
1035 struct rpc_srv_callbacks eventlog_cb;
1036 struct rpc_srv_callbacks initshutdown_cb;
1037 struct rpc_srv_callbacks netdfs_cb;
1038#ifdef DEVELOPER
1039 struct rpc_srv_callbacks rpcecho_cb;
1040#endif
1041 struct rpc_srv_callbacks dssetup_cb;
1042 struct rpc_srv_callbacks wkssvc_cb;
1043
1044 const char *rpcsrv_type;
1045
1046 ep_ctx = talloc(ev_ctx, struct dcesrv_ep_context);
1047 if (ep_ctx == NULL) {
1048 return false;
1049 }
1050
1051 ep_ctx->ev_ctx = ev_ctx;
1052 ep_ctx->msg_ctx = msg_ctx;
1053
1054 /* start endpoint mapper only if enabled */
1055 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1056 "rpc_server",
1057 "epmapper",
1058 "none");
1059 if (StrCaseCmp(rpcsrv_type, "embedded") == 0) {
1060 epmapper_cb.init = epmapper_init_cb;
1061 epmapper_cb.shutdown = epmapper_shutdown_cb;
1062 epmapper_cb.private_data = ep_ctx;
1063
1064 if (!NT_STATUS_IS_OK(rpc_epmapper_init(&epmapper_cb))) {
1065 return false;
1066 }
1067 } else if (StrCaseCmp(rpcsrv_type, "daemon") == 0) {
1068 if (!NT_STATUS_IS_OK(rpc_epmapper_init(NULL))) {
1069 return false;
1070 }
1071 }
1072
1073 winreg_cb.init = winreg_init_cb;
1074 winreg_cb.shutdown = NULL;
1075 winreg_cb.private_data = ep_ctx;
1076 if (!NT_STATUS_IS_OK(rpc_winreg_init(&winreg_cb))) {
1077 return false;
1078 }
1079
1080 srvsvc_cb.init = srvsvc_init_cb;
1081 srvsvc_cb.shutdown = NULL;
1082 srvsvc_cb.private_data = ep_ctx;
1083 if (!NT_STATUS_IS_OK(rpc_srvsvc_init(&srvsvc_cb))) {
1084 return false;
1085 }
1086
1087
1088 lsarpc_cb.init = lsarpc_init_cb;
1089 lsarpc_cb.shutdown = NULL;
1090 lsarpc_cb.private_data = ep_ctx;
1091 if (!NT_STATUS_IS_OK(rpc_lsarpc_init(&lsarpc_cb))) {
1092 return false;
1093 }
1094
1095 samr_cb.init = samr_init_cb;
1096 samr_cb.shutdown = NULL;
1097 samr_cb.private_data = ep_ctx;
1098 if (!NT_STATUS_IS_OK(rpc_samr_init(&samr_cb))) {
1099 return false;
1100 }
1101
1102 netlogon_cb.init = netlogon_init_cb;
1103 netlogon_cb.shutdown = NULL;
1104 netlogon_cb.private_data = ep_ctx;
1105 if (!NT_STATUS_IS_OK(rpc_netlogon_init(&netlogon_cb))) {
1106 return false;
1107 }
1108
1109 rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1110 "rpc_server",
1111 "spoolss",
1112 "embedded");
1113 if (StrCaseCmp(rpcsrv_type, "embedded") == 0) {
1114 spoolss_cb.init = spoolss_init_cb;
1115 spoolss_cb.shutdown = spoolss_shutdown_cb;
1116 spoolss_cb.private_data = ep_ctx;
1117 if (!NT_STATUS_IS_OK(rpc_spoolss_init(&spoolss_cb))) {
1118 return false;
1119 }
1120 } else if (StrCaseCmp(rpcsrv_type, "daemon") == 0 ||
1121 StrCaseCmp(rpcsrv_type, "external") == 0) {
1122 if (!NT_STATUS_IS_OK(rpc_spoolss_init(NULL))) {
1123 return false;
1124 }
1125 }
1126
1127 svcctl_cb.init = svcctl_init_cb;
1128 svcctl_cb.shutdown = svcctl_shutdown_cb;
1129 svcctl_cb.private_data = ep_ctx;
1130 if (!NT_STATUS_IS_OK(rpc_svcctl_init(&svcctl_cb))) {
1131 return false;
1132 }
1133
1134 ntsvcs_cb.init = ntsvcs_init_cb;
1135 ntsvcs_cb.shutdown = NULL;
1136 ntsvcs_cb.private_data = ep_ctx;
1137 if (!NT_STATUS_IS_OK(rpc_ntsvcs_init(&ntsvcs_cb))) {
1138 return false;
1139 }
1140
1141 eventlog_cb.init = eventlog_init_cb;
1142 eventlog_cb.shutdown = NULL;
1143 eventlog_cb.private_data = ep_ctx;
1144 if (!NT_STATUS_IS_OK(rpc_eventlog_init(&eventlog_cb))) {
1145 return false;
1146 }
1147
1148 initshutdown_cb.init = initshutdown_init_cb;
1149 initshutdown_cb.shutdown = NULL;
1150 initshutdown_cb.private_data = ep_ctx;
1151 if (!NT_STATUS_IS_OK(rpc_initshutdown_init(&initshutdown_cb))) {
1152 return false;
1153 }
1154
1155 netdfs_cb.init = netdfs_init_cb;
1156 netdfs_cb.shutdown = NULL;
1157 netdfs_cb.private_data = ep_ctx;
1158 if (!NT_STATUS_IS_OK(rpc_netdfs_init(&netdfs_cb))) {
1159 return false;
1160 }
1161
1162#ifdef DEVELOPER
1163 rpcecho_cb.init = rpcecho_init_cb;
1164 rpcecho_cb.shutdown = NULL;
1165 rpcecho_cb.private_data = ep_ctx;
1166 if (!NT_STATUS_IS_OK(rpc_rpcecho_init(&rpcecho_cb))) {
1167 return false;
1168 }
1169#endif
1170
1171 dssetup_cb.init = dssetup_init_cb;
1172 dssetup_cb.shutdown = NULL;
1173 dssetup_cb.private_data = ep_ctx;
1174 if (!NT_STATUS_IS_OK(rpc_dssetup_init(&dssetup_cb))) {
1175 return false;
1176 }
1177
1178 wkssvc_cb.init = wkssvc_init_cb;
1179 wkssvc_cb.shutdown = NULL;
1180 wkssvc_cb.private_data = ep_ctx;
1181 if (!NT_STATUS_IS_OK(rpc_wkssvc_init(&wkssvc_cb))) {
1182 return false;
1183 }
1184
1185 return true;
1186}
1187
1188/* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */
Note: See TracBrowser for help on using the repository browser.