c6cbfc23edad58868c4d3d2c57259b78feba6fdc
[kai/samba-autobuild/.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 "source3/lib/messages_dgm.h"
34
35 struct standard_child_state {
36         const char *name;
37         pid_t pid;
38         int to_parent_fd;
39         int from_child_fd;
40         struct tevent_fd *from_child_fde;
41 };
42
43 NTSTATUS process_model_standard_init(TALLOC_CTX *);
44
45 static int from_parent_fd;
46
47 /*
48   called when the process model is selected
49 */
50 static void standard_model_init(void)
51 {
52 }
53
54 static void sighup_signal_handler(struct tevent_context *ev,
55                                 struct tevent_signal *se,
56                                 int signum, int count, void *siginfo,
57                                 void *private_data)
58 {
59         debug_schedule_reopen_logs();
60 }
61
62 static void sigterm_signal_handler(struct tevent_context *ev,
63                                 struct tevent_signal *se,
64                                 int signum, int count, void *siginfo,
65                                 void *private_data)
66 {
67 #if HAVE_GETPGRP
68         if (getpgrp() == getpid()) {
69                 /*
70                  * We're the process group leader, send
71                  * SIGTERM to our process group.
72                  */
73                 DEBUG(0,("SIGTERM: killing children\n"));
74                 kill(-getpgrp(), SIGTERM);
75         }
76 #endif
77         DEBUG(0,("Exiting pid %u on SIGTERM\n", (unsigned int)getpid()));
78         talloc_free(ev);
79         exit(127);
80 }
81
82 /*
83   handle EOF on the parent-to-all-children pipe in the child
84 */
85 static void standard_pipe_handler(struct tevent_context *event_ctx, struct tevent_fd *fde, 
86                                   uint16_t flags, void *private_data)
87 {
88         DEBUG(10,("Child %d exiting\n", (int)getpid()));
89         talloc_free(event_ctx);
90         exit(0);
91 }
92
93 /*
94   handle EOF on the child pipe in the parent, so we know when a
95   process terminates without using SIGCHLD or waiting on all possible pids.
96
97   We need to ensure we do not ignore SIGCHLD because we need it to
98   work to get a valid error code from samba_runcmd_*().
99  */
100 static void standard_child_pipe_handler(struct tevent_context *ev,
101                                         struct tevent_fd *fde,
102                                         uint16_t flags,
103                                         void *private_data)
104 {
105         struct standard_child_state *state
106                 = talloc_get_type_abort(private_data, struct standard_child_state);
107         int status = 0;
108         pid_t pid;
109
110         messaging_dgm_cleanup(state->pid);
111
112         /* the child has closed the pipe, assume its dead */
113         errno = 0;
114         pid = waitpid(state->pid, &status, 0);
115
116         if (pid != state->pid) {
117                 if (errno == ECHILD) {
118                         /*
119                          * this happens when the
120                          * parent has set SIGCHLD to
121                          * SIG_IGN. In that case we
122                          * can only get error
123                          * information for the child
124                          * via its logging. We should
125                          * stop using SIG_IGN on
126                          * SIGCHLD in the standard
127                          * process model.
128                          */
129                         DEBUG(0, ("Error in waitpid() unexpectedly got ECHILD "
130                                   "for child %d (%s) - %s, someone has set SIGCHLD "
131                                   "to SIG_IGN!\n",
132                                   (int)state->pid, state->name,
133                                   strerror(errno)));
134                         TALLOC_FREE(state);
135                         return;
136                 }
137                 DEBUG(0, ("Error in waitpid() for child %d (%s) - %s \n",
138                           (int)state->pid, state->name, strerror(errno)));
139                 if (errno == 0) {
140                         errno = ECHILD;
141                 }
142                 TALLOC_FREE(state);
143                 return;
144         }
145         if (WIFEXITED(status)) {
146                 status = WEXITSTATUS(status);
147                 DEBUG(2, ("Child %d (%s) exited with status %d\n",
148                           (int)state->pid, state->name, status));
149         } else if (WIFSIGNALED(status)) {
150                 status = WTERMSIG(status);
151                 DEBUG(0, ("Child %d (%s) terminated with signal %d\n",
152                           (int)state->pid, state->name, status));
153         }
154         TALLOC_FREE(state);
155         return;
156 }
157
158 static struct standard_child_state *setup_standard_child_pipe(struct tevent_context *ev,
159                                                               const char *name)
160 {
161         struct standard_child_state *state;
162         int parent_child_pipe[2];
163         int ret;
164
165         /*
166          * Prepare a pipe to allow us to know when the child exits,
167          * because it will trigger a read event on this private
168          * pipe.
169          *
170          * We do all this before the accept and fork(), so we can
171          * clean up if it fails.
172          */
173         state = talloc_zero(ev, struct standard_child_state);
174         if (state == NULL) {
175                 return NULL;
176         }
177
178         if (name == NULL) {
179                 name = "";
180         }
181
182         state->name = talloc_strdup(state, name);
183         if (state->name == NULL) {
184                 TALLOC_FREE(state);
185                 return NULL;
186         }
187
188         ret = pipe(parent_child_pipe);
189         if (ret == -1) {
190                 DEBUG(0, ("Failed to create parent-child pipe to handle "
191                           "SIGCHLD to track new process for socket\n"));
192                 TALLOC_FREE(state);
193                 return NULL;
194         }
195
196         smb_set_close_on_exec(parent_child_pipe[0]);
197         smb_set_close_on_exec(parent_child_pipe[1]);
198
199         state->from_child_fd = parent_child_pipe[0];
200         state->to_parent_fd = parent_child_pipe[1];
201
202         /*
203          * The basic purpose of calling this handler is to ensure we
204          * call waitpid() and so avoid zombies (now that we no longer
205          * user SIGIGN on for SIGCHLD), but it also allows us to clean
206          * up other resources in the future.
207          */
208         state->from_child_fde = tevent_add_fd(ev, state,
209                                               state->from_child_fd,
210                                               TEVENT_FD_READ,
211                                               standard_child_pipe_handler,
212                                               state);
213         if (state->from_child_fde == NULL) {
214                 TALLOC_FREE(state);
215                 return NULL;
216         }
217         tevent_fd_set_auto_close(state->from_child_fde);
218
219         return state;
220 }
221
222 /*
223   called when a listening socket becomes readable. 
224 */
225 static void standard_accept_connection(struct tevent_context *ev, 
226                                        struct loadparm_context *lp_ctx,
227                                        struct socket_context *sock, 
228                                        void (*new_conn)(struct tevent_context *,
229                                                         struct loadparm_context *, struct socket_context *, 
230                                                         struct server_id , void *), 
231                                        void *private_data)
232 {
233         NTSTATUS status;
234         struct socket_context *sock2;
235         pid_t pid;
236         struct socket_address *c, *s;
237         struct standard_child_state *state;
238         struct tevent_fd *fde = NULL;
239         struct tevent_signal *se = NULL;
240
241         state = setup_standard_child_pipe(ev, NULL);
242         if (state == NULL) {
243                 return;
244         }
245
246         /* accept an incoming connection. */
247         status = socket_accept(sock, &sock2);
248         if (!NT_STATUS_IS_OK(status)) {
249                 DEBUG(0,("standard_accept_connection: accept: %s\n",
250                          nt_errstr(status)));
251                 /* this looks strange, but is correct. We need to throttle things until
252                    the system clears enough resources to handle this new socket */
253                 sleep(1);
254                 close(state->to_parent_fd);
255                 state->to_parent_fd = -1;
256                 TALLOC_FREE(state);
257                 return;
258         }
259
260         pid = fork();
261
262         if (pid != 0) {
263                 close(state->to_parent_fd);
264                 state->to_parent_fd = -1;
265
266                 if (pid > 0) {
267                         state->pid = pid;
268                 } else {
269                         TALLOC_FREE(state);
270                 }
271
272                 /* parent or error code ... */
273                 talloc_free(sock2);
274                 /* go back to the event loop */
275                 return;
276         }
277
278         /* this leaves state->to_parent_fd open */
279         TALLOC_FREE(state);
280
281         pid = getpid();
282
283         /* This is now the child code. We need a completely new event_context to work with */
284
285         if (tevent_re_initialise(ev) != 0) {
286                 smb_panic("Failed to re-initialise tevent after fork");
287         }
288
289         /* this will free all the listening sockets and all state that
290            is not associated with this new connection */
291         talloc_free(sock);
292
293         /* we don't care if the dup fails, as its only a select()
294            speed optimisation */
295         socket_dup(sock2);
296                         
297         /* tdb needs special fork handling */
298         ldb_wrap_fork_hook();
299
300         /* Must be done after a fork() to reset messaging contexts. */
301         status = imessaging_reinit_all();
302         if (!NT_STATUS_IS_OK(status)) {
303                 smb_panic("Failed to re-initialise imessaging after fork");
304         }
305
306         fde = tevent_add_fd(ev, ev, from_parent_fd, TEVENT_FD_READ,
307                       standard_pipe_handler, NULL);
308         if (fde == NULL) {
309                 smb_panic("Failed to add fd handler after fork");
310         }
311
312         se = tevent_add_signal(ev,
313                                 ev,
314                                 SIGHUP,
315                                 0,
316                                 sighup_signal_handler,
317                                 NULL);
318         if (se == NULL) {
319                 smb_panic("Failed to add SIGHUP handler after fork");
320         }
321
322         se = tevent_add_signal(ev,
323                                 ev,
324                                 SIGTERM,
325                                 0,
326                                 sigterm_signal_handler,
327                                 NULL);
328         if (se == NULL) {
329                 smb_panic("Failed to add SIGTERM handler after fork");
330         }
331
332         /* setup the process title */
333         c = socket_get_peer_addr(sock2, ev);
334         s = socket_get_my_addr(sock2, ev);
335         if (s && c) {
336                 setproctitle("conn c[%s:%u] s[%s:%u] server_id[%d]",
337                              c->addr, c->port, s->addr, s->port, (int)pid);
338         }
339         talloc_free(c);
340         talloc_free(s);
341
342         /* setup this new connection.  Cluster ID is PID based for this process model */
343         new_conn(ev, lp_ctx, sock2, cluster_id(pid, 0), private_data);
344
345         /* we can't return to the top level here, as that event context is gone,
346            so we now process events in the new event context until there are no
347            more to process */      
348         tevent_loop_wait(ev);
349
350         talloc_free(ev);
351         exit(0);
352 }
353
354 /*
355   called to create a new server task
356 */
357 static void standard_new_task(struct tevent_context *ev,
358                               struct loadparm_context *lp_ctx,
359                               const char *service_name,
360                               void (*new_task)(struct tevent_context *, struct loadparm_context *lp_ctx, struct server_id , void *),
361                               void *private_data,
362                               int new_from_parent_fd)
363 {
364         pid_t pid;
365         NTSTATUS status;
366         struct standard_child_state *state;
367         struct tevent_fd *fde = NULL;
368         struct tevent_signal *se = NULL;
369
370         state = setup_standard_child_pipe(ev, service_name);
371         if (state == NULL) {
372                 return;
373         }
374         from_parent_fd = new_from_parent_fd;
375
376         pid = fork();
377
378         if (pid != 0) {
379                 close(state->to_parent_fd);
380                 state->to_parent_fd = -1;
381
382                 if (pid > 0) {
383                         state->pid = pid;
384                 } else {
385                         TALLOC_FREE(state);
386                 }
387
388                 /* parent or error code ... go back to the event loop */
389                 return;
390         }
391
392         /* this leaves state->to_parent_fd open */
393         TALLOC_FREE(state);
394
395         pid = getpid();
396
397         /* this will free all the listening sockets and all state that
398            is not associated with this new connection */
399         if (tevent_re_initialise(ev) != 0) {
400                 smb_panic("Failed to re-initialise tevent after fork");
401         }
402
403         /* ldb/tdb need special fork handling */
404         ldb_wrap_fork_hook();
405
406         /* Must be done after a fork() to reset messaging contexts. */
407         status = imessaging_reinit_all();
408         if (!NT_STATUS_IS_OK(status)) {
409                 smb_panic("Failed to re-initialise imessaging after fork");
410         }
411
412         fde = tevent_add_fd(ev, ev, from_parent_fd, TEVENT_FD_READ,
413                       standard_pipe_handler, NULL);
414         if (fde == NULL) {
415                 smb_panic("Failed to add fd handler after fork");
416         }
417
418         se = tevent_add_signal(ev,
419                                 ev,
420                                 SIGHUP,
421                                 0,
422                                 sighup_signal_handler,
423                                 NULL);
424         if (se == NULL) {
425                 smb_panic("Failed to add SIGHUP handler after fork");
426         }
427
428         se = tevent_add_signal(ev,
429                                 ev,
430                                 SIGTERM,
431                                 0,
432                                 sigterm_signal_handler,
433                                 NULL);
434         if (se == NULL) {
435                 smb_panic("Failed to add SIGTERM handler after fork");
436         }
437
438         setproctitle("task %s server_id[%d]", service_name, (int)pid);
439
440         /* setup this new task.  Cluster ID is PID based for this process model */
441         new_task(ev, lp_ctx, cluster_id(pid, 0), private_data);
442
443         /* we can't return to the top level here, as that event context is gone,
444            so we now process events in the new event context until there are no
445            more to process */      
446         tevent_loop_wait(ev);
447
448         talloc_free(ev);
449         exit(0);
450 }
451
452
453 /* called when a task goes down */
454 _NORETURN_ static void standard_terminate(struct tevent_context *ev, struct loadparm_context *lp_ctx,
455                                           const char *reason) 
456 {
457         DEBUG(2,("standard_terminate: reason[%s]\n",reason));
458
459         /* this reload_charcnv() has the effect of freeing the iconv context memory,
460            which makes leak checking easier */
461         reload_charcnv(lp_ctx);
462
463         /* Always free event context last before exit. */
464         talloc_free(ev);
465
466         /* terminate this process */
467         exit(0);
468 }
469
470 /* called to set a title of a task or connection */
471 static void standard_set_title(struct tevent_context *ev, const char *title) 
472 {
473         if (title) {
474                 setproctitle("%s", title);
475         } else {
476                 setproctitle(NULL);
477         }
478 }
479
480 static const struct model_ops standard_ops = {
481         .name                   = "standard",
482         .model_init             = standard_model_init,
483         .accept_connection      = standard_accept_connection,
484         .new_task               = standard_new_task,
485         .terminate              = standard_terminate,
486         .set_title              = standard_set_title,
487 };
488
489 /*
490   initialise the standard process model, registering ourselves with the process model subsystem
491  */
492 NTSTATUS process_model_standard_init(TALLOC_CTX *ctx)
493 {
494         return register_process_model(&standard_ops);
495 }