Update 4.2 Roadmap file
[mat/samba.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 "serverid.h"
21 #include "smbd/smbd.h"
22
23 #include "lib/util/util_process.h"
24
25 #include "messages.h"
26 #include "include/printing.h"
27 #include "printing/nt_printing_migrate_internal.h"
28 #include "printing/queue_process.h"
29 #include "printing/pcap.h"
30 #include "printing/load.h"
31 #include "ntdomain.h"
32 #include "librpc/gen_ndr/srv_winreg.h"
33 #include "librpc/gen_ndr/srv_spoolss.h"
34 #include "rpc_server/rpc_server.h"
35 #include "rpc_server/rpc_ep_register.h"
36 #include "rpc_server/rpc_config.h"
37 #include "rpc_server/spoolss/srv_spoolss_nt.h"
38 #include "librpc/rpc/dcerpc_ep.h"
39 #include "lib/server_prefork.h"
40 #include "lib/server_prefork_util.h"
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(ev, msg);
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         struct messaging_context *msg_ctx;
219
220         msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
221
222         change_to_root_user();
223         DEBUG(1,("Reloading printers after SIGHUP\n"));
224         load_printers(ev, msg_ctx);
225         spoolss_reopen_logs(spoolss_child_id);
226 }
227
228 static bool spoolss_setup_chld_hup_handler(struct tevent_context *ev_ctx,
229                                            struct messaging_context *msg_ctx,
230                                            struct pf_worker_data *pf)
231 {
232         struct tevent_signal *se;
233
234         se = tevent_add_signal(ev_ctx,
235                                ev_ctx,
236                                SIGHUP, 0,
237                                spoolss_chld_sig_hup_handler,
238                                msg_ctx);
239         if (!se) {
240                 DEBUG(1, ("failed to setup SIGHUP handler"));
241                 return false;
242         }
243
244         return true;
245 }
246
247 static void parent_ping(struct messaging_context *msg_ctx,
248                         void *private_data,
249                         uint32_t msg_type,
250                         struct server_id server_id,
251                         DATA_BLOB *data)
252 {
253
254         /* The fact we received this message is enough to let make the event
255          * loop if it was idle. spoolss_children_main will cycle through
256          * spoolss_next_client at least once. That function will take whatever
257          * action is necessary */
258
259         DEBUG(10, ("Got message that the parent changed status.\n"));
260         return;
261 }
262
263 static bool spoolss_child_init(struct tevent_context *ev_ctx,
264                                int child_id, struct pf_worker_data *pf)
265 {
266         NTSTATUS status;
267         struct rpc_srv_callbacks spoolss_cb;
268         struct messaging_context *msg_ctx = server_messaging_context();
269         bool ok;
270
271         status = reinit_after_fork(msg_ctx, ev_ctx,
272                                    true);
273         if (!NT_STATUS_IS_OK(status)) {
274                 DEBUG(0,("reinit_after_fork() failed\n"));
275                 smb_panic("reinit_after_fork() failed");
276         }
277
278         prctl_set_comment("spoolssd-child");
279
280         spoolss_child_id = child_id;
281         spoolss_reopen_logs(child_id);
282
283         ok = spoolss_setup_chld_hup_handler(ev_ctx, msg_ctx, pf);
284         if (!ok) {
285                 return false;
286         }
287
288         if (!serverid_register(messaging_server_id(msg_ctx),
289                                 FLAG_MSG_GENERAL |
290                                 FLAG_MSG_PRINT_GENERAL)) {
291                 return false;
292         }
293
294         if (!locking_init()) {
295                 return false;
296         }
297
298         messaging_register(msg_ctx, ev_ctx,
299                            MSG_SMB_CONF_UPDATED, smb_conf_updated);
300         messaging_register(msg_ctx, ev_ctx,
301                            MSG_PREFORK_PARENT_EVENT, parent_ping);
302
303         /* As soon as messaging is up check if pcap has been loaded already.
304          * If so then we probably missed a message and should load_printers()
305          * ourselves. If pcap has not been loaded yet, then ignore, we will get
306          * a message as soon as the bq process completes the reload. */
307         if (pcap_cache_loaded(NULL)) {
308                 load_printers(ev_ctx, msg_ctx);
309         }
310
311         /* try to reinit rpc queues */
312         spoolss_cb.init = spoolss_init_cb;
313         spoolss_cb.shutdown = spoolss_shutdown_cb;
314         spoolss_cb.private_data = msg_ctx;
315
316         status = rpc_winreg_init(NULL);
317         if (!NT_STATUS_IS_OK(status)) {
318                 DEBUG(0, ("Failed to register winreg rpc inteface! (%s)\n",
319                           nt_errstr(status)));
320                 return false;
321         }
322
323         status = rpc_spoolss_init(&spoolss_cb);
324         if (!NT_STATUS_IS_OK(status)) {
325                 DEBUG(0, ("Failed to register spoolss rpc inteface! (%s)\n",
326                           nt_errstr(status)));
327                 return false;
328         }
329
330         return true;
331 }
332
333 struct spoolss_children_data {
334         struct tevent_context *ev_ctx;
335         struct messaging_context *msg_ctx;
336         struct pf_worker_data *pf;
337         int listen_fd_size;
338         int *listen_fds;
339 };
340
341 static void spoolss_next_client(void *pvt);
342
343 static int spoolss_children_main(struct tevent_context *ev_ctx,
344                                  struct messaging_context *msg_ctx,
345                                  struct pf_worker_data *pf,
346                                  int child_id,
347                                  int listen_fd_size,
348                                  int *listen_fds,
349                                  void *private_data)
350 {
351         struct spoolss_children_data *data;
352         bool ok;
353         int ret = 0;
354
355         ok = spoolss_child_init(ev_ctx, child_id, pf);
356         if (!ok) {
357                 return 1;
358         }
359
360         data = talloc(ev_ctx, struct spoolss_children_data);
361         if (!data) {
362                 return 1;
363         }
364         data->pf = pf;
365         data->ev_ctx = ev_ctx;
366         data->msg_ctx = msg_ctx;
367         data->listen_fd_size = listen_fd_size;
368         data->listen_fds = listen_fds;
369
370         /* loop until it is time to exit */
371         while (pf->status != PF_WORKER_EXITING) {
372                 /* try to see if it is time to schedule the next client */
373                 spoolss_next_client(data);
374
375                 ret = tevent_loop_once(ev_ctx);
376                 if (ret != 0) {
377                         DEBUG(0, ("tevent_loop_once() exited with %d: %s\n",
378                                   ret, strerror(errno)));
379                         pf->status = PF_WORKER_EXITING;
380                 }
381         }
382
383         return ret;
384 }
385
386 static void spoolss_client_terminated(void *pvt)
387 {
388         struct spoolss_children_data *data;
389
390         data = talloc_get_type_abort(pvt, struct spoolss_children_data);
391
392         pfh_client_terminated(data->pf);
393
394         spoolss_next_client(pvt);
395 }
396
397 struct spoolss_new_client {
398         struct spoolss_children_data *data;
399         struct tsocket_address *srv_addr;
400         struct tsocket_address *cli_addr;
401 };
402
403 static void spoolss_handle_client(struct tevent_req *req);
404
405 static void spoolss_next_client(void *pvt)
406 {
407         struct tevent_req *req;
408         struct spoolss_children_data *data;
409         struct spoolss_new_client *next;
410
411         data = talloc_get_type_abort(pvt, struct spoolss_children_data);
412
413         if (!pfh_child_allowed_to_accept(data->pf)) {
414                 /* nothing to do for now we are already listening
415                  * or we are not allowed to listen further */
416                 return;
417         }
418
419         next = talloc_zero(data, struct spoolss_new_client);
420         if (!next) {
421                 DEBUG(1, ("Out of memory!?\n"));
422                 return;
423         }
424         next->data = data;
425
426         req = prefork_listen_send(next, data->ev_ctx, data->pf,
427                                   data->listen_fd_size,
428                                   data->listen_fds);
429         if (!req) {
430                 DEBUG(1, ("Failed to make listening request!?\n"));
431                 talloc_free(next);
432                 return;
433         }
434         tevent_req_set_callback(req, spoolss_handle_client, next);
435 }
436
437 static void spoolss_handle_client(struct tevent_req *req)
438 {
439         struct spoolss_children_data *data;
440         struct spoolss_new_client *client;
441         const DATA_BLOB ping = data_blob_null;
442         int ret;
443         int sd;
444
445         client = tevent_req_callback_data(req, struct spoolss_new_client);
446         data = client->data;
447
448         ret = prefork_listen_recv(req, client, &sd,
449                                   &client->srv_addr, &client->cli_addr);
450
451         /* this will free the request too */
452         talloc_free(client);
453
454         if (ret != 0) {
455                 DEBUG(6, ("No client connection was available after all!\n"));
456                 return;
457         }
458
459         /* Warn parent that our status changed */
460         messaging_send(data->msg_ctx, parent_id,
461                         MSG_PREFORK_CHILD_EVENT, &ping);
462
463         DEBUG(2, ("Spoolss preforked child %d got client connection!\n",
464                   (int)(data->pf->pid)));
465
466         named_pipe_accept_function(data->ev_ctx, data->msg_ctx,
467                                    SPOOLSS_PIPE_NAME, sd,
468                                    spoolss_client_terminated, data);
469 }
470
471 /* ==== Main Process Functions ==== */
472
473 extern pid_t background_lpq_updater_pid;
474 static char *bq_logfile;
475
476 static void check_updater_child(struct tevent_context *ev_ctx,
477                                 struct messaging_context *msg_ctx)
478 {
479         int status;
480         pid_t pid;
481
482         if (background_lpq_updater_pid == -1) {
483                 return;
484         }
485
486         pid = sys_waitpid(background_lpq_updater_pid, &status, WNOHANG);
487         if (pid > 0) {
488                 DEBUG(2, ("The background queue child died... Restarting!\n"));
489                 pid = start_background_queue(ev_ctx, msg_ctx, bq_logfile);
490                 background_lpq_updater_pid = pid;
491         }
492 }
493
494 static void child_ping(struct messaging_context *msg_ctx,
495                         void *private_data,
496                         uint32_t msg_type,
497                         struct server_id server_id,
498                         DATA_BLOB *data)
499 {
500         struct tevent_context *ev_ctx;
501
502         ev_ctx = talloc_get_type_abort(private_data, struct tevent_context);
503
504         DEBUG(10, ("Got message that a child changed status.\n"));
505         pfh_manage_pool(ev_ctx, msg_ctx, &pf_spoolss_cfg, spoolss_pool);
506 }
507
508 static bool spoolssd_schedule_check(struct tevent_context *ev_ctx,
509                                     struct messaging_context *msg_ctx,
510                                     struct timeval current_time);
511 static void spoolssd_check_children(struct tevent_context *ev_ctx,
512                                     struct tevent_timer *te,
513                                     struct timeval current_time,
514                                     void *pvt);
515
516 static void spoolssd_sigchld_handler(struct tevent_context *ev_ctx,
517                                      struct prefork_pool *pfp,
518                                      void *pvt)
519 {
520         struct messaging_context *msg_ctx;
521
522         msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
523
524         /* run pool management so we can fork/retire or increase
525          * the allowed connections per child based on load */
526         pfh_manage_pool(ev_ctx, msg_ctx, &pf_spoolss_cfg, spoolss_pool);
527
528         /* also check if the updater child is alive and well */
529         check_updater_child(ev_ctx, msg_ctx);
530 }
531
532 static bool spoolssd_setup_children_monitor(struct tevent_context *ev_ctx,
533                                             struct messaging_context *msg_ctx)
534 {
535         bool ok;
536
537         /* add our oun sigchld callback */
538         prefork_set_sigchld_callback(spoolss_pool,
539                                      spoolssd_sigchld_handler, msg_ctx);
540
541         ok = spoolssd_schedule_check(ev_ctx, msg_ctx,
542                                      tevent_timeval_current());
543         return ok;
544 }
545
546 static bool spoolssd_schedule_check(struct tevent_context *ev_ctx,
547                                     struct messaging_context *msg_ctx,
548                                     struct timeval current_time)
549 {
550         struct tevent_timer *te;
551         struct timeval next_event;
552
553         /* check situation again in 10 seconds */
554         next_event = tevent_timeval_current_ofs(10, 0);
555
556         /* TODO: check when the socket becomes readable, so that children
557          * are checked only when there is some activity ? */
558         te = tevent_add_timer(ev_ctx, spoolss_pool, next_event,
559                                 spoolssd_check_children, msg_ctx);
560         if (!te) {
561                 DEBUG(2, ("Failed to set up children monitoring!\n"));
562                 return false;
563         }
564
565         return true;
566 }
567
568 static void spoolssd_check_children(struct tevent_context *ev_ctx,
569                                     struct tevent_timer *te,
570                                     struct timeval current_time,
571                                     void *pvt)
572 {
573         struct messaging_context *msg_ctx;
574
575         msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
576
577         pfh_manage_pool(ev_ctx, msg_ctx, &pf_spoolss_cfg, spoolss_pool);
578
579         spoolssd_schedule_check(ev_ctx, msg_ctx, current_time);
580 }
581
582 static void print_queue_forward(struct messaging_context *msg,
583                                 void *private_data,
584                                 uint32_t msg_type,
585                                 struct server_id server_id,
586                                 DATA_BLOB *data)
587 {
588         messaging_send_buf(msg, pid_to_procid(background_lpq_updater_pid),
589                            MSG_PRINTER_UPDATE, data->data, data->length);
590 }
591
592 static char *get_bq_logfile(void)
593 {
594         char *lfile = lp_logfile(talloc_tos());
595         int rc;
596
597         if (lfile == NULL || lfile[0] == '\0') {
598                 rc = asprintf(&lfile, "%s/log.%s.bq",
599                                         get_dyn_LOGFILEBASE(), DAEMON_NAME);
600         } else {
601                 rc = asprintf(&lfile, "%s.bq", lp_logfile(talloc_tos()));
602         }
603         if (rc == -1) {
604                 lfile = NULL;
605         }
606         return lfile;
607 }
608
609 pid_t start_spoolssd(struct tevent_context *ev_ctx,
610                     struct messaging_context *msg_ctx)
611 {
612         enum rpc_service_mode_e epm_mode = rpc_epmapper_mode();
613         struct rpc_srv_callbacks spoolss_cb;
614         struct dcerpc_binding_vector *v;
615         TALLOC_CTX *mem_ctx;
616         pid_t pid;
617         NTSTATUS status;
618         int listen_fd;
619         int ret;
620         bool ok;
621
622         DEBUG(1, ("Forking SPOOLSS Daemon\n"));
623
624         /*
625          * Block signals before forking child as it will have to
626          * set its own handlers. Child will re-enable SIGHUP as
627          * soon as the handlers are set up.
628          */
629         BlockSignals(true, SIGTERM);
630         BlockSignals(true, SIGHUP);
631
632         pid = fork();
633
634         if (pid == -1) {
635                 DEBUG(0, ("Failed to fork SPOOLSS [%s]\n",
636                            strerror(errno)));
637         }
638
639         /* parent or error */
640         if (pid != 0) {
641
642                 /* Re-enable SIGHUP before returnig */
643                 BlockSignals(false, SIGTERM);
644                 BlockSignals(false, SIGHUP);
645                 return pid;
646         }
647
648         status = smbd_reinit_after_fork(msg_ctx, ev_ctx, true);
649         if (!NT_STATUS_IS_OK(status)) {
650                 DEBUG(0,("reinit_after_fork() failed\n"));
651                 smb_panic("reinit_after_fork() failed");
652         }
653
654         prctl_set_comment("spoolssd-master");
655
656         /* save the parent process id so the children can use it later */
657         parent_id = messaging_server_id(msg_ctx);
658
659         spoolss_reopen_logs(0);
660         pfh_daemon_config(DAEMON_NAME,
661                           &pf_spoolss_cfg,
662                           &default_pf_spoolss_cfg);
663
664         spoolss_setup_sig_term_handler(ev_ctx);
665         spoolss_setup_sig_hup_handler(ev_ctx, msg_ctx);
666
667         BlockSignals(false, SIGTERM);
668         BlockSignals(false, SIGHUP);
669
670         /* always start the backgroundqueue listner in spoolssd */
671         bq_logfile = get_bq_logfile();
672         pid = start_background_queue(ev_ctx, msg_ctx, bq_logfile);
673         if (pid > 0) {
674                 background_lpq_updater_pid = pid;
675         }
676
677         /* the listening fd must be created before the children are actually
678          * forked out. */
679         listen_fd = create_named_pipe_socket(SPOOLSS_PIPE_NAME);
680         if (listen_fd == -1) {
681                 exit(1);
682         }
683
684         ret = listen(listen_fd, pf_spoolss_cfg.max_allowed_clients);
685         if (ret == -1) {
686                 DEBUG(0, ("Failed to listen on spoolss pipe - %s\n",
687                           strerror(errno)));
688                 exit(1);
689         }
690
691         /* start children before any more initialization is done */
692         ok = prefork_create_pool(ev_ctx, /* mem_ctx */
693                                  ev_ctx, msg_ctx,
694                                  1, &listen_fd,
695                                  pf_spoolss_cfg.min_children,
696                                  pf_spoolss_cfg.max_children,
697                                  &spoolss_children_main, NULL,
698                                  &spoolss_pool);
699         if (!ok) {
700                 exit(1);
701         }
702
703         if (!serverid_register(messaging_server_id(msg_ctx),
704                                 FLAG_MSG_GENERAL |
705                                 FLAG_MSG_PRINT_GENERAL)) {
706                 exit(1);
707         }
708
709         if (!locking_init()) {
710                 exit(1);
711         }
712
713         messaging_register(msg_ctx, ev_ctx,
714                            MSG_SMB_CONF_UPDATED, smb_conf_updated);
715         messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
716                            print_queue_forward);
717         messaging_register(msg_ctx, ev_ctx,
718                            MSG_PREFORK_CHILD_EVENT, child_ping);
719
720         /*
721          * As soon as messaging is up check if pcap has been loaded already.
722          * If pcap has not been loaded yet, then ignore, as we will reload on
723          * client enumeration anyway.
724          */
725         if (pcap_cache_loaded(NULL)) {
726                 load_printers(ev_ctx, msg_ctx);
727         }
728
729         mem_ctx = talloc_new(NULL);
730         if (mem_ctx == NULL) {
731                 exit(1);
732         }
733
734         /*
735          * Initialize spoolss with an init function to convert printers first.
736          * static_init_rpc will try to initialize the spoolss server too but you
737          * can't register it twice.
738          */
739         spoolss_cb.init = spoolss_init_cb;
740         spoolss_cb.shutdown = spoolss_shutdown_cb;
741         spoolss_cb.private_data = msg_ctx;
742
743         status = rpc_winreg_init(NULL);
744         if (!NT_STATUS_IS_OK(status)) {
745                 DEBUG(0, ("Failed to register winreg rpc inteface! (%s)\n",
746                           nt_errstr(status)));
747                 exit(1);
748         }
749
750         status = rpc_spoolss_init(&spoolss_cb);
751         if (!NT_STATUS_IS_OK(status)) {
752                 DEBUG(0, ("Failed to register spoolss rpc inteface! (%s)\n",
753                           nt_errstr(status)));
754                 exit(1);
755         }
756
757         if (epm_mode != RPC_SERVICE_MODE_DISABLED &&
758             (lp_parm_bool(-1, "rpc_server", "register_embedded_np", false))) {
759                 status = dcerpc_binding_vector_new(mem_ctx, &v);
760                 if (!NT_STATUS_IS_OK(status)) {
761                         DEBUG(0, ("Failed to create binding vector (%s)\n",
762                                   nt_errstr(status)));
763                         exit(1);
764                 }
765
766                 status = dcerpc_binding_vector_add_np_default(&ndr_table_spoolss, v);
767                 if (!NT_STATUS_IS_OK(status)) {
768                         DEBUG(0, ("Failed to add np to binding vector (%s)\n",
769                                   nt_errstr(status)));
770                         exit(1);
771                 }
772
773                 status = rpc_ep_register(ev_ctx, msg_ctx, &ndr_table_spoolss, v);
774                 if (!NT_STATUS_IS_OK(status)) {
775                         DEBUG(0, ("Failed to register spoolss endpoint! (%s)\n",
776                                   nt_errstr(status)));
777                         exit(1);
778                 }
779         }
780
781         talloc_free(mem_ctx);
782
783         ok = spoolssd_setup_children_monitor(ev_ctx, msg_ctx);
784         if (!ok) {
785                 DEBUG(0, ("Failed to setup children monitoring!\n"));
786                 exit(1);
787         }
788
789         DEBUG(1, ("SPOOLSS Daemon Started (%u)\n", (unsigned int)getpid()));
790
791         pfh_manage_pool(ev_ctx, msg_ctx, &pf_spoolss_cfg, spoolss_pool);
792
793         /* loop forever */
794         ret = tevent_loop_wait(ev_ctx);
795
796         /* should not be reached */
797         DEBUG(0,("spoolssd tevent_loop_wait() exited with %d - %s\n",
798                  ret, (ret == 0) ? "out of events" : strerror(errno)));
799         exit(1);
800 }