s3-rpc_server: Added disconnect callback function.
[idra/samba.git] / source3 / rpc_server / rpc_ep_setup.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *
4  *  SMBD RPC service callbacks
5  *
6  *  Copyright (c) 2011      Andreas Schneider <asn@samba.org>
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 3 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "includes.h"
23
24 #include "../librpc/gen_ndr/ndr_epmapper_c.h"
25 #include "../librpc/gen_ndr/srv_epmapper.h"
26 #include "../librpc/gen_ndr/srv_srvsvc.h"
27 #include "../librpc/gen_ndr/srv_winreg.h"
28 #include "../librpc/gen_ndr/srv_dfs.h"
29 #include "../librpc/gen_ndr/srv_dssetup.h"
30 #include "../librpc/gen_ndr/srv_echo.h"
31 #include "../librpc/gen_ndr/srv_eventlog.h"
32 #include "../librpc/gen_ndr/srv_initshutdown.h"
33 #include "../librpc/gen_ndr/srv_lsa.h"
34 #include "../librpc/gen_ndr/srv_netlogon.h"
35 #include "../librpc/gen_ndr/srv_ntsvcs.h"
36 #include "../librpc/gen_ndr/srv_samr.h"
37 #include "../librpc/gen_ndr/srv_spoolss.h"
38 #include "../librpc/gen_ndr/srv_svcctl.h"
39 #include "../librpc/gen_ndr/srv_wkssvc.h"
40
41 #include "printing/nt_printing_migrate.h"
42 #include "rpc_server/eventlog/srv_eventlog_reg.h"
43 #include "rpc_server/svcctl/srv_svcctl_reg.h"
44
45 #include "librpc/rpc/dcerpc_ep.h"
46
47 #include "rpc_server/rpc_ep_setup.h"
48 #include "rpc_server/rpc_server.h"
49 #include "rpc_server/epmapper/srv_epmapper.h"
50
51 struct dcesrv_ep_context {
52         struct tevent_context *ev_ctx;
53         struct messaging_context *msg_ctx;
54 };
55
56 static uint16_t _open_sockets(struct tevent_context *ev_ctx,
57                               struct messaging_context *msg_ctx,
58                               struct ndr_syntax_id syntax_id,
59                               uint16_t port)
60 {
61         uint32_t num_ifs = iface_count();
62         uint32_t i;
63         uint16_t p = 0;
64
65         if (lp_interfaces() && lp_bind_interfaces_only()) {
66                 /*
67                  * We have been given an interfaces line, and been told to only
68                  * bind to those interfaces. Create a socket per interface and
69                  * bind to only these.
70                  */
71
72                 /* Now open a listen socket for each of the interfaces. */
73                 for(i = 0; i < num_ifs; i++) {
74                         const struct sockaddr_storage *ifss =
75                                         iface_n_sockaddr_storage(i);
76
77                         p = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
78                                                             msg_ctx,
79                                                             syntax_id,
80                                                             ifss,
81                                                             port);
82                         if (p == 0) {
83                                 return 0;
84                         }
85                         port = p;
86                 }
87         } else {
88                 const char *sock_addr = lp_socket_address();
89                 const char *sock_ptr;
90                 char *sock_tok;
91
92                 if (strequal(sock_addr, "0.0.0.0") ||
93                     strequal(sock_addr, "::")) {
94 #if HAVE_IPV6
95                         sock_addr = "::";
96 #else
97                         sock_addr = "0.0.0.0";
98 #endif
99                 }
100
101                 for (sock_ptr = sock_addr;
102                      next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,");
103                     ) {
104                         struct sockaddr_storage ss;
105
106                         /* open an incoming socket */
107                         if (!interpret_string_addr(&ss,
108                                                    sock_tok,
109                                                    AI_NUMERICHOST|AI_PASSIVE)) {
110                                 continue;
111                         }
112
113                         p = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
114                                                             msg_ctx,
115                                                             syntax_id,
116                                                             &ss,
117                                                             port);
118                         if (p == 0) {
119                                 return 0;
120                         }
121                         port = p;
122                 }
123         }
124
125         return p;
126 }
127
128 static NTSTATUS _rpc_ep_unregister(const struct ndr_interface_table *iface)
129 {
130         struct dcerpc_binding_vector *v = NULL;
131         NTSTATUS status;
132
133         status = dcerpc_binding_vector_create(talloc_tos(),
134                                               iface,
135                                               0,
136                                               NULL,
137                                               &v);
138         if (!NT_STATUS_IS_OK(status)) {
139                 return status;
140         }
141
142         status = dcerpc_ep_unregister(iface,
143                                       v,
144                                       &iface->syntax_id.uuid);
145         if (!NT_STATUS_IS_OK(status)) {
146                 return status;
147         }
148
149         return status;
150 }
151
152 static void rpc_ep_setup_register_loop(struct tevent_req *subreq);
153 static NTSTATUS rpc_ep_setup_try_register(TALLOC_CTX *mem_ctx,
154                                           struct tevent_context *ev_ctx,
155                                           struct messaging_context *msg_ctx,
156                                           const struct ndr_interface_table *iface,
157                                           const char *name,
158                                           uint16_t port,
159                                           struct dcerpc_binding_handle **pbh);
160
161 struct rpc_ep_regsiter_state {
162         struct dcerpc_binding_handle *h;
163
164         TALLOC_CTX *mem_ctx;
165         struct tevent_context *ev_ctx;
166         struct messaging_context *msg_ctx;
167
168         const struct ndr_interface_table *iface;
169
170         const char *ncalrpc;
171         uint16_t port;
172
173         uint32_t wait_time;
174 };
175
176 static NTSTATUS rpc_ep_setup_register(struct tevent_context *ev_ctx,
177                                       struct messaging_context *msg_ctx,
178                                       const struct ndr_interface_table *iface,
179                                       const char *ncalrpc,
180                                       uint16_t port)
181 {
182         struct rpc_ep_regsiter_state *state;
183         struct tevent_req *req;
184
185         state = talloc(ev_ctx, struct rpc_ep_regsiter_state);
186         if (state == NULL) {
187                 return NT_STATUS_NO_MEMORY;
188         }
189
190         state->mem_ctx = talloc_named(state,
191                                       0,
192                                       "ep %s %p",
193                                       iface->name, state);
194         if (state->mem_ctx == NULL) {
195                 talloc_free(state);
196                 return NT_STATUS_NO_MEMORY;
197         }
198
199         state->wait_time = 1;
200         state->ev_ctx = ev_ctx;
201         state->msg_ctx = msg_ctx;
202         state->iface = iface;
203         state->ncalrpc = talloc_strdup(state, ncalrpc);
204         state->port = port;
205
206         req = tevent_wakeup_send(state->mem_ctx,
207                                  state->ev_ctx,
208                                  timeval_current_ofs(1, 0));
209         if (tevent_req_nomem(state->mem_ctx, req)) {
210                 talloc_free(state);
211                 return NT_STATUS_NO_MEMORY;
212         }
213
214         tevent_req_set_callback(req, rpc_ep_setup_register_loop, state);
215
216         return NT_STATUS_OK;
217 }
218
219 #define MONITOR_WAIT_TIME 15
220 static void rpc_ep_setup_monitor_loop(struct tevent_req *subreq);
221
222 static void rpc_ep_setup_register_loop(struct tevent_req *subreq)
223 {
224         struct rpc_ep_regsiter_state *state =
225                 tevent_req_callback_data(subreq, struct rpc_ep_regsiter_state);
226         NTSTATUS status;
227         bool ok;
228
229         ok = tevent_wakeup_recv(subreq);
230         TALLOC_FREE(subreq);
231         if (!ok) {
232                 talloc_free(state);
233                 return;
234         }
235
236         status = rpc_ep_setup_try_register(state->mem_ctx,
237                                            state->ev_ctx,
238                                            state->msg_ctx,
239                                            state->iface,
240                                            state->ncalrpc,
241                                            state->port,
242                                            &state->h);
243         if (NT_STATUS_IS_OK(status)) {
244                 /* endpoint registered, monitor the connnection. */
245                 subreq = tevent_wakeup_send(state->mem_ctx,
246                                             state->ev_ctx,
247                                             timeval_current_ofs(MONITOR_WAIT_TIME, 0));
248                 if (tevent_req_nomem(state->mem_ctx, subreq)) {
249                         talloc_free(state);
250                         return;
251                 }
252
253                 tevent_req_set_callback(subreq, rpc_ep_setup_monitor_loop, state);
254                 return;
255         }
256
257         state->wait_time = state->wait_time * 2;
258         if (state->wait_time > 16) {
259                 talloc_free(state);
260                 return;
261         }
262
263         subreq = tevent_wakeup_send(state->mem_ctx,
264                                     state->ev_ctx,
265                                     timeval_current_ofs(state->wait_time, 0));
266         if (tevent_req_nomem(state->mem_ctx, subreq)) {
267                 talloc_free(state);
268                 return;
269         }
270
271         tevent_req_set_callback(subreq, rpc_ep_setup_register_loop, state);
272         return;
273 }
274
275 static NTSTATUS rpc_ep_setup_try_register(TALLOC_CTX *mem_ctx,
276                                           struct tevent_context *ev_ctx,
277                                           struct messaging_context *msg_ctx,
278                                           const struct ndr_interface_table *iface,
279                                           const char *name,
280                                           uint16_t port,
281                                           struct dcerpc_binding_handle **pbh)
282 {
283         struct dcerpc_binding_vector *v = NULL;
284         NTSTATUS status;
285
286         status = dcerpc_binding_vector_create(mem_ctx,
287                                               iface,
288                                               port,
289                                               name,
290                                               &v);
291         if (!NT_STATUS_IS_OK(status)) {
292                 return status;
293         }
294
295         status = dcerpc_ep_register(mem_ctx,
296                                     iface,
297                                     v,
298                                     &iface->syntax_id.uuid,
299                                     name,
300                                     pbh);
301         talloc_free(v);
302         if (!NT_STATUS_IS_OK(status)) {
303                 return status;
304         }
305
306         return status;
307 }
308
309 /*
310  * Monitor the connection to the endpoint mapper and if it goes away, try to
311  * register the endpoint.
312  */
313 static void rpc_ep_setup_monitor_loop(struct tevent_req *subreq)
314 {
315         struct rpc_ep_regsiter_state *state =
316                 tevent_req_callback_data(subreq, struct rpc_ep_regsiter_state);
317         struct policy_handle entry_handle;
318         struct dcerpc_binding map_binding;
319         struct epm_twr_p_t towers[10];
320         struct epm_twr_t *map_tower;
321         uint32_t num_towers = 0;
322         struct GUID object;
323         NTSTATUS status;
324         uint32_t result = EPMAPPER_STATUS_CANT_PERFORM_OP;
325         TALLOC_CTX *tmp_ctx;
326         bool ok;
327
328         ZERO_STRUCT(object);
329         ZERO_STRUCT(entry_handle);
330
331         tmp_ctx = talloc_stackframe();
332         if (tmp_ctx == NULL) {
333                 talloc_free(state);
334                 return;
335         }
336
337         ok = tevent_wakeup_recv(subreq);
338         TALLOC_FREE(subreq);
339         if (!ok) {
340                 talloc_free(state);
341                 return;
342         }
343
344         /* Create map tower */
345         map_binding.transport = NCACN_NP;
346         map_binding.object = state->iface->syntax_id;
347         map_binding.host = "";
348         map_binding.endpoint = "";
349
350         map_tower = talloc_zero(tmp_ctx, struct epm_twr_t);
351         if (map_tower == NULL) {
352                 talloc_free(tmp_ctx);
353                 talloc_free(state);
354                 return;
355         }
356
357         status = dcerpc_binding_build_tower(map_tower, &map_binding,
358                                             &map_tower->tower);
359         if (!NT_STATUS_IS_OK(status)) {
360                 talloc_free(tmp_ctx);
361                 talloc_free(state);
362                 return;
363         }
364
365         ok = false;
366         status = dcerpc_epm_Map(state->h,
367                                 tmp_ctx,
368                                 &object,
369                                 map_tower,
370                                 &entry_handle,
371                                 10,
372                                 &num_towers,
373                                 towers,
374                                 &result);
375         if (NT_STATUS_IS_OK(status)) {
376                 ok = true;
377         }
378         if (result == EPMAPPER_STATUS_OK ||
379             result == EPMAPPER_STATUS_NO_MORE_ENTRIES) {
380                 ok = true;
381         }
382         if (num_towers == 0) {
383                 ok = false;
384         }
385
386         talloc_free(tmp_ctx);
387
388         subreq = tevent_wakeup_send(state->mem_ctx,
389                                     state->ev_ctx,
390                                     timeval_current_ofs(MONITOR_WAIT_TIME, 0));
391         if (tevent_req_nomem(state->mem_ctx, subreq)) {
392                 talloc_free(state);
393                 return;
394         }
395
396         if (ok) {
397                 tevent_req_set_callback(subreq, rpc_ep_setup_monitor_loop, state);
398         } else {
399                 TALLOC_FREE(state->h);
400                 state->wait_time = 1;
401
402                 tevent_req_set_callback(subreq, rpc_ep_setup_register_loop, state);
403         }
404
405         return;
406 }
407
408 static bool epmapper_init_cb(void *ptr)
409 {
410         struct dcesrv_ep_context *ep_ctx =
411                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
412         uint16_t port;
413
414         port = _open_sockets(ep_ctx->ev_ctx,
415                              ep_ctx->msg_ctx,
416                              ndr_table_epmapper.syntax_id,
417                              135);
418         if (port == 135) {
419                 return true;
420         }
421
422         return false;
423 }
424
425 static bool epmapper_shutdown_cb(void *ptr)
426 {
427         srv_epmapper_cleanup();
428
429         return true;
430 }
431
432 static bool winreg_init_cb(void *ptr)
433 {
434         struct dcesrv_ep_context *ep_ctx =
435                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
436         struct ndr_syntax_id abstract_syntax = ndr_table_winreg.syntax_id;
437         const char *pipe_name = "winreg";
438         const char *rpcsrv_type;
439         uint16_t port;
440
441         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
442                                            "rpc_server",
443                                            "epmapper",
444                                            "none");
445
446         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
447             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
448                 NTSTATUS status;
449                 bool ok;
450
451                 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
452                                                  ep_ctx->msg_ctx,
453                                                  abstract_syntax,
454                                                  pipe_name,
455                                                  NULL);
456                 if (!ok) {
457                         return false;
458                 }
459                 port = _open_sockets(ep_ctx->ev_ctx,
460                                      ep_ctx->msg_ctx,
461                                      abstract_syntax,
462                                      0);
463                 if (port == 0) {
464                         return false;
465                 }
466
467                 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
468                                                 ep_ctx->msg_ctx,
469                                                 &ndr_table_winreg,
470                                                 pipe_name,
471                                                 port);
472                 if (!NT_STATUS_IS_OK(status)) {
473                         return false;
474                 }
475         }
476
477         return true;
478 }
479
480 static bool winreg_shutdown_cb(void *ptr)
481 {
482         const char *rpcsrv_type;
483
484         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
485                                            "rpc_server",
486                                            "epmapper",
487                                            "none");
488
489         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
490             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
491                 NTSTATUS status;
492
493                 status = _rpc_ep_unregister(&ndr_table_winreg);
494                 if (!NT_STATUS_IS_OK(status)) {
495                         return false;
496                 }
497         }
498
499         return true;
500 }
501
502 static bool srvsvc_init_cb(void *ptr)
503 {
504         struct dcesrv_ep_context *ep_ctx =
505                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
506         struct ndr_syntax_id abstract_syntax = ndr_table_srvsvc.syntax_id;
507         const char *pipe_name = "srvsvc";
508         const char *rpcsrv_type;
509         uint16_t port;
510
511         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
512                                            "rpc_server",
513                                            "epmapper",
514                                            "none");
515
516         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
517             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
518                 NTSTATUS status;
519                 bool ok;
520
521                 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
522                                                  ep_ctx->msg_ctx,
523                                                  abstract_syntax,
524                                                  pipe_name,
525                                                  NULL);
526                 if (!ok) {
527                         return false;
528                 }
529
530                 port = _open_sockets(ep_ctx->ev_ctx,
531                                      ep_ctx->msg_ctx,
532                                      abstract_syntax,
533                                      0);
534                 if (port == 0) {
535                         return false;
536                 }
537
538                 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
539                                           ep_ctx->msg_ctx,
540                                           &ndr_table_srvsvc,
541                                           pipe_name,
542                                           port);
543                 if (!NT_STATUS_IS_OK(status)) {
544                         return false;
545                 }
546         }
547
548         return true;
549 }
550
551 static bool srvsvc_shutdown_cb(void *ptr)
552 {
553         const char *rpcsrv_type;
554
555         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
556                                            "rpc_server",
557                                            "epmapper",
558                                            "none");
559
560         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
561             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
562                 NTSTATUS status;
563
564                 status =_rpc_ep_unregister(&ndr_table_srvsvc);
565                 if (!NT_STATUS_IS_OK(status)) {
566                         return false;
567                 }
568         }
569
570         return true;
571 }
572
573 static bool lsarpc_init_cb(void *ptr)
574 {
575         struct dcesrv_ep_context *ep_ctx =
576                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
577         struct ndr_syntax_id abstract_syntax = ndr_table_lsarpc.syntax_id;
578         const char *pipe_name = "lsarpc";
579         const char *rpcsrv_type;
580         uint16_t port;
581
582         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
583                                            "rpc_server",
584                                            "epmapper",
585                                            "none");
586
587         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
588             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
589                 NTSTATUS status;
590                 bool ok;
591
592                 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
593                                                  ep_ctx->msg_ctx,
594                                                  abstract_syntax,
595                                                  pipe_name,
596                                                  NULL);
597                 if (!ok) {
598                         return false;
599                 }
600
601                 port = _open_sockets(ep_ctx->ev_ctx,
602                                      ep_ctx->msg_ctx,
603                                      abstract_syntax,
604                                      0);
605                 if (port == 0) {
606                         return false;
607                 }
608
609                 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
610                                           ep_ctx->msg_ctx,
611                                           &ndr_table_lsarpc,
612                                           pipe_name,
613                                           port);
614                 if (!NT_STATUS_IS_OK(status)) {
615                         return false;
616                 }
617         }
618
619         return true;
620 }
621
622 static bool lsarpc_shutdown_cb(void *ptr)
623 {
624         const char *rpcsrv_type;
625
626         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
627                                            "rpc_server",
628                                            "epmapper",
629                                            "none");
630
631         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
632             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
633                 NTSTATUS status;
634
635                 status = _rpc_ep_unregister(&ndr_table_lsarpc);
636                 if (!NT_STATUS_IS_OK(status)) {
637                         return false;
638                 }
639         }
640
641         return true;
642 }
643
644 static bool samr_init_cb(void *ptr)
645 {
646         struct dcesrv_ep_context *ep_ctx =
647                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
648         struct ndr_syntax_id abstract_syntax = ndr_table_samr.syntax_id;
649         const char *pipe_name = "samr";
650         const char *rpcsrv_type;
651         uint16_t port;
652
653         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
654                                            "rpc_server",
655                                            "epmapper",
656                                            "none");
657
658         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
659             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
660                 NTSTATUS status;
661                 bool ok;
662
663                 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
664                                                  ep_ctx->msg_ctx,
665                                                  abstract_syntax,
666                                                  pipe_name,
667                                                  NULL);
668                 if (!ok) {
669                         return false;
670                 }
671
672                 port = _open_sockets(ep_ctx->ev_ctx,
673                                      ep_ctx->msg_ctx,
674                                      abstract_syntax,
675                                      0);
676                 if (port == 0) {
677                         return false;
678                 }
679
680                 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
681                                           ep_ctx->msg_ctx,
682                                           &ndr_table_samr,
683                                           pipe_name,
684                                           port);
685                 if (!NT_STATUS_IS_OK(status)) {
686                         return false;
687                 }
688         }
689
690         return true;
691 }
692
693 static bool samr_shutdown_cb(void *ptr)
694 {
695         const char *rpcsrv_type;
696
697         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
698                                            "rpc_server",
699                                            "epmapper",
700                                            "none");
701
702         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
703             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
704                 NTSTATUS status;
705
706                 status = _rpc_ep_unregister(&ndr_table_samr);
707                 if (!NT_STATUS_IS_OK(status)) {
708                         return false;
709                 }
710         }
711
712         return true;
713 }
714
715 static bool netlogon_init_cb(void *ptr)
716 {
717         struct dcesrv_ep_context *ep_ctx =
718                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
719         struct ndr_syntax_id abstract_syntax = ndr_table_netlogon.syntax_id;
720         const char *pipe_name = "netlogon";
721         const char *rpcsrv_type;
722         uint16_t port;
723
724         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
725                                            "rpc_server",
726                                            "epmapper",
727                                            "none");
728
729         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
730             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
731                 NTSTATUS status;
732                 bool ok;
733
734                 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
735                                                  ep_ctx->msg_ctx,
736                                                  abstract_syntax,
737                                                  pipe_name,
738                                                  NULL);
739                 if (!ok) {
740                         return false;
741                 }
742
743                 port = _open_sockets(ep_ctx->ev_ctx,
744                                      ep_ctx->msg_ctx,
745                                      abstract_syntax,
746                                      0);
747                 if (port == 0) {
748                         return false;
749                 }
750
751                 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
752                                           ep_ctx->msg_ctx,
753                                           &ndr_table_netlogon,
754                                           pipe_name,
755                                           port);
756                 if (!NT_STATUS_IS_OK(status)) {
757                         return false;
758                 }
759         }
760
761         return true;
762 }
763
764 static bool netlogon_shutdown_cb(void *ptr)
765 {
766         const char *rpcsrv_type;
767
768         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
769                                            "rpc_server",
770                                            "epmapper",
771                                            "none");
772
773         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
774             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
775                 NTSTATUS status;
776
777                 status = _rpc_ep_unregister(&ndr_table_netlogon);
778                 if (!NT_STATUS_IS_OK(status)) {
779                         return false;
780                 }
781         }
782
783         return true;
784 }
785
786 static bool spoolss_init_cb(void *ptr)
787 {
788         struct dcesrv_ep_context *ep_ctx =
789                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
790         const char *rpcsrv_type;
791         bool ok;
792
793         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
794                                            "rpc_server",
795                                            "epmapper",
796                                            "none");
797
798         /*
799          * Migrate the printers first.
800          */
801         ok = nt_printing_tdb_migrate(ep_ctx->msg_ctx);
802         if (!ok) {
803                 return false;
804         }
805
806         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
807             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
808                 NTSTATUS status;
809
810                 status =rpc_ep_setup_register(ep_ctx->ev_ctx,
811                                          ep_ctx->msg_ctx,
812                                          &ndr_table_spoolss,
813                                          "spoolss",
814                                          0);
815                 if (!NT_STATUS_IS_OK(status)) {
816                         return false;
817                 }
818         }
819
820         return true;
821 }
822
823 static bool spoolss_shutdown_cb(void *ptr)
824 {
825         const char *rpcsrv_type;
826
827         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
828                                            "rpc_server",
829                                            "epmapper",
830                                            "none");
831
832         srv_spoolss_cleanup();
833
834         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
835             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
836                 NTSTATUS status;
837
838                 status = _rpc_ep_unregister(&ndr_table_spoolss);
839                 if (!NT_STATUS_IS_OK(status)) {
840                         return false;
841                 }
842         }
843
844         return true;
845 }
846
847 static bool svcctl_init_cb(void *ptr)
848 {
849         struct dcesrv_ep_context *ep_ctx =
850                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
851         const char *rpcsrv_type;
852         bool ok;
853
854         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
855                                            "rpc_server",
856                                            "epmapper",
857                                            "none");
858
859         ok = svcctl_init_winreg(ep_ctx->msg_ctx);
860         if (!ok) {
861                 return false;
862         }
863
864         /* initialize the control hooks */
865         init_service_op_table();
866
867         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
868             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
869                 NTSTATUS status;
870
871                 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
872                                           ep_ctx->msg_ctx,
873                                           &ndr_table_svcctl,
874                                           "svcctl",
875                                           0);
876                 if (!NT_STATUS_IS_OK(status)) {
877                         return false;
878                 }
879         }
880
881         return true;
882 }
883
884 static bool svcctl_shutdown_cb(void *ptr)
885 {
886         const char *rpcsrv_type;
887
888         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
889                                            "rpc_server",
890                                            "epmapper",
891                                            "none");
892         shutdown_service_op_table();
893
894         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
895             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
896                 NTSTATUS status;
897
898                 status = _rpc_ep_unregister(&ndr_table_svcctl);
899                 if (!NT_STATUS_IS_OK(status)) {
900                         return false;
901                 }
902         }
903
904         return true;
905 }
906
907 static bool ntsvcs_init_cb(void *ptr)
908 {
909         struct dcesrv_ep_context *ep_ctx =
910                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
911         const char *rpcsrv_type;
912
913         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
914                                            "rpc_server",
915                                            "epmapper",
916                                            "none");
917
918         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
919             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
920                 NTSTATUS status;
921
922                 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
923                                           ep_ctx->msg_ctx,
924                                           &ndr_table_ntsvcs,
925                                           "ntsvcs",
926                                           0);
927                 if (!NT_STATUS_IS_OK(status)) {
928                         return false;
929                 }
930         }
931
932         return true;
933 }
934
935 static bool ntsvcs_shutdown_cb(void *ptr)
936 {
937         const char *rpcsrv_type;
938
939         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
940                                            "rpc_server",
941                                            "epmapper",
942                                            "none");
943
944         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
945             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
946                 NTSTATUS status;
947
948                 status = _rpc_ep_unregister(&ndr_table_ntsvcs);
949                 if (!NT_STATUS_IS_OK(status)) {
950                         return false;
951                 }
952         }
953
954         return true;
955 }
956
957 static bool eventlog_init_cb(void *ptr)
958 {
959         struct dcesrv_ep_context *ep_ctx =
960                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
961         const char *rpcsrv_type;
962         bool ok;
963
964         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
965                                            "rpc_server",
966                                            "epmapper",
967                                            "none");
968
969         ok = eventlog_init_winreg(ep_ctx->msg_ctx);
970         if (!ok) {
971                 return false;
972         }
973
974         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
975             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
976                 NTSTATUS status;
977
978                 status =rpc_ep_setup_register(ep_ctx->ev_ctx,
979                                          ep_ctx->msg_ctx,
980                                          &ndr_table_eventlog,
981                                          "eventlog",
982                                          0);
983                 if (!NT_STATUS_IS_OK(status)) {
984                         return false;
985                 }
986         }
987
988         return true;
989 }
990
991 static bool eventlog_shutdown_cb(void *ptr)
992 {
993         const char *rpcsrv_type;
994
995         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
996                                            "rpc_server",
997                                            "epmapper",
998                                            "none");
999
1000         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
1001             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
1002                 NTSTATUS status;
1003
1004                 status = _rpc_ep_unregister(&ndr_table_eventlog);
1005                 if (!NT_STATUS_IS_OK(status)) {
1006                         return false;
1007                 }
1008         }
1009
1010         return true;
1011 }
1012
1013 static bool initshutdown_init_cb(void *ptr)
1014 {
1015         struct dcesrv_ep_context *ep_ctx =
1016                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
1017         const char *rpcsrv_type;
1018
1019         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1020                                            "rpc_server",
1021                                            "epmapper",
1022                                            "none");
1023
1024         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
1025             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
1026                 NTSTATUS status;
1027
1028                 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
1029                                           ep_ctx->msg_ctx,
1030                                           &ndr_table_initshutdown,
1031                                           "initshutdown",
1032                                           0);
1033                 if (!NT_STATUS_IS_OK(status)) {
1034                         return false;
1035                 }
1036         }
1037
1038         return true;
1039 }
1040
1041 static bool initshutdown_shutdown_cb(void *ptr)
1042 {
1043         const char *rpcsrv_type;
1044
1045         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1046                                            "rpc_server",
1047                                            "epmapper",
1048                                            "none");
1049
1050         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
1051             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
1052                 NTSTATUS status;
1053
1054                 status = _rpc_ep_unregister(&ndr_table_initshutdown);
1055                 if (!NT_STATUS_IS_OK(status)) {
1056                         return false;
1057                 }
1058         }
1059
1060         return true;
1061 }
1062
1063 #ifdef DEVELOPER
1064 static bool rpcecho_init_cb(void *ptr) {
1065         struct dcesrv_ep_context *ep_ctx =
1066                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
1067         const char *rpcsrv_type;
1068         uint16_t port;
1069
1070         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1071                                            "rpc_server",
1072                                            "epmapper",
1073                                            "none");
1074
1075         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
1076             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
1077                 NTSTATUS status;
1078
1079                 port = _open_sockets(ep_ctx->ev_ctx,
1080                                      ep_ctx->msg_ctx,
1081                                      ndr_table_rpcecho.syntax_id,
1082                                      0);
1083                 if (port == 0) {
1084                         return false;
1085                 }
1086
1087                 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
1088                                           ep_ctx->msg_ctx,
1089                                           &ndr_table_rpcecho,
1090                                           "rpcecho",
1091                                           port);
1092                 if (!NT_STATUS_IS_OK(status)) {
1093                         return false;
1094                 }
1095         }
1096
1097         return true;
1098 }
1099
1100 static bool rpcecho_shutdown_cb(void *ptr)
1101 {
1102         const char *rpcsrv_type;
1103
1104         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1105                                            "rpc_server",
1106                                            "epmapper",
1107                                            "none");
1108
1109         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
1110             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
1111                 NTSTATUS status;
1112
1113                 status = _rpc_ep_unregister(&ndr_table_rpcecho);
1114                 if (!NT_STATUS_IS_OK(status)) {
1115                         return false;
1116                 }
1117         }
1118
1119         return true;
1120 }
1121 #endif
1122
1123 static bool netdfs_init_cb(void *ptr)
1124 {
1125         struct dcesrv_ep_context *ep_ctx =
1126                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
1127         struct ndr_syntax_id abstract_syntax = ndr_table_netdfs.syntax_id;
1128         const char *pipe_name = "netdfs";
1129         const char *rpcsrv_type;
1130         uint16_t port;
1131
1132         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1133                                            "rpc_server",
1134                                            "epmapper",
1135                                            "none");
1136         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
1137             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
1138                 NTSTATUS status;
1139                 bool ok;
1140
1141                 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
1142                                                  ep_ctx->msg_ctx,
1143                                                  abstract_syntax,
1144                                                  pipe_name,
1145                                                  NULL);
1146                 if (!ok) {
1147                         return false;
1148                 }
1149
1150                 port = _open_sockets(ep_ctx->ev_ctx,
1151                                      ep_ctx->msg_ctx,
1152                                      abstract_syntax,
1153                                      0);
1154                 if (port == 0) {
1155                         return false;
1156                 }
1157
1158                 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
1159                                           ep_ctx->msg_ctx,
1160                                           &ndr_table_netdfs,
1161                                           pipe_name,
1162                                           port);
1163                 if (!NT_STATUS_IS_OK(status)) {
1164                         return false;
1165                 }
1166         }
1167
1168         return true;
1169 }
1170
1171 static bool netdfs_shutdown_cb(void *ptr) {
1172         const char *rpcsrv_type;
1173
1174         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1175                                            "rpc_server",
1176                                            "epmapper",
1177                                            "none");
1178
1179         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
1180             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
1181                 NTSTATUS status;
1182
1183                 status = _rpc_ep_unregister(&ndr_table_netdfs);
1184                 if (!NT_STATUS_IS_OK(status)) {
1185                         return false;
1186                 }
1187         }
1188
1189         return true;
1190 }
1191
1192 static bool dssetup_init_cb(void *ptr)
1193 {
1194         struct dcesrv_ep_context *ep_ctx =
1195                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
1196         struct ndr_syntax_id abstract_syntax = ndr_table_dssetup.syntax_id;
1197         const char *pipe_name = "dssetup";
1198         const char *rpcsrv_type;
1199         uint16_t port;
1200
1201         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1202                                            "rpc_server",
1203                                            "epmapper",
1204                                            "none");
1205
1206         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
1207             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
1208                 NTSTATUS status;
1209                 bool ok;
1210
1211                 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
1212                                                  ep_ctx->msg_ctx,
1213                                                  abstract_syntax,
1214                                                  pipe_name,
1215                                                  NULL);
1216                 if (!ok) {
1217                         return false;
1218                 }
1219
1220                 port = _open_sockets(ep_ctx->ev_ctx,
1221                                      ep_ctx->msg_ctx,
1222                                      abstract_syntax,
1223                                      0);
1224                 if (port == 0) {
1225                         return false;
1226                 }
1227
1228                 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
1229                                           ep_ctx->msg_ctx,
1230                                           &ndr_table_dssetup,
1231                                           "dssetup",
1232                                           port);
1233                 if (!NT_STATUS_IS_OK(status)) {
1234                         return false;
1235                 }
1236         }
1237
1238         return true;
1239 }
1240
1241 static bool dssetup_shutdown_cb(void *ptr) {
1242         const char *rpcsrv_type;
1243
1244         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1245                                            "rpc_server",
1246                                            "epmapper",
1247                                            "none");
1248
1249         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
1250             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
1251                 NTSTATUS status;
1252
1253                 status = _rpc_ep_unregister(&ndr_table_dssetup);
1254                 if (!NT_STATUS_IS_OK(status)) {
1255                         return false;
1256                 }
1257         }
1258
1259         return true;
1260 }
1261
1262 static bool wkssvc_init_cb(void *ptr)
1263 {
1264         struct dcesrv_ep_context *ep_ctx =
1265                 talloc_get_type_abort(ptr, struct dcesrv_ep_context);
1266         struct ndr_syntax_id abstract_syntax = ndr_table_wkssvc.syntax_id;
1267         const char *pipe_name = "wkssvc";
1268         const char *rpcsrv_type;
1269         uint16_t port;
1270
1271         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1272                                            "rpc_server",
1273                                            "epmapper",
1274                                            "none");
1275         if (StrCaseCmp(rpcsrv_type, "embedded") == 0 ||
1276             StrCaseCmp(rpcsrv_type, "daemon") == 0) {
1277                 NTSTATUS status;
1278                 bool ok;
1279
1280                 ok = setup_dcerpc_ncalrpc_socket(ep_ctx->ev_ctx,
1281                                                  ep_ctx->msg_ctx,
1282                                                  abstract_syntax,
1283                                                  pipe_name,
1284                                                  NULL);
1285                 if (!ok) {
1286                         return false;
1287                 }
1288
1289                 port = _open_sockets(ep_ctx->ev_ctx,
1290                                      ep_ctx->msg_ctx,
1291                                      abstract_syntax,
1292                                      0);
1293                 if (port == 0) {
1294                         return false;
1295                 }
1296
1297                 status = rpc_ep_setup_register(ep_ctx->ev_ctx,
1298                                           ep_ctx->msg_ctx,
1299                                           &ndr_table_wkssvc,
1300                                           "wkssvc",
1301                                           port);
1302                 if (!NT_STATUS_IS_OK(status)) {
1303                         return false;
1304                 }
1305         }
1306
1307         return true;
1308 }
1309
1310 static bool wkssvc_shutdown_cb(void *ptr) {
1311         return NT_STATUS_IS_OK(_rpc_ep_unregister(&ndr_table_wkssvc));
1312 }
1313
1314 bool dcesrv_ep_setup(struct tevent_context *ev_ctx,
1315                      struct messaging_context *msg_ctx)
1316 {
1317         struct dcesrv_ep_context *ep_ctx;
1318
1319         struct rpc_srv_callbacks epmapper_cb;
1320
1321         struct rpc_srv_callbacks winreg_cb;
1322         struct rpc_srv_callbacks srvsvc_cb;
1323
1324         struct rpc_srv_callbacks lsarpc_cb;
1325         struct rpc_srv_callbacks samr_cb;
1326         struct rpc_srv_callbacks netlogon_cb;
1327
1328         struct rpc_srv_callbacks spoolss_cb;
1329         struct rpc_srv_callbacks svcctl_cb;
1330         struct rpc_srv_callbacks ntsvcs_cb;
1331         struct rpc_srv_callbacks eventlog_cb;
1332         struct rpc_srv_callbacks initshutdown_cb;
1333         struct rpc_srv_callbacks netdfs_cb;
1334 #ifdef DEVELOPER
1335         struct rpc_srv_callbacks rpcecho_cb;
1336 #endif
1337         struct rpc_srv_callbacks dssetup_cb;
1338         struct rpc_srv_callbacks wkssvc_cb;
1339
1340         const char *rpcsrv_type;
1341
1342         ep_ctx = talloc(ev_ctx, struct dcesrv_ep_context);
1343         if (ep_ctx == NULL) {
1344                 return false;
1345         }
1346
1347         ep_ctx->ev_ctx = ev_ctx;
1348         ep_ctx->msg_ctx = msg_ctx;
1349
1350         /* start endpoint mapper only if enabled */
1351         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
1352                                            "rpc_server",
1353                                            "epmapper",
1354                                            "none");
1355         if (StrCaseCmp(rpcsrv_type, "embedded") == 0) {
1356                 epmapper_cb.init         = epmapper_init_cb;
1357                 epmapper_cb.shutdown     = epmapper_shutdown_cb;
1358                 epmapper_cb.private_data = ep_ctx;
1359
1360                 if (!NT_STATUS_IS_OK(rpc_epmapper_init(&epmapper_cb))) {
1361                         return false;
1362                 }
1363         }
1364
1365         winreg_cb.init         = winreg_init_cb;
1366         winreg_cb.shutdown     = winreg_shutdown_cb;
1367         winreg_cb.private_data = ep_ctx;
1368         if (!NT_STATUS_IS_OK(rpc_winreg_init(&winreg_cb))) {
1369                 return false;
1370         }
1371
1372         srvsvc_cb.init         = srvsvc_init_cb;
1373         srvsvc_cb.shutdown     = srvsvc_shutdown_cb;
1374         srvsvc_cb.private_data = ep_ctx;
1375         if (!NT_STATUS_IS_OK(rpc_srvsvc_init(&srvsvc_cb))) {
1376                 return false;
1377         }
1378
1379
1380         lsarpc_cb.init         = lsarpc_init_cb;
1381         lsarpc_cb.shutdown     = lsarpc_shutdown_cb;
1382         lsarpc_cb.private_data = ep_ctx;
1383         if (!NT_STATUS_IS_OK(rpc_lsarpc_init(&lsarpc_cb))) {
1384                 return false;
1385         }
1386
1387         samr_cb.init         = samr_init_cb;
1388         samr_cb.shutdown     = samr_shutdown_cb;
1389         samr_cb.private_data = ep_ctx;
1390         if (!NT_STATUS_IS_OK(rpc_samr_init(&samr_cb))) {
1391                 return false;
1392         }
1393
1394         netlogon_cb.init         = netlogon_init_cb;
1395         netlogon_cb.shutdown     = netlogon_shutdown_cb;
1396         netlogon_cb.private_data = ep_ctx;
1397         if (!NT_STATUS_IS_OK(rpc_netlogon_init(&netlogon_cb))) {
1398                 return false;
1399         }
1400
1401         spoolss_cb.init         = spoolss_init_cb;
1402         spoolss_cb.shutdown     = spoolss_shutdown_cb;
1403         spoolss_cb.private_data = ep_ctx;
1404         if (!NT_STATUS_IS_OK(rpc_spoolss_init(&spoolss_cb))) {
1405                 return false;
1406         }
1407
1408
1409         svcctl_cb.init         = svcctl_init_cb;
1410         svcctl_cb.shutdown     = svcctl_shutdown_cb;
1411         svcctl_cb.private_data = ep_ctx;
1412         if (!NT_STATUS_IS_OK(rpc_svcctl_init(&svcctl_cb))) {
1413                 return false;
1414         }
1415
1416         ntsvcs_cb.init         = ntsvcs_init_cb;
1417         ntsvcs_cb.shutdown     = ntsvcs_shutdown_cb;
1418         ntsvcs_cb.private_data = ep_ctx;
1419         if (!NT_STATUS_IS_OK(rpc_ntsvcs_init(&ntsvcs_cb))) {
1420                 return false;
1421         }
1422
1423         eventlog_cb.init         = eventlog_init_cb;
1424         eventlog_cb.shutdown     = eventlog_shutdown_cb;
1425         eventlog_cb.private_data = ep_ctx;
1426         if (!NT_STATUS_IS_OK(rpc_eventlog_init(&eventlog_cb))) {
1427                 return false;
1428         }
1429
1430         initshutdown_cb.init         = initshutdown_init_cb;
1431         initshutdown_cb.shutdown     = initshutdown_shutdown_cb;
1432         initshutdown_cb.private_data = ep_ctx;
1433         if (!NT_STATUS_IS_OK(rpc_initshutdown_init(&initshutdown_cb))) {
1434                 return false;
1435         }
1436
1437         netdfs_cb.init         = netdfs_init_cb;
1438         netdfs_cb.shutdown     = netdfs_shutdown_cb;
1439         netdfs_cb.private_data = ep_ctx;
1440         if (!NT_STATUS_IS_OK(rpc_netdfs_init(&netdfs_cb))) {
1441                 return false;
1442         }
1443 #ifdef DEVELOPER
1444
1445         rpcecho_cb.init         = rpcecho_init_cb;
1446         rpcecho_cb.shutdown     = rpcecho_shutdown_cb;
1447         rpcecho_cb.private_data = ep_ctx;
1448         if (!NT_STATUS_IS_OK(rpc_rpcecho_init(&rpcecho_cb))) {
1449                 return false;
1450         }
1451 #endif
1452
1453         dssetup_cb.init         = dssetup_init_cb;
1454         dssetup_cb.shutdown     = dssetup_shutdown_cb;
1455         dssetup_cb.private_data = ep_ctx;
1456         if (!NT_STATUS_IS_OK(rpc_dssetup_init(&dssetup_cb))) {
1457                 return false;
1458         }
1459
1460         wkssvc_cb.init         = wkssvc_init_cb;
1461         wkssvc_cb.shutdown     = wkssvc_shutdown_cb;
1462         wkssvc_cb.private_data = ep_ctx;
1463         if (!NT_STATUS_IS_OK(rpc_wkssvc_init(&wkssvc_cb))) {
1464                 return false;
1465         }
1466
1467         return true;
1468 }
1469
1470 /* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */