s3-talloc Change TALLOC_ARRAY() to talloc_array()
[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                                                             ifss,
83                                                             port);
84                         if (p == 0) {
85                                 return 0;
86                         }
87                         port = p;
88                 }
89         } else {
90                 const char *sock_addr = lp_socket_address();
91                 const char *sock_ptr;
92                 char *sock_tok;
93
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
101                 }
102
103                 for (sock_ptr = sock_addr;
104                      next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,");
105                     ) {
106                         struct sockaddr_storage ss;
107
108                         /* open an incoming socket */
109                         if (!interpret_string_addr(&ss,
110                                                    sock_tok,
111                                                    AI_NUMERICHOST|AI_PASSIVE)) {
112                                 continue;
113                         }
114
115                         p = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
116                                                             msg_ctx,
117                                                             &ss,
118                                                             port);
119                         if (p == 0) {
120                                 return 0;
121                         }
122                         port = p;
123                 }
124         }
125
126         return p;
127 }
128
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);
137
138 struct rpc_ep_regsiter_state {
139         struct dcerpc_binding_handle *h;
140
141         TALLOC_CTX *mem_ctx;
142         struct tevent_context *ev_ctx;
143         struct messaging_context *msg_ctx;
144
145         const struct ndr_interface_table *iface;
146
147         const char *ncalrpc;
148         uint16_t port;
149
150         uint32_t wait_time;
151 };
152
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)
158 {
159         struct rpc_ep_regsiter_state *state;
160         struct tevent_req *req;
161
162         state = talloc(ev_ctx, struct rpc_ep_regsiter_state);
163         if (state == NULL) {
164                 return NT_STATUS_NO_MEMORY;
165         }
166
167         state->mem_ctx = talloc_named(state,
168                                       0,
169                                       "ep %s %p",
170                                       iface->name, state);
171         if (state->mem_ctx == NULL) {
172                 talloc_free(state);
173                 return NT_STATUS_NO_MEMORY;
174         }
175
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;
182
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;
189         }
190
191         tevent_req_set_callback(req, rpc_ep_setup_register_loop, state);
192
193         return NT_STATUS_OK;
194 }
195
196 #define MONITOR_WAIT_TIME 15
197 static void rpc_ep_setup_monitor_loop(struct tevent_req *subreq);
198
199 static void rpc_ep_setup_register_loop(struct tevent_req *subreq)
200 {
201         struct rpc_ep_regsiter_state *state =
202                 tevent_req_callback_data(subreq, struct rpc_ep_regsiter_state);
203         NTSTATUS status;
204         bool ok;
205
206         ok = tevent_wakeup_recv(subreq);
207         TALLOC_FREE(subreq);
208         if (!ok) {
209                 talloc_free(state);
210                 return;
211         }
212
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;
228                 }
229
230                 tevent_req_set_callback(subreq, rpc_ep_setup_monitor_loop, state);
231                 return;
232         }
233
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;
239         }
240
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;
247         }
248
249         tevent_req_set_callback(subreq, rpc_ep_setup_register_loop, state);
250         return;
251 }
252
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)
260 {
261         struct dcerpc_binding_vector *v = NULL;
262         NTSTATUS status;
263
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;
271         }
272
273         status = dcerpc_ep_register(mem_ctx,
274                                     iface,
275                                     v,
276                                     &iface->syntax_id.uuid,
277                                     iface->name,
278                                     pbh);
279         talloc_free(v);
280         if (!NT_STATUS_IS_OK(status)) {
281                 return status;
282         }
283
284         return status;
285 }
286
287 /*
288  * Monitor the connection to the endpoint mapper and if it goes away, try to
289  * register the endpoint.
290  */
291 static void rpc_ep_setup_monitor_loop(struct tevent_req *subreq)
292 {
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;
305
306         ZERO_STRUCT(object);
307         ZERO_STRUCT(entry_handle);
308
309         tmp_ctx = talloc_stackframe();
310         if (tmp_ctx == NULL) {
311                 talloc_free(state);
312                 return;
313         }
314
315         ok = tevent_wakeup_recv(subreq);
316         TALLOC_FREE(subreq);
317         if (!ok) {
318                 talloc_free(state);
319                 return;
320         }
321
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 = "";
327
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;
333         }
334
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;
341         }
342
343         ok = false;
344         status = dcerpc_epm_Map(state->h,
345                                 tmp_ctx,
346                                 &object,
347                                 map_tower,
348                                 &entry_handle,
349                                 10,
350                                 &num_towers,
351                                 towers,
352                                 &result);
353         if (NT_STATUS_IS_OK(status)) {
354                 ok = true;
355         }
356         if (result == EPMAPPER_STATUS_OK ||
357             result == EPMAPPER_STATUS_NO_MORE_ENTRIES) {
358                 ok = true;
359         }
360         if (num_towers == 0) {
361                 ok = false;
362         }
363
364         talloc_free(tmp_ctx);
365
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;
372         }
373
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;
379
380                 tevent_req_set_callback(subreq, rpc_ep_setup_register_loop, state);
381         }
382
383         return;
384 }
385
386 static bool epmapper_init_cb(void *ptr)
387 {
388         struct dcesrv_ep_context *ep_ctx =
389                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
390         uint16_t port;
391
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;
398         }
399
400         return false;
401 }
402
403 static bool epmapper_shutdown_cb(void *ptr)
404 {
405         srv_epmapper_cleanup();
406
407         return true;
408 }
409
410 static bool winreg_init_cb(void *ptr)
411 {
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;
418
419         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
420                                            "rpc_server",
421                                            "epmapper",
422                                            "none");
423
424         if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
425             strcasecmp_m(rpcsrv_type, "daemon") == 0) {
426                 NTSTATUS status;
427                 bool ok;
428
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;
435                 }
436                 port = _open_sockets(ep_ctx->ev_ctx,
437                                      ep_ctx->msg_ctx,
438                                      abstract_syntax,
439                                      0);
440                 if (port == 0) {
441                         return false;
442                 }
443
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;
451                 }
452         }
453
454         return true;
455 }
456
457 static bool srvsvc_init_cb(void *ptr)
458 {
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;
465
466         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
467                                            "rpc_server",
468                                            "epmapper",
469                                            "none");
470
471         if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
472             strcasecmp_m(rpcsrv_type, "daemon") == 0) {
473                 NTSTATUS status;
474                 bool ok;
475
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;
482                 }
483
484                 port = _open_sockets(ep_ctx->ev_ctx,
485                                      ep_ctx->msg_ctx,
486                                      abstract_syntax,
487                                      0);
488                 if (port == 0) {
489                         return false;
490                 }
491
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;
499                 }
500         }
501
502         return true;
503 }
504
505 static bool lsarpc_init_cb(void *ptr)
506 {
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;
513
514         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
515                                            "rpc_server",
516                                            "epmapper",
517                                            "none");
518
519         if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
520             strcasecmp_m(rpcsrv_type, "daemon") == 0) {
521                 NTSTATUS status;
522                 bool ok;
523
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;
530                 }
531
532                 port = _open_sockets(ep_ctx->ev_ctx,
533                                      ep_ctx->msg_ctx,
534                                      abstract_syntax,
535                                      0);
536                 if (port == 0) {
537                         return false;
538                 }
539
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;
547                 }
548         }
549
550         return true;
551 }
552
553 static bool samr_init_cb(void *ptr)
554 {
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;
561
562         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
563                                            "rpc_server",
564                                            "epmapper",
565                                            "none");
566
567         if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
568             strcasecmp_m(rpcsrv_type, "daemon") == 0) {
569                 NTSTATUS status;
570                 bool ok;
571
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;
578                 }
579
580                 port = _open_sockets(ep_ctx->ev_ctx,
581                                      ep_ctx->msg_ctx,
582                                      abstract_syntax,
583                                      0);
584                 if (port == 0) {
585                         return false;
586                 }
587
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;
595                 }
596         }
597
598         return true;
599 }
600
601 static bool netlogon_init_cb(void *ptr)
602 {
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;
609
610         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
611                                            "rpc_server",
612                                            "epmapper",
613                                            "none");
614
615         if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
616             strcasecmp_m(rpcsrv_type, "daemon") == 0) {
617                 NTSTATUS status;
618                 bool ok;
619
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;
626                 }
627
628                 port = _open_sockets(ep_ctx->ev_ctx,
629                                      ep_ctx->msg_ctx,
630                                      abstract_syntax,
631                                      0);
632                 if (port == 0) {
633                         return false;
634                 }
635
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;
643                 }
644         }
645
646         return true;
647 }
648
649 static bool spoolss_init_cb(void *ptr)
650 {
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;
655
656         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
657                                            "rpc_server",
658                                            "epmapper",
659                                            "none");
660
661         /*
662          * Migrate the printers first.
663          */
664         ok = nt_printing_tdb_migrate(ep_ctx->msg_ctx);
665         if (!ok) {
666                 return false;
667         }
668
669         if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
670             strcasecmp_m(rpcsrv_type, "daemon") == 0) {
671                 NTSTATUS status;
672
673                 status =rpc_ep_setup_register(ep_ctx->ev_ctx,
674                                          ep_ctx->msg_ctx,
675                                          &ndr_table_spoolss,
676                                          "spoolss",
677                                          0);
678                 if (!NT_STATUS_IS_OK(status)) {
679                         return false;
680                 }
681         }
682
683         return true;
684 }
685
686 static bool spoolss_shutdown_cb(void *ptr)
687 {
688         srv_spoolss_cleanup();
689
690         return true;
691 }
692
693 static bool svcctl_init_cb(void *ptr)
694 {
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;
699
700         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
701                                            "rpc_server",
702                                            "epmapper",
703                                            "none");
704
705         ok = svcctl_init_winreg(ep_ctx->msg_ctx);
706         if (!ok) {
707                 return false;
708         }
709
710         /* initialize the control hooks */
711         init_service_op_table();
712
713         if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
714             strcasecmp_m(rpcsrv_type, "daemon") == 0) {
715                 NTSTATUS status;
716
717                 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
718                                           ep_ctx->msg_ctx,
719                                           &ndr_table_svcctl,
720                                           "svcctl",
721                                           0);
722                 if (!NT_STATUS_IS_OK(status)) {
723                         return false;
724                 }
725         }
726
727         return true;
728 }
729
730 static bool svcctl_shutdown_cb(void *ptr)
731 {
732         shutdown_service_op_table();
733
734         return true;
735 }
736
737 static bool ntsvcs_init_cb(void *ptr)
738 {
739         struct dcesrv_ep_context *ep_ctx =
740                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
741         const char *rpcsrv_type;
742
743         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
744                                            "rpc_server",
745                                            "epmapper",
746                                            "none");
747
748         if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
749             strcasecmp_m(rpcsrv_type, "daemon") == 0) {
750                 NTSTATUS status;
751
752                 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
753                                           ep_ctx->msg_ctx,
754                                           &ndr_table_ntsvcs,
755                                           "ntsvcs",
756                                           0);
757                 if (!NT_STATUS_IS_OK(status)) {
758                         return false;
759                 }
760         }
761
762         return true;
763 }
764
765 static bool eventlog_init_cb(void *ptr)
766 {
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;
771
772         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
773                                            "rpc_server",
774                                            "epmapper",
775                                            "none");
776
777         ok = eventlog_init_winreg(ep_ctx->msg_ctx);
778         if (!ok) {
779                 return false;
780         }
781
782         if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
783             strcasecmp_m(rpcsrv_type, "daemon") == 0) {
784                 NTSTATUS status;
785
786                 status =rpc_ep_setup_register(ep_ctx->ev_ctx,
787                                          ep_ctx->msg_ctx,
788                                          &ndr_table_eventlog,
789                                          "eventlog",
790                                          0);
791                 if (!NT_STATUS_IS_OK(status)) {
792                         return false;
793                 }
794         }
795
796         return true;
797 }
798
799 static bool initshutdown_init_cb(void *ptr)
800 {
801         struct dcesrv_ep_context *ep_ctx =
802                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
803         const char *rpcsrv_type;
804
805         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
806                                            "rpc_server",
807                                            "epmapper",
808                                            "none");
809
810         if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
811             strcasecmp_m(rpcsrv_type, "daemon") == 0) {
812                 NTSTATUS status;
813
814                 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
815                                           ep_ctx->msg_ctx,
816                                           &ndr_table_initshutdown,
817                                           "initshutdown",
818                                           0);
819                 if (!NT_STATUS_IS_OK(status)) {
820                         return false;
821                 }
822         }
823
824         return true;
825 }
826
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;
833
834         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
835                                            "rpc_server",
836                                            "epmapper",
837                                            "none");
838
839         if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
840             strcasecmp_m(rpcsrv_type, "daemon") == 0) {
841                 NTSTATUS status;
842
843                 port = _open_sockets(ep_ctx->ev_ctx,
844                                      ep_ctx->msg_ctx,
845                                      ndr_table_rpcecho.syntax_id,
846                                      0);
847                 if (port == 0) {
848                         return false;
849                 }
850
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;
858                 }
859         }
860
861         return true;
862 }
863
864 #endif
865
866 static bool netdfs_init_cb(void *ptr)
867 {
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;
874
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;
883
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;
890                 }
891
892                 port = _open_sockets(ep_ctx->ev_ctx,
893                                      ep_ctx->msg_ctx,
894                                      abstract_syntax,
895                                      0);
896                 if (port == 0) {
897                         return false;
898                 }
899
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;
907                 }
908         }
909
910         return true;
911 }
912
913 static bool dssetup_init_cb(void *ptr)
914 {
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;
921
922         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
923                                            "rpc_server",
924                                            "epmapper",
925                                            "none");
926
927         if (strcasecmp_m(rpcsrv_type, "embedded") == 0 ||
928             strcasecmp_m(rpcsrv_type, "daemon") == 0) {
929                 NTSTATUS status;
930                 bool ok;
931
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;
938                 }
939
940                 port = _open_sockets(ep_ctx->ev_ctx,
941                                      ep_ctx->msg_ctx,
942                                      abstract_syntax,
943                                      0);
944                 if (port == 0) {
945                         return false;
946                 }
947
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;
955                 }
956         }
957
958         return true;
959 }
960
961 static bool wkssvc_init_cb(void *ptr)
962 {
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;
969
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;
978
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;
985                 }
986
987                 port = _open_sockets(ep_ctx->ev_ctx,
988                                      ep_ctx->msg_ctx,
989                                      abstract_syntax,
990                                      0);
991                 if (port == 0) {
992                         return false;
993                 }
994
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;
1002                 }
1003         }
1004
1005         return true;
1006 }
1007
1008 bool dcesrv_ep_setup(struct tevent_context *ev_ctx,
1009                      struct messaging_context *msg_ctx)
1010 {
1011         struct dcesrv_ep_context *ep_ctx;
1012
1013         struct rpc_srv_callbacks epmapper_cb;
1014
1015         struct rpc_srv_callbacks winreg_cb;
1016         struct rpc_srv_callbacks srvsvc_cb;
1017
1018         struct rpc_srv_callbacks lsarpc_cb;
1019         struct rpc_srv_callbacks samr_cb;
1020         struct rpc_srv_callbacks netlogon_cb;
1021
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;
1033
1034         const char *rpcsrv_type;
1035
1036         ep_ctx = talloc(ev_ctx, struct dcesrv_ep_context);
1037         if (ep_ctx == NULL) {
1038                 return false;
1039         }
1040
1041         ep_ctx->ev_ctx = ev_ctx;
1042         ep_ctx->msg_ctx = msg_ctx;
1043
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;
1053
1054                 if (!NT_STATUS_IS_OK(rpc_epmapper_init(&epmapper_cb))) {
1055                         return false;
1056                 }
1057         } else if (strcasecmp_m(rpcsrv_type, "daemon") == 0) {
1058                 if (!NT_STATUS_IS_OK(rpc_epmapper_init(NULL))) {
1059                         return false;
1060                 }
1061         }
1062
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;
1068         }
1069
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;
1075         }
1076
1077
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;
1083         }
1084
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;
1090         }
1091
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;
1097         }
1098
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;
1109                 }
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;
1114                 }
1115         }
1116
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;
1122         }
1123
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;
1129         }
1130
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;
1136         }
1137
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;
1143         }
1144
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;
1150         }
1151
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;
1158         }
1159 #endif
1160
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;
1166         }
1167
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;
1173         }
1174
1175         return true;
1176 }
1177
1178 /* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */