s3-rpc_server: run minimal_includes.pl.
[kai/samba.git] / source3 / rpc_server / rpc_ep_setup.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *
4  *  SMBD RPC service callbacks
5  *
6  *  Copyright (c) 2011      Andreas Schneider <asn@samba.org>
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.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
54 struct dcesrv_ep_context {
55         struct tevent_context *ev_ctx;
56         struct messaging_context *msg_ctx;
57 };
58
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)
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
131 static void rpc_ep_setup_register_loop(struct tevent_req *subreq);
132 static 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 *name,
137                                           uint16_t port,
138                                           struct dcerpc_binding_handle **pbh);
139
140 struct 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
155 NTSTATUS 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
199 static void rpc_ep_setup_monitor_loop(struct tevent_req *subreq);
200
201 static 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
255 static 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 *name,
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                                               name,
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                                     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  */
293 static 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
388 static 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
405 static bool epmapper_shutdown_cb(void *ptr)
406 {
407         srv_epmapper_cleanup();
408
409         return true;
410 }
411
412 static 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
460 static 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
509 static 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
558 static 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
607 static 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
656 static 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
693 static bool spoolss_shutdown_cb(void *ptr)
694 {
695         srv_spoolss_cleanup();
696
697         return true;
698 }
699
700 static 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
737 static bool svcctl_shutdown_cb(void *ptr)
738 {
739         shutdown_service_op_table();
740
741         return true;
742 }
743
744 static 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
772 static 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
806 static 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
835 static 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
873 static 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
921 static 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
970 static 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
1018 bool 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: */