08e9fe26a74b502add56c27910978292ef7bdb80
[metze/samba/wip.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 "messages.h"
24 #include "ntdomain.h"
25
26 #include "lib/id_cache.h"
27
28 #include "../lib/tsocket/tsocket.h"
29 #include "lib/server_prefork.h"
30 #include "lib/server_prefork_util.h"
31 #include "librpc/rpc/dcerpc_ep.h"
32
33 #include "rpc_server/rpc_server.h"
34 #include "rpc_server/rpc_ep_register.h"
35 #include "rpc_server/rpc_sock_helper.h"
36
37 #include "librpc/gen_ndr/srv_lsa.h"
38 #include "librpc/gen_ndr/srv_samr.h"
39 #include "librpc/gen_ndr/srv_netlogon.h"
40
41 #define DAEMON_NAME "lsasd"
42 #define LSASD_MAX_SOCKETS 64
43
44 static struct server_id parent_id;
45 static struct prefork_pool *lsasd_pool = NULL;
46 static int lsasd_child_id = 0;
47
48 static struct pf_daemon_config default_pf_lsasd_cfg = {
49         .prefork_status = PFH_INIT,
50         .min_children = 5,
51         .max_children = 25,
52         .spawn_rate = 5,
53         .max_allowed_clients = 100,
54         .child_min_life = 60 /* 1 minute minimum life time */
55 };
56 static struct pf_daemon_config pf_lsasd_cfg = { 0 };
57
58 void start_lsasd(struct tevent_context *ev_ctx,
59                  struct messaging_context *msg_ctx);
60
61 static void lsasd_reopen_logs(int child_id)
62 {
63         char *lfile = lp_logfile(talloc_tos());
64         char *extension;
65         int rc;
66
67         if (child_id) {
68                 rc = asprintf(&extension, "%s.%d", DAEMON_NAME, child_id);
69         } else {
70                 rc = asprintf(&extension, "%s", DAEMON_NAME);
71         }
72         if (rc == -1) {
73                 return;
74         }
75
76         rc = 0;
77         if (lfile == NULL || lfile[0] == '\0') {
78                 rc = asprintf(&lfile, "%s/log.%s",
79                               get_dyn_LOGFILEBASE(), extension);
80         } else {
81                 if (strstr(lfile, extension) == NULL) {
82                         if (child_id) {
83                                 rc = asprintf(&lfile, "%s.%d",
84                                                 lp_logfile(talloc_tos()),
85                                                 child_id);
86                         } else {
87                                 rc = asprintf(&lfile, "%s.%s",
88                                                 lp_logfile(talloc_tos()),
89                                                 extension);
90                         }
91                 }
92         }
93
94         if (rc > 0) {
95                 lp_set_logfile(lfile);
96                 SAFE_FREE(lfile);
97         }
98
99         SAFE_FREE(extension);
100
101         reopen_logs();
102 }
103
104 static void lsasd_smb_conf_updated(struct messaging_context *msg,
105                                   void *private_data,
106                                   uint32_t msg_type,
107                                   struct server_id server_id,
108                                   DATA_BLOB *data)
109 {
110         struct tevent_context *ev_ctx;
111
112         DEBUG(10, ("Got message saying smb.conf was updated. Reloading.\n"));
113         ev_ctx = talloc_get_type_abort(private_data, struct tevent_context);
114
115         change_to_root_user();
116         lp_load_global(get_dyn_CONFIGFILE());
117
118         lsasd_reopen_logs(lsasd_child_id);
119         if (lsasd_child_id == 0) {
120                 pfh_daemon_config(DAEMON_NAME,
121                                   &pf_lsasd_cfg,
122                                   &default_pf_lsasd_cfg);
123                 pfh_manage_pool(ev_ctx, msg, &pf_lsasd_cfg, lsasd_pool);
124         }
125 }
126
127 static void lsasd_sig_term_handler(struct tevent_context *ev,
128                                   struct tevent_signal *se,
129                                   int signum,
130                                   int count,
131                                   void *siginfo,
132                                   void *private_data)
133 {
134         rpc_netlogon_shutdown();
135         rpc_samr_shutdown();
136         rpc_lsarpc_shutdown();
137
138         DEBUG(0, ("termination signal\n"));
139         exit(0);
140 }
141
142 static void lsasd_setup_sig_term_handler(struct tevent_context *ev_ctx)
143 {
144         struct tevent_signal *se;
145
146         se = tevent_add_signal(ev_ctx,
147                                ev_ctx,
148                                SIGTERM, 0,
149                                lsasd_sig_term_handler,
150                                NULL);
151         if (!se) {
152                 DEBUG(0, ("failed to setup SIGTERM handler\n"));
153                 exit(1);
154         }
155 }
156
157 static void lsasd_sig_hup_handler(struct tevent_context *ev,
158                                     struct tevent_signal *se,
159                                     int signum,
160                                     int count,
161                                     void *siginfo,
162                                     void *pvt)
163 {
164
165         change_to_root_user();
166         lp_load_global(get_dyn_CONFIGFILE());
167
168         lsasd_reopen_logs(lsasd_child_id);
169         pfh_daemon_config(DAEMON_NAME,
170                           &pf_lsasd_cfg,
171                           &default_pf_lsasd_cfg);
172
173         /* relay to all children */
174         prefork_send_signal_to_all(lsasd_pool, SIGHUP);
175 }
176
177 static void lsasd_setup_sig_hup_handler(struct tevent_context *ev_ctx)
178 {
179         struct tevent_signal *se;
180
181         se = tevent_add_signal(ev_ctx,
182                                ev_ctx,
183                                SIGHUP, 0,
184                                lsasd_sig_hup_handler,
185                                NULL);
186         if (!se) {
187                 DEBUG(0, ("failed to setup SIGHUP handler\n"));
188                 exit(1);
189         }
190 }
191
192 /**********************************************************
193  * Children
194  **********************************************************/
195
196 static void lsasd_chld_sig_hup_handler(struct tevent_context *ev,
197                                          struct tevent_signal *se,
198                                          int signum,
199                                          int count,
200                                          void *siginfo,
201                                          void *pvt)
202 {
203         change_to_root_user();
204         lsasd_reopen_logs(lsasd_child_id);
205 }
206
207 static bool lsasd_setup_chld_hup_handler(struct tevent_context *ev_ctx)
208 {
209         struct tevent_signal *se;
210
211         se = tevent_add_signal(ev_ctx,
212                                ev_ctx,
213                                SIGHUP, 0,
214                                lsasd_chld_sig_hup_handler,
215                                NULL);
216         if (!se) {
217                 DEBUG(1, ("failed to setup SIGHUP handler"));
218                 return false;
219         }
220
221         return true;
222 }
223
224 static void parent_ping(struct messaging_context *msg_ctx,
225                         void *private_data,
226                         uint32_t msg_type,
227                         struct server_id server_id,
228                         DATA_BLOB *data)
229 {
230
231         /* The fact we received this message is enough to let make the event
232          * loop if it was idle. lsasd_children_main will cycle through
233          * lsasd_next_client at least once. That function will take whatever
234          * action is necessary */
235
236         DEBUG(10, ("Got message that the parent changed status.\n"));
237         return;
238 }
239
240 static bool lsasd_child_init(struct tevent_context *ev_ctx,
241                              int child_id,
242                              struct pf_worker_data *pf)
243 {
244         NTSTATUS status;
245         struct messaging_context *msg_ctx = server_messaging_context();
246         bool ok;
247
248         status = reinit_after_fork(msg_ctx, ev_ctx,
249                                    true, "lsasd-child");
250         if (!NT_STATUS_IS_OK(status)) {
251                 DEBUG(0,("reinit_after_fork() failed\n"));
252                 smb_panic("reinit_after_fork() failed");
253         }
254
255         lsasd_child_id = child_id;
256         lsasd_reopen_logs(child_id);
257
258         ok = lsasd_setup_chld_hup_handler(ev_ctx);
259         if (!ok) {
260                 return false;
261         }
262
263         messaging_register(msg_ctx, ev_ctx,
264                            MSG_SMB_CONF_UPDATED, lsasd_smb_conf_updated);
265         messaging_register(msg_ctx, ev_ctx,
266                            MSG_PREFORK_PARENT_EVENT, parent_ping);
267         id_cache_register_msgs(msg_ctx);
268
269         status = rpc_lsarpc_init(NULL);
270         if (!NT_STATUS_IS_OK(status)) {
271                 DEBUG(0, ("Failed to register lsarpc rpc interface! (%s)\n",
272                           nt_errstr(status)));
273                 return false;
274         }
275
276         status = rpc_samr_init(NULL);
277         if (!NT_STATUS_IS_OK(status)) {
278                 DEBUG(0, ("Failed to register samr rpc interface! (%s)\n",
279                           nt_errstr(status)));
280                 return false;
281         }
282
283         status = rpc_netlogon_init(NULL);
284         if (!NT_STATUS_IS_OK(status)) {
285                 DEBUG(0, ("Failed to register netlogon rpc interface! (%s)\n",
286                           nt_errstr(status)));
287                 return false;
288         }
289
290         return true;
291 }
292
293 struct lsasd_children_data {
294         struct tevent_context *ev_ctx;
295         struct messaging_context *msg_ctx;
296         struct pf_worker_data *pf;
297         int listen_fd_size;
298         int *listen_fds;
299 };
300
301 static void lsasd_next_client(void *pvt);
302
303 static int lsasd_children_main(struct tevent_context *ev_ctx,
304                                struct messaging_context *msg_ctx,
305                                struct pf_worker_data *pf,
306                                int child_id,
307                                int listen_fd_size,
308                                int *listen_fds,
309                                void *private_data)
310 {
311         struct lsasd_children_data *data;
312         bool ok;
313         int ret = 0;
314
315         ok = lsasd_child_init(ev_ctx, child_id, pf);
316         if (!ok) {
317                 return 1;
318         }
319
320         data = talloc(ev_ctx, struct lsasd_children_data);
321         if (!data) {
322                 return 1;
323         }
324         data->pf = pf;
325         data->ev_ctx = ev_ctx;
326         data->msg_ctx = msg_ctx;
327         data->listen_fd_size = listen_fd_size;
328         data->listen_fds = listen_fds;
329
330         /* loop until it is time to exit */
331         while (pf->status != PF_WORKER_EXITING) {
332                 /* try to see if it is time to schedule the next client */
333                 lsasd_next_client(data);
334
335                 ret = tevent_loop_once(ev_ctx);
336                 if (ret != 0) {
337                         DEBUG(0, ("tevent_loop_once() exited with %d: %s\n",
338                                   ret, strerror(errno)));
339                         pf->status = PF_WORKER_EXITING;
340                 }
341         }
342
343         return ret;
344 }
345
346 static void lsasd_client_terminated(void *pvt)
347 {
348         struct lsasd_children_data *data;
349
350         data = talloc_get_type_abort(pvt, struct lsasd_children_data);
351
352         pfh_client_terminated(data->pf);
353
354         lsasd_next_client(pvt);
355 }
356
357 struct lsasd_new_client {
358         struct lsasd_children_data *data;
359 };
360
361 static void lsasd_handle_client(struct tevent_req *req);
362
363 static void lsasd_next_client(void *pvt)
364 {
365         struct tevent_req *req;
366         struct lsasd_children_data *data;
367         struct lsasd_new_client *next;
368
369         data = talloc_get_type_abort(pvt, struct lsasd_children_data);
370
371         if (!pfh_child_allowed_to_accept(data->pf)) {
372                 /* nothing to do for now we are already listening
373                  * or we are not allowed to listen further */
374                 return;
375         }
376
377         next = talloc_zero(data, struct lsasd_new_client);
378         if (!next) {
379                 DEBUG(1, ("Out of memory!?\n"));
380                 return;
381         }
382         next->data = data;
383
384         req = prefork_listen_send(next,
385                                   data->ev_ctx,
386                                   data->pf,
387                                   data->listen_fd_size,
388                                   data->listen_fds);
389         if (!req) {
390                 DEBUG(1, ("Failed to make listening request!?\n"));
391                 talloc_free(next);
392                 return;
393         }
394         tevent_req_set_callback(req, lsasd_handle_client, next);
395 }
396
397 static void lsasd_handle_client(struct tevent_req *req)
398 {
399         struct lsasd_children_data *data;
400         struct lsasd_new_client *client;
401         const DATA_BLOB ping = data_blob_null;
402         int rc;
403         int sd;
404         TALLOC_CTX *tmp_ctx;
405         struct tsocket_address *srv_addr;
406         struct tsocket_address *cli_addr;
407
408         client = tevent_req_callback_data(req, struct lsasd_new_client);
409         data = client->data;
410
411         tmp_ctx = talloc_stackframe();
412         if (tmp_ctx == NULL) {
413                 DEBUG(1, ("Failed to allocate stackframe!\n"));
414                 return;
415         }
416
417         rc = prefork_listen_recv(req,
418                                  tmp_ctx,
419                                  &sd,
420                                  &srv_addr,
421                                  &cli_addr);
422
423         /* this will free the request too */
424         talloc_free(client);
425
426         if (rc != 0) {
427                 DEBUG(6, ("No client connection was available after all!\n"));
428                 goto done;
429         }
430
431         /* Warn parent that our status changed */
432         messaging_send(data->msg_ctx, parent_id,
433                         MSG_PREFORK_CHILD_EVENT, &ping);
434
435         DEBUG(2, ("LSASD preforked child %d got client connection!\n",
436                   (int)(data->pf->pid)));
437
438         if (tsocket_address_is_inet(srv_addr, "ip")) {
439                 DEBUG(3, ("Got a tcpip client connection from %s on interface %s\n",
440                            tsocket_address_string(cli_addr, tmp_ctx),
441                            tsocket_address_string(srv_addr, tmp_ctx)));
442
443                 dcerpc_ncacn_accept(data->ev_ctx,
444                                     data->msg_ctx,
445                                     NCACN_IP_TCP,
446                                     "IP",
447                                     cli_addr,
448                                     srv_addr,
449                                     sd,
450                                     NULL);
451         } else if (tsocket_address_is_unix(srv_addr)) {
452                 const char *p;
453                 const char *b;
454
455                 p = tsocket_address_unix_path(srv_addr, tmp_ctx);
456                 if (p == NULL) {
457                         talloc_free(tmp_ctx);
458                         return;
459                 }
460
461                 b = strrchr(p, '/');
462                 if (b != NULL) {
463                         b++;
464                 } else {
465                         b = p;
466                 }
467
468                 if (strstr(p, "/np/")) {
469                         named_pipe_accept_function(data->ev_ctx,
470                                                    data->msg_ctx,
471                                                    b,
472                                                    sd,
473                                                    lsasd_client_terminated,
474                                                    data);
475                 } else {
476                         dcerpc_ncacn_accept(data->ev_ctx,
477                                             data->msg_ctx,
478                                             NCALRPC,
479                                             b,
480                                             cli_addr,
481                                             srv_addr,
482                                             sd,
483                                             NULL);
484                 }
485         } else {
486                 DEBUG(0, ("ERROR: Unsupported socket!\n"));
487         }
488
489 done:
490         talloc_free(tmp_ctx);
491 }
492
493 /*
494  * MAIN
495  */
496
497 static void child_ping(struct messaging_context *msg_ctx,
498                         void *private_data,
499                         uint32_t msg_type,
500                         struct server_id server_id,
501                         DATA_BLOB *data)
502 {
503         struct tevent_context *ev_ctx;
504
505         ev_ctx = talloc_get_type_abort(private_data, struct tevent_context);
506
507         DEBUG(10, ("Got message that a child changed status.\n"));
508         pfh_manage_pool(ev_ctx, msg_ctx, &pf_lsasd_cfg, lsasd_pool);
509 }
510
511 static bool lsasd_schedule_check(struct tevent_context *ev_ctx,
512                                  struct messaging_context *msg_ctx,
513                                  struct timeval current_time);
514
515 static void lsasd_check_children(struct tevent_context *ev_ctx,
516                                     struct tevent_timer *te,
517                                     struct timeval current_time,
518                                     void *pvt);
519
520 static void lsasd_sigchld_handler(struct tevent_context *ev_ctx,
521                                   struct prefork_pool *pfp,
522                                   void *pvt)
523 {
524         struct messaging_context *msg_ctx;
525
526         msg_ctx = talloc_get_type_abort(pvt, struct messaging_context);
527
528         /* run pool management so we can fork/retire or increase
529          * the allowed connections per child based on load */
530         pfh_manage_pool(ev_ctx, msg_ctx, &pf_lsasd_cfg, lsasd_pool);
531 }
532
533 static bool lsasd_setup_children_monitor(struct tevent_context *ev_ctx,
534                                          struct messaging_context *msg_ctx)
535 {
536         bool ok;
537
538         /* add our oun sigchld callback */
539         prefork_set_sigchld_callback(lsasd_pool, lsasd_sigchld_handler, msg_ctx);
540
541         ok = lsasd_schedule_check(ev_ctx, msg_ctx, tevent_timeval_current());
542
543         return ok;
544 }
545
546 static bool lsasd_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, lsasd_pool, next_event,
559                               lsasd_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 lsasd_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_lsasd_cfg, lsasd_pool);
578
579         lsasd_schedule_check(ev_ctx, msg_ctx, current_time);
580 }
581
582 /*
583  * start it up
584  */
585
586 static bool lsasd_create_sockets(struct tevent_context *ev_ctx,
587                                  struct messaging_context *msg_ctx,
588                                  int *listen_fd,
589                                  int *listen_fd_size)
590 {
591         struct dcerpc_binding_vector *v, *v_orig;
592         TALLOC_CTX *tmp_ctx;
593         NTSTATUS status;
594         uint32_t i;
595         int fd = -1;
596         int rc;
597         bool ok = false;
598
599         tmp_ctx = talloc_stackframe();
600         if (tmp_ctx == NULL) {
601                 return false;
602         }
603
604         status = dcerpc_binding_vector_new(tmp_ctx, &v_orig);
605         if (!NT_STATUS_IS_OK(status)) {
606                 goto done;
607         }
608
609         /* Create only one tcpip listener for all services */
610         status = rpc_create_tcpip_sockets(&ndr_table_lsarpc,
611                                           v_orig,
612                                           0,
613                                           listen_fd,
614                                           listen_fd_size);
615         if (!NT_STATUS_IS_OK(status)) {
616                 goto done;
617         }
618
619         /* Start to listen on tcpip sockets */
620         for (i = 0; i < *listen_fd_size; i++) {
621                 rc = listen(listen_fd[i], pf_lsasd_cfg.max_allowed_clients);
622                 if (rc == -1) {
623                         DEBUG(0, ("Failed to listen on tcpip socket - %s\n",
624                                   strerror(errno)));
625                         goto done;
626                 }
627         }
628
629         /* LSARPC */
630         fd = create_named_pipe_socket("lsarpc");
631         if (fd < 0) {
632                 goto done;
633         }
634
635         rc = listen(fd, pf_lsasd_cfg.max_allowed_clients);
636         if (rc == -1) {
637                 DEBUG(0, ("Failed to listen on lsarpc pipe - %s\n",
638                           strerror(errno)));
639                 goto done;
640         }
641         listen_fd[*listen_fd_size] = fd;
642         (*listen_fd_size)++;
643
644         fd = create_named_pipe_socket("lsass");
645         if (fd < 0) {
646                 goto done;
647         }
648
649         rc = listen(fd, pf_lsasd_cfg.max_allowed_clients);
650         if (rc == -1) {
651                 DEBUG(0, ("Failed to listen on lsass pipe - %s\n",
652                           strerror(errno)));
653                 goto done;
654         }
655         listen_fd[*listen_fd_size] = fd;
656         (*listen_fd_size)++;
657
658         fd = create_dcerpc_ncalrpc_socket("lsarpc");
659         if (fd < 0) {
660                 goto done;
661         }
662
663         rc = listen(fd, pf_lsasd_cfg.max_allowed_clients);
664         if (rc == -1) {
665                 DEBUG(0, ("Failed to listen on lsarpc ncalrpc - %s\n",
666                           strerror(errno)));
667                 goto done;
668         }
669         listen_fd[*listen_fd_size] = fd;
670         (*listen_fd_size)++;
671         fd = -1;
672
673         v = dcerpc_binding_vector_dup(tmp_ctx, v_orig);
674         if (v == NULL) {
675                 goto done;
676         }
677
678         status = dcerpc_binding_vector_replace_iface(&ndr_table_lsarpc, v);
679         if (!NT_STATUS_IS_OK(status)) {
680                 goto done;
681         }
682
683         status = dcerpc_binding_vector_add_np_default(&ndr_table_lsarpc, v);
684         if (!NT_STATUS_IS_OK(status)) {
685                 goto done;
686         }
687
688         status = dcerpc_binding_vector_add_unix(&ndr_table_lsarpc, v, "lsarpc");
689         if (!NT_STATUS_IS_OK(status)) {
690                 goto done;
691         }
692
693         status = rpc_ep_register(ev_ctx, msg_ctx, &ndr_table_lsarpc, v);
694         if (!NT_STATUS_IS_OK(status)) {
695                 goto done;
696         }
697
698         /* SAMR */
699         fd = create_named_pipe_socket("samr");
700         if (fd < 0) {
701                 goto done;
702         }
703
704         rc = listen(fd, pf_lsasd_cfg.max_allowed_clients);
705         if (rc == -1) {
706                 DEBUG(0, ("Failed to listen on samr pipe - %s\n",
707                           strerror(errno)));
708                 goto done;
709         }
710         listen_fd[*listen_fd_size] = fd;
711         (*listen_fd_size)++;
712
713         fd = create_dcerpc_ncalrpc_socket("samr");
714         if (fd < 0) {
715                 goto done;
716         }
717
718         rc = listen(fd, pf_lsasd_cfg.max_allowed_clients);
719         if (rc == -1) {
720                 DEBUG(0, ("Failed to listen on samr ncalrpc - %s\n",
721                           strerror(errno)));
722                 goto done;
723         }
724         listen_fd[*listen_fd_size] = fd;
725         (*listen_fd_size)++;
726         fd = -1;
727
728         v = dcerpc_binding_vector_dup(tmp_ctx, v_orig);
729         if (v == NULL) {
730                 goto done;
731         }
732
733         status = dcerpc_binding_vector_replace_iface(&ndr_table_samr, v);
734         if (!NT_STATUS_IS_OK(status)) {
735                 goto done;
736         }
737
738         status = dcerpc_binding_vector_add_np_default(&ndr_table_samr, v);
739         if (!NT_STATUS_IS_OK(status)) {
740                 goto done;
741         }
742
743         status = dcerpc_binding_vector_add_unix(&ndr_table_lsarpc, v, "samr");
744         if (!NT_STATUS_IS_OK(status)) {
745                 goto done;
746         }
747
748         status = rpc_ep_register(ev_ctx, msg_ctx, &ndr_table_samr, v);
749         if (!NT_STATUS_IS_OK(status)) {
750                 goto done;
751         }
752
753         /* NETLOGON */
754         fd = create_named_pipe_socket("netlogon");
755         if (fd < 0) {
756                 goto done;
757         }
758
759         rc = listen(fd, pf_lsasd_cfg.max_allowed_clients);
760         if (rc == -1) {
761                 DEBUG(0, ("Failed to listen on samr pipe - %s\n",
762                           strerror(errno)));
763                 goto done;
764         }
765         listen_fd[*listen_fd_size] = fd;
766         (*listen_fd_size)++;
767
768         fd = create_dcerpc_ncalrpc_socket("netlogon");
769         if (fd < 0) {
770                 goto done;
771         }
772
773         rc = listen(fd, pf_lsasd_cfg.max_allowed_clients);
774         if (rc == -1) {
775                 DEBUG(0, ("Failed to listen on netlogon ncalrpc - %s\n",
776                           strerror(errno)));
777                 goto done;
778         }
779         listen_fd[*listen_fd_size] = fd;
780         (*listen_fd_size)++;
781         fd = -1;
782
783         v = dcerpc_binding_vector_dup(tmp_ctx, v_orig);
784         if (v == NULL) {
785                 goto done;
786         }
787
788         status = dcerpc_binding_vector_replace_iface(&ndr_table_netlogon, v);
789         if (!NT_STATUS_IS_OK(status)) {
790                 goto done;
791         }
792
793         status = dcerpc_binding_vector_add_np_default(&ndr_table_netlogon, v);
794         if (!NT_STATUS_IS_OK(status)) {
795                 goto done;
796         }
797
798         status = dcerpc_binding_vector_add_unix(&ndr_table_lsarpc, v, "netlogon");
799         if (!NT_STATUS_IS_OK(status)) {
800                 goto done;
801         }
802
803         status = rpc_ep_register(ev_ctx, msg_ctx, &ndr_table_netlogon, v);
804         if (!NT_STATUS_IS_OK(status)) {
805                 goto done;
806         }
807
808         ok = true;
809 done:
810         if (fd != -1) {
811                 close(fd);
812         }
813         talloc_free(tmp_ctx);
814         return ok;
815 }
816
817 void start_lsasd(struct tevent_context *ev_ctx,
818                  struct messaging_context *msg_ctx)
819 {
820         NTSTATUS status;
821         int listen_fd[LSASD_MAX_SOCKETS];
822         int listen_fd_size = 0;
823         pid_t pid;
824         int rc;
825         bool ok;
826
827         DEBUG(1, ("Forking LSA Service Daemon\n"));
828
829         /*
830          * Block signals before forking child as it will have to
831          * set its own handlers. Child will re-enable SIGHUP as
832          * soon as the handlers are set up.
833          */
834         BlockSignals(true, SIGTERM);
835         BlockSignals(true, SIGHUP);
836
837         pid = fork();
838         if (pid == -1) {
839                 DEBUG(0, ("Failed to fork LSASD [%s], aborting ...\n",
840                            strerror(errno)));
841                 exit(1);
842         }
843
844         /* parent or error */
845         if (pid != 0) {
846
847                 /* Re-enable SIGHUP before returnig */
848                 BlockSignals(false, SIGTERM);
849                 BlockSignals(false, SIGHUP);
850
851                 return;
852         }
853
854         status = smbd_reinit_after_fork(msg_ctx, ev_ctx, true, "lsasd-master");
855         if (!NT_STATUS_IS_OK(status)) {
856                 DEBUG(0,("reinit_after_fork() failed\n"));
857                 smb_panic("reinit_after_fork() failed");
858         }
859
860         /* save the parent process id so the children can use it later */
861         parent_id = messaging_server_id(msg_ctx);
862
863         lsasd_reopen_logs(0);
864         pfh_daemon_config(DAEMON_NAME,
865                           &pf_lsasd_cfg,
866                           &default_pf_lsasd_cfg);
867
868         lsasd_setup_sig_term_handler(ev_ctx);
869         lsasd_setup_sig_hup_handler(ev_ctx);
870
871         BlockSignals(false, SIGTERM);
872         BlockSignals(false, SIGHUP);
873
874         ok = lsasd_create_sockets(ev_ctx, msg_ctx, listen_fd, &listen_fd_size);
875         if (!ok) {
876                 exit(1);
877         }
878
879         /* start children before any more initialization is done */
880         ok = prefork_create_pool(ev_ctx, /* mem_ctx */
881                                  ev_ctx,
882                                  msg_ctx,
883                                  listen_fd_size,
884                                  listen_fd,
885                                  pf_lsasd_cfg.min_children,
886                                  pf_lsasd_cfg.max_children,
887                                  &lsasd_children_main,
888                                  NULL,
889                                  &lsasd_pool);
890         if (!ok) {
891                 exit(1);
892         }
893
894         messaging_register(msg_ctx,
895                            ev_ctx,
896                            MSG_SMB_CONF_UPDATED,
897                            lsasd_smb_conf_updated);
898         messaging_register(msg_ctx, ev_ctx,
899                            MSG_PREFORK_CHILD_EVENT, child_ping);
900
901         status = rpc_lsarpc_init(NULL);
902         if (!NT_STATUS_IS_OK(status)) {
903                 DEBUG(0, ("Failed to register lsarpc rpc interface in lsasd! (%s)\n",
904                           nt_errstr(status)));
905                 exit(1);
906         }
907
908         status = rpc_samr_init(NULL);
909         if (!NT_STATUS_IS_OK(status)) {
910                 DEBUG(0, ("Failed to register samr rpc interface in lsasd! (%s)\n",
911                           nt_errstr(status)));
912                 exit(1);
913         }
914
915         status = rpc_netlogon_init(NULL);
916         if (!NT_STATUS_IS_OK(status)) {
917                 DEBUG(0, ("Failed to register netlogon rpc interface in lsasd! (%s)\n",
918                           nt_errstr(status)));
919                 exit(1);
920         }
921
922         ok = lsasd_setup_children_monitor(ev_ctx, msg_ctx);
923         if (!ok) {
924                 DEBUG(0, ("Failed to setup children monitoring!\n"));
925                 exit(1);
926         }
927
928         DEBUG(1, ("LSASD Daemon Started (%u)\n", (unsigned int)getpid()));
929
930         /* loop forever */
931         rc = tevent_loop_wait(ev_ctx);
932
933         /* should not be reached */
934         DEBUG(0,("lsasd: tevent_loop_wait() exited with %d - %s\n",
935                  rc, (rc == 0) ? "out of events" : strerror(errno)));
936         exit(1);
937 }