s3:util: rename procid_equal() to serverid_equal()
[kai/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/rpc_config.h"
54 #include "rpc_server/epmapper/srv_epmapper.h"
55
56 /* Common routine for embedded RPC servers */
57 static bool rpc_setup_embedded(struct tevent_context *ev_ctx,
58                                struct messaging_context *msg_ctx,
59                                const struct ndr_interface_table *t,
60                                const char *pipe_name)
61 {
62         struct dcerpc_binding_vector *v;
63         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
64         NTSTATUS status;
65
66         /* Registration of ncacn_np services is problematic.  The
67          * ev_ctx passed in here is passed down to all children of the
68          * smbd process, and if the end point mapper ever goes away,
69          * they will all attempt to re-register.  But we want to test
70          * the code for now, so it is enabled in on environment in
71          * make test */
72         if (epm_mode != RPC_SERVICE_MODE_DISABLED && 
73             (lp_parm_bool(-1, "rpc_server", "register_embedded_np", false))) {
74                 status = dcerpc_binding_vector_new(talloc_tos(), &v);
75                 if (!NT_STATUS_IS_OK(status)) {
76                         return false;
77                 }
78
79                 status = dcerpc_binding_vector_add_np_default(t, v);
80                 if (!NT_STATUS_IS_OK(status)) {
81                         return false;
82                 }
83
84                 status = rpc_ep_register(ev_ctx,
85                                          msg_ctx,
86                                          t,
87                                          v);
88                 if (!NT_STATUS_IS_OK(status)) {
89                         return false;
90                 }
91         }
92
93         return true;
94 }
95
96 static bool rpc_setup_winreg(struct tevent_context *ev_ctx,
97                              struct messaging_context *msg_ctx)
98 {
99         const struct ndr_interface_table *t = &ndr_table_winreg;
100         const char *pipe_name = "winreg";
101         NTSTATUS status;
102         enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
103         if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
104                 return true;
105         }
106
107         status = rpc_winreg_init(NULL);
108         if (!NT_STATUS_IS_OK(status)) {
109                 return false;
110         }
111
112         return rpc_setup_embedded(ev_ctx, msg_ctx, t, pipe_name);
113 }
114
115 static bool rpc_setup_srvsvc(struct tevent_context *ev_ctx,
116                              struct messaging_context *msg_ctx)
117 {
118         const struct ndr_interface_table *t = &ndr_table_srvsvc;
119         const char *pipe_name = "srvsvc";
120         NTSTATUS status;
121         enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
122         if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
123                 return true;
124         }
125
126         status = rpc_srvsvc_init(NULL);
127         if (!NT_STATUS_IS_OK(status)) {
128                 return false;
129         }
130
131         return rpc_setup_embedded(ev_ctx, msg_ctx, t, pipe_name);
132 }
133
134 static bool rpc_setup_lsarpc(struct tevent_context *ev_ctx,
135                              struct messaging_context *msg_ctx)
136 {
137         const struct ndr_interface_table *t = &ndr_table_lsarpc;
138         const char *pipe_name = "lsarpc";
139         enum rpc_daemon_type_e lsasd_type = rpc_lsasd_daemon();
140         NTSTATUS status;
141         enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
142         if (service_mode != RPC_SERVICE_MODE_EMBEDDED || lsasd_type != RPC_DAEMON_EMBEDDED) {
143                 return true;
144         }
145
146         status = rpc_lsarpc_init(NULL);
147         if (!NT_STATUS_IS_OK(status)) {
148                 return false;
149         }
150
151         return rpc_setup_embedded(ev_ctx, msg_ctx, t, pipe_name);
152 }
153
154 static bool rpc_setup_samr(struct tevent_context *ev_ctx,
155                            struct messaging_context *msg_ctx)
156 {
157         const struct ndr_interface_table *t = &ndr_table_samr;
158         const char *pipe_name = "samr";
159         enum rpc_daemon_type_e lsasd_type = rpc_lsasd_daemon();
160         NTSTATUS status;
161         enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
162         if (service_mode != RPC_SERVICE_MODE_EMBEDDED || lsasd_type != RPC_DAEMON_EMBEDDED) {
163                 return true;
164         }
165
166         status = rpc_samr_init(NULL);
167         if (!NT_STATUS_IS_OK(status)) {
168                 return false;
169         }
170
171         return rpc_setup_embedded(ev_ctx, msg_ctx, t, pipe_name);
172 }
173
174 static bool rpc_setup_netlogon(struct tevent_context *ev_ctx,
175                                struct messaging_context *msg_ctx)
176 {
177         const struct ndr_interface_table *t = &ndr_table_netlogon;
178         const char *pipe_name = "netlogon";
179         enum rpc_daemon_type_e lsasd_type = rpc_lsasd_daemon();
180         NTSTATUS status;
181         enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
182         if (service_mode != RPC_SERVICE_MODE_EMBEDDED || lsasd_type != RPC_DAEMON_EMBEDDED) {
183                 return true;
184         }
185
186         status = rpc_netlogon_init(NULL);
187         if (!NT_STATUS_IS_OK(status)) {
188                 return false;
189         }
190
191         return rpc_setup_embedded(ev_ctx, msg_ctx, t, pipe_name);
192 }
193
194 static bool rpc_setup_netdfs(struct tevent_context *ev_ctx,
195                              struct messaging_context *msg_ctx)
196 {
197         const struct ndr_interface_table *t = &ndr_table_netdfs;
198         const char *pipe_name = "netdfs";
199         NTSTATUS status;
200         enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
201         if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
202                 return true;
203         }
204
205         status = rpc_netdfs_init(NULL);
206         if (!NT_STATUS_IS_OK(status)) {
207                 return false;
208         }
209
210         return rpc_setup_embedded(ev_ctx, msg_ctx, t, pipe_name);
211 }
212
213 #ifdef DEVELOPER
214 static bool rpc_setup_rpcecho(struct tevent_context *ev_ctx,
215                               struct messaging_context *msg_ctx)
216 {
217         const struct ndr_interface_table *t = &ndr_table_rpcecho;
218         const char *pipe_name = "rpcecho";
219         NTSTATUS status;
220         enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
221         if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
222                 return true;
223         }
224
225         status = rpc_rpcecho_init(NULL);
226         if (!NT_STATUS_IS_OK(status)) {
227                 return false;
228         }
229
230         return rpc_setup_embedded(ev_ctx, msg_ctx, t, pipe_name);
231 }
232 #endif
233
234 static bool rpc_setup_dssetup(struct tevent_context *ev_ctx,
235                               struct messaging_context *msg_ctx)
236 {
237         const struct ndr_interface_table *t = &ndr_table_dssetup;
238         const char *pipe_name = "dssetup";
239         NTSTATUS status;
240         enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
241         if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
242                 return true;
243         }
244
245         status = rpc_dssetup_init(NULL);
246         if (!NT_STATUS_IS_OK(status)) {
247                 return false;
248         }
249
250         return rpc_setup_embedded(ev_ctx, msg_ctx, t, pipe_name);
251 }
252
253 static bool rpc_setup_wkssvc(struct tevent_context *ev_ctx,
254                              struct messaging_context *msg_ctx)
255 {
256         const struct ndr_interface_table *t = &ndr_table_wkssvc;
257         const char *pipe_name = "wkssvc";
258         NTSTATUS status;
259         enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
260         if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
261                 return true;
262         }
263
264         status = rpc_wkssvc_init(NULL);
265         if (!NT_STATUS_IS_OK(status)) {
266                 return false;
267         }
268
269         return rpc_setup_embedded(ev_ctx, msg_ctx, t, pipe_name);
270 }
271
272 static bool spoolss_init_cb(void *ptr)
273 {
274         struct messaging_context *msg_ctx =
275                 talloc_get_type_abort(ptr, struct messaging_context);
276         bool ok;
277
278         /*
279          * Migrate the printers first.
280          */
281         ok = nt_printing_tdb_migrate(msg_ctx);
282         if (!ok) {
283                 return false;
284         }
285
286         return true;
287 }
288
289 static bool spoolss_shutdown_cb(void *ptr)
290 {
291         srv_spoolss_cleanup();
292
293         return true;
294 }
295
296 static bool rpc_setup_spoolss(struct tevent_context *ev_ctx,
297                               struct messaging_context *msg_ctx)
298 {
299         const struct ndr_interface_table *t = &ndr_table_spoolss;
300         struct rpc_srv_callbacks spoolss_cb;
301         enum rpc_daemon_type_e spoolss_type = rpc_spoolss_daemon();
302         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
303         enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
304
305         if (lp__disable_spoolss()) {
306                 return true;
307         }
308
309         if (service_mode != RPC_SERVICE_MODE_EMBEDDED || spoolss_type != RPC_DAEMON_EMBEDDED) {
310                 return true;
311         }
312
313         spoolss_cb.init         = spoolss_init_cb;
314         spoolss_cb.shutdown     = spoolss_shutdown_cb;
315         spoolss_cb.private_data = msg_ctx;
316
317         status = rpc_spoolss_init(&spoolss_cb);
318         if (!NT_STATUS_IS_OK(status)) {
319                 return false;
320         }
321
322         return rpc_setup_embedded(ev_ctx, msg_ctx, t, NULL);
323 }
324
325 static bool svcctl_init_cb(void *ptr)
326 {
327         struct messaging_context *msg_ctx =
328                 talloc_get_type_abort(ptr, struct messaging_context);
329         bool ok;
330
331         /* initialize the control hooks */
332         init_service_op_table();
333
334         ok = svcctl_init_winreg(msg_ctx);
335         if (!ok) {
336                 return false;
337         }
338
339         return true;
340 }
341
342 static bool svcctl_shutdown_cb(void *ptr)
343 {
344         shutdown_service_op_table();
345
346         return true;
347 }
348
349 static bool rpc_setup_svcctl(struct tevent_context *ev_ctx,
350                              struct messaging_context *msg_ctx)
351 {
352         const struct ndr_interface_table *t = &ndr_table_svcctl;
353         const char *pipe_name = "svcctl";
354         struct rpc_srv_callbacks svcctl_cb;
355         NTSTATUS status;
356         enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
357         if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
358                 return true;
359         }
360
361         svcctl_cb.init         = svcctl_init_cb;
362         svcctl_cb.shutdown     = svcctl_shutdown_cb;
363         svcctl_cb.private_data = msg_ctx;
364
365         status = rpc_svcctl_init(&svcctl_cb);
366         if (!NT_STATUS_IS_OK(status)) {
367                 return false;
368         }
369
370         return rpc_setup_embedded(ev_ctx, msg_ctx, t, pipe_name);
371 }
372
373 static bool rpc_setup_ntsvcs(struct tevent_context *ev_ctx,
374                              struct messaging_context *msg_ctx)
375 {
376         const struct ndr_interface_table *t = &ndr_table_ntsvcs;
377         NTSTATUS status;
378         enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
379         if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
380                 return true;
381         }
382
383         status = rpc_ntsvcs_init(NULL);
384         if (!NT_STATUS_IS_OK(status)) {
385                 return false;
386         }
387
388         return rpc_setup_embedded(ev_ctx, msg_ctx, t, NULL);
389 }
390
391 static bool eventlog_init_cb(void *ptr)
392 {
393         struct messaging_context *msg_ctx =
394                 talloc_get_type_abort(ptr, struct messaging_context);
395         bool ok;
396
397         ok = eventlog_init_winreg(msg_ctx);
398         if (!ok) {
399                 return false;
400         }
401
402         return true;
403 }
404
405 static bool rpc_setup_eventlog(struct tevent_context *ev_ctx,
406                                struct messaging_context *msg_ctx)
407 {
408         const struct ndr_interface_table *t = &ndr_table_eventlog;
409         struct rpc_srv_callbacks eventlog_cb;
410         NTSTATUS status;
411         enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
412         if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
413                 return true;
414         }
415
416         eventlog_cb.init         = eventlog_init_cb;
417         eventlog_cb.shutdown     = NULL;
418         eventlog_cb.private_data = msg_ctx;
419
420         status = rpc_eventlog_init(&eventlog_cb);
421         if (!NT_STATUS_IS_OK(status)) {
422                 return false;
423         }
424
425         return rpc_setup_embedded(ev_ctx, msg_ctx, t, NULL);
426 }
427
428 static bool rpc_setup_initshutdown(struct tevent_context *ev_ctx,
429                                    struct messaging_context *msg_ctx)
430 {
431         const struct ndr_interface_table *t = &ndr_table_initshutdown;
432         NTSTATUS status;
433         enum rpc_service_mode_e service_mode = rpc_service_mode(t->name);
434         if (service_mode != RPC_SERVICE_MODE_EMBEDDED) {
435                 return true;
436         }
437
438         status = rpc_initshutdown_init(NULL);
439         if (!NT_STATUS_IS_OK(status)) {
440                 return false;
441         }
442
443         return rpc_setup_embedded(ev_ctx, msg_ctx, t, NULL);
444 }
445
446 bool dcesrv_ep_setup(struct tevent_context *ev_ctx,
447                      struct messaging_context *msg_ctx)
448 {
449         TALLOC_CTX *tmp_ctx;
450         bool ok;
451
452         tmp_ctx = talloc_stackframe();
453         if (tmp_ctx == NULL) {
454                 return false;
455         }
456
457         ok = rpc_setup_winreg(ev_ctx, msg_ctx);
458         if (!ok) {
459                 goto done;
460         }
461
462         ok = rpc_setup_srvsvc(ev_ctx, msg_ctx);
463         if (!ok) {
464                 goto done;
465         }
466
467         ok = rpc_setup_lsarpc(ev_ctx, msg_ctx);
468         if (!ok) {
469                 goto done;
470         }
471
472         ok = rpc_setup_samr(ev_ctx, msg_ctx);
473         if (!ok) {
474                 goto done;
475         }
476
477         ok = rpc_setup_netlogon(ev_ctx, msg_ctx);
478         if (!ok) {
479                 goto done;
480         }
481
482         ok = rpc_setup_netdfs(ev_ctx, msg_ctx);
483         if (!ok) {
484                 goto done;
485         }
486
487 #ifdef DEVELOPER
488         ok = rpc_setup_rpcecho(ev_ctx, msg_ctx);
489         if (!ok) {
490                 goto done;
491         }
492 #endif
493
494         ok = rpc_setup_dssetup(ev_ctx, msg_ctx);
495         if (!ok) {
496                 goto done;
497         }
498
499         ok = rpc_setup_wkssvc(ev_ctx, msg_ctx);
500         if (!ok) {
501                 goto done;
502         }
503
504         ok = rpc_setup_spoolss(ev_ctx, msg_ctx);
505         if (!ok) {
506                 goto done;
507         }
508
509         ok = rpc_setup_svcctl(ev_ctx, msg_ctx);
510         if (!ok) {
511                 goto done;
512         }
513
514         ok = rpc_setup_ntsvcs(ev_ctx, msg_ctx);
515         if (!ok) {
516                 goto done;
517         }
518
519         ok = rpc_setup_eventlog(ev_ctx, msg_ctx);
520         if (!ok) {
521                 goto done;
522         }
523
524         ok = rpc_setup_initshutdown(ev_ctx, msg_ctx);
525         if (!ok) {
526                 goto done;
527         }
528
529 done:
530         talloc_free(tmp_ctx);
531         return ok;
532 }
533
534 /* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */