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