summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/providers/ipa/ipa_dyndns.c10
-rw-r--r--src/providers/krb5/krb5_child_handler.c2
-rw-r--r--src/providers/ldap/sdap_child_helpers.c2
-rw-r--r--src/util/child_common.c24
-rw-r--r--src/util/child_common.h8
5 files changed, 41 insertions, 5 deletions
diff --git a/src/providers/ipa/ipa_dyndns.c b/src/providers/ipa/ipa_dyndns.c
index 22a16a11a..a3d358ec2 100644
--- a/src/providers/ipa/ipa_dyndns.c
+++ b/src/providers/ipa/ipa_dyndns.c
@@ -860,6 +860,7 @@ failed:
struct nsupdate_send_ctx {
struct ipa_nsupdate_ctx *nsupdate_ctx;
+ struct sss_child_ctx_old *child_ctx;
int child_status;
};
@@ -1105,7 +1106,8 @@ fork_nsupdate_send(struct ipa_nsupdate_ctx *ctx)
/* Set up SIGCHLD handler */
ret = child_handler_setup(ctx->dyndns_ctx->ipa_ctx->id_ctx->sdap_id_ctx->be->ev,
- pid, ipa_dyndns_child_handler, req);
+ pid, ipa_dyndns_child_handler, req,
+ &state->child_ctx);
if (ret != EOK) {
return NULL;
}
@@ -1135,9 +1137,15 @@ static void ipa_dyndns_timeout(struct tevent_context *ev,
{
struct tevent_req *req =
talloc_get_type(pvt, struct tevent_req);
+ struct nsupdate_send_ctx *state =
+ tevent_req_data(req, struct nsupdate_send_ctx);
DEBUG(1, ("Timeout reached for dynamic DNS update\n"));
+ child_handler_destroy(state->child_ctx);
+ state->child_ctx = NULL;
+ state->child_status = ETIMEDOUT;
+
tevent_req_error(req, ETIMEDOUT);
}
diff --git a/src/providers/krb5/krb5_child_handler.c b/src/providers/krb5/krb5_child_handler.c
index e792db3f7..89ed0487e 100644
--- a/src/providers/krb5/krb5_child_handler.c
+++ b/src/providers/krb5/krb5_child_handler.c
@@ -275,7 +275,7 @@ static errno_t fork_child(struct tevent_req *req)
fd_nonblocking(state->io->read_from_child_fd);
fd_nonblocking(state->io->write_to_child_fd);
- ret = child_handler_setup(state->ev, pid, NULL, NULL);
+ ret = child_handler_setup(state->ev, pid, NULL, NULL, NULL);
if (ret != EOK) {
DEBUG(1, ("Could not set up child signal handler\n"));
return ret;
diff --git a/src/providers/ldap/sdap_child_helpers.c b/src/providers/ldap/sdap_child_helpers.c
index f2412f9e5..6db0dbf23 100644
--- a/src/providers/ldap/sdap_child_helpers.c
+++ b/src/providers/ldap/sdap_child_helpers.c
@@ -119,7 +119,7 @@ static errno_t sdap_fork_child(struct tevent_context *ev,
fd_nonblocking(child->read_from_child_fd);
fd_nonblocking(child->write_to_child_fd);
- ret = child_handler_setup(ev, pid, NULL, NULL);
+ ret = child_handler_setup(ev, pid, NULL, NULL, NULL);
if (ret != EOK) {
return ret;
}
diff --git a/src/util/child_common.c b/src/util/child_common.c
index 5f0b26595..fe4684fb0 100644
--- a/src/util/child_common.c
+++ b/src/util/child_common.c
@@ -260,7 +260,8 @@ struct sss_child_ctx_old {
};
int child_handler_setup(struct tevent_context *ev, int pid,
- sss_child_callback_t cb, void *pvt)
+ sss_child_callback_t cb, void *pvt,
+ struct sss_child_ctx_old **_child_ctx)
{
struct sss_child_ctx_old *child_ctx;
@@ -284,9 +285,30 @@ int child_handler_setup(struct tevent_context *ev, int pid,
child_ctx->pvt = pvt;
DEBUG(8, ("Signal handler set up for pid [%d]\n", pid));
+
+ if (_child_ctx != NULL) {
+ *_child_ctx = child_ctx;
+ }
+
return EOK;
}
+void child_handler_destroy(struct sss_child_ctx_old *ctx)
+{
+ errno_t ret;
+
+ /* We still want to wait for the child to finish, but the caller is not
+ * interested in the result anymore (e.g. timeout was reached). */
+ ctx->cb = NULL;
+ ctx->pvt = NULL;
+
+ ret = kill(ctx->pid, SIGKILL);
+ if (ret == -1) {
+ ret = errno;
+ DEBUG(SSSDBG_MINOR_FAILURE, ("kill failed [%d][%s].\n", ret, strerror(ret)));
+ }
+}
+
/* Async communication with the child process via a pipe */
struct write_pipe_state {
diff --git a/src/util/child_common.h b/src/util/child_common.h
index 237969f2f..95865bb52 100644
--- a/src/util/child_common.h
+++ b/src/util/child_common.h
@@ -78,9 +78,15 @@ typedef void (*sss_child_callback_t)(int child_status,
struct tevent_signal *sige,
void *pvt);
+struct sss_child_ctx_old;
+
/* Set up child termination signal handler */
int child_handler_setup(struct tevent_context *ev, int pid,
- sss_child_callback_t cb, void *pvt);
+ sss_child_callback_t cb, void *pvt,
+ struct sss_child_ctx_old **_child_ctx);
+
+/* Destroy child termination signal handler */
+void child_handler_destroy(struct sss_child_ctx_old *ctx);
/* Async communication with the child process via a pipe */
struct tevent_req *write_pipe_send(TALLOC_CTX *mem_ctx,