Fix event loop called via I/O log close function.
We need to set events that were pending in the old base in the new one. Fixes sending the final I/O log data and the ExitMessage to the server.
This commit is contained in:
@@ -727,18 +727,7 @@ sudoers_io_close(int exit_status, int error)
|
||||
debug_decl(sudoers_io_close, SUDOERS_DEBUG_PLUGIN)
|
||||
|
||||
if (iolog_remote) {
|
||||
if (client_closure.disabled)
|
||||
goto done;
|
||||
|
||||
if (!fmt_exit_message(&client_closure, exit_status, error))
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Main sudo event loop exited, use our own mini event loop
|
||||
* to flush the write queue and read the final commit messages.
|
||||
*/
|
||||
if (!client_loop(&client_closure))
|
||||
goto done;
|
||||
client_close(&client_closure, exit_status, error);
|
||||
} else {
|
||||
for (i = 0; i < IOFD_MAX; i++) {
|
||||
if (iolog_files[i].fd.v == NULL)
|
||||
@@ -747,8 +736,6 @@ sudoers_io_close(int exit_status, int error)
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
client_closure_free(&client_closure);
|
||||
sudo_freepwcache();
|
||||
sudo_freegrcache();
|
||||
|
||||
|
@@ -1390,28 +1390,61 @@ oom:
|
||||
}
|
||||
|
||||
/*
|
||||
* Custom event loop called from the plugin close function.
|
||||
* We cannot use the main sudo event loop as it has already exited.
|
||||
* Send ExitMessage, wait for final commit message and free closure.
|
||||
*/
|
||||
bool
|
||||
client_loop(struct client_closure *closure)
|
||||
client_close(struct client_closure *closure, int exit_status, int error)
|
||||
{
|
||||
struct sudo_event_base *evbase;
|
||||
debug_decl(client_loop, SUDOERS_DEBUG_UTIL)
|
||||
struct sudo_event_base *evbase = NULL;
|
||||
short events;
|
||||
bool ret = false;
|
||||
debug_decl(client_close, SUDOERS_DEBUG_UTIL)
|
||||
|
||||
/* Create private event base and reparent the read/write events. */
|
||||
if (closure->disabled)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Create private event base and reparent the read/write events.
|
||||
* We cannot use the main sudo event loop as it has already exited.
|
||||
*/
|
||||
if ((evbase = sudo_ev_base_alloc()) == NULL) {
|
||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
debug_return_bool(false);
|
||||
goto done;
|
||||
}
|
||||
|
||||
events = closure->read_ev->pending(closure->read_ev, SUDO_PLUGIN_EV_READ,
|
||||
NULL);
|
||||
closure->read_ev->setbase(closure->read_ev, evbase);
|
||||
closure->write_ev->setbase(closure->read_ev, evbase);
|
||||
if (events == SUDO_PLUGIN_EV_READ) {
|
||||
if (closure->read_ev->add(closure->read_ev,
|
||||
&closure->log_details->server_timeout) == -1) {
|
||||
sudo_warn(U_("unable to add event to queue"));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
events = closure->write_ev->pending(closure->write_ev, SUDO_PLUGIN_EV_WRITE,
|
||||
NULL);
|
||||
closure->write_ev->setbase(closure->write_ev, evbase);
|
||||
if (events == SUDO_PLUGIN_EV_WRITE) {
|
||||
if (closure->write_ev->add(closure->write_ev,
|
||||
&closure->log_details->server_timeout) == -1) {
|
||||
sudo_warn(U_("unable to add event to queue"));
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Format and append an ExitMessage to the write queue. */
|
||||
if (!fmt_exit_message(closure, exit_status, error))
|
||||
goto done;
|
||||
|
||||
/* Loop until queues are flushed and final commit point received. */
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||
"flushing buffers and waiting for final commit point");
|
||||
sudo_ev_dispatch(evbase);
|
||||
sudo_ev_base_free(evbase);
|
||||
ret = sudo_ev_dispatch(evbase) == 0;
|
||||
|
||||
debug_return_bool(true);
|
||||
done:
|
||||
sudo_ev_base_free(evbase);
|
||||
client_closure_free(closure);
|
||||
debug_return_bool(ret);
|
||||
}
|
||||
|
@@ -135,7 +135,7 @@ struct client_closure {
|
||||
|
||||
/* iolog_client.c */
|
||||
bool client_closure_fill(struct client_closure *closure, int sock, struct iolog_details *details, struct io_plugin *sudoers_io);
|
||||
bool client_loop(struct client_closure *closure);
|
||||
bool client_close(struct client_closure *closure, int exit_status, int error);
|
||||
bool fmt_accept_message(struct client_closure *closure);
|
||||
bool fmt_client_message(struct client_closure *closure, ClientMessage *msg);
|
||||
bool fmt_exit_message(struct client_closure *closure, int exit_status, int error);
|
||||
|
Reference in New Issue
Block a user