summaryrefslogtreecommitdiffstats
path: root/src/providers
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2016-05-19 17:24:51 +0200
committerJakub Hrozek <jhrozek@redhat.com>2016-05-31 13:07:08 +0200
commit518f5b83fd546e3188da01e4743ddb27a574e08f (patch)
treeb3917bf213a10bae5d662550805d6fbd32405af9 /src/providers
parent49d84c926b00ba1368372cdec255bceb58d66f43 (diff)
downloadsssd-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.c28
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;
}