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