s3-lsasd: Create a lsa service daemon.
[amitay/samba.git] / source3 / rpc_server / lsasd.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *
4  *  LSA service daemon
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 "serverid.h"
24 #include "messages.h"
25 #include "ntdomain.h"
26
27 #include "../lib/tsocket/tsocket.h"
28 #include "lib/server_prefork.h"
29 #include "librpc/rpc/dcerpc_ep.h"
30
31 #include "rpc_server/rpc_server.h"
32 #include "rpc_server/rpc_ep_register.h"
33 #include "rpc_server/rpc_sock_helper.h"
34
35 #include "librpc/gen_ndr/srv_lsa.h"
36 #include "librpc/gen_ndr/srv_samr.h"
37 #include "librpc/gen_ndr/srv_netlogon.h"
38
39 #define DAEMON_NAME "lsasd"
40
41 #define LSASD_MIN_CHILDREN 5
42 #define LSASD_MAX_CHILDREN 25
43 #define LSASD_SPAWN_RATE   5
44 #define LSASD_MIN_LIFE     60 /* 1 minute minimum life time */
45
46 #define LSASD_MAX_SOCKETS 64
47
48 #define LSASD_ALL_FINE 0x00
49 #define LSASD_NEW_MAX  0x01
50 #define LSASD_ENOSPC   0x02
51
52 static int lsasd_min_children;
53 static int lsasd_max_children;
54 static int lsasd_spawn_rate;
55 static int lsasd_prefork_status;
56
57 void start_lsasd(struct tevent_context *ev_ctx,
58                  struct messaging_context *msg_ctx);
59
60 static void lsasd_prefork_config(void)
61 {
62         static int lsasd_prefork_config_init = false;
63         const char *prefork_str;
64         int min, max, rate;
65         bool use_defaults = false;
66         int ret;
67
68         if (!lsasd_prefork_config_init) {
69                 lsasd_prefork_status = LSASD_ALL_FINE;
70                 lsasd_min_children = 0;
71                 lsasd_max_children = 0;
72                 lsasd_spawn_rate = 0;
73                 lsasd_prefork_config_init = true;
74         }
75
76         prefork_str = lp_parm_const_string(GLOBAL_SECTION_SNUM,
77                                            "lsasd", "prefork", "none");
78         if (strcmp(prefork_str, "none") == 0) {
79                 use_defaults = true;
80         } else {
81                 ret = sscanf(prefork_str, "%d:%d:%d", &min, &max, &rate);
82                 if (ret != 3) {
83                         DEBUG(0, ("invalid format for lsasd:prefork!\n"));
84                         use_defaults = true;
85                 }
86         }
87
88         if (use_defaults) {
89                 min = LSASD_MIN_CHILDREN;
90                 max = LSASD_MAX_CHILDREN;
91                 rate = LSASD_SPAWN_RATE;
92         }
93
94         if (max > lsasd_max_children && lsasd_max_children != 0) {
95                 lsasd_prefork_status |= LSASD_NEW_MAX;
96         }
97
98         lsasd_min_children = min;
99         lsasd_max_children = max;
100         lsasd_spawn_rate = rate;
101 }
102
103 static void lsasd_reopen_logs(int child_id)
104 {
105         char *lfile = lp_logfile();
106         char *extension;
107         int rc;
108
109         if (child_id) {
110                 rc = asprintf(&extension, "%s.%d", DAEMON_NAME, child_id);
111         } else {
112                 rc = asprintf(&extension, "%s", DAEMON_NAME);
113         }
114         if (rc == -1) {
115                 return;
116         }
117
118         rc = 0;
119         if (lfile == NULL || lfile[0] == '\0') {
120                 rc = asprintf(&lfile, "%s/log.%s",
121                               get_dyn_LOGFILEBASE(), extension);
122         } else {
123                 if (strstr(lfile, extension) == NULL) {
124                         if (child_id) {
125                                 rc = asprintf(&lfile, "%s.%d",
126                                                 lp_logfile(),
127                                                 child_id);
128                         } else {
129                                 rc = asprintf(&lfile, "%s.%s",
130                                                 lp_logfile(),
131                                                 extension);
132                         }
133                 }
134         }
135
136         if (rc > 0) {
137                 lp_set_logfile(lfile);
138                 SAFE_FREE(lfile);
139         }
140
141         SAFE_FREE(extension);
142
143         reopen_logs();
144 }
145
146 static void lsasd_smb_conf_updated(struct messaging_context *msg,
147                                   void *private_data,
148                                   uint32_t msg_type,
149                                   struct server_id server_id,
150                                   DATA_BLOB *data)
151 {
152         DEBUG(10, ("Got message saying smb.conf was updated. Reloading.\n"));
153         change_to_root_user();
154         lp_load(get_dyn_CONFIGFILE(), true, false, false, true);
155
156         lsasd_reopen_logs(0);
157         lsasd_prefork_config();
158 }
159
160 static void lsasd_sig_term_handler(struct tevent_context *ev,
161                                   struct tevent_signal *se,
162                                   int signum,
163                                   int count,
164                                   void *siginfo,
165                                   void *private_data)
166 {
167         rpc_netlogon_shutdown();
168         rpc_samr_shutdown();
169         rpc_lsarpc_shutdown();
170
171         DEBUG(0, ("termination signal\n"));
172         exit(0);
173 }
174
175 static void lsasd_setup_sig_term_handler(struct tevent_context *ev_ctx)
176 {
177         struct tevent_signal *se;
178
179         se = tevent_add_signal(ev_ctx,
180                                ev_ctx,
181                                SIGTERM, 0,
182                                lsasd_sig_term_handler,
183                                NULL);
184         if (!se) {
185                 DEBUG(0, ("failed to setup SIGTERM handler\n"));
186                 exit(1);
187         }
188 }
189
190 struct lsasd_hup_ctx {
191         struct messaging_context *msg_ctx;
192         struct prefork_pool *pfp;
193 };
194
195 static void lsasd_sig_hup_handler(struct tevent_context *ev,
196                                     struct tevent_signal *se,
197                                     int signum,
198                                     int count,
199                                     void *siginfo,
200                                     void *pvt)
201 {
202         struct lsasd_hup_ctx *hup_ctx;
203
204         hup_ctx = talloc_get_type_abort(pvt, struct lsasd_hup_ctx);
205
206         change_to_root_user();
207         lp_load(get_dyn_CONFIGFILE(), true, false, false, true);
208
209         lsasd_reopen_logs(0);
210         lsasd_prefork_config();
211
212         /* relay to all children */
213         prefork_send_signal_to_all(hup_ctx->pfp, SIGHUP);
214 }
215
216 static void lsasd_setup_sig_hup_handler(struct tevent_context *ev_ctx,
217                                         struct prefork_pool *pfp,
218                                         struct messaging_context *msg_ctx)
219 {
220         struct lsasd_hup_ctx *hup_ctx;
221         struct tevent_signal *se;
222
223         hup_ctx = talloc(ev_ctx, struct lsasd_hup_ctx);
224         if (!hup_ctx) {
225                 DEBUG(0, ("failed to setup SIGHUP handler\n"));
226                 exit(1);
227         }
228         hup_ctx->pfp = pfp;
229         hup_ctx->msg_ctx = msg_ctx;
230
231         se = tevent_add_signal(ev_ctx,
232                                ev_ctx,
233                                SIGHUP, 0,
234                                lsasd_sig_hup_handler,
235                                hup_ctx);
236         if (!se) {
237                 DEBUG(0, ("failed to setup SIGHUP handler\n"));
238                 exit(1);
239         }
240 }
241
242 /**********************************************************
243  * Children
244  **********************************************************/
245
246 struct lsasd_chld_sig_hup_ctx {
247         struct messaging_context *msg_ctx;
248         struct pf_worker_data *pf;
249         int child_id;
250 };
251
252 static void lsasd_chld_sig_hup_handler(struct tevent_context *ev,
253                                          struct tevent_signal *se,
254                                          int signum,
255                                          int count,
256                                          void *siginfo,
257                                          void *pvt)
258 {
259         struct lsasd_chld_sig_hup_ctx *shc;
260
261         shc = talloc_get_type_abort(pvt, struct lsasd_chld_sig_hup_ctx);
262
263         /* avoid wasting CPU cycles if we are going to exit soon anyways */
264         if (shc->pf != NULL &&
265             shc->pf->cmds == PF_SRV_MSG_EXIT) {
266                 return;
267         }
268
269         change_to_root_user();
270         lsasd_reopen_logs(shc->child_id);
271 }
272
273 static bool lsasd_setup_chld_hup_handler(struct tevent_context *ev_ctx,
274                                          struct pf_worker_data *pf,
275                                          struct messaging_context *msg_ctx,
276                                          int child_id)
277 {
278         struct lsasd_chld_sig_hup_ctx *shc;
279         struct tevent_signal *se;
280
281         shc = talloc(ev_ctx, struct lsasd_chld_sig_hup_ctx);
282         if (!shc) {
283                 DEBUG(1, ("failed to setup SIGHUP handler"));
284                 return false;
285         }
286         shc->child_id = child_id;
287         shc->pf = pf;
288         shc->msg_ctx = msg_ctx;
289
290         se = tevent_add_signal(ev_ctx,
291                                ev_ctx,
292                                SIGHUP, 0,
293                                lsasd_chld_sig_hup_handler,
294                                shc);
295         if (!se) {
296                 DEBUG(1, ("failed to setup SIGHUP handler"));
297                 return false;
298         }
299
300         return true;
301 }
302
303 static bool lsasd_child_init(struct tevent_context *ev_ctx,
304                              int child_id,
305                              struct pf_worker_data *pf)
306 {
307         NTSTATUS status;
308         struct messaging_context *msg_ctx = server_messaging_context();
309         bool ok;
310
311         status = reinit_after_fork(msg_ctx, ev_ctx,
312                                    procid_self(), true);
313         if (!NT_STATUS_IS_OK(status)) {
314                 DEBUG(0,("reinit_after_fork() failed\n"));
315                 smb_panic("reinit_after_fork() failed");
316         }
317
318         lsasd_reopen_logs(child_id);
319
320         ok = lsasd_setup_chld_hup_handler(ev_ctx, pf, msg_ctx, child_id);
321         if (!ok) {
322                 return false;
323         }
324
325         if (!serverid_register(procid_self(), FLAG_MSG_GENERAL)) {
326                 return false;
327         }
328
329         messaging_register(msg_ctx, ev_ctx,
330                            MSG_SMB_CONF_UPDATED, lsasd_smb_conf_updated);
331
332         status = rpc_lsarpc_init(NULL);
333         if (!NT_STATUS_IS_OK(status)) {
334                 DEBUG(0, ("Failed to register lsarpc rpc inteface! (%s)\n",
335                           nt_errstr(status)));
336                 return false;
337         }
338
339         status = rpc_samr_init(NULL);
340         if (!NT_STATUS_IS_OK(status)) {
341                 DEBUG(0, ("Failed to register samr rpc inteface! (%s)\n",
342                           nt_errstr(status)));
343                 return false;
344         }
345
346         status = rpc_netlogon_init(NULL);
347         if (!NT_STATUS_IS_OK(status)) {
348                 DEBUG(0, ("Failed to register netlogon rpc inteface! (%s)\n",
349                           nt_errstr(status)));
350                 return false;
351         }
352
353         return true;
354 }
355
356 struct lsasd_children_data {
357         struct tevent_context *ev_ctx;
358         struct messaging_context *msg_ctx;
359         int child_id;
360         struct pf_worker_data *pf;
361         int listen_fd_size;
362         int *listen_fds;
363         int lock_fd;
364
365         bool listening;
366 };
367
368 static void lsasd_next_client(void *pvt);
369
370 static int lsasd_children_main(struct tevent_context *ev_ctx,
371                                struct messaging_context *msg_ctx,
372                                struct pf_worker_data *pf,
373                                int child_id,
374                                int listen_fd_size,
375                                int *listen_fds,
376                                int lock_fd,
377                                void *private_data)
378 {
379         struct lsasd_children_data *data;
380         bool ok;
381         int ret;
382
383         ok = lsasd_child_init(ev_ctx, child_id, pf);
384         if (!ok) {
385                 return 1;
386         }
387
388         data = talloc(ev_ctx, struct lsasd_children_data);
389         if (!data) {
390                 return 1;
391         }
392         data->child_id = child_id;
393         data->pf = pf;
394         data->ev_ctx = ev_ctx;
395         data->msg_ctx = msg_ctx;
396         data->lock_fd = lock_fd;
397         data->listen_fd_size = listen_fd_size;
398         data->listen_fds = listen_fds;
399         data->listening = false;
400
401         /* loop until it is time to exit */
402         while (pf->status != PF_WORKER_EXITING) {
403                 /* try to see if it is time to schedule the next client */
404                 lsasd_next_client(data);
405
406                 ret = tevent_loop_once(ev_ctx);
407                 if (ret != 0) {
408                         DEBUG(0, ("tevent_loop_once() exited with %d: %s\n",
409                                   ret, strerror(errno)));
410                         pf->status = PF_WORKER_EXITING;
411                 }
412         }
413
414         return ret;
415 }
416
417 static void lsasd_client_terminated(void *pvt)
418 {
419         struct lsasd_children_data *data;
420
421         data = talloc_get_type_abort(pvt, struct lsasd_children_data);
422
423         if (data->pf->num_clients) {
424                 data->pf->num_clients--;
425         } else {
426                 DEBUG(2, ("Invalid num clients, aborting!\n"));
427                 data->pf->status = PF_WORKER_EXITING;
428                 return;
429         }
430
431         lsasd_next_client(pvt);
432 }
433
434 struct lsasd_new_client {
435         struct lsasd_children_data *data;
436 };
437
438 static void lsasd_handle_client(struct tevent_req *req);
439
440 static void lsasd_next_client(void *pvt)
441 {
442         struct tevent_req *req;
443         struct lsasd_children_data *data;
444         struct lsasd_new_client *next;
445
446         data = talloc_get_type_abort(pvt, struct lsasd_children_data);
447
448         if (data->pf->num_clients == 0) {
449                 data->pf->status = PF_WORKER_IDLE;
450         }
451
452         if (data->pf->cmds == PF_SRV_MSG_EXIT) {
453                 DEBUG(2, ("Parent process commands we terminate!\n"));
454                 return;
455         }
456
457         if (data->listening ||
458             data->pf->num_clients >= data->pf->allowed_clients) {
459                 /* nothing to do for now we are already listening
460                  * or reached the number of clients we are allowed
461                  * to handle in parallel */
462                 return;
463         }
464
465         next = talloc_zero(data, struct lsasd_new_client);
466         if (!next) {
467                 DEBUG(1, ("Out of memory!?\n"));
468                 return;
469         }
470         next->data = data;
471
472         req = prefork_listen_send(next,
473                                   data->ev_ctx,
474                                   data->pf,
475                                   data->listen_fd_size,
476                                   data->listen_fds,
477                                   data->lock_fd);
478         if (!req) {
479                 DEBUG(1, ("Failed to make listening request!?\n"));
480                 talloc_free(next);
481                 return;
482         }
483         tevent_req_set_callback(req, lsasd_handle_client, next);
484
485         data->listening = true;
486 }
487
488 static void lsasd_handle_client(struct tevent_req *req)
489 {
490         struct lsasd_children_data *data;
491         struct lsasd_new_client *client;
492         int rc;
493         int sd;
494         TALLOC_CTX *tmp_ctx;
495         struct tsocket_address *srv_addr;
496         struct tsocket_address *cli_addr;
497
498         client = tevent_req_callback_data(req, struct lsasd_new_client);
499         data = client->data;
500
501         tmp_ctx = talloc_stackframe();
502         if (tmp_ctx == NULL) {
503                 DEBUG(1, ("Failed to allocate stackframe!\n"));
504                 return;
505         }
506
507         rc = prefork_listen_recv(req,
508                                  tmp_ctx,
509                                  &sd,
510                                  &srv_addr,
511                                  &cli_addr);
512
513         /* this will free the request too */
514         talloc_free(client);
515         /* we are done listening */
516         data->listening = false;
517
518         if (rc > 0) {
519                 DEBUG(1, ("Failed to accept client connection!\n"));
520                 /* bail out if we are not serving any other client */
521                 if (data->pf->num_clients == 0) {
522                         data->pf->status = PF_WORKER_EXITING;
523                 }
524                 return;
525         }
526
527         if (rc == -2) {
528                 DEBUG(1, ("Server asks us to die!\n"));
529                 data->pf->status = PF_WORKER_EXITING;
530                 return;
531         }
532
533         DEBUG(2, ("LSASD preforked child %d got client connection!\n",
534                   (int)(data->pf->pid)));
535
536         if (tsocket_address_is_inet(srv_addr, "ip")) {
537                 DEBUG(3, ("Got a tcpip client connection from %s on inteface %s\n",
538                            tsocket_address_string(cli_addr, tmp_ctx),
539                            tsocket_address_string(srv_addr, tmp_ctx)));
540
541                 dcerpc_ncacn_accept(data->ev_ctx,
542                                     data->msg_ctx,
543                                     NCACN_IP_TCP,
544                                     "IP",
545                                     cli_addr,
546                                     srv_addr,
547                                     sd,
548                                     NULL);
549         } else if (tsocket_address_is_unix(srv_addr)) {
550                 char *p;
551
552                 p = tsocket_address_unix_path(srv_addr, tmp_ctx);
553                 if (p == NULL) {
554                         talloc_free(tmp_ctx);
555                         return;
556                 }
557
558                 if (strstr(p, "/np/")) {
559                         p = basename(p);
560
561                         named_pipe_accept_function(data->ev_ctx,
562                                                    data->msg_ctx,
563                                                    p,
564                                                    sd,
565                                                    lsasd_client_terminated,
566                                                    data);
567                 } else {
568                         p = basename(p);
569
570                         dcerpc_ncacn_accept(data->ev_ctx,
571                                             data->msg_ctx,
572                                             NCALRPC,
573                                             p,
574                                             cli_addr,
575                                             srv_addr,
576                                             sd,
577                                             NULL);
578                 }
579         } else {
580                 DEBUG(0, ("ERROR: Unsupported socket!\n"));
581         }
582
583         talloc_free(tmp_ctx);
584 }
585
586 /*
587  * MAIN
588  */
589
590 static bool lsasd_schedule_check(struct tevent_context *ev_ctx,
591                                  struct messaging_context *msg_ctx,
592                                  struct prefork_pool *pfp,
593                                  struct timeval current_time);
594
595 static void lsasd_check_children(struct tevent_context *ev_ctx,
596                                     struct tevent_timer *te,
597                                     struct timeval current_time,
598                                     void *pvt);
599
600 static void lsasd_sigchld_handler(struct tevent_context *ev_ctx,
601                                   struct prefork_pool *pfp,
602                                   void *pvt)
603 {
604         struct messaging_context *msg_ctx;
605         int active, total;
606         int n, r;
607
608         msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
609
610         /* now check we do not descend below the minimum */
611         active = prefork_count_active_children(pfp, &total);
612
613         n = 0;
614         if (total < lsasd_min_children) {
615                 n = total - lsasd_min_children;
616         } else if (total - active < (total / 4)) {
617                 n = lsasd_min_children;
618         }
619
620         if (n > 0) {
621                 r = prefork_add_children(ev_ctx, msg_ctx, pfp, n);
622                 if (r < n) {
623                         DEBUG(10, ("Tried to start %d children but only,"
624                                    "%d were actually started.!\n", n, r));
625                 }
626         }
627 }
628
629 static bool lsasd_setup_children_monitor(struct tevent_context *ev_ctx,
630                                          struct messaging_context *msg_ctx,
631                                          struct prefork_pool *pfp)
632 {
633         bool ok;
634
635         /* add our oun sigchld callback */
636         prefork_set_sigchld_callback(pfp, lsasd_sigchld_handler, msg_ctx);
637
638         ok = lsasd_schedule_check(ev_ctx,
639                                   msg_ctx,
640                                   pfp,
641                                   tevent_timeval_current());
642
643         return ok;
644 }
645
646 struct schedule_check_state {
647         struct messaging_context *msg_ctx;
648         struct prefork_pool *pfp;
649 };
650
651 static bool lsasd_schedule_check(struct tevent_context *ev_ctx,
652                                  struct messaging_context *msg_ctx,
653                                  struct prefork_pool *pfp,
654                                  struct timeval current_time)
655 {
656         struct tevent_timer *te;
657         struct timeval next_event;
658         struct schedule_check_state *state;
659
660         state = talloc(ev_ctx, struct schedule_check_state);
661         if (!state) {
662                 DEBUG(0, ("Out of memory!\n"));
663                 return false;
664         }
665         state->msg_ctx = msg_ctx;
666         state->pfp = pfp;
667
668         /* check situation again in 10 seconds */
669         next_event = tevent_timeval_current_ofs(10, 0);
670
671         /* TODO: check when the socket becomes readable, so that children
672          * are checked only when there is some activity ? */
673         te = tevent_add_timer(ev_ctx,
674                               pfp,
675                               next_event,
676                               lsasd_check_children,
677                               state);
678         if (!te) {
679                 DEBUG(2, ("Failed to set up children monitoring!\n"));
680                 talloc_free(state);
681                 return false;
682         }
683         talloc_steal(te, state);
684
685         return true;
686 }
687
688 static void lsasd_check_children(struct tevent_context *ev_ctx,
689                                  struct tevent_timer *te,
690                                  struct timeval current_time,
691                                  void *pvt)
692 {
693         struct schedule_check_state *state;
694         int active, total;
695         int rc, n;
696         bool ok;
697
698         state = talloc_get_type_abort(pvt, struct schedule_check_state);
699
700         if ((lsasd_prefork_status & LSASD_NEW_MAX) &&
701             !(lsasd_prefork_status & LSASD_ENOSPC)) {
702                 rc = prefork_expand_pool(state->pfp, lsasd_max_children);
703                 if (rc == ENOSPC) {
704                         lsasd_prefork_status |= LSASD_ENOSPC;
705                 }
706                 lsasd_prefork_status &= ~LSASD_NEW_MAX;
707         }
708
709         active = prefork_count_active_children(state->pfp, &total);
710
711         if (total - active < lsasd_spawn_rate) {
712                 n = prefork_add_children(ev_ctx,
713                                          state->msg_ctx,
714                                          state->pfp,
715                                          lsasd_spawn_rate);
716                 if (n < lsasd_spawn_rate) {
717                         DEBUG(10, ("Tried to start 5 children but only,"
718                                    "%d were actually started.!\n", n));
719                 }
720         }
721
722         if (total - active > lsasd_min_children) {
723                 if ((total - lsasd_min_children) >= lsasd_spawn_rate) {
724                         prefork_retire_children(state->pfp,
725                                                 lsasd_spawn_rate,
726                                                 time(NULL) - LSASD_MIN_LIFE);
727                 }
728         }
729
730         ok = lsasd_schedule_check(ev_ctx,
731                                   state->msg_ctx,
732                                   state->pfp,
733                                   current_time);
734 }
735
736 /*
737  * start it up
738  */
739
740 static bool lsasd_create_sockets(struct tevent_context *ev_ctx,
741                                  struct messaging_context *msg_ctx,
742                                  int *listen_fd,
743                                  int *listen_fd_size)
744 {
745         struct dcerpc_binding_vector *v, *v_orig;
746         TALLOC_CTX *tmp_ctx;
747         NTSTATUS status;
748         uint32_t i;
749         int fd;
750         int rc;
751         bool ok = true;
752
753         tmp_ctx = talloc_stackframe();
754         if (tmp_ctx == NULL) {
755                 return false;
756         }
757
758         status = dcerpc_binding_vector_new(tmp_ctx, &v_orig);
759         if (!NT_STATUS_IS_OK(status)) {
760                 ok = false;
761                 goto done;
762         }
763
764         /* Create only one tcpip listener for all services */
765         status = rpc_create_tcpip_sockets(&ndr_table_lsarpc,
766                                           v_orig,
767                                           0,
768                                           listen_fd,
769                                           listen_fd_size);
770         if (!NT_STATUS_IS_OK(status)) {
771                 ok = false;
772                 goto done;
773         }
774
775         /* Start to listen on tcpip sockets */
776         for (i = 0; i < *listen_fd_size; i++) {
777                 rc = listen(listen_fd[i], lsasd_max_children);
778                 if (rc == -1) {
779                         DEBUG(0, ("Failed to listen on tcpip socket - %s\n",
780                                   strerror(errno)));
781                         ok = false;
782                         goto done;
783                 }
784         }
785
786         /* LSARPC */
787         fd = create_named_pipe_socket("lsarpc");
788         if (fd < 0) {
789                 ok = false;
790                 goto done;
791         }
792         listen_fd[*listen_fd_size] = fd;
793         (*listen_fd_size)++;
794
795         rc = listen(fd, lsasd_max_children);
796         if (rc == -1) {
797                 DEBUG(0, ("Failed to listen on lsarpc pipe - %s\n",
798                           strerror(errno)));
799                 ok = false;
800                 goto done;
801         }
802
803         v = dcerpc_binding_vector_dup(tmp_ctx, v_orig);
804         if (v == NULL) {
805                 ok = false;
806                 goto done;
807         }
808
809         status = dcerpc_binding_vector_replace_iface(&ndr_table_lsarpc, v);
810         if (!NT_STATUS_IS_OK(status)) {
811                 return false;
812         }
813
814         status = dcerpc_binding_vector_add_np_default(&ndr_table_lsarpc, v);
815         if (!NT_STATUS_IS_OK(status)) {
816                 ok = false;
817                 goto done;
818         }
819
820         status = rpc_ep_register(ev_ctx, msg_ctx, &ndr_table_lsarpc, v);
821         if (!NT_STATUS_IS_OK(status)) {
822                 ok = false;
823                 goto done;
824         }
825
826         /* SAMR */
827         fd = create_named_pipe_socket("samr");
828         if (fd < 0) {
829                 ok = false;
830                 goto done;
831         }
832
833         rc = listen(fd, lsasd_max_children);
834         if (rc == -1) {
835                 DEBUG(0, ("Failed to listen on samr pipe - %s\n",
836                           strerror(errno)));
837                 ok = false;
838                 goto done;
839         }
840         listen_fd[*listen_fd_size] = fd;
841         (*listen_fd_size)++;
842
843         v = dcerpc_binding_vector_dup(tmp_ctx, v_orig);
844         if (v == NULL) {
845                 ok = false;
846                 goto done;
847         }
848
849         status = dcerpc_binding_vector_replace_iface(&ndr_table_samr, v);
850         if (!NT_STATUS_IS_OK(status)) {
851                 return false;
852         }
853
854         status = dcerpc_binding_vector_add_np_default(&ndr_table_samr, v);
855         if (!NT_STATUS_IS_OK(status)) {
856                 ok = false;
857                 goto done;
858         }
859
860         status = rpc_ep_register(ev_ctx, msg_ctx, &ndr_table_samr, v);
861         if (!NT_STATUS_IS_OK(status)) {
862                 ok = false;
863                 goto done;
864         }
865
866         /* NETLOGON */
867         fd = create_named_pipe_socket("netlogon");
868         if (fd < 0) {
869                 ok = false;
870                 goto done;
871         }
872
873         rc = listen(fd, lsasd_max_children);
874         if (rc == -1) {
875                 DEBUG(0, ("Failed to listen on samr pipe - %s\n",
876                           strerror(errno)));
877                 ok = false;
878                 goto done;
879         }
880         listen_fd[*listen_fd_size] = fd;
881         (*listen_fd_size)++;
882
883         v = dcerpc_binding_vector_dup(tmp_ctx, v_orig);
884         if (v == NULL) {
885                 ok = false;
886                 goto done;
887         }
888
889         status = dcerpc_binding_vector_replace_iface(&ndr_table_netlogon, v);
890         if (!NT_STATUS_IS_OK(status)) {
891                 return false;
892         }
893
894         status = dcerpc_binding_vector_add_np_default(&ndr_table_netlogon, v);
895         if (!NT_STATUS_IS_OK(status)) {
896                 ok = false;
897                 goto done;
898         }
899
900         status = rpc_ep_register(ev_ctx, msg_ctx, &ndr_table_netlogon, v);
901         if (!NT_STATUS_IS_OK(status)) {
902                 ok = false;
903                 goto done;
904         }
905
906 done:
907         talloc_free(tmp_ctx);
908         return ok;
909 }
910
911 void start_lsasd(struct tevent_context *ev_ctx,
912                  struct messaging_context *msg_ctx)
913 {
914         struct prefork_pool *pool;
915         NTSTATUS status;
916         int listen_fd[LSASD_MAX_SOCKETS];
917         int listen_fd_size = 0;
918         pid_t pid;
919         int rc;
920         bool ok;
921
922         DEBUG(1, ("Forking LSA Service Daemon\n"));
923
924         /*
925          * Block signals before forking child as it will have to
926          * set its own handlers. Child will re-enable SIGHUP as
927          * soon as the handlers are set up.
928          */
929         BlockSignals(true, SIGTERM);
930         BlockSignals(true, SIGHUP);
931
932         pid = sys_fork();
933         if (pid == -1) {
934                 DEBUG(0, ("Failed to fork LSASD [%s], aborting ...\n",
935                            strerror(errno)));
936                 exit(1);
937         }
938
939         /* parent or error */
940         if (pid != 0) {
941
942                 /* Re-enable SIGHUP before returnig */
943                 BlockSignals(false, SIGTERM);
944                 BlockSignals(false, SIGHUP);
945
946                 return;
947         }
948
949         /* child */
950         close_low_fds(false);
951
952         status = reinit_after_fork(msg_ctx,
953                                    ev_ctx,
954                                    procid_self(), true);
955         if (!NT_STATUS_IS_OK(status)) {
956                 DEBUG(0,("reinit_after_fork() failed\n"));
957                 smb_panic("reinit_after_fork() failed");
958         }
959
960         lsasd_reopen_logs(0);
961         lsasd_prefork_config();
962
963         lsasd_setup_sig_term_handler(ev_ctx);
964         lsasd_setup_sig_hup_handler(ev_ctx, pool, msg_ctx);
965
966         BlockSignals(false, SIGTERM);
967         BlockSignals(false, SIGHUP);
968
969         ok = lsasd_create_sockets(ev_ctx, msg_ctx, listen_fd, &listen_fd_size);
970         if (!ok) {
971                 exit(1);
972         }
973
974         /* start children before any more initialization is done */
975         ok = prefork_create_pool(ev_ctx, /* mem_ctx */
976                                  ev_ctx,
977                                  msg_ctx,
978                                  listen_fd_size,
979                                  listen_fd,
980                                  lsasd_min_children,
981                                  lsasd_max_children,
982                                  &lsasd_children_main,
983                                  NULL,
984                                  &pool);
985         if (!ok) {
986                 exit(1);
987         }
988
989         if (!serverid_register(procid_self(), FLAG_MSG_GENERAL)) {
990                 exit(1);
991         }
992
993         messaging_register(msg_ctx,
994                            ev_ctx,
995                            MSG_SMB_CONF_UPDATED,
996                            lsasd_smb_conf_updated);
997
998         status = rpc_lsarpc_init(NULL);
999         if (!NT_STATUS_IS_OK(status)) {
1000                 DEBUG(0, ("Failed to register winreg rpc inteface! (%s)\n",
1001                           nt_errstr(status)));
1002                 exit(1);
1003         }
1004
1005         status = rpc_samr_init(NULL);
1006         if (!NT_STATUS_IS_OK(status)) {
1007                 DEBUG(0, ("Failed to register lsasd rpc inteface! (%s)\n",
1008                           nt_errstr(status)));
1009                 exit(1);
1010         }
1011
1012         status = rpc_netlogon_init(NULL);
1013         if (!NT_STATUS_IS_OK(status)) {
1014                 DEBUG(0, ("Failed to register lsasd rpc inteface! (%s)\n",
1015                           nt_errstr(status)));
1016                 exit(1);
1017         }
1018
1019         ok = lsasd_setup_children_monitor(ev_ctx, msg_ctx, pool);
1020         if (!ok) {
1021                 DEBUG(0, ("Failed to setup children monitoring!\n"));
1022                 exit(1);
1023         }
1024
1025         DEBUG(1, ("LSASD Daemon Started (%d)\n", getpid()));
1026
1027         /* loop forever */
1028         rc = tevent_loop_wait(ev_ctx);
1029
1030         /* should not be reached */
1031         DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1032                  rc, (rc == 0) ? "out of events" : strerror(errno)));
1033         exit(1);
1034 }