From cbb7b4afa6b6c8b46d8f174b6a16cffaa3984d3e Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Thu, 3 Dec 2020 14:10:30 -0700 Subject: [PATCH] Audit errors from policy_init_session(), audit_accept(), and audit_reject(). --- src/sudo.c | 88 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 29 deletions(-) diff --git a/src/sudo.c b/src/sudo.c index 7f8c4c61d..4a556db8d 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -1349,7 +1349,11 @@ policy_init_session(struct command_details *details) &details->envp, &errstr); } sudo_debug_set_active_instance(sudo_debug_instance); - /* TODO: audit on error */ + if (ret != 1) { + audit_error(policy_plugin.name, SUDO_POLICY_PLUGIN, + errstr ? errstr : _("policy plugin error"), + details->info); + } } done: debug_return_int(ret); @@ -1624,6 +1628,47 @@ audit_show_version(int verbose) debug_return; } +/* + * Error from plugin or front-end. + * The error will not be sent to plugin source, if specified. + */ +static void +audit_error2(struct plugin_container *source, const char *plugin_name, + unsigned int plugin_type, const char *audit_msg, char * const command_info[]) +{ + struct plugin_container *plugin; + const char *errstr = NULL; + int ok; + debug_decl(audit_error2, SUDO_DEBUG_PCOMM); + + TAILQ_FOREACH(plugin, &audit_plugins, entries) { + if (plugin->u.audit->error == NULL) + continue; + + /* Avoid a loop if the audit plugin itself has an error. */ + if (plugin == source) + continue; + + sudo_debug_set_active_instance(plugin->debug_instance); + ok = plugin->u.audit->error(plugin_name, plugin_type, + audit_msg, command_info, &errstr); + sudo_debug_set_active_instance(sudo_debug_instance); + if (ok != 1) { + /* + * Don't propagate the error to other audit plugins. + * It is not worth the trouble to avoid potential loops. + */ + sudo_debug_printf(SUDO_DEBUG_ERROR, + "%s: plugin %s error failed, ret %d", __func__, + plugin->name, ok); + sudo_warnx(U_("%s: unable to log error event%s%s"), + plugin->name, errstr ? ": " : "", errstr ? errstr : ""); + } + } + + debug_return; +} + /* * Command accepted by policy. * See command_info[] for additional info. @@ -1648,12 +1693,17 @@ audit_accept(const char *plugin_name, unsigned int plugin_type, command_info, run_argv, run_envp, &errstr); sudo_debug_set_active_instance(sudo_debug_instance); if (ok != 1) { - /* TODO: notify other audit plugins of the error. */ sudo_debug_printf(SUDO_DEBUG_ERROR, "%s: plugin %s accept failed, ret %d", __func__, plugin->name, ok); - sudo_fatalx(U_("%s: unable to log accept event%s%s"), + sudo_warnx(U_("%s: unable to log accept event%s%s"), plugin->name, errstr ? ": " : "", errstr ? errstr : ""); + + /* Notify other audit plugins and exit. */ + audit_error2(plugin, plugin->name, SUDO_AUDIT_PLUGIN, + errstr ? errstr : _("audit plugin error"), command_info); + audit_close(SUDO_PLUGIN_NO_STATUS, 0); + exit(EXIT_FAILURE); } } @@ -1681,12 +1731,15 @@ audit_reject(const char *plugin_name, unsigned int plugin_type, audit_msg, command_info, &errstr); sudo_debug_set_active_instance(sudo_debug_instance); if (ok != 1) { - /* TODO: notify other audit plugins of the error. */ sudo_debug_printf(SUDO_DEBUG_ERROR, "%s: plugin %s reject failed, ret %d", __func__, plugin->name, ok); sudo_warnx(U_("%s: unable to log reject event%s%s"), plugin->name, errstr ? ": " : "", errstr ? errstr : ""); + + /* Notify other audit plugins. */ + audit_error2(plugin, plugin->name, SUDO_AUDIT_PLUGIN, + errstr ? errstr : _("audit plugin error"), command_info); } } @@ -1694,36 +1747,13 @@ audit_reject(const char *plugin_name, unsigned int plugin_type, } /* - * Error from policy or I/O plugin. + * Error from plugin or front-end. */ void audit_error(const char *plugin_name, unsigned int plugin_type, const char *audit_msg, char * const command_info[]) { - struct plugin_container *plugin; - const char *errstr = NULL; - int ok; - debug_decl(audit_error, SUDO_DEBUG_PCOMM); - - TAILQ_FOREACH(plugin, &audit_plugins, entries) { - if (plugin->u.audit->error == NULL) - continue; - - sudo_debug_set_active_instance(plugin->debug_instance); - ok = plugin->u.audit->error(plugin_name, plugin_type, - audit_msg, command_info, &errstr); - sudo_debug_set_active_instance(sudo_debug_instance); - if (ok != 1) { - /* TODO: notify other audit plugins of the error. */ - sudo_debug_printf(SUDO_DEBUG_ERROR, - "%s: plugin %s error failed, ret %d", __func__, - plugin->name, ok); - sudo_warnx(U_("%s: unable to log error event%s%s"), - plugin->name, errstr ? ": " : "", errstr ? errstr : ""); - } - } - - debug_return; + audit_error2(NULL, plugin_name, plugin_type, audit_msg, command_info); } static int