From: Todd C. Miller Date: Tue, 4 May 2010 23:17:31 +0000 (-0400) Subject: Add pointer to a printf like function to plugin open functon. X-Git-Tag: SUDO_1_8_0~666 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9fbec34fed59b0c23c0d2e23faf680584432e9b2;p=sudo Add pointer to a printf like function to plugin open functon. This can be used instead of the conversation function to display info and error messages. --- diff --git a/include/sudo_plugin.h b/include/sudo_plugin.h index e694ec9e9..21c9c6a07 100644 --- a/include/sudo_plugin.h +++ b/include/sudo_plugin.h @@ -49,6 +49,7 @@ struct sudo_conv_reply { typedef int (*sudo_conv_t)(int num_msgs, const struct sudo_conv_message msgs[], struct sudo_conv_reply replies[]); +typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...); /* Policy plugin type and defines */ struct policy_plugin { @@ -56,8 +57,8 @@ struct policy_plugin { unsigned int type; /* always SUDO_POLICY_PLUGIN */ unsigned int version; /* always SUDO_API_VERSION */ int (*open)(unsigned int version, sudo_conv_t conversation, - char * const settings[], char * const user_info[], - char * const user_env[]); + sudo_printf_t sudo_printf, char * const settings[], + char * const user_info[], char * const user_env[]); void (*close)(int exit_status, int error); /* wait status or error */ int (*show_version)(int verbose); int (*check_policy)(int argc, char * const argv[], @@ -75,8 +76,8 @@ struct io_plugin { unsigned int type; /* always SUDO_IO_PLUGIN */ unsigned int version; /* always SUDO_API_VERSION */ int (*open)(unsigned int version, sudo_conv_t conversation, - char * const settings[], char * const user_info[], - char * const user_env[]); + sudo_printf_t sudo_printf, char * const settings[], + char * const user_info[], char * const user_env[]); void (*close)(int exit_status, int error); /* wait status or error */ int (*show_version)(int verbose); int (*log_input)(const char *buf, unsigned int len); diff --git a/plugins/sample/sample_plugin.c b/plugins/sample/sample_plugin.c index 772f9f83e..03a8f0632 100644 --- a/plugins/sample/sample_plugin.c +++ b/plugins/sample/sample_plugin.c @@ -77,6 +77,7 @@ static struct plugin_state { char * const *user_info; } plugin_state; static sudo_conv_t sudo_conv; +static sudo_printf_t sudo_log; static FILE *input, *output; static uid_t runas_uid = ROOT_UID; static gid_t runas_gid = -1; @@ -104,41 +105,13 @@ fmt_string(const char *var, const char *val) return(str); } -/* - * Display warning via conversation function. - */ -static void -sudo_log(int type, const char *fmt, ...) -{ - struct sudo_conv_message msg[2]; - struct sudo_conv_reply repl[2]; - va_list ap; - char *str; - int rc; - - va_start(ap, fmt); - rc = vasprintf(&str, fmt, ap); - va_end(ap); - if (rc == -1) - return; - - /* Call conversation function */ - memset(&msg, 0, sizeof(msg)); - msg[0].msg_type = type; - msg[0].msg = str; - msg[1].msg_type = type; - msg[1].msg = "\n"; - memset(&repl, 0, sizeof(repl)); - sudo_conv(2, msg, repl); -} - /* * Plugin policy open function. */ static int policy_open(unsigned int version, sudo_conv_t conversation, - char * const settings[], char * const user_info[], - char * const user_env[]) + sudo_printf_t sudo_printf, char * const settings[], + char * const user_info[], char * const user_env[]) { char * const *ui; struct passwd *pw; @@ -146,11 +119,14 @@ policy_open(unsigned int version, sudo_conv_t conversation, struct group *gr; const char *runas_group = NULL; - sudo_conv = conversation; + if (!sudo_conv) + sudo_conv = conversation; + if (!sudo_log) + sudo_log = sudo_printf; if (SUDO_API_VERSION_GET_MAJOR(version) != SUDO_API_VERSION_MAJOR) { sudo_log(SUDO_CONV_ERROR_MSG, - "the sample plugin requires API version %d.x", + "the sample plugin requires API version %d.x\n", SUDO_API_VERSION_MAJOR); return ERROR; } @@ -171,14 +147,14 @@ policy_open(unsigned int version, sudo_conv_t conversation, } if (runas_user != NULL) { if ((pw = getpwnam(runas_user)) == NULL) { - sudo_log(SUDO_CONV_ERROR_MSG, "unknown user %s", runas_user); + sudo_log(SUDO_CONV_ERROR_MSG, "unknown user %s\n", runas_user); return 0; } runas_uid = pw->pw_uid; } if (runas_group != NULL) { if ((gr = getgrnam(runas_group)) == NULL) { - sudo_log(SUDO_CONV_ERROR_MSG, "unknown group %s", runas_group); + sudo_log(SUDO_CONV_ERROR_MSG, "unknown group %s\n", runas_group); return 0; } runas_gid = gr->gr_gid; @@ -207,13 +183,13 @@ policy_check(int argc, char * const argv[], int i = 0; if (!argc || argv[0] == NULL) { - sudo_log(SUDO_CONV_ERROR_MSG, "no command specified"); + sudo_log(SUDO_CONV_ERROR_MSG, "no command specified\n"); return FALSE; } /* Only allow fully qualified paths to keep things simple. */ if (argv[0][0] != '/') { sudo_log(SUDO_CONV_ERROR_MSG, - "only fully qualified pathnames may be specified"); + "only fully qualified pathnames may be specified\n"); return FALSE; } @@ -224,11 +200,11 @@ policy_check(int argc, char * const argv[], memset(&repl, 0, sizeof(repl)); sudo_conv(1, &msg, &repl); if (repl.reply == NULL) { - sudo_log(SUDO_CONV_ERROR_MSG, "missing password"); + sudo_log(SUDO_CONV_ERROR_MSG, "missing password\n"); return FALSE; } if (strcmp(repl.reply, "test") != 0) { - sudo_log(SUDO_CONV_ERROR_MSG, "incorrect password"); + sudo_log(SUDO_CONV_ERROR_MSG, "incorrect password\n"); return FALSE; } @@ -239,19 +215,19 @@ policy_check(int argc, char * const argv[], /* Setup command info. */ command_info = calloc(32, sizeof(char *)); if (command_info == NULL) { - sudo_log(SUDO_CONV_ERROR_MSG, "out of memory"); + sudo_log(SUDO_CONV_ERROR_MSG, "out of memory\n"); return ERROR; } if ((command_info[i++] = fmt_string("command", argv[0])) == NULL || asprintf(&command_info[i++], "runas_euid=%ld", (long)runas_uid) == -1 || asprintf(&command_info[i++], "runas_uid=%ld", (long)runas_uid) == -1) { - sudo_log(SUDO_CONV_ERROR_MSG, "out of memory"); + sudo_log(SUDO_CONV_ERROR_MSG, "out of memory\n"); return ERROR; } if (runas_gid != -1) { if (asprintf(&command_info[i++], "runas_gid=%ld", (long)runas_gid) == -1 || asprintf(&command_info[i++], "runas_egid=%ld", (long)runas_gid) == -1) { - sudo_log(SUDO_CONV_ERROR_MSG, "out of memory"); + sudo_log(SUDO_CONV_ERROR_MSG, "out of memory\n"); return ERROR; } } @@ -270,14 +246,14 @@ policy_list(int argc, char * const argv[], int verbose, const char *list_user) /* * List user's capabilities. */ - sudo_log(SUDO_CONV_INFO_MSG, "Validated users may run any command"); + sudo_log(SUDO_CONV_INFO_MSG, "Validated users may run any command\n"); return TRUE; } static int policy_version(int verbose) { - sudo_log(SUDO_CONV_INFO_MSG, "Sample policy plugin version %s", PACKAGE_VERSION); + sudo_log(SUDO_CONV_INFO_MSG, "Sample policy plugin version %s\n", PACKAGE_VERSION); return TRUE; } @@ -289,13 +265,13 @@ policy_close(int exit_status, int error) * In this example, we just print a message. */ if (error) { - sudo_log(SUDO_CONV_ERROR_MSG, "Command error: %s", strerror(error)); + sudo_log(SUDO_CONV_ERROR_MSG, "Command error: %s\n", strerror(error)); } else { if (WIFEXITED(exit_status)) { - sudo_log(SUDO_CONV_INFO_MSG, "Command exited with status %d", + sudo_log(SUDO_CONV_INFO_MSG, "Command exited with status %d\n", WEXITSTATUS(exit_status)); } else if (WIFSIGNALED(exit_status)) { - sudo_log(SUDO_CONV_INFO_MSG, "Command killed by signal %d", + sudo_log(SUDO_CONV_INFO_MSG, "Command killed by signal %d\n", WTERMSIG(exit_status)); } } @@ -303,12 +279,17 @@ policy_close(int exit_status, int error) static int io_open(unsigned int version, sudo_conv_t conversation, - char * const settings[], char * const user_info[], - char * const user_env[]) + sudo_printf_t sudo_printf, char * const settings[], + char * const user_info[], char * const user_env[]) { int fd; char path[PATH_MAX]; + if (!sudo_conv) + sudo_conv = conversation; + if (!sudo_log) + sudo_log = sudo_printf; + /* Open input and output files. */ snprintf(path, sizeof(path), "/var/tmp/sample-%u.output", (unsigned int)getpid()); @@ -337,7 +318,8 @@ io_close(int exit_status, int error) static int io_version(int verbose) { - sudo_log(SUDO_CONV_INFO_MSG, "Sample I/O plugin version %s", PACKAGE_VERSION); + sudo_log(SUDO_CONV_INFO_MSG, "Sample I/O plugin version %s\n", + PACKAGE_VERSION); return TRUE; } diff --git a/plugins/sudoers/iolog.c b/plugins/sudoers/iolog.c index 3066b7f0c..ef0595915 100644 --- a/plugins/sudoers/iolog.c +++ b/plugins/sudoers/iolog.c @@ -177,7 +177,8 @@ build_idpath(char *pathbuf, size_t pathsize) int sudoers_io_open(unsigned int version, sudo_conv_t conversation, - char * const settings[], char * const user_info[], char * const user_env[]) + sudo_printf_t plugin_printf, char * const settings[], + char * const user_info[], char * const user_env[]) { char pathbuf[PATH_MAX]; FILE *io_logfile; @@ -185,6 +186,8 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation, if (!sudo_conv) sudo_conv = conversation; + if (!sudo_printf) + sudo_printf = plugin_printf; if (!def_transcript) return FALSE; diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c index 70d0942d6..5861008a8 100644 --- a/plugins/sudoers/ldap.c +++ b/plugins/sudoers/ldap.c @@ -940,70 +940,81 @@ sudo_ldap_read_config(void) ldap_conf.bind_timelimit *= 1000; /* convert to ms */ if (ldap_conf.debug > 1) { - char num[12]; - - print_error(1, "LDAP Config Summary\n"); - print_error(1, "===================\n"); + sudo_printf(SUDO_CONV_ERROR_MSG, "LDAP Config Summary\n"); + sudo_printf(SUDO_CONV_ERROR_MSG, "===================\n"); if (ldap_conf.uri) { - print_error(3, "uri ", ldap_conf.uri, "\n"); + sudo_printf(SUDO_CONV_ERROR_MSG, "uri %s\n", + ldap_conf.uri); } else { - print_error(3, "host ", ldap_conf.host ? - ldap_conf.host : "(NONE)", "\n"); - snprintf(num, sizeof(num), "%d", ldap_conf.port); - print_error(3, "port ", num, "\n"); + sudo_printf(SUDO_CONV_ERROR_MSG, "host %s\n", + ldap_conf.host ? ldap_conf.host : "(NONE)"); + sudo_printf(SUDO_CONV_ERROR_MSG, "port %d\n", + ldap_conf.port); } - snprintf(num, sizeof(num), "%d", ldap_conf.version); - print_error(3, "ldap_version ", num, "\n"); - - print_error(3, "sudoers_base ", ldap_conf.base ? - ldap_conf.base : "(NONE) <---Sudo will ignore ldap)", "\n"); - print_error(3, "binddn ", ldap_conf.binddn ? - ldap_conf.binddn : "(anonymous)", "\n"); - print_error(3, "bindpw ", ldap_conf.bindpw ? - ldap_conf.bindpw : "(anonymous)", "\n"); + sudo_printf(SUDO_CONV_ERROR_MSG, "ldap_version %d\n", + ldap_conf.version); + + sudo_printf(SUDO_CONV_ERROR_MSG, "sudoers_base %s\n", + ldap_conf.base ? ldap_conf.base : "(NONE: LDAP disabled)"); + sudo_printf(SUDO_CONV_ERROR_MSG, "binddn %s\n", + ldap_conf.binddn ? ldap_conf.binddn : "(anonymous)"); + sudo_printf(SUDO_CONV_ERROR_MSG, "bindpw %s\n", + ldap_conf.bindpw ? ldap_conf.bindpw : "(anonymous)"); if (ldap_conf.bind_timelimit > 0) { - snprintf(num, sizeof(num), "%d", ldap_conf.bind_timelimit); - print_error(3, "bind_timelimit ", num, "\n"); + sudo_printf(SUDO_CONV_ERROR_MSG, "bind_timelimit %d\n", + ldap_conf.bind_timelimit); } if (ldap_conf.timelimit > 0) { - snprintf(num, sizeof(num), "%d", ldap_conf.timelimit); - print_error(3, "timelimit ", num, "\n"); + sudo_printf(SUDO_CONV_ERROR_MSG, "timelimit %d\n", + ldap_conf.timelimit); + } + sudo_printf(SUDO_CONV_ERROR_MSG, "ssl %s\n", + ldap_conf.ssl ? ldap_conf.ssl : "(no)"); + if (ldap_conf.tls_checkpeer != -1) { + sudo_printf(SUDO_CONV_ERROR_MSG, "tls_checkpeer %s\n", + ldap_conf.tls_checkpeer ? "(yes)" : "(no)"); + } + if (ldap_conf.tls_cacertfile != NULL) { + sudo_printf(SUDO_CONV_ERROR_MSG, "tls_cacertfile %s\n", + ldap_conf.tls_cacertfile); + } + if (ldap_conf.tls_cacertdir != NULL) { + sudo_printf(SUDO_CONV_ERROR_MSG, "tls_cacertdir %s\n", + ldap_conf.tls_cacertdir); + } + if (ldap_conf.tls_random_file != NULL) { + sudo_printf(SUDO_CONV_ERROR_MSG, "tls_random_file %s\n", + ldap_conf.tls_random_file); + } + if (ldap_conf.tls_cipher_suite != NULL) { + sudo_printf(SUDO_CONV_ERROR_MSG, "tls_cipher_suite %s\n", + ldap_conf.tls_cipher_suite); + } + if (ldap_conf.tls_certfile != NULL) { + sudo_printf(SUDO_CONV_ERROR_MSG, "tls_certfile %s\n", + ldap_conf.tls_certfile); + } + if (ldap_conf.tls_keyfile != NULL) { + sudo_printf(SUDO_CONV_ERROR_MSG, "tls_keyfile %s\n", + ldap_conf.tls_keyfile); } - print_error(3, "ssl ", ldap_conf.ssl ? - ldap_conf.ssl : "(no)", "\n"); - if (ldap_conf.tls_checkpeer != -1) - print_error(3, "tls_checkpeer ", ldap_conf.tls_checkpeer ? - "(yes)" : "(no)", "\n"); - if (ldap_conf.tls_cacertfile != NULL) - print_error(3, "tls_cacertfile ", ldap_conf.tls_cacertfile, "\n"); - if (ldap_conf.tls_cacertdir != NULL) - print_error(3, "tls_cacertdir ", ldap_conf.tls_cacertdir, "\n"); - if (ldap_conf.tls_random_file != NULL) - print_error(3, "tls_random_file ", ldap_conf.tls_random_file, "\n"); - if (ldap_conf.tls_cipher_suite != NULL) - print_error(3, "tls_cipher_suite ", ldap_conf.tls_cipher_suite, "\n"); - if (ldap_conf.tls_certfile != NULL) - print_error(3, "tls_certfile ", ldap_conf.tls_certfile, "\n"); - if (ldap_conf.tls_keyfile != NULL) - print_error(3, "tls_keyfile ", ldap_conf.tls_keyfile, "\n"); #ifdef HAVE_LDAP_SASL_INTERACTIVE_BIND_S if (ldap_conf.use_sasl != -1) { - print_error(3, "use_sasl ", - ldap_conf.use_sasl ? "yes" : "no", "\n"); - print_error(3, "sasl_auth_id ", ldap_conf.sasl_auth_id ? - ldap_conf.sasl_auth_id : "(NONE)", "\n"); - print_error(3, "rootuse_sasl ", - ldap_conf.rootuse_sasl == TRUE ? "true" : - ldap_conf.rootuse_sasl == FALSE ? "false" : "(NONE)", "\n"); - print_error(3, "rootsasl_auth_id ", ldap_conf.rootsasl_auth_id ? - ldap_conf.rootsasl_auth_id : "(NONE)", "\n"); - print_error(3, "sasl_secprops ", ldap_conf.sasl_secprops ? - ldap_conf.sasl_secprops : "(NONE)", "\n"); - print_error(3, "krb5_ccname ", ldap_conf.krb5_ccname ? - ldap_conf.krb5_ccname : "(NONE)", "\n"); + sudo_printf(SUDO_CONV_ERROR_MSG, "use_sasl %s\n", + ldap_conf.use_sasl ? "yes" : "no"); + sudo_printf(SUDO_CONV_ERROR_MSG, "sasl_auth_id %s\n", + ldap_conf.sasl_auth_id ? ldap_conf.sasl_auth_id : "(NONE)"); + sudo_printf(SUDO_CONV_ERROR_MSG, "rootuse_sasl %d\n", + ldap_conf.rootuse_sasl); + sudo_printf(SUDO_CONV_ERROR_MSG, "rootsasl_auth_id %s\n", + ldap_conf.rootsasl_auth_id ? ldap_conf.rootsasl_auth_id : "(NONE)"); + sudo_printf(SUDO_CONV_ERROR_MSG, "sasl_secprops %s\n", + ldap_conf.sasl_secprops ? ldap_conf.sasl_secprops : "(NONE)"); + sudo_printf(SUDO_CONV_ERROR_MSG, "krb5_ccname %s\n", + ldap_conf.krb5_ccname ? ldap_conf.krb5_ccname : "(NONE)"); } #endif - print_error(1, "===================\n"); + sudo_printf(SUDO_CONV_ERROR_MSG, "===================\n"); } if (!ldap_conf.base) return(FALSE); /* if no base is defined, ignore LDAP */ diff --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c index 7eaa9de19..8a79f6063 100644 --- a/plugins/sudoers/logging.c +++ b/plugins/sudoers/logging.c @@ -276,22 +276,23 @@ log_denial(int status, int inform_user) /* Inform the user if they failed to authenticate. */ if (inform_user) { if (ISSET(status, FLAG_NO_USER)) { - print_error(2, user_name, " is not in the sudoers file. " - "This incident will be reported.\n"); + sudo_printf(SUDO_CONV_ERROR_MSG, "%s is not in the sudoers file. " + "This incident will be reported.\n", user_name); } else if (ISSET(status, FLAG_NO_HOST)) { - print_error(4, user_name, " is not allowed to run sudo on ", - user_shost, ". This incident will be reported.\n"); + sudo_printf(SUDO_CONV_ERROR_MSG, "%s is not allowed to run sudo " + "on %s. This incident will be reported.\n", + user_name, user_shost); } else if (ISSET(status, FLAG_NO_CHECK)) { - print_error(5, "Sorry, user ", user_name, " may not run sudo on ", - user_shost, ".\n"); + sudo_printf(SUDO_CONV_ERROR_MSG, "Sorry, user %s may not run " + "sudo on %s.\n", user_name, user_shost); } else { - print_error(13, "Sorry, user ", user_name, - " is not allowed to execute '", user_cmnd, - user_args ? " " : "", user_args ? user_args : "", "' ", - list_pw ? list_pw->pw_name : - runas_pw ? runas_pw->pw_name : user_name, - runas_gr ? ":" : "", runas_gr ? runas_gr->gr_name : "", " on ", - user_shost, ".\n"); + sudo_printf(SUDO_CONV_ERROR_MSG, "Sorry, user %s is not allowed " + "to execute '%s%s%s' as %s%s%s on %s.\n", + user_name, user_cmnd, user_args ? " " : "", + user_args ? user_args : "", + list_pw ? list_pw->pw_name : runas_pw ? + runas_pw->pw_name : user_name, runas_gr ? ":" : "", + runas_gr ? runas_gr->gr_name : "", user_host); } } diff --git a/plugins/sudoers/plugin_error.c b/plugins/sudoers/plugin_error.c index 8730ef904..c12c247ac 100644 --- a/plugins/sudoers/plugin_error.c +++ b/plugins/sudoers/plugin_error.c @@ -106,28 +106,3 @@ _warning(int use_errno, const char *fmt, va_list ap) memset(&repl, 0, sizeof(repl)); sudo_conv(nmsgs, msg, repl); } - -void -print_error(int nmsgs, ...) -{ - struct sudo_conv_message *msg; - struct sudo_conv_reply *repl; - va_list ap; - int i; - - if (nmsgs <= 0) - return; - - msg = emalloc2(nmsgs, sizeof(*msg)); - repl = emalloc2(nmsgs, sizeof(*repl)); - memset(repl, 0, nmsgs * sizeof(*repl)); - - va_start(ap, nmsgs); - for (i = 0; i < nmsgs; i++) { - msg[i].msg_type = SUDO_CONV_ERROR_MSG; - msg[i].msg = va_arg(ap, char *); - } - va_end(ap); - - sudo_conv(nmsgs, msg, repl); -} diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index da8c47014..86d67a5b9 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -148,6 +148,7 @@ char *login_style; #endif /* HAVE_BSD_AUTH_H */ sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp; sudo_conv_t sudo_conv; +sudo_printf_t sudo_printf; static char *runas_user; static char *runas_group; @@ -164,8 +165,8 @@ static int sudo_mode; static int sudoers_policy_open(unsigned int version, sudo_conv_t conversation, - char * const settings[], char * const user_info[], - char * const envp[]) + sudo_printf_t plugin_printf, char * const settings[], + char * const user_info[], char * const envp[]) { int sources = 0; sigaction_t sa; @@ -179,7 +180,10 @@ sudoers_policy_open(unsigned int version, sudo_conv_t conversation, # endif #endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */ - sudo_conv = conversation; /* XXX, stash elsewhere? */ + if (!sudo_conv) + sudo_conv = conversation; + if (!sudo_printf) + sudo_printf = plugin_printf; if (sigsetjmp(error_jmp, 1)) { /* called via error(), errorx() or log_error() */ diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h index c2d54ecfc..36dcf68f9 100644 --- a/plugins/sudoers/sudoers.h +++ b/plugins/sudoers/sudoers.h @@ -289,7 +289,8 @@ int get_boottime(struct timeval *); /* iolog.c */ int sudoers_io_open(unsigned int version, sudo_conv_t conversation, - char * const settings[], char * const user_info[], char * const user_env[]); + sudo_printf_t sudo_printf, char * const settings[], + char * const user_info[], char * const user_env[]); void sudoers_io_close(int exit_status, int error); int sudoers_io_version(int verbose); int sudoers_io_log_output(const char *buf, unsigned int len); @@ -311,15 +312,13 @@ void cleanup(int); void set_fqdn(void); FILE *open_sudoers(const char *, int, int *); -/* plugin_error.c */ -void print_error(int nmsgs, ...); - #ifndef _SUDO_MAIN extern struct sudo_user sudo_user; extern struct passwd *auth_pw, *list_pw; extern int long_list; extern uid_t timestamp_uid; extern sudo_conv_t sudo_conv; +extern sudo_printf_t sudo_printf; #endif /* Some systems don't declare errno in errno.h */ diff --git a/src/conversation.c b/src/conversation.c index 93c711de9..0183ceb6a 100644 --- a/src/conversation.c +++ b/src/conversation.c @@ -44,6 +44,7 @@ #ifdef HAVE_UNISTD_H # include #endif /* HAVE_UNISTD_H */ +#include #include "sudo.h" #include "sudo_plugin.h" @@ -89,7 +90,7 @@ sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[], } } - return(0); + return 0; err: /* Zero and free allocated memory and return an error. */ @@ -102,5 +103,30 @@ err: } } while (n--); - return(-1); + return -1; +} + +int +sudo_printf(int msg_type, const char *fmt, ...) +{ + va_list ap; + FILE *fp; + + switch (msg_type) { + case SUDO_CONV_INFO_MSG: + fp = stdout; + break; + case SUDO_CONV_ERROR_MSG: + fp = stderr; + break; + default: + errno = EINVAL; + return -1; + } + + va_start(ap, fmt); + vfprintf(fp, fmt, ap); + va_end(ap); + + return 0; } diff --git a/src/sudo.c b/src/sudo.c index c8196cd54..3046208f6 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -148,7 +148,7 @@ main(int argc, char *argv[], char *envp[]) /* Open policy plugin. */ ok = policy_plugin.u.policy->open(SUDO_API_VERSION, sudo_conversation, - settings, user_info, envp); + sudo_printf, settings, user_info, envp); if (ok != TRUE) { if (ok == -2) usage(1); @@ -162,7 +162,7 @@ main(int argc, char *argv[], char *envp[]) policy_plugin.u.policy->show_version(!user_details.uid); tq_foreach_fwd(&io_plugins, plugin) { ok = plugin->u.io->open(SUDO_API_VERSION, sudo_conversation, - settings, user_info, envp); + sudo_printf, settings, user_info, envp); if (ok == TRUE) plugin->u.io->show_version(user_details.uid == ROOT_UID); } @@ -212,8 +212,8 @@ main(int argc, char *argv[], char *envp[]) /* Open I/O plugins once policy plugin succeeds. */ for (plugin = io_plugins.first; plugin != NULL; plugin = next) { next = plugin->next; - ok = plugin->u.io->open(SUDO_API_VERSION, sudo_conversation, settings, - user_info, envp); + ok = plugin->u.io->open(SUDO_API_VERSION, sudo_conversation, + sudo_printf, settings, user_info, envp); switch (ok) { case TRUE: break; diff --git a/src/sudo_plugin_int.h b/src/sudo_plugin_int.h index 3d1b802eb..7d3c2c73a 100644 --- a/src/sudo_plugin_int.h +++ b/src/sudo_plugin_int.h @@ -31,6 +31,7 @@ extern struct plugin_container_list io_plugins; int sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[], struct sudo_conv_reply replies[]); +int sudo_printf(int msg_type, const char *fmt, ...); void sudo_load_plugins(const char *conf_file, struct plugin_container *policy_plugin,