diff options
author | Jakub Hrozek <jhrozek@redhat.com> | 2016-05-19 17:24:51 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2016-05-31 13:07:08 +0200 |
commit | 518f5b83fd546e3188da01e4743ddb27a574e08f (patch) | |
tree | b3917bf213a10bae5d662550805d6fbd32405af9 /src/providers | |
parent | 49d84c926b00ba1368372cdec255bceb58d66f43 (diff) | |
download | sssd-518f5b83fd546e3188da01e4743ddb27a574e08f.tar.gz sssd-518f5b83fd546e3188da01e4743ddb27a574e08f.tar.xz sssd-518f5b83fd546e3188da01e4743ddb27a574e08f.zip |
AD: Do not leak file descriptors during machine password renewal
Resolves:
https://fedorahosted.org/sssd/ticket/3017
The AD renewal task was opening a pipe to write to the child process but
never closed it, leaking the fd. This patch uses a desctructor we
already use for pipes towards other child processes.
Reviewed-by: Petr Cech <pcech@redhat.com>
Diffstat (limited to 'src/providers')
-rw-r--r-- | src/providers/ad/ad_machine_pw_renewal.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/src/providers/ad/ad_machine_pw_renewal.c b/src/providers/ad/ad_machine_pw_renewal.c index b0d2cf64a..205e623e0 100644 --- a/src/providers/ad/ad_machine_pw_renewal.c +++ b/src/providers/ad/ad_machine_pw_renewal.c @@ -101,8 +101,7 @@ struct renewal_state { struct tevent_timer *timeout_handler; struct tevent_context *ev; - int write_to_child_fd; - int read_from_child_fd; + struct child_io_fds *io; }; static void ad_machine_account_password_renewal_done(struct tevent_req *subreq); @@ -140,8 +139,15 @@ ad_machine_account_password_renewal_send(TALLOC_CTX *mem_ctx, state->ev = ev; state->child_status = EFAULT; - state->read_from_child_fd = -1; - state->write_to_child_fd = -1; + state->io = talloc(state, struct child_io_fds); + if (state->io == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); + ret = ENOMEM; + goto done; + } + state->io->write_to_child_fd = -1; + state->io->read_from_child_fd = -1; + talloc_set_destructor((void *) state->io, child_io_destructor); server_name = be_fo_get_active_server_name(be_ctx, AD_SERVICE_NAME); talloc_zfree(renewal_data->extra_args[0]); @@ -183,13 +189,13 @@ ad_machine_account_password_renewal_send(TALLOC_CTX *mem_ctx, DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec renewal child\n"); } else if (child_pid > 0) { /* parent */ - state->read_from_child_fd = pipefd_from_child[0]; + state->io->read_from_child_fd = pipefd_from_child[0]; close(pipefd_from_child[1]); - sss_fd_nonblocking(state->read_from_child_fd); + sss_fd_nonblocking(state->io->read_from_child_fd); - state->write_to_child_fd = pipefd_to_child[1]; + state->io->write_to_child_fd = pipefd_to_child[1]; close(pipefd_to_child[0]); - sss_fd_nonblocking(state->write_to_child_fd); + sss_fd_nonblocking(state->io->write_to_child_fd); /* Set up SIGCHLD handler */ ret = child_handler_setup(ev, child_pid, NULL, NULL, &state->child_ctx); @@ -210,7 +216,7 @@ ad_machine_account_password_renewal_send(TALLOC_CTX *mem_ctx, goto done; } - subreq = read_pipe_send(state, ev, state->read_from_child_fd); + subreq = read_pipe_send(state, ev, state->io->read_from_child_fd); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "read_pipe_send failed.\n"); ret = ERR_RENEWAL_CHILD; @@ -262,10 +268,6 @@ static void ad_machine_account_password_renewal_done(struct tevent_req *subreq) "---adcli output end---\n", (int) buf_len, buf); - close(state->read_from_child_fd); - state->read_from_child_fd = -1; - - tevent_req_done(req); return; } |