Line data Source code
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 "samba/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 30 : static void standard_model_init(void)
59 : {
60 30 : }
61 :
62 0 : 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 0 : debug_schedule_reopen_logs();
68 0 : }
69 :
70 0 : 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 0 : if (getpgrp() == getpid()) {
77 : /*
78 : * We're the process group leader, send
79 : * SIGTERM to our process group.
80 : */
81 0 : DBG_ERR("SIGTERM: killing children\n");
82 0 : kill(-getpgrp(), SIGTERM);
83 : }
84 : #endif
85 0 : DBG_ERR("Exiting pid %u on SIGTERM\n", (unsigned int)getpid());
86 0 : talloc_free(ev);
87 0 : exit(127);
88 : }
89 :
90 : /*
91 : handle EOF on the parent-to-all-children pipe in the child
92 : */
93 386 : static void standard_pipe_handler(struct tevent_context *event_ctx, struct tevent_fd *fde,
94 : uint16_t flags, void *private_data)
95 : {
96 386 : DBG_DEBUG("Child %d exiting\n", (int)getpid());
97 386 : talloc_free(event_ctx);
98 386 : 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 15426 : 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 0 : struct standard_child_state *state
114 15426 : = talloc_get_type_abort(private_data, struct standard_child_state);
115 15426 : int status = 0;
116 0 : pid_t pid;
117 :
118 15426 : messaging_dgm_cleanup(state->pid);
119 :
120 : /* the child has closed the pipe, assume its dead */
121 15426 : errno = 0;
122 15426 : pid = waitpid(state->pid, &status, 0);
123 :
124 15426 : if (pid != state->pid) {
125 0 : 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 0 : 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 0 : TALLOC_FREE(state);
143 0 : return;
144 : }
145 0 : DBG_ERR("Error in waitpid() for child %d (%s) - %s \n",
146 : (int)state->pid, state->name, strerror(errno));
147 0 : if (errno == 0) {
148 0 : errno = ECHILD;
149 : }
150 0 : goto done;
151 : }
152 15426 : if (WIFEXITED(status)) {
153 15426 : status = WEXITSTATUS(status);
154 15426 : if (status != 0) {
155 0 : DBG_ERR("Child %d (%s) exited with status %d\n",
156 : (int)state->pid, state->name, status);
157 : }
158 0 : } else if (WIFSIGNALED(status)) {
159 0 : status = WTERMSIG(status);
160 0 : DBG_ERR("Child %d (%s) terminated with signal %d\n",
161 : (int)state->pid, state->name, status);
162 : }
163 0 : done:
164 15426 : TALLOC_FREE(state);
165 15426 : if (smbd_max_processes > 0) {
166 21 : if (connections_active < 1) {
167 0 : DBG_ERR("Number of active connections "
168 : "less than 1 (%d)\n",
169 : connections_active);
170 0 : connections_active = 1;
171 : }
172 21 : connections_active--;
173 : }
174 15426 : return;
175 : }
176 :
177 15843 : static struct standard_child_state *setup_standard_child_pipe(struct tevent_context *ev,
178 : const char *name)
179 : {
180 0 : struct standard_child_state *state;
181 0 : int parent_child_pipe[2];
182 0 : 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 15843 : state = talloc_zero(ev, struct standard_child_state);
193 15843 : if (state == NULL) {
194 0 : return NULL;
195 : }
196 :
197 15843 : if (name == NULL) {
198 15423 : name = "";
199 : }
200 :
201 15843 : state->name = talloc_strdup(state, name);
202 15843 : if (state->name == NULL) {
203 0 : TALLOC_FREE(state);
204 0 : return NULL;
205 : }
206 :
207 15843 : ret = pipe(parent_child_pipe);
208 15843 : if (ret == -1) {
209 0 : DBG_ERR("Failed to create parent-child pipe to handle "
210 : "SIGCHLD to track new process for socket\n");
211 0 : TALLOC_FREE(state);
212 0 : return NULL;
213 : }
214 :
215 15843 : smb_set_close_on_exec(parent_child_pipe[0]);
216 15843 : smb_set_close_on_exec(parent_child_pipe[1]);
217 :
218 15843 : state->from_child_fd = parent_child_pipe[0];
219 15843 : 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 15843 : 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 15843 : if (state->from_child_fde == NULL) {
233 0 : TALLOC_FREE(state);
234 0 : return NULL;
235 : }
236 15843 : tevent_fd_set_auto_close(state->from_child_fde);
237 :
238 15843 : return state;
239 : }
240 :
241 : /*
242 : called when a listening socket becomes readable.
243 : */
244 52609 : 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 0 : NTSTATUS status;
258 0 : struct socket_context *sock2;
259 0 : pid_t pid;
260 0 : struct socket_address *c, *s;
261 0 : struct standard_child_state *state;
262 52609 : struct tevent_fd *fde = NULL;
263 52609 : struct tevent_signal *se = NULL;
264 52609 : struct process_context *proc_ctx = NULL;
265 :
266 :
267 : /* accept an incoming connection. */
268 52609 : status = socket_accept(sock, &sock2);
269 52609 : if (!NT_STATUS_IS_OK(status)) {
270 0 : 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 0 : sleep(1);
277 0 : return;
278 : }
279 :
280 52609 : proc_ctx = talloc_get_type_abort(process_context,
281 : struct process_context);
282 :
283 52609 : if (proc_ctx->inhibit_fork_on_accept) {
284 37185 : 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 37185 : talloc_steal(private_data, sock2);
292 37185 : new_conn(ev, lp_ctx, sock2,
293 37185 : cluster_id(pid, socket_get_fd(sock2)), private_data,
294 : process_context);
295 37185 : return;
296 : }
297 :
298 15424 : if (smbd_max_processes > 0) {
299 22 : if (connections_active >= smbd_max_processes) {
300 1 : 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 1 : talloc_free(sock2);
308 1 : return;
309 : }
310 21 : connections_active++;
311 : }
312 :
313 15423 : state = setup_standard_child_pipe(ev, NULL);
314 15423 : if (state == NULL) {
315 0 : return;
316 : }
317 15423 : pid = fork();
318 :
319 30846 : if (pid != 0) {
320 15423 : close(state->to_parent_fd);
321 15423 : state->to_parent_fd = -1;
322 :
323 15423 : if (pid > 0) {
324 15423 : state->pid = pid;
325 : } else {
326 0 : TALLOC_FREE(state);
327 : }
328 :
329 : /* parent or error code ... */
330 15423 : talloc_free(sock2);
331 : /* go back to the event loop */
332 15423 : return;
333 : }
334 :
335 : /* this leaves state->to_parent_fd open */
336 15423 : 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 15423 : proc_ctx->forked_on_accept = true;
342 :
343 15423 : pid = getpid();
344 :
345 15423 : process_set_title("%s[work]", "task[%s] standard worker", proc_ctx->name);
346 :
347 : /* This is now the child code. We need a completely new event_context to work with */
348 :
349 15423 : if (tevent_re_initialise(ev) != 0) {
350 0 : smb_panic("Failed to re-initialise tevent after fork");
351 : }
352 :
353 : /* this will free all the listening sockets and all state that
354 : is not associated with this new connection */
355 15423 : talloc_free(sock);
356 :
357 : /* we don't care if the dup fails, as its only a select()
358 : speed optimisation */
359 15423 : socket_dup(sock2);
360 :
361 : /* tdb needs special fork handling */
362 15423 : ldb_wrap_fork_hook();
363 :
364 : /* Must be done after a fork() to reset messaging contexts. */
365 15423 : status = imessaging_reinit_all();
366 15423 : if (!NT_STATUS_IS_OK(status)) {
367 0 : smb_panic("Failed to re-initialise imessaging after fork");
368 : }
369 :
370 15423 : fde = tevent_add_fd(ev, ev, proc_ctx->from_parent_fd, TEVENT_FD_READ,
371 : standard_pipe_handler, NULL);
372 15423 : if (fde == NULL) {
373 0 : smb_panic("Failed to add fd handler after fork");
374 : }
375 :
376 15423 : se = tevent_add_signal(ev,
377 : ev,
378 : SIGHUP,
379 : 0,
380 : sighup_signal_handler,
381 : NULL);
382 15423 : if (se == NULL) {
383 0 : smb_panic("Failed to add SIGHUP handler after fork");
384 : }
385 :
386 15423 : se = tevent_add_signal(ev,
387 : ev,
388 : SIGTERM,
389 : 0,
390 : sigterm_signal_handler,
391 : NULL);
392 15423 : if (se == NULL) {
393 0 : smb_panic("Failed to add SIGTERM handler after fork");
394 : }
395 :
396 : /* setup the process title */
397 15423 : c = socket_get_peer_addr(sock2, ev);
398 15423 : s = socket_get_my_addr(sock2, ev);
399 15423 : if (s && c) {
400 15423 : setproctitle("conn c[%s:%u] s[%s:%u] server_id[%d]",
401 : c->addr, c->port, s->addr, s->port, (int)pid);
402 : }
403 15423 : talloc_free(c);
404 15423 : talloc_free(s);
405 :
406 15423 : force_check_log_size();
407 :
408 : /* setup this new connection. Cluster ID is PID based for this process model */
409 15423 : new_conn(ev, lp_ctx, sock2, cluster_id(pid, 0), private_data,
410 : process_context);
411 :
412 : /* we can't return to the top level here, as that event context is gone,
413 : so we now process events in the new event context until there are no
414 : more to process */
415 15423 : tevent_loop_wait(ev);
416 :
417 0 : talloc_free(ev);
418 0 : exit(0);
419 : }
420 :
421 : /*
422 : called to create a new server task
423 : */
424 420 : static void standard_new_task(struct tevent_context *ev,
425 : struct loadparm_context *lp_ctx,
426 : const char *service_name,
427 : struct task_server *(*new_task)(struct tevent_context *, struct loadparm_context *lp_ctx, struct server_id , void *, void *),
428 : void *private_data,
429 : const struct service_details *service_details,
430 : int from_parent_fd)
431 : {
432 0 : pid_t pid;
433 0 : NTSTATUS status;
434 0 : struct standard_child_state *state;
435 420 : struct tevent_fd *fde = NULL;
436 420 : struct tevent_signal *se = NULL;
437 420 : struct process_context *proc_ctx = NULL;
438 420 : struct task_server* task = NULL;
439 :
440 420 : state = setup_standard_child_pipe(ev, service_name);
441 420 : if (state == NULL) {
442 0 : return;
443 : }
444 :
445 420 : pid = fork();
446 :
447 840 : if (pid != 0) {
448 420 : close(state->to_parent_fd);
449 420 : state->to_parent_fd = -1;
450 :
451 420 : if (pid > 0) {
452 420 : state->pid = pid;
453 : } else {
454 0 : TALLOC_FREE(state);
455 : }
456 :
457 : /* parent or error code ... go back to the event loop */
458 420 : return;
459 : }
460 :
461 : /* this leaves state->to_parent_fd open */
462 420 : TALLOC_FREE(state);
463 :
464 420 : pid = getpid();
465 :
466 : /* this will free all the listening sockets and all state that
467 : is not associated with this new connection */
468 420 : if (tevent_re_initialise(ev) != 0) {
469 0 : smb_panic("Failed to re-initialise tevent after fork");
470 : }
471 :
472 : /* ldb/tdb need special fork handling */
473 420 : ldb_wrap_fork_hook();
474 :
475 : /* Must be done after a fork() to reset messaging contexts. */
476 420 : status = imessaging_reinit_all();
477 420 : if (!NT_STATUS_IS_OK(status)) {
478 0 : smb_panic("Failed to re-initialise imessaging after fork");
479 : }
480 :
481 420 : fde = tevent_add_fd(ev, ev, from_parent_fd, TEVENT_FD_READ,
482 : standard_pipe_handler, NULL);
483 420 : if (fde == NULL) {
484 0 : smb_panic("Failed to add fd handler after fork");
485 : }
486 :
487 420 : se = tevent_add_signal(ev,
488 : ev,
489 : SIGHUP,
490 : 0,
491 : sighup_signal_handler,
492 : NULL);
493 420 : if (se == NULL) {
494 0 : smb_panic("Failed to add SIGHUP handler after fork");
495 : }
496 :
497 420 : se = tevent_add_signal(ev,
498 : ev,
499 : SIGTERM,
500 : 0,
501 : sigterm_signal_handler,
502 : NULL);
503 420 : if (se == NULL) {
504 0 : smb_panic("Failed to add SIGTERM handler after fork");
505 : }
506 :
507 420 : process_set_title("%s[task]", "task[%s]", service_name);
508 :
509 420 : force_check_log_size();
510 :
511 : /*
512 : * Set up the process context to be passed through to the terminate
513 : * and accept_connection functions
514 : */
515 420 : proc_ctx = talloc(ev, struct process_context);
516 420 : proc_ctx->name = talloc_strdup(ev, service_name);
517 420 : proc_ctx->from_parent_fd = from_parent_fd;
518 420 : proc_ctx->inhibit_fork_on_accept =
519 420 : service_details->inhibit_fork_on_accept;
520 420 : proc_ctx->forked_on_accept = false;
521 :
522 420 : smbd_max_processes = lpcfg_max_smbd_processes(lp_ctx);
523 :
524 : /* setup this new task. Cluster ID is PID based for this process model */
525 420 : task = new_task(ev, lp_ctx, cluster_id(pid, 0), private_data, proc_ctx);
526 : /*
527 : * Currently we don't support the post_fork functionality in the
528 : * standard model, i.e. it is only called here not after a new process
529 : * is forked in standard_accept_connection.
530 : */
531 378 : if (task != NULL && service_details->post_fork != NULL) {
532 70 : struct process_details pd = initial_process_details;
533 70 : service_details->post_fork(task, &pd);
534 : }
535 :
536 378 : if (task != NULL && service_details->before_loop != NULL) {
537 24 : service_details->before_loop(task);
538 : }
539 :
540 : /* we can't return to the top level here, as that event context is gone,
541 : so we now process events in the new event context until there are no
542 : more to process */
543 378 : tevent_loop_wait(ev);
544 :
545 0 : talloc_free(ev);
546 0 : exit(0);
547 : }
548 :
549 :
550 : /* called when a task goes down */
551 42 : static void standard_terminate_task(struct tevent_context *ev,
552 : struct loadparm_context *lp_ctx,
553 : const char *reason,
554 : bool fatal,
555 : void *process_context)
556 : {
557 42 : if (fatal == true) {
558 0 : exit(127);
559 : }
560 42 : exit(0);
561 : }
562 :
563 : /* called when a connection terminates*/
564 52595 : static void standard_terminate_connection(struct tevent_context *ev,
565 : struct loadparm_context *lp_ctx,
566 : const char *reason,
567 : void *process_context)
568 : {
569 52595 : struct process_context *proc_ctx = NULL;
570 :
571 52595 : DBG_DEBUG("connection terminating reason[%s]\n", reason);
572 52595 : if (process_context == NULL) {
573 0 : smb_panic("Panicking process_context is NULL");
574 : }
575 :
576 52595 : proc_ctx = talloc_get_type(process_context, struct process_context);
577 52595 : if (proc_ctx->forked_on_accept == false) {
578 : /*
579 : * The current task was not forked on accept, so it needs to
580 : * keep running and process requests from other connections
581 : */
582 37180 : return;
583 : }
584 : /*
585 : * The current process was forked on accept to handle a single
586 : * connection/request. That request has now finished and the process
587 : * should terminate
588 : */
589 :
590 : /* this reload_charcnv() has the effect of freeing the iconv context memory,
591 : which makes leak checking easier */
592 15415 : reload_charcnv(lp_ctx);
593 :
594 : /* Always free event context last before exit. */
595 15415 : talloc_free(ev);
596 :
597 : /* terminate this process */
598 15415 : exit(0);
599 : }
600 : /* called to set a title of a task or connection */
601 52983 : static void standard_set_title(struct tevent_context *ev, const char *title)
602 : {
603 52983 : if (title) {
604 52983 : setproctitle("%s", title);
605 : } else {
606 0 : setproctitle(NULL);
607 : }
608 52983 : }
609 :
610 : static const struct model_ops standard_ops = {
611 : .name = "standard",
612 : .model_init = standard_model_init,
613 : .accept_connection = standard_accept_connection,
614 : .new_task = standard_new_task,
615 : .terminate_task = standard_terminate_task,
616 : .terminate_connection = standard_terminate_connection,
617 : .set_title = standard_set_title,
618 : };
619 :
620 : /*
621 : initialise the standard process model, registering ourselves with the process model subsystem
622 : */
623 68 : NTSTATUS process_model_standard_init(TALLOC_CTX *ctx)
624 : {
625 68 : return register_process_model(&standard_ops);
626 : }
|