1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-09 08:58:35 +03:00

s3:winbindd: fix problems with SIGCHLD handling (bug #7317)

The main problem is that we call CatchChild() within the
parent winbindd, which overwrites the signal handler
that was registered by winbindd_setup_sig_chld_handler().

That means winbindd_sig_chld_handler() and winbind_child_died()
are never triggered when a winbindd domain child dies.
As a result will get "broken pipe" for all requests to that domain.

To reduce the risk of similar bugs in future we call
CatchChild() in winbindd_reinit_after_fork() now.

We also use a full winbindd_reinit_after_fork() in the
cache validation child now instead instead of just resetting
the SIGCHLD handler by hand. This will also fix possible
tdb problems on systems without pread/pwrite and disabled mmap
as we now correctly reopen the tdb handle for the child.

metze
This commit is contained in:
Stefan Metzmacher 2010-04-01 16:23:06 +02:00
parent 3475c61179
commit 73577205cf
3 changed files with 6 additions and 17 deletions

View File

@ -407,7 +407,6 @@ static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
* so we don't block the main winbindd and the validation
* code can safely use fork/waitpid...
*/
CatchChild();
child_pid = sys_fork();
if (child_pid == -1) {
@ -425,16 +424,9 @@ static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
/* child */
/* install default SIGCHLD handler: validation code uses fork/waitpid */
ZERO_STRUCT(act);
act.sa_handler = SIG_DFL;
#ifdef SA_RESTART
/* We *want* SIGALRM to interrupt a system call. */
act.sa_flags = SA_RESTART;
#endif
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask,SIGCHLD);
sigaction(SIGCHLD,&act,&oldact);
if (!winbindd_reinit_after_fork(NULL)) {
_exit(0);
}
ret = (uint8)winbindd_validate_cache_nobackup();
DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));

View File

@ -180,9 +180,6 @@ static bool fork_child_dc_connect(struct winbindd_domain *domain)
pid_t parent_pid = sys_getpid();
char *lfile = NULL;
/* Stop zombies */
CatchChild();
if (domain->dc_probe_pid != (pid_t)-1) {
/*
* We might already have a DC probe

View File

@ -1215,6 +1215,9 @@ bool winbindd_reinit_after_fork(const char *logfilename)
logfilename))
return false;
/* Stop zombies in children */
CatchChild();
/* Don't handle the same messages as our parent. */
messaging_deregister(winbind_messaging_context(),
MSG_SMB_CONF_UPDATED, NULL);
@ -1338,9 +1341,6 @@ static bool fork_domain_child(struct winbindd_child *child)
DEBUG(10, ("Child process %d\n", (int)sys_getpid()));
/* Stop zombies in children */
CatchChild();
state.sock = fdpair[0];
close(fdpair[1]);