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