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