f6cc97d7267bf9616b5f858faa241bd2e8332c27
[mat/samba.git] / source3 / rpc_server / rpc_service_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_internal.h"
43 #include "rpc_server/eventlog/srv_eventlog_reg.h"
44 #include "rpc_server/svcctl/srv_svcctl_reg.h"
45 #include "rpc_server/spoolss/srv_spoolss_nt.h"
46 #include "rpc_server/svcctl/srv_svcctl_nt.h"
47
48 #include "librpc/rpc/dcerpc_ep.h"
49 #include "rpc_server/rpc_sock_helper.h"
50 #include "rpc_server/rpc_service_setup.h"
51 #include "rpc_server/rpc_ep_register.h"
52 #include "rpc_server/rpc_server.h"
53 #include "rpc_server/epmapper/srv_epmapper.h"
54
55 enum rpc_service_mode_e rpc_epmapper_mode(void)
56 {
57         const char *rpcsrv_type;
58         enum rpc_service_mode_e state;
59
60         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
61                                            "rpc_server",
62                                            "epmapper",
63                                            "daemon");
64
65         if (strcasecmp_m(rpcsrv_type, "external") == 0) {
66                 state = RPC_SERVICE_MODE_EXTERNAL;
67         } else if (strcasecmp_m(rpcsrv_type, "daemon") == 0) {
68                 state = RPC_SERVICE_MODE_DAEMON;
69         } else {
70                 state = RPC_SERVICE_MODE_DISABLED;
71         }
72
73         return state;
74 }
75
76 enum rpc_service_mode_e rpc_spoolss_mode(void)
77 {
78         const char *rpcsrv_type;
79         enum rpc_service_mode_e state;
80
81         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
82                                            "rpc_server",
83                                            "spoolss",
84                                            "embedded");
85
86         if (strcasecmp_m(rpcsrv_type, "embedded") == 0) {
87                 state = RPC_SERVICE_MODE_EMBEDDED;
88         } else if (strcasecmp_m(rpcsrv_type, "external") == 0) {
89                 state = RPC_SERVICE_MODE_EXTERNAL;
90         } else if (strcasecmp_m(rpcsrv_type, "daemon") == 0) {
91                 state = RPC_SERVICE_MODE_DAEMON;
92         } else {
93                 state = RPC_SERVICE_MODE_DISABLED;
94         }
95
96         return state;
97 }
98
99 static bool rpc_setup_epmapper(struct tevent_context *ev_ctx,
100                                struct messaging_context *msg_ctx)
101 {
102         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
103         NTSTATUS status;
104
105         if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
106                 status = rpc_epmapper_init(NULL);
107                 if (!NT_STATUS_IS_OK(status)) {
108                         return false;
109                 }
110         }
111
112         return true;
113 }
114
115 static bool rpc_setup_winreg(struct tevent_context *ev_ctx,
116                              struct messaging_context *msg_ctx,
117                              const struct dcerpc_binding_vector *v)
118 {
119         const struct ndr_interface_table *t = &ndr_table_winreg;
120         const char *pipe_name = "winreg";
121         struct dcerpc_binding_vector *v2;
122         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
123         NTSTATUS status;
124         bool ok;
125
126         status = rpc_winreg_init(NULL);
127         if (!NT_STATUS_IS_OK(status)) {
128                 return false;
129         }
130
131         if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
132                 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
133                 if (v2 == NULL) {
134                         return false;
135                 }
136
137                 status = dcerpc_binding_vector_replace_iface(t, v2);
138                 if (!NT_STATUS_IS_OK(status)) {
139                         return false;
140                 }
141
142                 status = dcerpc_binding_vector_add_np_default(t, v2);
143                 if (!NT_STATUS_IS_OK(status)) {
144                         return false;
145                 }
146
147                 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
148                                                  msg_ctx,
149                                                  pipe_name,
150                                                  NULL);
151                 if (!ok) {
152                         return false;
153                 }
154
155                 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
156                 if (!NT_STATUS_IS_OK(status)) {
157                         return false;
158                 }
159
160                 status = rpc_ep_register(ev_ctx,
161                                          msg_ctx,
162                                          t,
163                                          v2);
164                 if (!NT_STATUS_IS_OK(status)) {
165                         return false;
166                 }
167         }
168
169         return true;
170 }
171
172 static bool rpc_setup_srvsvc(struct tevent_context *ev_ctx,
173                              struct messaging_context *msg_ctx,
174                              const struct dcerpc_binding_vector *v)
175 {
176         const struct ndr_interface_table *t = &ndr_table_srvsvc;
177         const char *pipe_name = "srvsvc";
178         struct dcerpc_binding_vector *v2;
179         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
180         NTSTATUS status;
181         bool ok;
182
183         status = rpc_srvsvc_init(NULL);
184         if (!NT_STATUS_IS_OK(status)) {
185                 return false;
186         }
187
188         if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
189                 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
190                 if (v2 == NULL) {
191                         return false;
192                 }
193
194                 status = dcerpc_binding_vector_replace_iface(t, v2);
195                 if (!NT_STATUS_IS_OK(status)) {
196                         return false;
197                 }
198
199                 status = dcerpc_binding_vector_add_np_default(t, v2);
200                 if (!NT_STATUS_IS_OK(status)) {
201                         return false;
202                 }
203
204                 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
205                                                  msg_ctx,
206                                                  pipe_name,
207                                                  NULL);
208                 if (!ok) {
209                         return false;
210                 }
211
212                 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
213                 if (!NT_STATUS_IS_OK(status)) {
214                         return false;
215                 }
216
217                 status = rpc_ep_register(ev_ctx,
218                                          msg_ctx,
219                                          t,
220                                          v2);
221                 if (!NT_STATUS_IS_OK(status)) {
222                         return false;
223                 }
224         }
225
226         return true;
227 }
228
229 static bool rpc_setup_lsarpc(struct tevent_context *ev_ctx,
230                              struct messaging_context *msg_ctx,
231                              const struct dcerpc_binding_vector *v)
232 {
233         const struct ndr_interface_table *t = &ndr_table_lsarpc;
234         const char *pipe_name = "lsarpc";
235         struct dcerpc_binding_vector *v2;
236         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
237         NTSTATUS status;
238         bool ok;
239
240         status = rpc_lsarpc_init(NULL);
241         if (!NT_STATUS_IS_OK(status)) {
242                 return false;
243         }
244
245         if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
246                 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
247                 if (v2 == NULL) {
248                         return false;
249                 }
250
251                 status = dcerpc_binding_vector_replace_iface(t, v2);
252                 if (!NT_STATUS_IS_OK(status)) {
253                         return false;
254                 }
255
256                 status = dcerpc_binding_vector_add_np_default(t, v2);
257                 if (!NT_STATUS_IS_OK(status)) {
258                         return false;
259                 }
260
261                 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
262                                                  msg_ctx,
263                                                  pipe_name,
264                                                  NULL);
265                 if (!ok) {
266                         return false;
267                 }
268
269                 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
270                 if (!NT_STATUS_IS_OK(status)) {
271                         return false;
272                 }
273
274                 status = rpc_ep_register(ev_ctx,
275                                          msg_ctx,
276                                          t,
277                                          v2);
278                 if (!NT_STATUS_IS_OK(status)) {
279                         return false;
280                 }
281         }
282
283         return true;
284 }
285
286 static bool rpc_setup_samr(struct tevent_context *ev_ctx,
287                            struct messaging_context *msg_ctx,
288                            const struct dcerpc_binding_vector *v)
289 {
290         const struct ndr_interface_table *t = &ndr_table_samr;
291         const char *pipe_name = "samr";
292         struct dcerpc_binding_vector *v2;
293         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
294         NTSTATUS status;
295         bool ok;
296
297         status = rpc_samr_init(NULL);
298         if (!NT_STATUS_IS_OK(status)) {
299                 return false;
300         }
301
302         if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
303                 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
304                 if (v2 == NULL) {
305                         return false;
306                 }
307
308                 status = dcerpc_binding_vector_replace_iface(t, v2);
309                 if (!NT_STATUS_IS_OK(status)) {
310                         return false;
311                 }
312
313                 status = dcerpc_binding_vector_add_np_default(t, v2);
314                 if (!NT_STATUS_IS_OK(status)) {
315                         return false;
316                 }
317
318                 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
319                                                  msg_ctx,
320                                                  pipe_name,
321                                                  NULL);
322                 if (!ok) {
323                         return false;
324                 }
325
326                 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
327                 if (!NT_STATUS_IS_OK(status)) {
328                         return false;
329                 }
330
331                 status = rpc_ep_register(ev_ctx,
332                                          msg_ctx,
333                                          t,
334                                          v2);
335                 if (!NT_STATUS_IS_OK(status)) {
336                         return false;
337                 }
338         }
339
340         return true;
341 }
342
343 static bool rpc_setup_netlogon(struct tevent_context *ev_ctx,
344                                struct messaging_context *msg_ctx,
345                                const struct dcerpc_binding_vector *v)
346 {
347         const struct ndr_interface_table *t = &ndr_table_netlogon;
348         const char *pipe_name = "netlogon";
349         struct dcerpc_binding_vector *v2;
350         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
351         NTSTATUS status;
352         bool ok;
353
354         status = rpc_netlogon_init(NULL);
355         if (!NT_STATUS_IS_OK(status)) {
356                 return false;
357         }
358
359         if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
360                 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
361                 if (v2 == NULL) {
362                         return false;
363                 }
364
365                 status = dcerpc_binding_vector_replace_iface(t, v2);
366                 if (!NT_STATUS_IS_OK(status)) {
367                         return false;
368                 }
369
370                 status = dcerpc_binding_vector_add_np_default(t, v2);
371                 if (!NT_STATUS_IS_OK(status)) {
372                         return false;
373                 }
374
375                 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
376                                                  msg_ctx,
377                                                  pipe_name,
378                                                  NULL);
379                 if (!ok) {
380                         return false;
381                 }
382
383                 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
384                 if (!NT_STATUS_IS_OK(status)) {
385                         return false;
386                 }
387
388                 status = rpc_ep_register(ev_ctx,
389                                          msg_ctx,
390                                          t,
391                                          v2);
392                 if (!NT_STATUS_IS_OK(status)) {
393                         return false;
394                 }
395         }
396
397         return true;
398 }
399
400 static bool rpc_setup_netdfs(struct tevent_context *ev_ctx,
401                              struct messaging_context *msg_ctx,
402                              const struct dcerpc_binding_vector *v)
403 {
404         const struct ndr_interface_table *t = &ndr_table_netdfs;
405         const char *pipe_name = "netdfs";
406         struct dcerpc_binding_vector *v2;
407         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
408         NTSTATUS status;
409         bool ok;
410
411         status = rpc_netdfs_init(NULL);
412         if (!NT_STATUS_IS_OK(status)) {
413                 return false;
414         }
415
416         if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
417                 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
418                 if (v2 == NULL) {
419                         return false;
420                 }
421
422                 status = dcerpc_binding_vector_replace_iface(t, v2);
423                 if (!NT_STATUS_IS_OK(status)) {
424                         return false;
425                 }
426
427                 status = dcerpc_binding_vector_add_np_default(t, v2);
428                 if (!NT_STATUS_IS_OK(status)) {
429                         return false;
430                 }
431
432                 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
433                                                  msg_ctx,
434                                                  pipe_name,
435                                                  NULL);
436                 if (!ok) {
437                         return false;
438                 }
439
440                 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
441                 if (!NT_STATUS_IS_OK(status)) {
442                         return false;
443                 }
444
445                 status = rpc_ep_register(ev_ctx,
446                                          msg_ctx,
447                                          t,
448                                          v2);
449                 if (!NT_STATUS_IS_OK(status)) {
450                         return false;
451                 }
452         }
453
454         return true;
455 }
456
457 #ifdef DEVELOPER
458 static bool rpc_setup_rpcecho(struct tevent_context *ev_ctx,
459                               struct messaging_context *msg_ctx,
460                               const struct dcerpc_binding_vector *v)
461 {
462         const struct ndr_interface_table *t = &ndr_table_rpcecho;
463         const char *pipe_name = "rpcecho";
464         struct dcerpc_binding_vector *v2;
465         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
466         NTSTATUS status;
467         bool ok;
468
469         status = rpc_rpcecho_init(NULL);
470         if (!NT_STATUS_IS_OK(status)) {
471                 return false;
472         }
473
474         if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
475                 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
476                 if (v2 == NULL) {
477                         return false;
478                 }
479
480                 status = dcerpc_binding_vector_replace_iface(t, v2);
481                 if (!NT_STATUS_IS_OK(status)) {
482                         return false;
483                 }
484
485                 status = dcerpc_binding_vector_add_np_default(t, v2);
486                 if (!NT_STATUS_IS_OK(status)) {
487                         return false;
488                 }
489
490                 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
491                                                  msg_ctx,
492                                                  pipe_name,
493                                                  NULL);
494                 if (!ok) {
495                         return false;
496                 }
497
498                 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
499                 if (!NT_STATUS_IS_OK(status)) {
500                         return false;
501                 }
502
503                 status = rpc_ep_register(ev_ctx,
504                                          msg_ctx,
505                                          t,
506                                          v2);
507                 if (!NT_STATUS_IS_OK(status)) {
508                         return false;
509                 }
510         }
511
512         return true;
513 }
514 #endif
515
516 static bool rpc_setup_dssetup(struct tevent_context *ev_ctx,
517                               struct messaging_context *msg_ctx,
518                               const struct dcerpc_binding_vector *v)
519 {
520         const struct ndr_interface_table *t = &ndr_table_dssetup;
521         const char *pipe_name = "dssetup";
522         struct dcerpc_binding_vector *v2;
523         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
524         NTSTATUS status;
525         bool ok;
526
527         status = rpc_dssetup_init(NULL);
528         if (!NT_STATUS_IS_OK(status)) {
529                 return false;
530         }
531
532         if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
533                 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
534                 if (v2 == NULL) {
535                         return false;
536                 }
537
538                 status = dcerpc_binding_vector_replace_iface(t, v2);
539                 if (!NT_STATUS_IS_OK(status)) {
540                         return false;
541                 }
542
543                 status = dcerpc_binding_vector_add_np_default(t, v2);
544                 if (!NT_STATUS_IS_OK(status)) {
545                         return false;
546                 }
547
548                 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
549                                                  msg_ctx,
550                                                  pipe_name,
551                                                  NULL);
552                 if (!ok) {
553                         return false;
554                 }
555
556                 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
557                 if (!NT_STATUS_IS_OK(status)) {
558                         return false;
559                 }
560
561                 status = rpc_ep_register(ev_ctx,
562                                          msg_ctx,
563                                          t,
564                                          v2);
565                 if (!NT_STATUS_IS_OK(status)) {
566                         return false;
567                 }
568         }
569
570         return true;
571 }
572
573 static bool rpc_setup_wkssvc(struct tevent_context *ev_ctx,
574                              struct messaging_context *msg_ctx,
575                              const struct dcerpc_binding_vector *v)
576 {
577         const struct ndr_interface_table *t = &ndr_table_wkssvc;
578         const char *pipe_name = "wkssvc";
579         struct dcerpc_binding_vector *v2;
580         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
581         NTSTATUS status;
582         bool ok;
583
584         status = rpc_wkssvc_init(NULL);
585         if (!NT_STATUS_IS_OK(status)) {
586                 return false;
587         }
588
589         if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
590                 v2 = dcerpc_binding_vector_dup(talloc_tos(), v);
591                 if (v2 == NULL) {
592                         return false;
593                 }
594
595                 status = dcerpc_binding_vector_replace_iface(t, v2);
596                 if (!NT_STATUS_IS_OK(status)) {
597                         return false;
598                 }
599
600                 status = dcerpc_binding_vector_add_np_default(t, v2);
601                 if (!NT_STATUS_IS_OK(status)) {
602                         return false;
603                 }
604
605                 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
606                                                  msg_ctx,
607                                                  pipe_name,
608                                                  NULL);
609                 if (!ok) {
610                         return false;
611                 }
612
613                 status = dcerpc_binding_vector_add_unix(t, v2, pipe_name);
614                 if (!NT_STATUS_IS_OK(status)) {
615                         return false;
616                 }
617
618                 status = rpc_ep_register(ev_ctx,
619                                          msg_ctx,
620                                          t,
621                                          v2);
622                 if (!NT_STATUS_IS_OK(status)) {
623                         return false;
624                 }
625         }
626
627         return true;
628 }
629
630 static bool spoolss_init_cb(void *ptr)
631 {
632         struct messaging_context *msg_ctx =
633                 talloc_get_type_abort(ptr, struct messaging_context);
634         bool ok;
635
636         /*
637          * Migrate the printers first.
638          */
639         ok = nt_printing_tdb_migrate(msg_ctx);
640         if (!ok) {
641                 return false;
642         }
643
644         return true;
645 }
646
647 static bool spoolss_shutdown_cb(void *ptr)
648 {
649         srv_spoolss_cleanup();
650
651         return true;
652 }
653
654 static bool rpc_setup_spoolss(struct tevent_context *ev_ctx,
655                               struct messaging_context *msg_ctx)
656 {
657         const struct ndr_interface_table *t = &ndr_table_spoolss;
658         struct rpc_srv_callbacks spoolss_cb;
659         struct dcerpc_binding_vector *v;
660         enum rpc_service_mode_e spoolss_mode = rpc_spoolss_mode();
661         NTSTATUS status;
662
663         if (_lp_disable_spoolss() ||
664             spoolss_mode == RPC_SERVICE_MODE_DISABLED) {
665                 return true;
666         }
667
668         if (spoolss_mode == RPC_SERVICE_MODE_EMBEDDED) {
669                 spoolss_cb.init         = spoolss_init_cb;
670                 spoolss_cb.shutdown     = spoolss_shutdown_cb;
671                 spoolss_cb.private_data = msg_ctx;
672
673                 status = rpc_spoolss_init(&spoolss_cb);
674         } else if (spoolss_mode == RPC_SERVICE_MODE_EXTERNAL ||
675                    spoolss_mode == RPC_SERVICE_MODE_DAEMON) {
676                 status = rpc_spoolss_init(NULL);
677         }
678         if (!NT_STATUS_IS_OK(status)) {
679                 return false;
680         }
681
682         if (spoolss_mode == RPC_SERVICE_MODE_EMBEDDED) {
683                 enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
684
685                 if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
686                         status = dcerpc_binding_vector_new(talloc_tos(), &v);
687                         if (!NT_STATUS_IS_OK(status)) {
688                                 return false;
689                         }
690
691                         status = dcerpc_binding_vector_add_np_default(t, v);
692                         if (!NT_STATUS_IS_OK(status)) {
693                                 return false;
694                         }
695
696                         status = rpc_ep_register(ev_ctx,
697                                                  msg_ctx,
698                                                  t,
699                                                  v);
700                         if (!NT_STATUS_IS_OK(status)) {
701                                 return false;
702                         }
703                 }
704         }
705
706         return true;
707 }
708
709 static bool svcctl_init_cb(void *ptr)
710 {
711         struct messaging_context *msg_ctx =
712                 talloc_get_type_abort(ptr, struct messaging_context);
713         bool ok;
714
715         /* initialize the control hooks */
716         init_service_op_table();
717
718         ok = svcctl_init_winreg(msg_ctx);
719         if (!ok) {
720                 return false;
721         }
722
723         return true;
724 }
725
726 static bool svcctl_shutdown_cb(void *ptr)
727 {
728         shutdown_service_op_table();
729
730         return true;
731 }
732
733 static bool rpc_setup_svcctl(struct tevent_context *ev_ctx,
734                              struct messaging_context *msg_ctx)
735 {
736         const struct ndr_interface_table *t = &ndr_table_svcctl;
737         const char *pipe_name = "svcctl";
738         struct dcerpc_binding_vector *v;
739         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
740         struct rpc_srv_callbacks svcctl_cb;
741         NTSTATUS status;
742         bool ok;
743
744         svcctl_cb.init         = svcctl_init_cb;
745         svcctl_cb.shutdown     = svcctl_shutdown_cb;
746         svcctl_cb.private_data = msg_ctx;
747
748         status = rpc_svcctl_init(&svcctl_cb);
749         if (!NT_STATUS_IS_OK(status)) {
750                 return false;
751         }
752
753         if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
754                 status = dcerpc_binding_vector_new(talloc_tos(), &v);
755                 if (!NT_STATUS_IS_OK(status)) {
756                         return false;
757                 }
758
759                 status = dcerpc_binding_vector_add_np_default(t, v);
760                 if (!NT_STATUS_IS_OK(status)) {
761                         return false;
762                 }
763
764                 ok = setup_dcerpc_ncalrpc_socket(ev_ctx,
765                                                  msg_ctx,
766                                                  pipe_name,
767                                                  NULL);
768                 if (!ok) {
769                         return false;
770                 }
771
772                 status = dcerpc_binding_vector_add_unix(t, v, pipe_name);
773                 if (!NT_STATUS_IS_OK(status)) {
774                         return false;
775                 }
776
777                 status = rpc_ep_register(ev_ctx,
778                                          msg_ctx,
779                                          t,
780                                          v);
781                 if (!NT_STATUS_IS_OK(status)) {
782                         return false;
783                 }
784         }
785
786         return true;
787 }
788
789 static bool rpc_setup_ntsvcs(struct tevent_context *ev_ctx,
790                              struct messaging_context *msg_ctx)
791 {
792         const struct ndr_interface_table *t = &ndr_table_ntsvcs;
793         struct dcerpc_binding_vector *v;
794         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
795         NTSTATUS status;
796
797         status = rpc_ntsvcs_init(NULL);
798         if (!NT_STATUS_IS_OK(status)) {
799                 return false;
800         }
801
802         if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
803                 status = dcerpc_binding_vector_new(talloc_tos(), &v);
804                 if (!NT_STATUS_IS_OK(status)) {
805                         return false;
806                 }
807
808                 status = dcerpc_binding_vector_add_np_default(t, v);
809                 if (!NT_STATUS_IS_OK(status)) {
810                         return false;
811                 }
812
813                 status = rpc_ep_register(ev_ctx,
814                                          msg_ctx,
815                                          t,
816                                          v);
817                 if (!NT_STATUS_IS_OK(status)) {
818                         return false;
819                 }
820         }
821
822         return true;
823 }
824
825 static bool eventlog_init_cb(void *ptr)
826 {
827         struct messaging_context *msg_ctx =
828                 talloc_get_type_abort(ptr, struct messaging_context);
829         bool ok;
830
831         ok = eventlog_init_winreg(msg_ctx);
832         if (!ok) {
833                 return false;
834         }
835
836         return true;
837 }
838
839 static bool rpc_setup_eventlog(struct tevent_context *ev_ctx,
840                                struct messaging_context *msg_ctx)
841 {
842         const struct ndr_interface_table *t = &ndr_table_eventlog;
843         struct rpc_srv_callbacks eventlog_cb;
844         struct dcerpc_binding_vector *v;
845         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
846         NTSTATUS status;
847
848         eventlog_cb.init         = eventlog_init_cb;
849         eventlog_cb.shutdown     = NULL;
850         eventlog_cb.private_data = msg_ctx;
851
852         status = rpc_eventlog_init(&eventlog_cb);
853         if (!NT_STATUS_IS_OK(status)) {
854                 return false;
855         }
856
857         if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
858                 status = dcerpc_binding_vector_new(talloc_tos(), &v);
859                 if (!NT_STATUS_IS_OK(status)) {
860                         return false;
861                 }
862
863                 status = dcerpc_binding_vector_add_np_default(t, v);
864                 if (!NT_STATUS_IS_OK(status)) {
865                         return false;
866                 }
867
868                 status = rpc_ep_register(ev_ctx,
869                                          msg_ctx,
870                                          t,
871                                          v);
872                 if (!NT_STATUS_IS_OK(status)) {
873                         return false;
874                 }
875         }
876
877         return true;
878 }
879
880 static bool rpc_setup_initshutdown(struct tevent_context *ev_ctx,
881                                    struct messaging_context *msg_ctx)
882 {
883         const struct ndr_interface_table *t = &ndr_table_initshutdown;
884         struct dcerpc_binding_vector *v;
885         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
886         NTSTATUS status;
887
888         status = rpc_initshutdown_init(NULL);
889         if (!NT_STATUS_IS_OK(status)) {
890                 return false;
891         }
892
893         if (epm_mode != RPC_SERVICE_MODE_DISABLED) {
894                 status = dcerpc_binding_vector_new(talloc_tos(), &v);
895                 if (!NT_STATUS_IS_OK(status)) {
896                         return false;
897                 }
898
899                 status = dcerpc_binding_vector_add_np_default(t, v);
900                 if (!NT_STATUS_IS_OK(status)) {
901                         return false;
902                 }
903
904                 status = rpc_ep_register(ev_ctx,
905                                          msg_ctx,
906                                          t,
907                                          v);
908                 if (!NT_STATUS_IS_OK(status)) {
909                         return false;
910                 }
911         }
912
913         return true;
914 }
915
916 bool dcesrv_ep_setup(struct tevent_context *ev_ctx,
917                      struct messaging_context *msg_ctx)
918 {
919         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
920         struct dcerpc_binding_vector *v;
921         const char *rpcsrv_type;
922         TALLOC_CTX *tmp_ctx;
923         NTSTATUS status;
924         bool ok;
925
926         tmp_ctx = talloc_stackframe();
927         if (tmp_ctx == NULL) {
928                 return false;
929         }
930
931         status = dcerpc_binding_vector_new(tmp_ctx,
932                                            &v);
933         if (!NT_STATUS_IS_OK(status)) {
934                 ok = false;
935                 goto done;
936         }
937
938         ok = rpc_setup_epmapper(ev_ctx, msg_ctx);
939         if (!ok) {
940                 goto done;
941         }
942
943         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
944                                            "rpc_server",
945                                            "tcpip",
946                                            "no");
947
948         if ((strcasecmp_m(rpcsrv_type, "yes") == 0 ||
949              strcasecmp_m(rpcsrv_type, "true") == 0)
950             && epm_mode != RPC_SERVICE_MODE_DISABLED) {
951                 status = rpc_setup_tcpip_sockets(ev_ctx,
952                                                  msg_ctx,
953                                                  &ndr_table_winreg,
954                                                  v,
955                                                  0);
956                 if (!NT_STATUS_IS_OK(status)) {
957                         ok = false;
958                         goto done;
959                 }
960         }
961
962         ok = rpc_setup_winreg(ev_ctx, msg_ctx, v);
963         if (!ok) {
964                 goto done;
965         }
966
967         ok = rpc_setup_srvsvc(ev_ctx, msg_ctx, v);
968         if (!ok) {
969                 goto done;
970         }
971
972         ok = rpc_setup_lsarpc(ev_ctx, msg_ctx, v);
973         if (!ok) {
974                 goto done;
975         }
976
977         ok = rpc_setup_samr(ev_ctx, msg_ctx, v);
978         if (!ok) {
979                 goto done;
980         }
981
982         ok = rpc_setup_netlogon(ev_ctx, msg_ctx, v);
983         if (!ok) {
984                 goto done;
985         }
986
987         ok = rpc_setup_netdfs(ev_ctx, msg_ctx, v);
988         if (!ok) {
989                 goto done;
990         }
991
992 #ifdef DEVELOPER
993         ok = rpc_setup_rpcecho(ev_ctx, msg_ctx, v);
994         if (!ok) {
995                 goto done;
996         }
997 #endif
998
999         ok = rpc_setup_dssetup(ev_ctx, msg_ctx, v);
1000         if (!ok) {
1001                 goto done;
1002         }
1003
1004         ok = rpc_setup_wkssvc(ev_ctx, msg_ctx, v);
1005         if (!ok) {
1006                 goto done;
1007         }
1008
1009         ok = rpc_setup_spoolss(ev_ctx, msg_ctx);
1010         if (!ok) {
1011                 goto done;
1012         }
1013
1014         ok = rpc_setup_svcctl(ev_ctx, msg_ctx);
1015         if (!ok) {
1016                 goto done;
1017         }
1018
1019         ok = rpc_setup_ntsvcs(ev_ctx, msg_ctx);
1020         if (!ok) {
1021                 goto done;
1022         }
1023
1024         ok = rpc_setup_eventlog(ev_ctx, msg_ctx);
1025         if (!ok) {
1026                 goto done;
1027         }
1028
1029         ok = rpc_setup_initshutdown(ev_ctx, msg_ctx);
1030         if (!ok) {
1031                 goto done;
1032         }
1033
1034 done:
1035         talloc_free(tmp_ctx);
1036         return ok;
1037 }
1038
1039 /* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */