Add sudo_warn_set_conversation() to specify a conversation function
to use for warn/fatal. If no conversation function is specified, the standard error will be used. We now only need sudo_printf() for things that use the parser.
This commit is contained in:
2
MANIFEST
2
MANIFEST
@@ -161,7 +161,6 @@ lib/util/strtonum.c
|
||||
lib/util/sudo_conf.c
|
||||
lib/util/sudo_debug.c
|
||||
lib/util/sudo_dso.c
|
||||
lib/util/sudo_printf.c
|
||||
lib/util/term.c
|
||||
lib/util/ttysize.c
|
||||
lib/util/util.exp.in
|
||||
@@ -429,6 +428,7 @@ plugins/sudoers/solaris_audit.h
|
||||
plugins/sudoers/sssd.c
|
||||
plugins/sudoers/sudo_nss.c
|
||||
plugins/sudoers/sudo_nss.h
|
||||
plugins/sudoers/sudo_printf.c
|
||||
plugins/sudoers/sudoers.c
|
||||
plugins/sudoers/sudoers.exp
|
||||
plugins/sudoers/sudoers.h
|
||||
|
@@ -114,6 +114,9 @@
|
||||
|
||||
typedef void (*sudo_fatal_callback_t)(void);
|
||||
|
||||
struct sudo_conv_message;
|
||||
struct sudo_conv_reply;
|
||||
|
||||
__dso_public int sudo_fatal_callback_deregister_v1(sudo_fatal_callback_t func);
|
||||
__dso_public int sudo_fatal_callback_register_v1(sudo_fatal_callback_t func);
|
||||
__dso_public char *sudo_warn_gettext_v1(const char *msgid) __format_arg(1);
|
||||
@@ -126,6 +129,7 @@ __dso_public void sudo_warn_nodebug_v1(const char *fmt, ...) __printf0like(1, 2)
|
||||
__dso_public void sudo_warnx_nodebug_v1(const char *fmt, ...) __printflike(1, 2);
|
||||
__dso_public void sudo_vwarn_nodebug_v1(const char *fmt, va_list ap) __printf0like(1, 0);
|
||||
__dso_public void sudo_vwarnx_nodebug_v1(const char *fmt, va_list ap) __printflike(1, 0);
|
||||
__dso_public void sudo_warn_set_conversation_v1(int (*conv)(int num_msgs, const struct sudo_conv_message *msgs, struct sudo_conv_reply *replies));
|
||||
|
||||
#define sudo_fatal_callback_deregister(_a) sudo_fatal_callback_deregister_v1((_a))
|
||||
#define sudo_fatal_callback_register(_a) sudo_fatal_callback_register_v1((_a))
|
||||
@@ -139,5 +143,6 @@ __dso_public void sudo_vwarnx_nodebug_v1(const char *fmt, va_list ap) __printfli
|
||||
#define sudo_warnx_nodebug sudo_warnx_nodebug_v1
|
||||
#define sudo_vwarn_nodebug(_a, _b) sudo_vwarn_nodebug_v1((_a), (_b))
|
||||
#define sudo_vwarnx_nodebug(_a, _b) sudo_vwarnx_nodebug_v1((_a), (_b))
|
||||
#define sudo_warn_set_conversation(_a) sudo_warn_set_conversation_v1(_a)
|
||||
|
||||
#endif /* _SUDO_FATAL_H_ */
|
||||
|
@@ -98,7 +98,7 @@ SHELL = @SHELL@
|
||||
LTOBJS = alloc.lo event.lo fatal.lo key_val.lo gidlist.lo lbuf.lo locking.lo \
|
||||
parseln.lo progname.lo secure_path.lo setgroups.lo strtobool.lo \
|
||||
strtoid.lo strtomode.lo sudo_conf.lo sudo_debug.lo sudo_dso.lo \
|
||||
sudo_printf.lo term.lo ttysize.lo @COMMON_OBJS@ @LTLIBOBJS@
|
||||
term.lo ttysize.lo @COMMON_OBJS@ @LTLIBOBJS@
|
||||
|
||||
ATOFOO_TEST_OBJS = atofoo_test.lo locale_stub.lo
|
||||
|
||||
@@ -494,10 +494,6 @@ sudo_debug.lo: $(srcdir)/sudo_debug.c $(incdir)/compat/stdbool.h \
|
||||
sudo_dso.lo: $(srcdir)/sudo_dso.c $(incdir)/sudo_compat.h $(incdir)/sudo_dso.h \
|
||||
$(top_builddir)/config.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sudo_dso.c
|
||||
sudo_printf.lo: $(srcdir)/sudo_printf.c $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_debug.h $(incdir)/sudo_plugin.h \
|
||||
$(top_builddir)/config.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sudo_printf.c
|
||||
term.lo: $(srcdir)/term.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_debug.h $(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/term.c
|
||||
|
@@ -44,7 +44,8 @@ struct sudo_fatal_callback {
|
||||
};
|
||||
SLIST_HEAD(sudo_fatal_callback_list, sudo_fatal_callback);
|
||||
|
||||
static struct sudo_fatal_callback_list callbacks;
|
||||
static struct sudo_fatal_callback_list callbacks = SLIST_HEAD_INITIALIZER(&callbacks);
|
||||
static sudo_conv_t sudo_warn_conversation;
|
||||
|
||||
static void _warning(int errnum, const char *fmt, va_list ap);
|
||||
|
||||
@@ -135,24 +136,44 @@ sudo_vwarnx_nodebug_v1(const char *fmt, va_list ap)
|
||||
static void
|
||||
_warning(int errnum, const char *fmt, va_list ap)
|
||||
{
|
||||
char *str;
|
||||
if (sudo_warn_conversation != NULL) {
|
||||
struct sudo_conv_message msgs[6];
|
||||
int nmsgs = 0;
|
||||
char *str = NULL;
|
||||
|
||||
sudo_evasprintf(&str, fmt, ap);
|
||||
if (errnum) {
|
||||
/* Use conversation function. */
|
||||
msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
|
||||
msgs[nmsgs++].msg = getprogname();
|
||||
if (fmt != NULL) {
|
||||
sudo_printf(SUDO_CONV_ERROR_MSG,
|
||||
_("%s: %s: %s\n"), getprogname(), str,
|
||||
sudo_warn_strerror(errnum));
|
||||
} else {
|
||||
sudo_printf(SUDO_CONV_ERROR_MSG,
|
||||
_("%s: %s\n"), getprogname(),
|
||||
sudo_warn_strerror(errnum));
|
||||
sudo_evasprintf(&str, fmt, ap);
|
||||
msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
|
||||
msgs[nmsgs++].msg = ": ";
|
||||
msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
|
||||
msgs[nmsgs++].msg = str;
|
||||
}
|
||||
} else {
|
||||
sudo_printf(SUDO_CONV_ERROR_MSG,
|
||||
_("%s: %s\n"), getprogname(), str ? str : "(null)");
|
||||
if (errnum) {
|
||||
msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
|
||||
msgs[nmsgs++].msg = ": ";
|
||||
msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
|
||||
msgs[nmsgs++].msg = sudo_warn_strerror(errnum);
|
||||
}
|
||||
msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG;
|
||||
msgs[nmsgs++].msg = "\n";
|
||||
sudo_warn_conversation(nmsgs, msgs, NULL);
|
||||
sudo_efree(str);
|
||||
} else {
|
||||
/* Write to the standard error. */
|
||||
fputs(getprogname(), stderr);
|
||||
if (fmt != NULL) {
|
||||
fputs(": ", stderr);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
}
|
||||
if (errnum) {
|
||||
fputs(": ", stderr);
|
||||
fputs(sudo_warn_strerror(errnum), stderr);
|
||||
}
|
||||
putc('\n', stderr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -201,3 +222,13 @@ sudo_fatal_callback_deregister_v1(sudo_fatal_callback_t func)
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the conversation function to use for output insteaf of the
|
||||
* standard error. If conv is NULL, switch back to standard error.
|
||||
*/
|
||||
void
|
||||
sudo_warn_set_conversation_v1(sudo_conv_t conv)
|
||||
{
|
||||
sudo_warn_conversation = conv;
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
@COMPAT_EXP@_sudo_printf
|
||||
@COMPAT_EXP@
|
||||
initprogname
|
||||
sudo_conf_askpass_path_v1
|
||||
sudo_conf_debug_flags_v1
|
||||
@@ -70,7 +70,6 @@ sudo_lock_file_v1
|
||||
sudo_new_key_val_v1
|
||||
sudo_parse_gids_v1
|
||||
sudo_parseln_v1
|
||||
sudo_printf
|
||||
sudo_secure_dir_v1
|
||||
sudo_secure_file_v1
|
||||
sudo_setgroups_v1
|
||||
@@ -90,3 +89,4 @@ sudo_vwarn_nodebug_v1
|
||||
sudo_vwarnx_nodebug_v1
|
||||
sudo_warn_nodebug_v1
|
||||
sudo_warnx_nodebug_v1
|
||||
sudo_warn_set_conversation_v1
|
||||
|
@@ -138,7 +138,7 @@ AUTH_OBJS = sudo_auth.lo @AUTH_OBJS@
|
||||
|
||||
LIBPARSESUDOERS_OBJS = alias.lo audit.lo base64.lo defaults.lo hexchar.lo \
|
||||
gram.lo match.lo match_addr.lo pwutil.lo pwutil_impl.lo \
|
||||
timestr.lo toke.lo toke_util.lo redblack.lo
|
||||
redblack.lo timestr.lo toke.lo toke_util.lo
|
||||
|
||||
SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo env.lo find_path.lo \
|
||||
goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
|
||||
@@ -146,14 +146,15 @@ SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo env.lo find_path.lo \
|
||||
policy.lo prompt.lo set_perms.lo sudo_nss.lo sudoers.lo \
|
||||
timestamp.lo @SUDOERS_OBJS@
|
||||
|
||||
VISUDO_OBJS = find_path.o goodpath.o locale.o visudo.o visudo_json.o
|
||||
VISUDO_OBJS = find_path.o goodpath.o locale.o sudo_printf.o visudo.o \
|
||||
visudo_json.o
|
||||
|
||||
REPLAY_OBJS = getdate.o locale.o sudoreplay.o
|
||||
|
||||
TEST_OBJS = group_plugin.o interfaces.o locale.o net_ifs.o \
|
||||
testsudoers.o tsgetgrpw.o
|
||||
sudo_printf.o testsudoers.o tsgetgrpw.o
|
||||
|
||||
CHECK_ADDR_OBJS = check_addr.o interfaces.o locale.o match_addr.o
|
||||
CHECK_ADDR_OBJS = check_addr.o interfaces.o locale.o match_addr.o sudo_printf.o
|
||||
|
||||
CHECK_BASE64_OBJS = check_base64.o base64.o locale.o
|
||||
|
||||
@@ -896,6 +897,10 @@ sudo_nss.lo: $(srcdir)/sudo_nss.c $(devdir)/def_data.h \
|
||||
$(srcdir)/logging.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
|
||||
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sudo_nss.c
|
||||
sudo_printf.o: $(srcdir)/sudo_printf.c $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_debug.h $(incdir)/sudo_plugin.h \
|
||||
$(top_builddir)/config.h
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sudo_printf.c
|
||||
sudoers.lo: $(srcdir)/sudoers.c $(devdir)/def_data.h \
|
||||
$(incdir)/compat/getaddrinfo.h $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_alloc.h $(incdir)/sudo_compat.h \
|
||||
|
@@ -33,7 +33,7 @@
|
||||
#include "sudo_plugin.h"
|
||||
#include "sudo_debug.h"
|
||||
|
||||
__dso_public int
|
||||
static int
|
||||
_sudo_printf(int msg_type, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@@ -59,4 +59,4 @@ _sudo_printf(int msg_type, const char *fmt, ...)
|
||||
return len;
|
||||
}
|
||||
|
||||
__dso_public sudo_printf_t sudo_printf = _sudo_printf;
|
||||
sudo_printf_t sudo_printf = _sudo_printf;
|
@@ -104,6 +104,7 @@ uid_t timestamp_uid;
|
||||
char *login_style;
|
||||
#endif /* HAVE_BSD_AUTH_H */
|
||||
int sudo_mode;
|
||||
sudo_printf_t sudo_printf;
|
||||
|
||||
static char *prev_user;
|
||||
static char *runas_user;
|
||||
|
@@ -364,6 +364,7 @@ extern int long_list;
|
||||
extern int sudo_mode;
|
||||
extern uid_t timestamp_uid;
|
||||
extern sudo_conv_t sudo_conv;
|
||||
extern sudo_printf_t sudo_printf;
|
||||
#endif
|
||||
|
||||
#endif /* _SUDOERS_SUDOERS_H */
|
||||
|
@@ -111,3 +111,29 @@ err:
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
sudo_conversation_printf(int msg_type, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int len;
|
||||
|
||||
switch (msg_type) {
|
||||
case SUDO_CONV_INFO_MSG:
|
||||
va_start(ap, fmt);
|
||||
len = vfprintf(stdout, fmt, ap);
|
||||
va_end(ap);
|
||||
break;
|
||||
case SUDO_CONV_ERROR_MSG:
|
||||
va_start(ap, fmt);
|
||||
len = vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
break;
|
||||
default:
|
||||
len = -1;
|
||||
errno = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
19
src/sudo.c
19
src/sudo.c
@@ -168,6 +168,9 @@ main(int argc, char *argv[], char *envp[])
|
||||
# endif
|
||||
#endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */
|
||||
|
||||
/* Use conversation function for sudo_(warn|fatal)x?. */
|
||||
sudo_warn_set_conversation(sudo_conversation);
|
||||
|
||||
/* Make sure we are setuid root. */
|
||||
sudo_check_suid(argv[0]);
|
||||
|
||||
@@ -1085,11 +1088,13 @@ policy_open(struct plugin_container *plugin, char * const settings[],
|
||||
case SUDO_API_MKVERSION(1, 0):
|
||||
case SUDO_API_MKVERSION(1, 1):
|
||||
rval = plugin->u.policy_1_0->open(plugin->u.io_1_0->version,
|
||||
sudo_conversation, _sudo_printf, settings, user_info, user_env);
|
||||
sudo_conversation, sudo_conversation_printf, settings,
|
||||
user_info, user_env);
|
||||
break;
|
||||
default:
|
||||
rval = plugin->u.policy->open(SUDO_API_VERSION, sudo_conversation,
|
||||
_sudo_printf, settings, user_info, user_env, plugin->options);
|
||||
sudo_conversation_printf, settings, user_info, user_env,
|
||||
plugin->options);
|
||||
}
|
||||
|
||||
debug_return_bool(rval);
|
||||
@@ -1205,17 +1210,17 @@ iolog_open(struct plugin_container *plugin, char * const settings[],
|
||||
switch (plugin->u.generic->version) {
|
||||
case SUDO_API_MKVERSION(1, 0):
|
||||
rval = plugin->u.io_1_0->open(plugin->u.io_1_0->version,
|
||||
sudo_conversation, _sudo_printf, settings, user_info, argc, argv,
|
||||
user_env);
|
||||
sudo_conversation, sudo_conversation_printf, settings,
|
||||
user_info, argc, argv, user_env);
|
||||
break;
|
||||
case SUDO_API_MKVERSION(1, 1):
|
||||
rval = plugin->u.io_1_1->open(plugin->u.io_1_1->version,
|
||||
sudo_conversation, _sudo_printf, settings, user_info,
|
||||
command_info, argc, argv, user_env);
|
||||
sudo_conversation, sudo_conversation_printf, settings,
|
||||
user_info, command_info, argc, argv, user_env);
|
||||
break;
|
||||
default:
|
||||
rval = plugin->u.io->open(SUDO_API_VERSION, sudo_conversation,
|
||||
_sudo_printf, settings, user_info, command_info,
|
||||
sudo_conversation_printf, settings, user_info, command_info,
|
||||
argc, argv, user_env, plugin->options);
|
||||
}
|
||||
debug_return_bool(rval);
|
||||
|
@@ -101,7 +101,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, ...);
|
||||
int sudo_conversation_printf(int msg_type, const char *fmt, ...);
|
||||
|
||||
bool sudo_load_plugins(struct plugin_container *policy_plugin,
|
||||
struct plugin_container_list *io_plugins);
|
||||
|
Reference in New Issue
Block a user