s3:spoolssd Start spoolssd from printing_subsystem_init
[mat/samba.git] / source3 / printing / spoolssd.c
1 /*
2    Unix SMB/Netbios implementation.
3    SPOOLSS Daemon
4    Copyright (C) Simo Sorce 2010
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 "messages.h"
24 #include "include/printing.h"
25 #include "printing/nt_printing_migrate_internal.h"
26 #include "printing/queue_process.h"
27 #include "printing/pcap.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/spoolss/srv_spoolss_nt.h"
34 #include "librpc/rpc/dcerpc_ep.h"
35 #include "lib/server_prefork.h"
36
37 #define SPOOLSS_PIPE_NAME "spoolss"
38 #define DAEMON_NAME "spoolssd"
39
40 #define SPOOLSS_MIN_CHILDREN 5
41 #define SPOOLSS_MAX_CHILDREN 25
42 #define SPOOLSS_SPAWN_RATE 5
43 #define SPOOLSS_MIN_LIFE 60 /* 1 minute minimum life time */
44
45 #define SPOOLSS_ALL_FINE 0x00
46 #define SPOOLSS_NEW_MAX  0x01
47 #define SPOLLSS_ENOSPC   0x02
48
49 static int spoolss_min_children;
50 static int spoolss_max_children;
51 static int spoolss_spawn_rate;
52 static int spoolss_prefork_status;
53
54 static void spoolss_prefork_config(void)
55 {
56         static int spoolss_prefork_config_init = false;
57         const char *prefork_str;
58         int min, max, rate;
59         bool use_defaults = false;
60         int ret;
61
62         if (!spoolss_prefork_config_init) {
63                 spoolss_prefork_status = SPOOLSS_ALL_FINE;
64                 spoolss_min_children = 0;
65                 spoolss_max_children = 0;
66                 spoolss_spawn_rate = 0;
67                 spoolss_prefork_config_init = true;
68         }
69
70         prefork_str = lp_parm_const_string(GLOBAL_SECTION_SNUM,
71                                            "spoolssd", "prefork", "none");
72         if (strcmp(prefork_str, "none") == 0) {
73                 use_defaults = true;
74         } else {
75                 ret = sscanf(prefork_str, "%d:%d:%d", &min, &max, &rate);
76                 if (ret != 3) {
77                         DEBUG(0, ("invalid format for spoolssd:prefork!\n"));
78                         use_defaults = true;
79                 }
80         }
81
82         if (use_defaults) {
83                 min = SPOOLSS_MIN_CHILDREN;
84                 max = SPOOLSS_MAX_CHILDREN;
85                 rate = SPOOLSS_SPAWN_RATE;
86         }
87
88         if (max > spoolss_max_children && spoolss_max_children != 0) {
89                 spoolss_prefork_status |= SPOOLSS_NEW_MAX;
90         }
91
92         spoolss_min_children = min;
93         spoolss_max_children = max;
94         spoolss_spawn_rate = rate;
95 }
96
97 static void spoolss_reopen_logs(void)
98 {
99         char *lfile = lp_logfile();
100         int rc;
101
102         if (lfile == NULL || lfile[0] == '\0') {
103                 rc = asprintf(&lfile, "%s/log.%s", get_dyn_LOGFILEBASE(), DAEMON_NAME);
104                 if (rc > 0) {
105                         lp_set_logfile(lfile);
106                         SAFE_FREE(lfile);
107                 }
108         } else {
109                 if (strstr(lfile, DAEMON_NAME) == NULL) {
110                         rc = asprintf(&lfile, "%s.%s", lp_logfile(), DAEMON_NAME);
111                         if (rc > 0) {
112                                 lp_set_logfile(lfile);
113                                 SAFE_FREE(lfile);
114                         }
115                 }
116         }
117
118         reopen_logs();
119 }
120
121 static void update_conf(struct tevent_context *ev,
122                         struct messaging_context *msg)
123 {
124         change_to_root_user();
125         lp_load(get_dyn_CONFIGFILE(), true, false, false, true);
126         reload_printers(ev, msg);
127
128         spoolss_reopen_logs();
129         spoolss_prefork_config();
130 }
131
132 static void smb_conf_updated(struct messaging_context *msg,
133                              void *private_data,
134                              uint32_t msg_type,
135                              struct server_id server_id,
136                              DATA_BLOB *data)
137 {
138         struct tevent_context *ev_ctx = talloc_get_type_abort(private_data,
139                                                              struct tevent_context);
140
141         DEBUG(10, ("Got message saying smb.conf was updated. Reloading.\n"));
142         update_conf(ev_ctx, msg);
143 }
144
145 static void spoolss_sig_term_handler(struct tevent_context *ev,
146                                      struct tevent_signal *se,
147                                      int signum,
148                                      int count,
149                                      void *siginfo,
150                                      void *private_data)
151 {
152         exit_server_cleanly("termination signal");
153 }
154
155 static void spoolss_setup_sig_term_handler(struct tevent_context *ev_ctx)
156 {
157         struct tevent_signal *se;
158
159         se = tevent_add_signal(ev_ctx,
160                                ev_ctx,
161                                SIGTERM, 0,
162                                spoolss_sig_term_handler,
163                                NULL);
164         if (!se) {
165                 exit_server("failed to setup SIGTERM handler");
166         }
167 }
168
169 struct spoolss_hup_ctx {
170         struct messaging_context *msg_ctx;
171         struct prefork_pool *pfp;
172 };
173
174 static void spoolss_sig_hup_handler(struct tevent_context *ev,
175                                     struct tevent_signal *se,
176                                     int signum,
177                                     int count,
178                                     void *siginfo,
179                                     void *pvt)
180 {
181         struct spoolss_hup_ctx *hup_ctx;
182
183         hup_ctx = talloc_get_type_abort(pvt, struct spoolss_hup_ctx);
184
185         DEBUG(1,("Reloading printers after SIGHUP\n"));
186         update_conf(ev, hup_ctx->msg_ctx);
187
188         /* relay to all children */
189         prefork_send_signal_to_all(hup_ctx->pfp, SIGHUP);
190 }
191
192 static void spoolss_setup_sig_hup_handler(struct tevent_context *ev_ctx,
193                                           struct prefork_pool *pfp,
194                                           struct messaging_context *msg_ctx)
195 {
196         struct spoolss_hup_ctx *hup_ctx;
197         struct tevent_signal *se;
198
199         hup_ctx = talloc(ev_ctx, struct spoolss_hup_ctx);
200         if (!hup_ctx) {
201                 exit_server("failed to setup SIGHUP handler");
202         }
203         hup_ctx->pfp = pfp;
204         hup_ctx->msg_ctx = msg_ctx;
205
206         se = tevent_add_signal(ev_ctx,
207                                ev_ctx,
208                                SIGHUP, 0,
209                                spoolss_sig_hup_handler,
210                                hup_ctx);
211         if (!se) {
212                 exit_server("failed to setup SIGHUP handler");
213         }
214 }
215
216 static bool spoolss_init_cb(void *ptr)
217 {
218         struct messaging_context *msg_ctx = talloc_get_type_abort(
219                 ptr, struct messaging_context);
220
221         return nt_printing_tdb_migrate(msg_ctx);
222 }
223
224 static bool spoolss_shutdown_cb(void *ptr)
225 {
226         srv_spoolss_cleanup();
227
228         return true;
229 }
230
231 /* Childrens */
232
233 struct spoolss_chld_sig_hup_ctx {
234         struct messaging_context *msg_ctx;
235         struct pf_worker_data *pf;
236 };
237
238 static void spoolss_chld_sig_hup_handler(struct tevent_context *ev,
239                                          struct tevent_signal *se,
240                                          int signum,
241                                          int count,
242                                          void *siginfo,
243                                          void *pvt)
244 {
245         struct spoolss_chld_sig_hup_ctx *shc;
246
247         shc = talloc_get_type_abort(pvt, struct spoolss_chld_sig_hup_ctx);
248
249         /* avoid wasting CPU cycles if we are going to exit soon anyways */
250         if (shc->pf != NULL &&
251             shc->pf->cmds == PF_SRV_MSG_EXIT) {
252                 return;
253         }
254
255         change_to_root_user();
256         DEBUG(1,("Reloading printers after SIGHUP\n"));
257         reload_printers(ev, shc->msg_ctx);
258         spoolss_reopen_logs();
259 }
260
261 static bool spoolss_setup_chld_hup_handler(struct tevent_context *ev_ctx,
262                                            struct pf_worker_data *pf,
263                                            struct messaging_context *msg_ctx)
264 {
265         struct spoolss_chld_sig_hup_ctx *shc;
266         struct tevent_signal *se;
267
268         shc = talloc(ev_ctx, struct spoolss_chld_sig_hup_ctx);
269         if (!shc) {
270                 DEBUG(1, ("failed to setup SIGHUP handler"));
271                 return false;
272         }
273         shc->pf = pf;
274         shc->msg_ctx = msg_ctx;
275
276         se = tevent_add_signal(ev_ctx,
277                                ev_ctx,
278                                SIGHUP, 0,
279                                spoolss_chld_sig_hup_handler,
280                                shc);
281         if (!se) {
282                 DEBUG(1, ("failed to setup SIGHUP handler"));
283                 return false;
284         }
285
286         return true;
287 }
288
289 static bool spoolss_child_init(struct tevent_context *ev_ctx,
290                                         struct pf_worker_data *pf)
291 {
292         NTSTATUS status;
293         struct rpc_srv_callbacks spoolss_cb;
294         struct messaging_context *msg_ctx = server_messaging_context();
295         bool ok;
296
297         status = reinit_after_fork(msg_ctx, ev_ctx,
298                                    procid_self(), true);
299         if (!NT_STATUS_IS_OK(status)) {
300                 DEBUG(0,("reinit_after_fork() failed\n"));
301                 smb_panic("reinit_after_fork() failed");
302         }
303
304         spoolss_reopen_logs();
305
306         ok = spoolss_setup_chld_hup_handler(ev_ctx, pf, msg_ctx);
307         if (!ok) {
308                 return false;
309         }
310
311         if (!serverid_register(procid_self(), FLAG_MSG_GENERAL)) {
312                 return false;
313         }
314
315         if (!locking_init()) {
316                 return false;
317         }
318
319         messaging_register(msg_ctx, ev_ctx,
320                            MSG_SMB_CONF_UPDATED, smb_conf_updated);
321
322         /* try to reinit rpc queues */
323         spoolss_cb.init = spoolss_init_cb;
324         spoolss_cb.shutdown = spoolss_shutdown_cb;
325         spoolss_cb.private_data = msg_ctx;
326
327         status = rpc_winreg_init(NULL);
328         if (!NT_STATUS_IS_OK(status)) {
329                 DEBUG(0, ("Failed to register winreg rpc inteface! (%s)\n",
330                           nt_errstr(status)));
331                 return false;
332         }
333
334         status = rpc_spoolss_init(&spoolss_cb);
335         if (!NT_STATUS_IS_OK(status)) {
336                 DEBUG(0, ("Failed to register spoolss rpc inteface! (%s)\n",
337                           nt_errstr(status)));
338                 return false;
339         }
340
341         reload_printers(ev_ctx, msg_ctx);
342
343         return true;
344 }
345
346 struct spoolss_children_data {
347         struct tevent_context *ev_ctx;
348         struct messaging_context *msg_ctx;
349         struct pf_worker_data *pf;
350         int listen_fd_size;
351         int *listen_fds;
352         int lock_fd;
353
354         bool listening;
355 };
356
357 static void spoolss_next_client(void *pvt);
358
359 static int spoolss_children_main(struct tevent_context *ev_ctx,
360                                  struct pf_worker_data *pf,
361                                  int listen_fd_size,
362                                  int *listen_fds,
363                                  int lock_fd,
364                                  void *private_data)
365 {
366         struct messaging_context *msg_ctx = server_messaging_context();
367         struct spoolss_children_data *data;
368         bool ok;
369         int ret;
370
371         ok = spoolss_child_init(ev_ctx, pf);
372         if (!ok) {
373                 return 1;
374         }
375
376         data = talloc(ev_ctx, struct spoolss_children_data);
377         if (!data) {
378                 return 1;
379         }
380         data->pf = pf;
381         data->ev_ctx = ev_ctx;
382         data->msg_ctx = msg_ctx;
383         data->lock_fd = lock_fd;
384         data->listen_fd_size = listen_fd_size;
385         data->listen_fds = listen_fds;
386         data->listening = false;
387
388         /* loop until it is time to exit */
389         while (pf->status != PF_WORKER_EXITING) {
390                 /* try to see if it is time to schedule the next client */
391                 spoolss_next_client(data);
392
393                 ret = tevent_loop_once(ev_ctx);
394                 if (ret != 0) {
395                         DEBUG(0, ("tevent_loop_once() exited with %d: %s\n",
396                                   ret, strerror(errno)));
397                         pf->status = PF_WORKER_EXITING;
398                 }
399         }
400
401         return ret;
402 }
403
404 static void spoolss_client_terminated(void *pvt)
405 {
406         struct spoolss_children_data *data;
407
408         data = talloc_get_type_abort(pvt, struct spoolss_children_data);
409
410         if (data->pf->num_clients) {
411                 data->pf->num_clients--;
412         } else {
413                 DEBUG(2, ("Invalid num clients, aborting!\n"));
414                 data->pf->status = PF_WORKER_EXITING;
415                 return;
416         }
417
418         spoolss_next_client(pvt);
419 }
420
421 struct spoolss_new_client {
422         struct spoolss_children_data *data;
423         struct sockaddr_un sunaddr;
424         socklen_t addrlen;
425 };
426
427 static void spoolss_handle_client(struct tevent_req *req);
428
429 static void spoolss_next_client(void *pvt)
430 {
431         struct tevent_req *req;
432         struct spoolss_children_data *data;
433         struct spoolss_new_client *next;
434
435         data = talloc_get_type_abort(pvt, struct spoolss_children_data);
436
437         if (data->pf->num_clients == 0) {
438                 data->pf->status = PF_WORKER_IDLE;
439         }
440
441         if (data->pf->cmds == PF_SRV_MSG_EXIT) {
442                 DEBUG(2, ("Parent process commands we terminate!\n"));
443                 return;
444         }
445
446         if (data->listening ||
447             data->pf->num_clients >= data->pf->allowed_clients) {
448                 /* nothing to do for now we are already listening
449                  * or reached the number of clients we are allowed
450                  * to handle in parallel */
451                 return;
452         }
453
454         next = talloc_zero(data, struct spoolss_new_client);
455         if (!next) {
456                 DEBUG(1, ("Out of memory!?\n"));
457                 return;
458         }
459         next->data = data;
460         next->addrlen = sizeof(next->sunaddr);
461
462         req = prefork_listen_send(next, data->ev_ctx, data->pf,
463                                   data->listen_fd_size,
464                                   data->listen_fds,
465                                   data->lock_fd,
466                                   (struct sockaddr *)&next->sunaddr,
467                                   &next->addrlen);
468         if (!req) {
469                 DEBUG(1, ("Failed to make listening request!?\n"));
470                 talloc_free(next);
471                 return;
472         }
473         tevent_req_set_callback(req, spoolss_handle_client, next);
474
475         data->listening = true;
476 }
477
478 static void spoolss_handle_client(struct tevent_req *req)
479 {
480         struct spoolss_children_data *data;
481         struct spoolss_new_client *client;
482         int ret;
483         int sd;
484
485         client = tevent_req_callback_data(req, struct spoolss_new_client);
486         data = client->data;
487
488         ret = prefork_listen_recv(req, &sd);
489
490         /* this will free the request too */
491         talloc_free(client);
492         /* we are done listening */
493         data->listening = false;
494
495         if (ret > 0) {
496                 DEBUG(1, ("Failed to accept client connection!\n"));
497                 /* bail out if we are not serving any other client */
498                 if (data->pf->num_clients == 0) {
499                         data->pf->status = PF_WORKER_EXITING;
500                 }
501                 return;
502         }
503
504         if (ret == -2) {
505                 DEBUG(1, ("Server asks us to die!\n"));
506                 data->pf->status = PF_WORKER_EXITING;
507                 return;
508         }
509
510         DEBUG(2, ("Spoolss preforked child %d got client connection!\n",
511                   (int)(data->pf->pid)));
512
513         named_pipe_accept_function(data->ev_ctx, data->msg_ctx,
514                                    SPOOLSS_PIPE_NAME, sd,
515                                    spoolss_client_terminated, data);
516 }
517
518 /* ==== Main Process Functions ==== */
519
520 extern pid_t background_lpq_updater_pid;
521
522 static void check_updater_child(void)
523 {
524         int status;
525         pid_t pid;
526
527         if (background_lpq_updater_pid == -1) {
528                 return;
529         }
530
531         pid = sys_waitpid(background_lpq_updater_pid, &status, WNOHANG);
532         if (pid > 0) {
533                 DEBUG(2, ("The background queue child died... Restarting!\n"));
534                 pid = start_background_queue(server_event_context(),
535                                              server_messaging_context());
536                 background_lpq_updater_pid = pid;
537         }
538 }
539
540 static void spoolssd_sig_chld_handler(struct tevent_context *ev_ctx,
541                                       struct tevent_signal *se,
542                                       int signum, int count,
543                                       void *siginfo, void *pvt)
544 {
545         struct prefork_pool *pfp;
546         int active, total;
547         int n, r;
548
549         pfp = talloc_get_type_abort(pvt, struct prefork_pool);
550
551         /* run the cleanup function to make sure all dead children are
552          * properly and timely retired. */
553         prefork_cleanup_loop(pfp);
554
555         /* now check we do not descend below the minimum */
556         active = prefork_count_active_children(pfp, &total);
557
558         n = 0;
559         if (total < spoolss_min_children) {
560                 n = total - spoolss_min_children;
561         } else if (total - active < (total / 4)) {
562                 n = spoolss_min_children;
563         }
564
565         if (n > 0) {
566                 r = prefork_add_children(ev_ctx, pfp, n);
567                 if (r < n) {
568                         DEBUG(10, ("Tried to start %d children but only,"
569                                    "%d were actually started.!\n", n, r));
570                 }
571         }
572
573         /* also check if the updater child is alive and well */
574         check_updater_child();
575 }
576
577 static bool spoolssd_setup_sig_chld_handler(struct tevent_context *ev_ctx,
578                                             struct prefork_pool *pfp)
579 {
580         struct tevent_signal *se;
581
582         se = tevent_add_signal(ev_ctx, ev_ctx, SIGCHLD, 0,
583                                 spoolssd_sig_chld_handler, pfp);
584         if (!se) {
585                 DEBUG(0, ("Failed to setup SIGCHLD handler!\n"));
586                 return false;
587         }
588
589         return true;
590 }
591
592 static bool spoolssd_schedule_check(struct tevent_context *ev_ctx,
593                                     struct prefork_pool *pfp,
594                                     struct timeval current_time);
595 static void spoolssd_check_children(struct tevent_context *ev_ctx,
596                                     struct tevent_timer *te,
597                                     struct timeval current_time,
598                                     void *pvt);
599
600 static bool spoolssd_setup_children_monitor(struct tevent_context *ev_ctx,
601                                             struct prefork_pool *pfp)
602 {
603         bool ok;
604
605         ok = spoolssd_setup_sig_chld_handler(ev_ctx, pfp);
606         if (!ok) {
607                 return false;
608         }
609
610         ok = spoolssd_schedule_check(ev_ctx, pfp, tevent_timeval_current());
611         return ok;
612 }
613
614 static bool spoolssd_schedule_check(struct tevent_context *ev_ctx,
615                                     struct prefork_pool *pfp,
616                                     struct timeval current_time)
617 {
618         struct tevent_timer *te;
619         struct timeval next_event;
620
621         /* check situation again in 10 seconds */
622         next_event = tevent_timeval_current_ofs(10, 0);
623
624         /* TODO: check when the socket becomes readable, so that children
625          * are checked only when there is some activity ? */
626         te = tevent_add_timer(ev_ctx, pfp, next_event,
627                                 spoolssd_check_children, pfp);
628         if (!te) {
629                 DEBUG(2, ("Failed to set up children monitoring!\n"));
630                 return false;
631         }
632
633         return true;
634 }
635
636 static void spoolssd_check_children(struct tevent_context *ev_ctx,
637                                     struct tevent_timer *te,
638                                     struct timeval current_time,
639                                     void *pvt)
640 {
641         struct prefork_pool *pfp;
642         int active, total;
643         int ret, n;
644
645         pfp = talloc_get_type_abort(pvt, struct prefork_pool);
646
647         if ((spoolss_prefork_status & SPOOLSS_NEW_MAX) &&
648             !(spoolss_prefork_status & SPOLLSS_ENOSPC)) {
649                 ret = prefork_expand_pool(pfp, spoolss_max_children);
650                 if (ret == ENOSPC) {
651                         spoolss_prefork_status |= SPOLLSS_ENOSPC;
652                 }
653                 spoolss_prefork_status &= ~SPOOLSS_NEW_MAX;
654         }
655
656         active = prefork_count_active_children(pfp, &total);
657
658         if (total - active < spoolss_spawn_rate) {
659                 n = prefork_add_children(ev_ctx, pfp, spoolss_spawn_rate);
660                 if (n < spoolss_spawn_rate) {
661                         DEBUG(10, ("Tried to start 5 children but only,"
662                                    "%d were actually started.!\n", n));
663                 }
664         }
665
666         if (total - active > spoolss_min_children) {
667                 if ((total - spoolss_min_children) >= spoolss_spawn_rate) {
668                         prefork_retire_children(pfp, spoolss_spawn_rate,
669                                                 time(NULL) - SPOOLSS_MIN_LIFE);
670                 }
671         }
672
673         ret = spoolssd_schedule_check(ev_ctx, pfp, current_time);
674 }
675
676 static void print_queue_forward(struct messaging_context *msg,
677                                 void *private_data,
678                                 uint32_t msg_type,
679                                 struct server_id server_id,
680                                 DATA_BLOB *data)
681 {
682         messaging_send_buf(msg, pid_to_procid(background_lpq_updater_pid),
683                            MSG_PRINTER_UPDATE, data->data, data->length);
684 }
685
686 pid_t start_spoolssd(struct tevent_context *ev_ctx,
687                     struct messaging_context *msg_ctx)
688 {
689         struct prefork_pool *pool;
690         struct rpc_srv_callbacks spoolss_cb;
691         struct dcerpc_binding_vector *v;
692         TALLOC_CTX *mem_ctx;
693         pid_t pid;
694         NTSTATUS status;
695         int listen_fd;
696         int ret;
697         bool ok;
698
699         DEBUG(1, ("Forking SPOOLSS Daemon\n"));
700
701         pid = sys_fork();
702
703         if (pid == -1) {
704                 DEBUG(0, ("Failed to fork SPOOLSS [%s]\n",
705                            strerror(errno)));
706         }
707         if (pid != 0) {
708                 /* parent or error */
709                 return pid;
710         }
711
712         /* child */
713         close_low_fds(false);
714
715         status = reinit_after_fork(msg_ctx,
716                                    ev_ctx,
717                                    procid_self(), true);
718         if (!NT_STATUS_IS_OK(status)) {
719                 DEBUG(0,("reinit_after_fork() failed\n"));
720                 smb_panic("reinit_after_fork() failed");
721         }
722
723         spoolss_reopen_logs();
724         spoolss_prefork_config();
725
726         /* Publish nt printers, this requires a working winreg pipe */
727         pcap_cache_reload(ev_ctx, msg_ctx, &reload_printers);
728
729         /* always start the backgroundqueue listner in spoolssd */
730         pid = start_background_queue(ev_ctx, msg_ctx);
731         if (pid > 0) {
732                 background_lpq_updater_pid = pid;
733         }
734
735         /* the listening fd must be created before the children are actually
736          * forked out. */
737         listen_fd = create_named_pipe_socket(SPOOLSS_PIPE_NAME);
738         if (listen_fd == -1) {
739                 exit(1);
740         }
741
742         ret = listen(listen_fd, spoolss_max_children);
743         if (ret == -1) {
744                 DEBUG(0, ("Failed to listen on spoolss pipe - %s\n",
745                           strerror(errno)));
746                 exit(1);
747         }
748
749
750         /* start children before any more initialization is done */
751         ok = prefork_create_pool(ev_ctx, ev_ctx, 1, &listen_fd,
752                                  spoolss_min_children,
753                                  spoolss_max_children,
754                                  &spoolss_children_main, NULL,
755                                  &pool);
756
757         spoolss_setup_sig_term_handler(ev_ctx);
758         spoolss_setup_sig_hup_handler(ev_ctx, pool, msg_ctx);
759
760         if (!serverid_register(procid_self(),
761                                 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
762                                 |FLAG_MSG_PRINT_GENERAL)) {
763                 exit(1);
764         }
765
766         if (!locking_init()) {
767                 exit(1);
768         }
769
770         messaging_register(msg_ctx, ev_ctx,
771                            MSG_SMB_CONF_UPDATED, smb_conf_updated);
772         messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
773                            print_queue_forward);
774
775         mem_ctx = talloc_new(NULL);
776         if (mem_ctx == NULL) {
777                 exit(1);
778         }
779
780         /*
781          * Initialize spoolss with an init function to convert printers first.
782          * static_init_rpc will try to initialize the spoolss server too but you
783          * can't register it twice.
784          */
785         spoolss_cb.init = spoolss_init_cb;
786         spoolss_cb.shutdown = spoolss_shutdown_cb;
787         spoolss_cb.private_data = msg_ctx;
788
789         status = rpc_winreg_init(NULL);
790         if (!NT_STATUS_IS_OK(status)) {
791                 DEBUG(0, ("Failed to register winreg rpc inteface! (%s)\n",
792                           nt_errstr(status)));
793                 exit(1);
794         }
795
796         status = rpc_spoolss_init(&spoolss_cb);
797         if (!NT_STATUS_IS_OK(status)) {
798                 DEBUG(0, ("Failed to register spoolss rpc inteface! (%s)\n",
799                           nt_errstr(status)));
800                 exit(1);
801         }
802
803         status = dcerpc_binding_vector_new(mem_ctx, &v);
804         if (!NT_STATUS_IS_OK(status)) {
805                 DEBUG(0, ("Failed to create binding vector (%s)\n",
806                           nt_errstr(status)));
807                 exit(1);
808         }
809
810         status = dcerpc_binding_vector_add_np_default(&ndr_table_spoolss, v);
811         if (!NT_STATUS_IS_OK(status)) {
812                 DEBUG(0, ("Failed to add np to binding vector (%s)\n",
813                           nt_errstr(status)));
814                 exit(1);
815         }
816
817         status = rpc_ep_register(ev_ctx, msg_ctx, &ndr_table_spoolss, v);
818         if (!NT_STATUS_IS_OK(status)) {
819                 DEBUG(0, ("Failed to register spoolss endpoint! (%s)\n",
820                           nt_errstr(status)));
821                 exit(1);
822         }
823
824         talloc_free(mem_ctx);
825
826         ok = spoolssd_setup_children_monitor(ev_ctx, pool);
827         if (!ok) {
828                 DEBUG(0, ("Failed to setup children monitoring!\n"));
829                 exit(1);
830         }
831
832         DEBUG(1, ("SPOOLSS Daemon Started (%d)\n", getpid()));
833
834         /* loop forever */
835         ret = tevent_loop_wait(ev_ctx);
836
837         /* should not be reached */
838         DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
839                  ret, (ret == 0) ? "out of events" : strerror(errno)));
840         exit(1);
841 }