s3:rpc_server: Unify RPC client disconnect and termination functions
[metze/samba/wip.git] / source3 / printing / spoolssd.c
1 /*
2    Unix SMB/Netbios implementation.
3    SPOOLSS Daemon
4    Copyright (C) Simo Sorce <idra@samba.org> 2010-2011
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "includes.h"
20 #include "smbd/smbd.h"
21
22 #include "messages.h"
23 #include "include/printing.h"
24 #include "printing/nt_printing_migrate_internal.h"
25 #include "printing/queue_process.h"
26 #include "printing/pcap.h"
27 #include "printing/load.h"
28 #include "ntdomain.h"
29 #include "librpc/gen_ndr/srv_winreg.h"
30 #include "librpc/gen_ndr/srv_spoolss.h"
31 #include "rpc_server/rpc_server.h"
32 #include "rpc_server/rpc_ep_register.h"
33 #include "rpc_server/rpc_config.h"
34 #include "rpc_server/spoolss/srv_spoolss_nt.h"
35 #include "librpc/rpc/dcerpc_ep.h"
36 #include "lib/server_prefork.h"
37 #include "lib/server_prefork_util.h"
38
39 #undef DBGC_CLASS
40 #define DBGC_CLASS DBGC_RPC_SRV
41
42 #define SPOOLSS_PIPE_NAME "spoolss"
43 #define DAEMON_NAME "spoolssd"
44
45 static struct server_id parent_id;
46 static struct prefork_pool *spoolss_pool = NULL;
47 static int spoolss_child_id = 0;
48
49 static struct pf_daemon_config default_pf_spoolss_cfg = {
50         .prefork_status = PFH_INIT,
51         .min_children = 5,
52         .max_children = 25,
53         .spawn_rate = 5,
54         .max_allowed_clients = 100,
55         .child_min_life = 60 /* 1 minute minimum life time */
56 };
57 static struct pf_daemon_config pf_spoolss_cfg = { 0 };
58
59 pid_t start_spoolssd(struct tevent_context *ev_ctx,
60                      struct messaging_context *msg_ctx);
61
62 static void spoolss_reopen_logs(int child_id)
63 {
64         char *lfile = lp_logfile(talloc_tos());
65         char *ext;
66         int rc;
67
68         if (child_id) {
69                 rc = asprintf(&ext, "%s.%d", DAEMON_NAME, child_id);
70         } else {
71                 rc = asprintf(&ext, "%s", DAEMON_NAME);
72         }
73
74         if (rc == -1) {
75                 return;
76         }
77
78         rc = 0;
79         if (lfile == NULL || lfile[0] == '\0') {
80                 rc = asprintf(&lfile, "%s/log.%s",
81                               get_dyn_LOGFILEBASE(), ext);
82         } else {
83                 if (strstr(lfile, ext) == NULL) {
84                         if (child_id) {
85                                 rc = asprintf(&lfile, "%s.%d",
86                                               lp_logfile(talloc_tos()),
87                                               child_id);
88                         } else {
89                                 rc = asprintf(&lfile, "%s.%s",
90                                               lp_logfile(talloc_tos()),
91                                               ext);
92                         }
93                 }
94         }
95
96         if (rc > 0) {
97                 lp_set_logfile(lfile);
98                 SAFE_FREE(lfile);
99         }
100
101         SAFE_FREE(ext);
102
103         reopen_logs();
104 }
105
106 static void update_conf(struct tevent_context *ev,
107                         struct messaging_context *msg)
108 {
109         change_to_root_user();
110         lp_load_global(get_dyn_CONFIGFILE());
111         load_printers();
112
113         spoolss_reopen_logs(spoolss_child_id);
114         if (spoolss_child_id == 0) {
115                 pfh_daemon_config(DAEMON_NAME,
116                                   &pf_spoolss_cfg,
117                                   &default_pf_spoolss_cfg);
118                 pfh_manage_pool(ev, msg, &pf_spoolss_cfg, spoolss_pool);
119         }
120 }
121
122 static void smb_conf_updated(struct messaging_context *msg,
123                              void *private_data,
124                              uint32_t msg_type,
125                              struct server_id server_id,
126                              DATA_BLOB *data)
127 {
128         struct tevent_context *ev_ctx = talloc_get_type_abort(private_data,
129                                                              struct tevent_context);
130
131         DEBUG(10, ("Got message saying smb.conf was updated. Reloading.\n"));
132         update_conf(ev_ctx, msg);
133 }
134
135 static void spoolss_sig_term_handler(struct tevent_context *ev,
136                                      struct tevent_signal *se,
137                                      int signum,
138                                      int count,
139                                      void *siginfo,
140                                      void *private_data)
141 {
142         exit_server_cleanly("termination signal");
143 }
144
145 static void spoolss_setup_sig_term_handler(struct tevent_context *ev_ctx)
146 {
147         struct tevent_signal *se;
148
149         se = tevent_add_signal(ev_ctx,
150                                ev_ctx,
151                                SIGTERM, 0,
152                                spoolss_sig_term_handler,
153                                NULL);
154         if (!se) {
155                 exit_server("failed to setup SIGTERM handler");
156         }
157 }
158
159 static void spoolss_sig_hup_handler(struct tevent_context *ev,
160                                     struct tevent_signal *se,
161                                     int signum,
162                                     int count,
163                                     void *siginfo,
164                                     void *pvt)
165 {
166         struct messaging_context *msg_ctx;
167
168         msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
169
170         DEBUG(1,("Reloading printers after SIGHUP\n"));
171         update_conf(ev, msg_ctx);
172
173         /* relay to all children */
174         if (spoolss_pool) {
175                 prefork_send_signal_to_all(spoolss_pool, SIGHUP);
176         }
177 }
178
179 static void spoolss_setup_sig_hup_handler(struct tevent_context *ev_ctx,
180                                           struct messaging_context *msg_ctx)
181 {
182         struct tevent_signal *se;
183
184         se = tevent_add_signal(ev_ctx,
185                                ev_ctx,
186                                SIGHUP, 0,
187                                spoolss_sig_hup_handler,
188                                msg_ctx);
189         if (!se) {
190                 exit_server("failed to setup SIGHUP handler");
191         }
192 }
193
194 static bool spoolss_init_cb(void *ptr)
195 {
196         struct messaging_context *msg_ctx = talloc_get_type_abort(
197                 ptr, struct messaging_context);
198
199         return nt_printing_tdb_migrate(msg_ctx);
200 }
201
202 static bool spoolss_shutdown_cb(void *ptr)
203 {
204         srv_spoolss_cleanup();
205
206         return true;
207 }
208
209 /* Children */
210
211 static void spoolss_chld_sig_hup_handler(struct tevent_context *ev,
212                                          struct tevent_signal *se,
213                                          int signum,
214                                          int count,
215                                          void *siginfo,
216                                          void *pvt)
217 {
218         change_to_root_user();
219         DEBUG(1,("Reloading printers after SIGHUP\n"));
220         load_printers();
221         spoolss_reopen_logs(spoolss_child_id);
222 }
223
224 static bool spoolss_setup_chld_hup_handler(struct tevent_context *ev_ctx,
225                                            struct messaging_context *msg_ctx,
226                                            struct pf_worker_data *pf)
227 {
228         struct tevent_signal *se;
229
230         se = tevent_add_signal(ev_ctx,
231                                ev_ctx,
232                                SIGHUP, 0,
233                                spoolss_chld_sig_hup_handler,
234                                msg_ctx);
235         if (!se) {
236                 DEBUG(1, ("failed to setup SIGHUP handler"));
237                 return false;
238         }
239
240         return true;
241 }
242
243 static void parent_ping(struct messaging_context *msg_ctx,
244                         void *private_data,
245                         uint32_t msg_type,
246                         struct server_id server_id,
247                         DATA_BLOB *data)
248 {
249
250         /* The fact we received this message is enough to let make the event
251          * loop if it was idle. spoolss_children_main will cycle through
252          * spoolss_next_client at least once. That function will take whatever
253          * action is necessary */
254
255         DEBUG(10, ("Got message that the parent changed status.\n"));
256         return;
257 }
258
259 static bool spoolss_child_init(struct tevent_context *ev_ctx,
260                                int child_id, struct pf_worker_data *pf)
261 {
262         NTSTATUS status;
263         struct rpc_srv_callbacks spoolss_cb;
264         struct messaging_context *msg_ctx = global_messaging_context();
265         bool ok;
266
267         status = reinit_after_fork(msg_ctx, ev_ctx, true, "spoolssd-child");
268         if (!NT_STATUS_IS_OK(status)) {
269                 DEBUG(0,("reinit_after_fork() failed\n"));
270                 smb_panic("reinit_after_fork() failed");
271         }
272
273         spoolss_child_id = child_id;
274         spoolss_reopen_logs(child_id);
275
276         ok = spoolss_setup_chld_hup_handler(ev_ctx, msg_ctx, pf);
277         if (!ok) {
278                 return false;
279         }
280
281         if (!locking_init()) {
282                 return false;
283         }
284
285         messaging_register(msg_ctx, ev_ctx,
286                            MSG_SMB_CONF_UPDATED, smb_conf_updated);
287         messaging_register(msg_ctx, ev_ctx,
288                            MSG_PREFORK_PARENT_EVENT, parent_ping);
289
290         /* As soon as messaging is up check if pcap has been loaded already.
291          * If so then we probably missed a message and should load_printers()
292          * ourselves. If pcap has not been loaded yet, then ignore, we will get
293          * a message as soon as the bq process completes the reload. */
294         load_printers();
295
296         /* try to reinit rpc queues */
297         spoolss_cb.init = spoolss_init_cb;
298         spoolss_cb.shutdown = spoolss_shutdown_cb;
299         spoolss_cb.private_data = msg_ctx;
300
301         status = rpc_winreg_init(NULL);
302         if (!NT_STATUS_IS_OK(status)) {
303                 DEBUG(0, ("Failed to register winreg rpc interface! (%s)\n",
304                           nt_errstr(status)));
305                 return false;
306         }
307
308         status = rpc_spoolss_init(&spoolss_cb);
309         if (!NT_STATUS_IS_OK(status)) {
310                 DEBUG(0, ("Failed to register spoolss rpc interface! (%s)\n",
311                           nt_errstr(status)));
312                 return false;
313         }
314
315         return true;
316 }
317
318 struct spoolss_children_data {
319         struct tevent_context *ev_ctx;
320         struct messaging_context *msg_ctx;
321         struct pf_worker_data *pf;
322         int listen_fd_size;
323         struct pf_listen_fd *listen_fds;
324 };
325
326 static void spoolss_next_client(void *pvt);
327
328 static int spoolss_children_main(struct tevent_context *ev_ctx,
329                                  struct messaging_context *msg_ctx,
330                                  struct pf_worker_data *pf,
331                                  int child_id,
332                                  int listen_fd_size,
333                                  struct pf_listen_fd *listen_fds,
334                                  void *private_data)
335 {
336         struct spoolss_children_data *data;
337         bool ok;
338         int ret = 0;
339
340         ok = spoolss_child_init(ev_ctx, child_id, pf);
341         if (!ok) {
342                 return 1;
343         }
344
345         data = talloc(ev_ctx, struct spoolss_children_data);
346         if (!data) {
347                 return 1;
348         }
349         data->pf = pf;
350         data->ev_ctx = ev_ctx;
351         data->msg_ctx = msg_ctx;
352         data->listen_fd_size = listen_fd_size;
353         data->listen_fds = listen_fds;
354
355         /* loop until it is time to exit */
356         while (pf->status != PF_WORKER_EXITING) {
357                 /* try to see if it is time to schedule the next client */
358                 spoolss_next_client(data);
359
360                 ret = tevent_loop_once(ev_ctx);
361                 if (ret != 0) {
362                         DEBUG(0, ("tevent_loop_once() exited with %d: %s\n",
363                                   ret, strerror(errno)));
364                         pf->status = PF_WORKER_EXITING;
365                 }
366         }
367
368         return ret;
369 }
370
371 static void spoolss_client_terminated(struct pipes_struct *p, void *pvt)
372 {
373         struct spoolss_children_data *data;
374
375         data = talloc_get_type_abort(pvt, struct spoolss_children_data);
376
377         pfh_client_terminated(data->pf);
378
379         spoolss_next_client(pvt);
380 }
381
382 struct spoolss_new_client {
383         struct spoolss_children_data *data;
384 };
385
386 static void spoolss_handle_client(struct tevent_req *req);
387
388 static void spoolss_next_client(void *pvt)
389 {
390         struct tevent_req *req;
391         struct spoolss_children_data *data;
392         struct spoolss_new_client *next;
393
394         data = talloc_get_type_abort(pvt, struct spoolss_children_data);
395
396         if (!pfh_child_allowed_to_accept(data->pf)) {
397                 /* nothing to do for now we are already listening
398                  * or we are not allowed to listen further */
399                 return;
400         }
401
402         next = talloc_zero(data, struct spoolss_new_client);
403         if (!next) {
404                 DEBUG(1, ("Out of memory!?\n"));
405                 return;
406         }
407         next->data = data;
408
409         req = prefork_listen_send(next, data->ev_ctx, data->pf,
410                                   data->listen_fd_size,
411                                   data->listen_fds);
412         if (!req) {
413                 DEBUG(1, ("Failed to make listening request!?\n"));
414                 talloc_free(next);
415                 return;
416         }
417         tevent_req_set_callback(req, spoolss_handle_client, next);
418 }
419
420 static void spoolss_handle_client(struct tevent_req *req)
421 {
422         struct spoolss_children_data *data;
423         struct spoolss_new_client *client;
424         const DATA_BLOB ping = data_blob_null;
425         int ret;
426         int sd;
427         struct tsocket_address *srv_addr = NULL;
428         struct tsocket_address *cli_addr = NULL;
429
430         client = tevent_req_callback_data(req, struct spoolss_new_client);
431         data = client->data;
432
433         ret = prefork_listen_recv(req, data, &sd, NULL,
434                                   &srv_addr, &cli_addr);
435
436         /* this will free the request too */
437         talloc_free(client);
438
439         if (ret != 0) {
440                 DEBUG(6, ("No client connection was available after all!\n"));
441                 return;
442         }
443
444         /* Warn parent that our status changed */
445         messaging_send(data->msg_ctx, parent_id,
446                         MSG_PREFORK_CHILD_EVENT, &ping);
447
448         DEBUG(2, ("Spoolss preforked child %d got client connection!\n",
449                   (int)(data->pf->pid)));
450
451         dcerpc_ncacn_accept(data->ev_ctx,
452                             data->msg_ctx,
453                             NCACN_NP,
454                             SPOOLSS_PIPE_NAME,
455                             cli_addr,
456                             srv_addr,
457                             sd,
458                             spoolss_client_terminated,
459                             data);
460 }
461
462 /* ==== Main Process Functions ==== */
463
464 extern pid_t background_lpq_updater_pid;
465 static char *bq_logfile;
466
467 static void check_updater_child(struct tevent_context *ev_ctx,
468                                 struct messaging_context *msg_ctx)
469 {
470         int status;
471         pid_t pid;
472
473         if (background_lpq_updater_pid == -1) {
474                 return;
475         }
476
477         pid = waitpid(background_lpq_updater_pid, &status, WNOHANG);
478         if (pid > 0) {
479                 DEBUG(2, ("The background queue child died... Restarting!\n"));
480                 pid = start_background_queue(ev_ctx, msg_ctx, bq_logfile);
481                 background_lpq_updater_pid = pid;
482         }
483 }
484
485 static void child_ping(struct messaging_context *msg_ctx,
486                         void *private_data,
487                         uint32_t msg_type,
488                         struct server_id server_id,
489                         DATA_BLOB *data)
490 {
491         struct tevent_context *ev_ctx;
492
493         ev_ctx = talloc_get_type_abort(private_data, struct tevent_context);
494
495         DEBUG(10, ("Got message that a child changed status.\n"));
496         pfh_manage_pool(ev_ctx, msg_ctx, &pf_spoolss_cfg, spoolss_pool);
497 }
498
499 static bool spoolssd_schedule_check(struct tevent_context *ev_ctx,
500                                     struct messaging_context *msg_ctx,
501                                     struct timeval current_time);
502 static void spoolssd_check_children(struct tevent_context *ev_ctx,
503                                     struct tevent_timer *te,
504                                     struct timeval current_time,
505                                     void *pvt);
506
507 static void spoolssd_sigchld_handler(struct tevent_context *ev_ctx,
508                                      struct prefork_pool *pfp,
509                                      void *pvt)
510 {
511         struct messaging_context *msg_ctx;
512
513         msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
514
515         /* run pool management so we can fork/retire or increase
516          * the allowed connections per child based on load */
517         pfh_manage_pool(ev_ctx, msg_ctx, &pf_spoolss_cfg, spoolss_pool);
518
519         /* also check if the updater child is alive and well */
520         check_updater_child(ev_ctx, msg_ctx);
521 }
522
523 static bool spoolssd_setup_children_monitor(struct tevent_context *ev_ctx,
524                                             struct messaging_context *msg_ctx)
525 {
526         bool ok;
527
528         /* add our oun sigchld callback */
529         prefork_set_sigchld_callback(spoolss_pool,
530                                      spoolssd_sigchld_handler, msg_ctx);
531
532         ok = spoolssd_schedule_check(ev_ctx, msg_ctx,
533                                      tevent_timeval_current());
534         return ok;
535 }
536
537 static bool spoolssd_schedule_check(struct tevent_context *ev_ctx,
538                                     struct messaging_context *msg_ctx,
539                                     struct timeval current_time)
540 {
541         struct tevent_timer *te;
542         struct timeval next_event;
543
544         /* check situation again in 10 seconds */
545         next_event = tevent_timeval_current_ofs(10, 0);
546
547         /* TODO: check when the socket becomes readable, so that children
548          * are checked only when there is some activity ? */
549         te = tevent_add_timer(ev_ctx, spoolss_pool, next_event,
550                                 spoolssd_check_children, msg_ctx);
551         if (!te) {
552                 DEBUG(2, ("Failed to set up children monitoring!\n"));
553                 return false;
554         }
555
556         return true;
557 }
558
559 static void spoolssd_check_children(struct tevent_context *ev_ctx,
560                                     struct tevent_timer *te,
561                                     struct timeval current_time,
562                                     void *pvt)
563 {
564         struct messaging_context *msg_ctx;
565
566         msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
567
568         pfh_manage_pool(ev_ctx, msg_ctx, &pf_spoolss_cfg, spoolss_pool);
569
570         spoolssd_schedule_check(ev_ctx, msg_ctx, current_time);
571 }
572
573 static void print_queue_forward(struct messaging_context *msg,
574                                 void *private_data,
575                                 uint32_t msg_type,
576                                 struct server_id server_id,
577                                 DATA_BLOB *data)
578 {
579         messaging_send_buf(msg, pid_to_procid(background_lpq_updater_pid),
580                            MSG_PRINTER_UPDATE, data->data, data->length);
581 }
582
583 static char *get_bq_logfile(void)
584 {
585         char *lfile = lp_logfile(talloc_tos());
586         int rc;
587
588         if (lfile == NULL || lfile[0] == '\0') {
589                 rc = asprintf(&lfile, "%s/log.%s.bq",
590                                         get_dyn_LOGFILEBASE(), DAEMON_NAME);
591         } else {
592                 rc = asprintf(&lfile, "%s.bq", lp_logfile(talloc_tos()));
593         }
594         if (rc == -1) {
595                 lfile = NULL;
596         }
597         return lfile;
598 }
599
600 pid_t start_spoolssd(struct tevent_context *ev_ctx,
601                     struct messaging_context *msg_ctx)
602 {
603         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
604         struct rpc_srv_callbacks spoolss_cb;
605         struct dcerpc_binding_vector *v;
606         TALLOC_CTX *mem_ctx;
607         pid_t pid;
608         NTSTATUS status;
609         struct pf_listen_fd listen_fds[1];
610         int ret;
611         bool ok;
612
613         DEBUG(1, ("Forking SPOOLSS Daemon\n"));
614
615         /*
616          * Block signals before forking child as it will have to
617          * set its own handlers. Child will re-enable SIGHUP as
618          * soon as the handlers are set up.
619          */
620         BlockSignals(true, SIGTERM);
621         BlockSignals(true, SIGHUP);
622
623         pid = fork();
624
625         if (pid == -1) {
626                 DEBUG(0, ("Failed to fork SPOOLSS [%s]\n",
627                            strerror(errno)));
628                 exit(1);
629         }
630
631         /* parent or error */
632         if (pid != 0) {
633
634                 /* Re-enable SIGHUP before returnig */
635                 BlockSignals(false, SIGTERM);
636                 BlockSignals(false, SIGHUP);
637                 return pid;
638         }
639
640         status = smbd_reinit_after_fork(msg_ctx, ev_ctx, true,
641                                         "spoolssd-master");
642         if (!NT_STATUS_IS_OK(status)) {
643                 DEBUG(0,("reinit_after_fork() failed\n"));
644                 smb_panic("reinit_after_fork() failed");
645         }
646
647         /* save the parent process id so the children can use it later */
648         parent_id = messaging_server_id(msg_ctx);
649
650         spoolss_reopen_logs(0);
651         pfh_daemon_config(DAEMON_NAME,
652                           &pf_spoolss_cfg,
653                           &default_pf_spoolss_cfg);
654
655         spoolss_setup_sig_term_handler(ev_ctx);
656         spoolss_setup_sig_hup_handler(ev_ctx, msg_ctx);
657
658         BlockSignals(false, SIGTERM);
659         BlockSignals(false, SIGHUP);
660
661         /* always start the backgroundqueue listner in spoolssd */
662         bq_logfile = get_bq_logfile();
663         pid = start_background_queue(ev_ctx, msg_ctx, bq_logfile);
664         if (pid > 0) {
665                 background_lpq_updater_pid = pid;
666         }
667
668         /* the listening fd must be created before the children are actually
669          * forked out. */
670         status = dcesrv_create_ncacn_np_socket(SPOOLSS_PIPE_NAME,
671                                                &listen_fds[0].fd);
672         if (!NT_STATUS_IS_OK(status)) {
673                 exit(1);
674         }
675         listen_fds[0].fd_data = NULL;
676
677         ret = listen(listen_fds[0].fd, pf_spoolss_cfg.max_allowed_clients);
678         if (ret == -1) {
679                 DEBUG(0, ("Failed to listen on spoolss pipe - %s\n",
680                           strerror(errno)));
681                 exit(1);
682         }
683
684         /* start children before any more initialization is done */
685         ok = prefork_create_pool(ev_ctx, /* mem_ctx */
686                                  ev_ctx, msg_ctx,
687                                  1, listen_fds,
688                                  pf_spoolss_cfg.min_children,
689                                  pf_spoolss_cfg.max_children,
690                                  &spoolss_children_main, NULL,
691                                  &spoolss_pool);
692         if (!ok) {
693                 exit(1);
694         }
695
696         if (!locking_init()) {
697                 exit(1);
698         }
699
700         messaging_register(msg_ctx, ev_ctx,
701                            MSG_SMB_CONF_UPDATED, smb_conf_updated);
702         messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
703                            print_queue_forward);
704         messaging_register(msg_ctx, ev_ctx,
705                            MSG_PREFORK_CHILD_EVENT, child_ping);
706
707         /*
708          * As soon as messaging is up check if pcap has been loaded already.
709          * If pcap has not been loaded yet, then ignore, as we will reload on
710          * client enumeration anyway.
711          */
712         load_printers();
713
714         mem_ctx = talloc_new(NULL);
715         if (mem_ctx == NULL) {
716                 exit(1);
717         }
718
719         /*
720          * Initialize spoolss with an init function to convert printers first.
721          * static_init_rpc will try to initialize the spoolss server too but you
722          * can't register it twice.
723          */
724         spoolss_cb.init = spoolss_init_cb;
725         spoolss_cb.shutdown = spoolss_shutdown_cb;
726         spoolss_cb.private_data = msg_ctx;
727
728         status = rpc_winreg_init(NULL);
729         if (!NT_STATUS_IS_OK(status)) {
730                 DEBUG(0, ("Failed to register winreg rpc interface! (%s)\n",
731                           nt_errstr(status)));
732                 exit(1);
733         }
734
735         status = rpc_spoolss_init(&spoolss_cb);
736         if (!NT_STATUS_IS_OK(status)) {
737                 DEBUG(0, ("Failed to register spoolss rpc interface! (%s)\n",
738                           nt_errstr(status)));
739                 exit(1);
740         }
741
742         if (epm_mode != RPC_SERVICE_MODE_DISABLED &&
743             (lp_parm_bool(-1, "rpc_server", "register_embedded_np", false))) {
744                 status = dcerpc_binding_vector_new(mem_ctx, &v);
745                 if (!NT_STATUS_IS_OK(status)) {
746                         DEBUG(0, ("Failed to create binding vector (%s)\n",
747                                   nt_errstr(status)));
748                         exit(1);
749                 }
750
751                 status = dcerpc_binding_vector_add_np_default(&ndr_table_spoolss, v);
752                 if (!NT_STATUS_IS_OK(status)) {
753                         DEBUG(0, ("Failed to add np to binding vector (%s)\n",
754                                   nt_errstr(status)));
755                         exit(1);
756                 }
757
758                 status = rpc_ep_register(ev_ctx, msg_ctx, &ndr_table_spoolss, v);
759                 if (!NT_STATUS_IS_OK(status)) {
760                         DEBUG(0, ("Failed to register spoolss endpoint! (%s)\n",
761                                   nt_errstr(status)));
762                         exit(1);
763                 }
764         }
765
766         talloc_free(mem_ctx);
767
768         ok = spoolssd_setup_children_monitor(ev_ctx, msg_ctx);
769         if (!ok) {
770                 DEBUG(0, ("Failed to setup children monitoring!\n"));
771                 exit(1);
772         }
773
774         DEBUG(1, ("SPOOLSS Daemon Started (%u)\n", (unsigned int)getpid()));
775
776         pfh_manage_pool(ev_ctx, msg_ctx, &pf_spoolss_cfg, spoolss_pool);
777
778         /* loop forever */
779         ret = tevent_loop_wait(ev_ctx);
780
781         /* should not be reached */
782         DEBUG(0,("spoolssd tevent_loop_wait() exited with %d - %s\n",
783                  ret, (ret == 0) ? "out of events" : strerror(errno)));
784         exit(1);
785 }