lib/messaging: Move messages_dgm out of source3
[samba.git] / source4 / smbd / process_standard.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    process model: standard (1 process per client connection)
5
6    Copyright (C) Andrew Tridgell 1992-2005
7    Copyright (C) James J Myers 2003 <myersjj@samba.org>
8    Copyright (C) Stefan (metze) Metzmacher 2004
9    
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "lib/events/events.h"
26 #include "smbd/process_model.h"
27 #include "system/filesys.h"
28 #include "cluster/cluster.h"
29 #include "param/param.h"
30 #include "ldb_wrap.h"
31 #include "lib/messaging/messaging.h"
32 #include "lib/util/debug.h"
33 #include "lib/messaging/messages_dgm.h"
34 #include "lib/util/util_process.h"
35
36 static unsigned connections_active = 0;
37 static unsigned smbd_max_processes = 0;
38
39 struct standard_child_state {
40         const char *name;
41         pid_t pid;
42         int to_parent_fd;
43         int from_child_fd;
44         struct tevent_fd *from_child_fde;
45 };
46
47 NTSTATUS process_model_standard_init(TALLOC_CTX *);
48 struct process_context {
49         char *name;
50         int from_parent_fd;
51         bool inhibit_fork_on_accept;
52         bool forked_on_accept;
53 };
54
55 /*
56   called when the process model is selected
57 */
58 static void standard_model_init(void)
59 {
60 }
61
62 static void sighup_signal_handler(struct tevent_context *ev,
63                                 struct tevent_signal *se,
64                                 int signum, int count, void *siginfo,
65                                 void *private_data)
66 {
67         debug_schedule_reopen_logs();
68 }
69
70 static void sigterm_signal_handler(struct tevent_context *ev,
71                                 struct tevent_signal *se,
72                                 int signum, int count, void *siginfo,
73                                 void *private_data)
74 {
75 #ifdef HAVE_GETPGRP
76         if (getpgrp() == getpid()) {
77                 /*
78                  * We're the process group leader, send
79                  * SIGTERM to our process group.
80                  */
81                 DBG_ERR("SIGTERM: killing children\n");
82                 kill(-getpgrp(), SIGTERM);
83         }
84 #endif
85         DBG_ERR("Exiting pid %u on SIGTERM\n", (unsigned int)getpid());
86         talloc_free(ev);
87         exit(127);
88 }
89
90 /*
91   handle EOF on the parent-to-all-children pipe in the child
92 */
93 static void standard_pipe_handler(struct tevent_context *event_ctx, struct tevent_fd *fde, 
94                                   uint16_t flags, void *private_data)
95 {
96         DBG_DEBUG("Child %d exiting\n", (int)getpid());
97         talloc_free(event_ctx);
98         exit(0);
99 }
100
101 /*
102   handle EOF on the child pipe in the parent, so we know when a
103   process terminates without using SIGCHLD or waiting on all possible pids.
104
105   We need to ensure we do not ignore SIGCHLD because we need it to
106   work to get a valid error code from samba_runcmd_*().
107  */
108 static void standard_child_pipe_handler(struct tevent_context *ev,
109                                         struct tevent_fd *fde,
110                                         uint16_t flags,
111                                         void *private_data)
112 {
113         struct standard_child_state *state
114                 = talloc_get_type_abort(private_data, struct standard_child_state);
115         int status = 0;
116         pid_t pid;
117
118         messaging_dgm_cleanup(state->pid);
119
120         /* the child has closed the pipe, assume its dead */
121         errno = 0;
122         pid = waitpid(state->pid, &status, 0);
123
124         if (pid != state->pid) {
125                 if (errno == ECHILD) {
126                         /*
127                          * this happens when the
128                          * parent has set SIGCHLD to
129                          * SIG_IGN. In that case we
130                          * can only get error
131                          * information for the child
132                          * via its logging. We should
133                          * stop using SIG_IGN on
134                          * SIGCHLD in the standard
135                          * process model.
136                          */
137                         DBG_ERR("Error in waitpid() unexpectedly got ECHILD "
138                                 "for child %d (%s) - %s, someone has set SIGCHLD "
139                                 "to SIG_IGN!\n",
140                                 (int)state->pid, state->name,
141                                 strerror(errno));
142                         TALLOC_FREE(state);
143                         return;
144                 }
145                 DBG_ERR("Error in waitpid() for child %d (%s) - %s \n",
146                         (int)state->pid, state->name, strerror(errno));
147                 if (errno == 0) {
148                         errno = ECHILD;
149                 }
150                 goto done;
151         }
152         if (WIFEXITED(status)) {
153                 status = WEXITSTATUS(status);
154                 if (status != 0) {
155                         DBG_ERR("Child %d (%s) exited with status %d\n",
156                                 (int)state->pid, state->name, status);
157                 }
158         } else if (WIFSIGNALED(status)) {
159                 status = WTERMSIG(status);
160                 DBG_ERR("Child %d (%s) terminated with signal %d\n",
161                         (int)state->pid, state->name, status);
162         }
163 done:
164         TALLOC_FREE(state);
165         if (smbd_max_processes > 0) {
166                 if (connections_active < 1) {
167                         DBG_ERR("Number of active connections "
168                                 "less than 1 (%d)\n",
169                                 connections_active);
170                         connections_active = 1;
171                 }
172                 connections_active--;
173         }
174         return;
175 }
176
177 static struct standard_child_state *setup_standard_child_pipe(struct tevent_context *ev,
178                                                               const char *name)
179 {
180         struct standard_child_state *state;
181         int parent_child_pipe[2];
182         int ret;
183
184         /*
185          * Prepare a pipe to allow us to know when the child exits,
186          * because it will trigger a read event on this private
187          * pipe.
188          *
189          * We do all this before the accept and fork(), so we can
190          * clean up if it fails.
191          */
192         state = talloc_zero(ev, struct standard_child_state);
193         if (state == NULL) {
194                 return NULL;
195         }
196
197         if (name == NULL) {
198                 name = "";
199         }
200
201         state->name = talloc_strdup(state, name);
202         if (state->name == NULL) {
203                 TALLOC_FREE(state);
204                 return NULL;
205         }
206
207         ret = pipe(parent_child_pipe);
208         if (ret == -1) {
209                 DBG_ERR("Failed to create parent-child pipe to handle "
210                         "SIGCHLD to track new process for socket\n");
211                 TALLOC_FREE(state);
212                 return NULL;
213         }
214
215         smb_set_close_on_exec(parent_child_pipe[0]);
216         smb_set_close_on_exec(parent_child_pipe[1]);
217
218         state->from_child_fd = parent_child_pipe[0];
219         state->to_parent_fd = parent_child_pipe[1];
220
221         /*
222          * The basic purpose of calling this handler is to ensure we
223          * call waitpid() and so avoid zombies (now that we no longer
224          * user SIGIGN on for SIGCHLD), but it also allows us to clean
225          * up other resources in the future.
226          */
227         state->from_child_fde = tevent_add_fd(ev, state,
228                                               state->from_child_fd,
229                                               TEVENT_FD_READ,
230                                               standard_child_pipe_handler,
231                                               state);
232         if (state->from_child_fde == NULL) {
233                 TALLOC_FREE(state);
234                 return NULL;
235         }
236         tevent_fd_set_auto_close(state->from_child_fde);
237
238         return state;
239 }
240
241 /*
242   called when a listening socket becomes readable. 
243 */
244 static void standard_accept_connection(
245                 struct tevent_context *ev,
246                 struct loadparm_context *lp_ctx,
247                 struct socket_context *sock,
248                 void (*new_conn)(struct tevent_context *,
249                                 struct loadparm_context *,
250                                 struct socket_context *,
251                                 struct server_id,
252                                 void *,
253                                 void *),
254                 void *private_data,
255                 void *process_context)
256 {
257         NTSTATUS status;
258         struct socket_context *sock2;
259         pid_t pid;
260         struct socket_address *c, *s;
261         struct standard_child_state *state;
262         struct tevent_fd *fde = NULL;
263         struct tevent_signal *se = NULL;
264         struct process_context *proc_ctx = NULL;
265
266
267         /* accept an incoming connection. */
268         status = socket_accept(sock, &sock2);
269         if (!NT_STATUS_IS_OK(status)) {
270                 DBG_DEBUG("standard_accept_connection: accept: %s\n",
271                           nt_errstr(status));
272                 /* this looks strange, but is correct. We need to throttle
273                  * things until the system clears enough resources to handle
274                  * this new socket
275                  */
276                 sleep(1);
277                 return;
278         }
279
280         proc_ctx = talloc_get_type_abort(process_context,
281                                          struct process_context);
282
283         if (proc_ctx->inhibit_fork_on_accept) {
284                 pid = getpid();
285                 /*
286                  * Service does not support forking a new process on a
287                  * new connection, either it's maintaining shared
288                  * state or the overhead of forking a new process is a
289                  * significant fraction of the response time.
290                  */
291                 talloc_steal(private_data, sock2);
292                 new_conn(ev, lp_ctx, sock2,
293                          cluster_id(pid, socket_get_fd(sock2)), private_data,
294                          process_context);
295                 return;
296         }
297
298         if (smbd_max_processes > 0) {
299                 if (connections_active >= smbd_max_processes) {
300                         DBG_ERR("(%d) connections already active, "
301                                 "maximum is (%d). Dropping request\n",
302                                 connections_active,
303                                 smbd_max_processes);
304                         /*
305                          * Drop the connection as we're overloaded at the moment
306                          */
307                         talloc_free(sock2);
308                         return;
309                 }
310                 connections_active++;
311         }
312
313         state = setup_standard_child_pipe(ev, NULL);
314         if (state == NULL) {
315                 return;
316         }
317         pid = fork();
318
319         if (pid != 0) {
320                 close(state->to_parent_fd);
321                 state->to_parent_fd = -1;
322
323                 if (pid > 0) {
324                         state->pid = pid;
325                 } else {
326                         TALLOC_FREE(state);
327                 }
328
329                 /* parent or error code ... */
330                 talloc_free(sock2);
331                 /* go back to the event loop */
332                 return;
333         }
334
335         /* this leaves state->to_parent_fd open */
336         TALLOC_FREE(state);
337
338         /* Now in the child code so indicate that we forked
339          * so the terminate code knows what to do
340          */
341         proc_ctx->forked_on_accept = true;
342
343         pid = getpid();
344         setproctitle("task[%s] standard worker", proc_ctx->name);
345
346         /*
347          * We must fit within 15 chars of text or we will truncate, so
348          * we put the constant part last
349          */
350         prctl_set_comment("%s[work]", proc_ctx->name);
351
352         /* This is now the child code. We need a completely new event_context to work with */
353
354         if (tevent_re_initialise(ev) != 0) {
355                 smb_panic("Failed to re-initialise tevent after fork");
356         }
357
358         /* this will free all the listening sockets and all state that
359            is not associated with this new connection */
360         talloc_free(sock);
361
362         /* we don't care if the dup fails, as its only a select()
363            speed optimisation */
364         socket_dup(sock2);
365                         
366         /* tdb needs special fork handling */
367         ldb_wrap_fork_hook();
368
369         /* Must be done after a fork() to reset messaging contexts. */
370         status = imessaging_reinit_all();
371         if (!NT_STATUS_IS_OK(status)) {
372                 smb_panic("Failed to re-initialise imessaging after fork");
373         }
374
375         fde = tevent_add_fd(ev, ev, proc_ctx->from_parent_fd, TEVENT_FD_READ,
376                       standard_pipe_handler, NULL);
377         if (fde == NULL) {
378                 smb_panic("Failed to add fd handler after fork");
379         }
380
381         se = tevent_add_signal(ev,
382                                 ev,
383                                 SIGHUP,
384                                 0,
385                                 sighup_signal_handler,
386                                 NULL);
387         if (se == NULL) {
388                 smb_panic("Failed to add SIGHUP handler after fork");
389         }
390
391         se = tevent_add_signal(ev,
392                                 ev,
393                                 SIGTERM,
394                                 0,
395                                 sigterm_signal_handler,
396                                 NULL);
397         if (se == NULL) {
398                 smb_panic("Failed to add SIGTERM handler after fork");
399         }
400
401         /* setup the process title */
402         c = socket_get_peer_addr(sock2, ev);
403         s = socket_get_my_addr(sock2, ev);
404         if (s && c) {
405                 setproctitle("conn c[%s:%u] s[%s:%u] server_id[%d]",
406                              c->addr, c->port, s->addr, s->port, (int)pid);
407         }
408         talloc_free(c);
409         talloc_free(s);
410
411         /* setup this new connection.  Cluster ID is PID based for this process model */
412         new_conn(ev, lp_ctx, sock2, cluster_id(pid, 0), private_data,
413                  process_context);
414
415         /* we can't return to the top level here, as that event context is gone,
416            so we now process events in the new event context until there are no
417            more to process */      
418         tevent_loop_wait(ev);
419
420         talloc_free(ev);
421         exit(0);
422 }
423
424 /*
425   called to create a new server task
426 */
427 static void standard_new_task(struct tevent_context *ev,
428                               struct loadparm_context *lp_ctx,
429                               const char *service_name,
430                               struct task_server *(*new_task)(struct tevent_context *, struct loadparm_context *lp_ctx, struct server_id , void *, void *),
431                               void *private_data,
432                               const struct service_details *service_details,
433                               int from_parent_fd)
434 {
435         pid_t pid;
436         NTSTATUS status;
437         struct standard_child_state *state;
438         struct tevent_fd *fde = NULL;
439         struct tevent_signal *se = NULL;
440         struct process_context *proc_ctx = NULL;
441         struct task_server* task = NULL;
442
443         state = setup_standard_child_pipe(ev, service_name);
444         if (state == NULL) {
445                 return;
446         }
447
448         pid = fork();
449
450         if (pid != 0) {
451                 close(state->to_parent_fd);
452                 state->to_parent_fd = -1;
453
454                 if (pid > 0) {
455                         state->pid = pid;
456                 } else {
457                         TALLOC_FREE(state);
458                 }
459
460                 /* parent or error code ... go back to the event loop */
461                 return;
462         }
463
464         /* this leaves state->to_parent_fd open */
465         TALLOC_FREE(state);
466
467         pid = getpid();
468
469         /* this will free all the listening sockets and all state that
470            is not associated with this new connection */
471         if (tevent_re_initialise(ev) != 0) {
472                 smb_panic("Failed to re-initialise tevent after fork");
473         }
474
475         /* ldb/tdb need special fork handling */
476         ldb_wrap_fork_hook();
477
478         /* Must be done after a fork() to reset messaging contexts. */
479         status = imessaging_reinit_all();
480         if (!NT_STATUS_IS_OK(status)) {
481                 smb_panic("Failed to re-initialise imessaging after fork");
482         }
483
484         fde = tevent_add_fd(ev, ev, from_parent_fd, TEVENT_FD_READ,
485                       standard_pipe_handler, NULL);
486         if (fde == NULL) {
487                 smb_panic("Failed to add fd handler after fork");
488         }
489
490         se = tevent_add_signal(ev,
491                                 ev,
492                                 SIGHUP,
493                                 0,
494                                 sighup_signal_handler,
495                                 NULL);
496         if (se == NULL) {
497                 smb_panic("Failed to add SIGHUP handler after fork");
498         }
499
500         se = tevent_add_signal(ev,
501                                 ev,
502                                 SIGTERM,
503                                 0,
504                                 sigterm_signal_handler,
505                                 NULL);
506         if (se == NULL) {
507                 smb_panic("Failed to add SIGTERM handler after fork");
508         }
509
510         setproctitle("task[%s]", service_name);
511         /*
512          * We must fit within 15 chars of text or we will truncate, so
513          * we put the constant part last
514          */
515         prctl_set_comment("%s[task]", service_name);
516
517         /*
518          * Set up the process context to be passed through to the terminate
519          * and accept_connection functions
520          */
521         proc_ctx = talloc(ev, struct process_context);
522         proc_ctx->name = talloc_strdup(ev, service_name);
523         proc_ctx->from_parent_fd = from_parent_fd;
524         proc_ctx->inhibit_fork_on_accept  =
525                 service_details->inhibit_fork_on_accept;
526         proc_ctx->forked_on_accept = false;
527
528         smbd_max_processes = lpcfg_max_smbd_processes(lp_ctx);
529
530         /* setup this new task.  Cluster ID is PID based for this process model */
531         task = new_task(ev, lp_ctx, cluster_id(pid, 0), private_data, proc_ctx);
532         /*
533          * Currently we don't support the post_fork functionality in the
534          * standard model, i.e. it is only called here not after a new process
535          * is forked in standard_accept_connection.
536          */
537         if (task != NULL && service_details->post_fork != NULL) {
538                 struct process_details pd = initial_process_details;
539                 service_details->post_fork(task, &pd);
540         }
541
542
543         /* we can't return to the top level here, as that event context is gone,
544            so we now process events in the new event context until there are no
545            more to process */
546         tevent_loop_wait(ev);
547
548         talloc_free(ev);
549         exit(0);
550 }
551
552
553 /* called when a task goes down */
554 static void standard_terminate_task(struct tevent_context *ev,
555                                     struct loadparm_context *lp_ctx,
556                                     const char *reason,
557                                     bool fatal,
558                                     void *process_context)
559 {
560         if (fatal == true) {
561                 exit(127);
562         }
563         exit(0);
564 }
565
566 /* called when a connection terminates*/
567 static void standard_terminate_connection(struct tevent_context *ev,
568                                           struct loadparm_context *lp_ctx,
569                                           const char *reason,
570                                           void *process_context)
571 {
572         struct process_context *proc_ctx = NULL;
573
574         DBG_DEBUG("connection terminating reason[%s]\n", reason);
575         if (process_context == NULL) {
576                 smb_panic("Panicking process_context is NULL");
577         }
578
579         proc_ctx = talloc_get_type(process_context, struct process_context);
580         if (proc_ctx->forked_on_accept == false) {
581                 /*
582                  * The current task was not forked on accept, so it needs to
583                  * keep running and process requests from other connections
584                  */
585                 return;
586         }
587         /*
588          * The current process was forked on accept to handle a single
589          * connection/request. That request has now finished and the process
590          * should terminate
591          */
592
593         /* this reload_charcnv() has the effect of freeing the iconv context memory,
594            which makes leak checking easier */
595         reload_charcnv(lp_ctx);
596
597         /* Always free event context last before exit. */
598         talloc_free(ev);
599
600         /* terminate this process */
601         exit(0);
602 }
603 /* called to set a title of a task or connection */
604 static void standard_set_title(struct tevent_context *ev, const char *title) 
605 {
606         if (title) {
607                 setproctitle("%s", title);
608         } else {
609                 setproctitle(NULL);
610         }
611 }
612
613 static const struct model_ops standard_ops = {
614         .name                   = "standard",
615         .model_init             = standard_model_init,
616         .accept_connection      = standard_accept_connection,
617         .new_task               = standard_new_task,
618         .terminate_task         = standard_terminate_task,
619         .terminate_connection   = standard_terminate_connection,
620         .set_title              = standard_set_title,
621 };
622
623 /*
624   initialise the standard process model, registering ourselves with the process model subsystem
625  */
626 NTSTATUS process_model_standard_init(TALLOC_CTX *ctx)
627 {
628         return register_process_model(&standard_ops);
629 }