Iterate over io_plugins list in the iolog_* wrappers.

Moving the iteration into the wrapper functions simplifies the calling code.
This commit is contained in:
Todd C. Miller
2020-01-07 20:05:29 -07:00
parent b0a84c4292
commit 0d2195c374

View File

@@ -118,13 +118,13 @@ static int policy_validate(void);
static void policy_invalidate(int remove); static void policy_invalidate(int remove);
/* I/O log plugin convenience functions. */ /* I/O log plugin convenience functions. */
static int iolog_open(struct plugin_container *plugin, static void iolog_open(struct sudo_settings *settings, char * const user_info[],
struct sudo_settings *settings, char * const user_info[],
char * const command_details[], int argc, char * const argv[], char * const command_details[], int argc, char * const argv[],
char * const user_env[]); char * const user_env[]);
static void iolog_close(struct plugin_container *plugin, int exit_status, static void iolog_close(int exit_status, int error);
int error); static void iolog_show_version(int verbose, struct sudo_settings *settings,
static int iolog_show_version(struct plugin_container *plugin, int verbose); char * const user_info[], int argc, char * const argv[],
char * const user_env[]);
static void iolog_unlink(struct plugin_container *plugin); static void iolog_unlink(struct plugin_container *plugin);
static void free_plugin_container(struct plugin_container *plugin, bool ioplugin); static void free_plugin_container(struct plugin_container *plugin, bool ioplugin);
@@ -137,7 +137,6 @@ main(int argc, char *argv[], char *envp[])
char **nargv, **env_add; char **nargv, **env_add;
char **user_info, **command_info, **argv_out, **user_env_out; char **user_info, **command_info, **argv_out, **user_env_out;
struct sudo_settings *settings; struct sudo_settings *settings;
struct plugin_container *plugin, *next;
sigset_t mask; sigset_t mask;
debug_decl_vars(main, SUDO_DEBUG_MAIN); debug_decl_vars(main, SUDO_DEBUG_MAIN);
@@ -228,12 +227,8 @@ main(int argc, char *argv[], char *envp[])
switch (sudo_mode & MODE_MASK) { switch (sudo_mode & MODE_MASK) {
case MODE_VERSION: case MODE_VERSION:
policy_show_version(!user_details.uid); policy_show_version(!user_details.uid);
TAILQ_FOREACH(plugin, &io_plugins, entries) { iolog_show_version(!user_details.uid, settings, user_info,
ok = iolog_open(plugin, settings, user_info, NULL,
nargc, nargv, envp); nargc, nargv, envp);
if (ok != -1)
iolog_show_version(plugin, !user_details.uid);
}
break; break;
case MODE_VALIDATE: case MODE_VALIDATE:
case MODE_VALIDATE|MODE_INVALIDATE: case MODE_VALIDATE|MODE_INVALIDATE:
@@ -261,31 +256,18 @@ main(int argc, char *argv[], char *envp[])
usage(1); usage(1);
exit(EXIT_FAILURE); /* plugin printed error message */ exit(EXIT_FAILURE); /* plugin printed error message */
} }
/* Reset nargv/nargc based on argv_out. */ /* Reset nargv/nargc based on argv_out. */
/* XXX - leaks old nargv in shell mode */ /* XXX - leaks old nargv in shell mode */
for (nargv = argv_out, nargc = 0; nargv[nargc] != NULL; nargc++) for (nargv = argv_out, nargc = 0; nargv[nargc] != NULL; nargc++)
continue; continue;
if (nargc == 0) if (nargc == 0)
sudo_fatalx(U_("plugin did not return a command to execute")); sudo_fatalx(U_("plugin did not return a command to execute"));
/* Open I/O plugins once policy plugin succeeds. */ /* Open I/O plugins once policy plugin succeeds. */
TAILQ_FOREACH_SAFE(plugin, &io_plugins, entries, next) { iolog_open(settings, user_info, command_info, nargc, nargv,
ok = iolog_open(plugin, settings, user_info, user_env_out);
command_info, nargc, nargv, user_env_out);
switch (ok) {
case 1:
break;
case 0:
/* I/O plugin asked to be disabled, remove and free. */
iolog_unlink(plugin);
break;
case -2:
usage(1);
break;
default:
sudo_fatalx(U_("error initializing I/O plugin %s"),
plugin->name);
}
}
/* Setup command details and run command/edit. */ /* Setup command details and run command/edit. */
command_info_to_details(command_info, &command_details); command_info_to_details(command_info, &command_details);
command_details.tty = user_details.tty; command_details.tty = user_details.tty;
@@ -945,7 +927,6 @@ done:
int int
run_command(struct command_details *details) run_command(struct command_details *details)
{ {
struct plugin_container *plugin;
struct command_status cstat; struct command_status cstat;
int status = W_EXITCODE(1, 0); int status = W_EXITCODE(1, 0);
debug_decl(run_command, SUDO_DEBUG_EXEC); debug_decl(run_command, SUDO_DEBUG_EXEC);
@@ -958,14 +939,8 @@ run_command(struct command_details *details)
switch (cstat.type) { switch (cstat.type) {
case CMD_ERRNO: case CMD_ERRNO:
/* exec_setup() or execve() returned an error. */ /* exec_setup() or execve() returned an error. */
sudo_debug_printf(SUDO_DEBUG_DEBUG,
"calling policy close with errno %d", cstat.val);
policy_close(0, cstat.val); policy_close(0, cstat.val);
TAILQ_FOREACH(plugin, &io_plugins, entries) { iolog_close(0, cstat.val);
sudo_debug_printf(SUDO_DEBUG_DEBUG,
"calling I/O close with errno %d", cstat.val);
iolog_close(plugin, 0, cstat.val);
}
break; break;
case CMD_WSTATUS: case CMD_WSTATUS:
/* Command ran, exited or was killed. */ /* Command ran, exited or was killed. */
@@ -974,14 +949,8 @@ run_command(struct command_details *details)
if (ISSET(details->flags, CD_SUDOEDIT_COPY)) if (ISSET(details->flags, CD_SUDOEDIT_COPY))
break; break;
#endif #endif
sudo_debug_printf(SUDO_DEBUG_DEBUG,
"calling policy close with wait status %d", status);
policy_close(status, 0); policy_close(status, 0);
TAILQ_FOREACH(plugin, &io_plugins, entries) { iolog_close(status, 0);
sudo_debug_printf(SUDO_DEBUG_DEBUG,
"calling I/O close with wait status %d", status);
iolog_close(plugin, status, 0);
}
break; break;
default: default:
sudo_warnx(U_("unexpected child termination condition: %d"), cstat.type); sudo_warnx(U_("unexpected child termination condition: %d"), cstat.type);
@@ -1096,6 +1065,16 @@ static void
policy_close(int exit_status, int error_code) policy_close(int exit_status, int error_code)
{ {
debug_decl(policy_close, SUDO_DEBUG_PCOMM); debug_decl(policy_close, SUDO_DEBUG_PCOMM);
if (error_code != 0) {
sudo_debug_printf(SUDO_DEBUG_DEBUG,
"%s: calling policy close with errno %d",
policy_plugin.name, error_code);
} else {
sudo_debug_printf(SUDO_DEBUG_DEBUG,
"%s: calling policy close with wait status %d",
policy_plugin.name, exit_status);
}
if (policy_plugin.u.policy->close != NULL) { if (policy_plugin.u.policy->close != NULL) {
sudo_debug_set_active_instance(policy_plugin.debug_instance); sudo_debug_set_active_instance(policy_plugin.debug_instance);
policy_plugin.u.policy->close(exit_status, error_code); policy_plugin.u.policy->close(exit_status, error_code);
@@ -1253,13 +1232,13 @@ done:
} }
static int static int
iolog_open(struct plugin_container *plugin, struct sudo_settings *settings, iolog_open_int(struct plugin_container *plugin, struct sudo_settings *settings,
char * const user_info[], char * const command_info[], char * const user_info[], char * const command_info[],
int argc, char * const argv[], char * const user_env[]) int argc, char * const argv[], char * const user_env[])
{ {
char **plugin_settings; char **plugin_settings;
int ret; int ret;
debug_decl(iolog_open, SUDO_DEBUG_PCOMM); debug_decl(iolog_open_int, SUDO_DEBUG_PCOMM);
/* Convert struct sudo_settings to plugin_settings[] */ /* Convert struct sudo_settings to plugin_settings[] */
plugin_settings = format_plugin_settings(plugin, settings); plugin_settings = format_plugin_settings(plugin, settings);
@@ -1297,35 +1276,87 @@ iolog_open(struct plugin_container *plugin, struct sudo_settings *settings,
} }
static void static void
iolog_close(struct plugin_container *plugin, int exit_status, int error_code) iolog_open(struct sudo_settings *settings, char * const user_info[],
char * const command_info[], int argc, char * const argv[],
char * const user_env[])
{ {
struct plugin_container *plugin, *next;
debug_decl(iolog_open, SUDO_DEBUG_PCOMM);
TAILQ_FOREACH_SAFE(plugin, &io_plugins, entries, next) {
int ok = iolog_open_int(plugin, settings, user_info,
command_info, argc, argv, user_env);
switch (ok) {
case 1:
break;
case 0:
/* I/O plugin asked to be disabled, remove and free. */
iolog_unlink(plugin);
break;
case -2:
usage(1);
break;
default:
sudo_fatalx(U_("error initializing I/O plugin %s"),
plugin->name);
}
}
debug_return;
}
static void
iolog_close(int exit_status, int error_code)
{
struct plugin_container *plugin;
debug_decl(iolog_close, SUDO_DEBUG_PCOMM); debug_decl(iolog_close, SUDO_DEBUG_PCOMM);
TAILQ_FOREACH(plugin, &io_plugins, entries) {
if (plugin->u.io->close != NULL) { if (plugin->u.io->close != NULL) {
if (error_code != 0) {
sudo_debug_printf(SUDO_DEBUG_DEBUG,
"%s: calling I/O close with errno %d",
plugin->name, error_code);
} else {
sudo_debug_printf(SUDO_DEBUG_DEBUG,
"%s: calling I/O close with wait status %d",
plugin->name, exit_status);
}
sudo_debug_set_active_instance(plugin->debug_instance); sudo_debug_set_active_instance(plugin->debug_instance);
plugin->u.io->close(exit_status, error_code); plugin->u.io->close(exit_status, error_code);
sudo_debug_set_active_instance(sudo_debug_instance); sudo_debug_set_active_instance(sudo_debug_instance);
} }
}
debug_return; debug_return;
} }
static int static void
iolog_show_version(struct plugin_container *plugin, int verbose) iolog_show_version(int verbose, struct sudo_settings *settings,
char * const user_info[], int argc, char * const argv[],
char * const user_env[])
{ {
int ret; struct plugin_container *plugin;
debug_decl(iolog_show_version, SUDO_DEBUG_PCOMM); debug_decl(iolog_show_version, SUDO_DEBUG_PCOMM);
if (plugin->u.io->show_version == NULL) TAILQ_FOREACH(plugin, &io_plugins, entries) {
debug_return_int(true); int ok = iolog_open_int(plugin, settings, user_info, NULL,
argc, argv, user_env);
if (ok != -1) {
if (plugin->u.io->show_version != NULL) {
sudo_debug_set_active_instance(plugin->debug_instance); sudo_debug_set_active_instance(plugin->debug_instance);
ret = plugin->u.io->show_version(verbose); /* Return value of show_version currently ignored. */
plugin->u.io->show_version(verbose);
if (plugin->u.io->version >= SUDO_API_MKVERSION(1, 15)) { if (plugin->u.io->version >= SUDO_API_MKVERSION(1, 15)) {
if (plugin->u.io->close != NULL) if (plugin->u.io->close != NULL)
plugin->u.io->close(0, 0); plugin->u.io->close(0, 0);
} }
sudo_debug_set_active_instance(sudo_debug_instance); sudo_debug_set_active_instance(sudo_debug_instance);
debug_return_int(ret); }
}
}
debug_return;
} }
/* /*