From: Todd C. Miller Date: Mon, 5 Nov 2018 16:08:05 +0000 (-0700) Subject: Add sudo_gai_fatal, sudo_gai_vfatal, sudo_gai_vwarn, sudo_gai_warn X-Git-Tag: SUDO_1_8_26^2~7 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cdd5bb32eb56b02dfc802a05ebad8051a644c360;p=sudo Add sudo_gai_fatal, sudo_gai_vfatal, sudo_gai_vwarn, sudo_gai_warn and gai_log_warning that use gai_strerror() instead of strerror(). --- diff --git a/NEWS b/NEWS index 0843873da..f27296127 100644 --- a/NEWS +++ b/NEWS @@ -49,6 +49,10 @@ What's new in Sudo 1.8.26 * The sudoers LDAP back-end now supports negated sudoRunAsUser and sudoRunAsGroup entries. + * Sudo now provides a proper error message when the "fqdn" sudoers + option is set and it is unable to resolve the local host name. + Bug #859. + What's new in Sudo 1.8.25p1 * Fixed a bug introduced in sudo 1.8.25 that caused a crash on diff --git a/configure b/configure index f5e6a4682..794516296 100755 --- a/configure +++ b/configure @@ -21629,7 +21629,7 @@ LIBS="$OLIBS" # If it was added to LIBOBJS we need to export the symbols. # OLIBS="$LIBS" -LIBS="${LIBS} ${NET_LIBS}" +GETADDRINFO_LIBS= { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo" >&5 $as_echo_n "checking for getaddrinfo... " >&6; } if ${ax_cv_func_getaddrinfo+:} false; then : @@ -21810,11 +21810,25 @@ fi ;; *) for lib in $LIBS; do - case "$NET_LIBS" in + case "$OLIBS" in *"$lib"*) ;; - *) NET_LIBS="${NET_LIBS} $lib";; + *) GETADDRINFO_LIBS="${GETADDRINFO_LIBS}${GETADDRINFO_LIBS+ }$lib";; esac done + if test -n "${GETADDRINFO_LIBS}"; then + # We need libsudo_util to pull in dependent libraries for + # gai_strerror() + LT_DEP_LIBS="${LT_DEP_LIBS}${LT_DEP_LIBS+ }${GETADDRINFO_LIBS}" + LIBS="${LIBS}${LIBS+ }${GETADDRINFO_LIBS}" + + # Add to NET_LIBS if necessary + for lib in $GETADDRINFO_LIBS; do + case "$NET_LIBS" in + *"$lib"*) ;; + *) NET_LIBS="${NET_LIBS}${NET_LIBS+ }$lib";; + esac + done + fi ;; esac LIBS="$OLIBS" diff --git a/configure.ac b/configure.ac index ff9efb446..86e0627c8 100644 --- a/configure.ac +++ b/configure.ac @@ -3023,7 +3023,7 @@ LIBS="$OLIBS" # If it was added to LIBOBJS we need to export the symbols. # OLIBS="$LIBS" -LIBS="${LIBS} ${NET_LIBS}" +GETADDRINFO_LIBS= AX_FUNC_GETADDRINFO case " $LIBOBJS " in *" getaddrinfo.$ac_objext "* ) @@ -3053,11 +3053,25 @@ case " $LIBOBJS " in ;; *) for lib in $LIBS; do - case "$NET_LIBS" in + case "$OLIBS" in *"$lib"*) ;; - *) NET_LIBS="${NET_LIBS} $lib";; + *) GETADDRINFO_LIBS="${GETADDRINFO_LIBS}${GETADDRINFO_LIBS+ }$lib";; esac done + if test -n "${GETADDRINFO_LIBS}"; then + # We need libsudo_util to pull in dependent libraries for + # gai_strerror() + LT_DEP_LIBS="${LT_DEP_LIBS}${LT_DEP_LIBS+ }${GETADDRINFO_LIBS}" + LIBS="${LIBS}${LIBS+ }${GETADDRINFO_LIBS}" + + # Add to NET_LIBS if necessary + for lib in $GETADDRINFO_LIBS; do + case "$NET_LIBS" in + *"$lib"*) ;; + *) NET_LIBS="${NET_LIBS}${NET_LIBS+ }$lib";; + esac + done + fi ;; esac LIBS="$OLIBS" diff --git a/include/sudo_fatal.h b/include/sudo_fatal.h index 576644adc..ea92b3b6e 100644 --- a/include/sudo_fatal.h +++ b/include/sudo_fatal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2010-2014 Todd C. Miller + * Copyright (c) 2004, 2010-2015, 2017-2018 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -31,12 +31,16 @@ #if (defined(SUDO_ERROR_WRAP) && SUDO_ERROR_WRAP == 0) || defined(NO_VARIADIC_MACROS) # define sudo_fatal sudo_fatal_nodebug_v1 # define sudo_fatalx sudo_fatalx_nodebug_v1 +# define sudo_gai_fatal sudo_gai_fatal_nodebug_v1 # define sudo_warn sudo_warn_nodebug_v1 # define sudo_warnx sudo_warnx_nodebug_v1 +# define sudo_gai_warn sudo_gai_warn_nodebug_v1 # define sudo_vfatal(fmt, ap) sudo_vfatal_nodebug_v1((fmt), (ap)) # define sudo_vfatalx(fmt, ap) sudo_vfatalx_nodebug_v1((fmt), (ap)) +# define sudo_gai_vfatal(en, fmt, ap) sudo_vfatal_nodebug_v1((en), (fmt), (ap)) # define sudo_vwarn(fmt, ap) sudo_vwarn_nodebug_v1((fmt), (ap)) # define sudo_vwarnx(fmt, ap) sudo_vwarnx_nodebug_v1((fmt), (ap)) +# define sudo_gai_vwarn(en, fmt, ap) sudo_vwarn_nodebug_v1((en), (fmt), (ap)) #else /* SUDO_ERROR_WRAP */ # if defined(__GNUC__) && __GNUC__ == 2 # define sudo_fatal(fmt...) do { \ @@ -48,7 +52,12 @@ # define sudo_fatalx(fmt...) do { \ sudo_debug_printf2(__func__, __FILE__, __LINE__, \ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt); \ - sudo_fatalx_nodebug_v1(fmt); \ + sudo_fatalx_nodebug_v1(fmt); \ +} while (0) +# define sudo_gai_fatal(en, fmt...) do { \ + sudo_debug_printf2(__func__, __FILE__, __LINE__, \ + SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt); \ + sudo_gai_fatal_nodebug_v1((en), fmt); \ } while (0) # define sudo_warn(fmt...) do { \ sudo_debug_printf2(__func__, __FILE__, __LINE__, \ @@ -61,6 +70,11 @@ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt); \ sudo_warnx_nodebug_v1(fmt); \ } while (0) +# define sudo_gai_warn(en, fmt...) do { \ + sudo_debug_printf2(__func__, __FILE__, __LINE__, \ + SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt); \ + sudo_gai_warn_nodebug_v1((en), fmt); \ +} while (0) # else # define sudo_fatal(...) do { \ sudo_debug_printf2(__func__, __FILE__, __LINE__, \ @@ -71,7 +85,12 @@ # define sudo_fatalx(...) do { \ sudo_debug_printf2(__func__, __FILE__, __LINE__, \ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__); \ - sudo_fatalx_nodebug_v1(__VA_ARGS__); \ + sudo_fatalx_nodebug_v1(__VA_ARGS__); \ +} while (0) +# define sudo_gai_fatal(en, ...) do { \ + sudo_debug_printf2(__func__, __FILE__, __LINE__, \ + SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__); \ + sudo_gai_fatal_nodebug_v1((en), __VA_ARGS__); \ } while (0) # define sudo_warn(...) do { \ sudo_debug_printf2(__func__, __FILE__, __LINE__, \ @@ -84,6 +103,11 @@ SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__); \ sudo_warnx_nodebug_v1(__VA_ARGS__); \ } while (0) +# define sudo_gai_warn(en, ...) do { \ + sudo_debug_printf2(__func__, __FILE__, __LINE__, \ + SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__); \ + sudo_gai_warn_nodebug_v1((en), __VA_ARGS__); \ +} while (0) # endif /* __GNUC__ == 2 */ # define sudo_vfatal(fmt, ap) do { \ va_list ap2; \ @@ -98,7 +122,14 @@ va_copy(ap2, (ap)); \ sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2); \ - sudo_vfatalx_nodebug_v1((fmt), (ap)); \ + sudo_vfatalx_nodebug_v1((fmt), (ap)); \ +} while (0) +# define sudo_gai_vfatal(en, fmt, ap) do { \ + va_list ap2; \ + va_copy(ap2, (ap)); \ + sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \ + SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2); \ + sudo_gai_vfatal_nodebug_v1((en), (fmt), (ap)); \ } while (0) # define sudo_vwarn(fmt, ap) do { \ va_list ap2; \ @@ -113,7 +144,14 @@ va_copy(ap2, (ap)); \ sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \ SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2); \ - sudo_vwarnx_nodebug_v1((fmt), (ap)); \ + sudo_vwarnx_nodebug_v1((fmt), (ap)); \ +} while (0) +# define sudo_gai_vwarn(en, fmt, ap) do { \ + va_list ap2; \ + va_copy(ap2, (ap)); \ + sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \ + SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2); \ + sudo_gai_vwarn_nodebug_v1((en), (fmt), (ap)); \ } while (0) #endif /* SUDO_ERROR_WRAP */ @@ -129,12 +167,16 @@ __dso_public char *sudo_warn_gettext_v1(const char *domainname, const char *msgi __dso_public void sudo_warn_set_locale_func_v1(bool (*func)(bool, int *)); __dso_public void sudo_fatal_nodebug_v1(const char *fmt, ...) __printf0like(1, 2) __attribute__((__noreturn__)); __dso_public void sudo_fatalx_nodebug_v1(const char *fmt, ...) __printflike(1, 2) __attribute__((__noreturn__)); +__dso_public void sudo_gai_fatal_nodebug_v1(int errnum, const char *fmt, ...) __printflike(2, 3) __attribute__((__noreturn__)); __dso_public void sudo_vfatal_nodebug_v1(const char *fmt, va_list ap) __printf0like(1, 0) __attribute__((__noreturn__)); __dso_public void sudo_vfatalx_nodebug_v1(const char *fmt, va_list ap) __printflike(1, 0) __attribute__((__noreturn__)); +__dso_public void sudo_gai_vfatal_nodebug_v1(int errnum, const char *fmt, va_list ap) __printflike(2, 0) __attribute__((__noreturn__)); __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_gai_warn_nodebug_v1(int errnum, const char *fmt, ...) __printflike(2, 3); __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_gai_vwarn_nodebug_v1(int errnum, const char *fmt, va_list ap) __printflike(2, 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, struct sudo_conv_callback *callback)); #define sudo_fatal_callback_deregister(_a) sudo_fatal_callback_deregister_v1((_a)) @@ -142,12 +184,16 @@ __dso_public void sudo_warn_set_conversation_v1(int (*conv)(int num_msgs, const #define sudo_warn_set_locale_func(_a) sudo_warn_set_locale_func_v1((_a)) #define sudo_fatal_nodebug sudo_fatal_nodebug_v1 #define sudo_fatalx_nodebug sudo_fatalx_nodebug_v1 +#define sudo_gai_fatal_nodebug sudo_gai_fatal_nodebug_v1 #define sudo_vfatal_nodebug(_a, _b) sudo_vfatal_nodebug_v1((_a), (_b)) #define sudo_vfatalx_nodebug(_a, _b) sudo_vfatalx_nodebug_v1((_a), (_b)) +#define sudo_gai_vfatal_nodebug(_a, _b, _c) sudo_gai_vfatal_nodebug_v1((_a), (_b), (_c)) #define sudo_warn_nodebug sudo_warn_nodebug_v1 #define sudo_warnx_nodebug sudo_warnx_nodebug_v1 +#define sudo_gai_warn_nodebug sudo_gai_warn_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_gai_vwarn_nodebug(_a, _b, _c) sudo_gai_vwarn_nodebug_v1((_a), (_b), (_c)) #define sudo_warn_set_conversation(_a) sudo_warn_set_conversation_v1(_a) #ifdef DEFAULT_TEXT_DOMAIN diff --git a/lib/util/Makefile.in b/lib/util/Makefile.in index 6f5ab84b2..cadfcf250 100644 --- a/lib/util/Makefile.in +++ b/lib/util/Makefile.in @@ -512,12 +512,14 @@ event_select.i: $(srcdir)/event_select.c $(incdir)/compat/stdbool.h \ $(CC) -E -o $@ $(CPPFLAGS) $< event_select.plog: event_select.i rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/event_select.c --i-file $< --output-file $@ -fatal.lo: $(srcdir)/fatal.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ +fatal.lo: $(srcdir)/fatal.c $(incdir)/compat/getaddrinfo.h \ + $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \ $(top_builddir)/config.h $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/fatal.c -fatal.i: $(srcdir)/fatal.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ +fatal.i: $(srcdir)/fatal.c $(incdir)/compat/getaddrinfo.h \ + $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \ $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \ $(top_builddir)/config.h diff --git a/lib/util/fatal.c b/lib/util/fatal.c index 77b1a85b3..645b59082 100644 --- a/lib/util/fatal.c +++ b/lib/util/fatal.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2004-2005, 2010-2014 Todd C. Miller + * Copyright (c) 2004-2005, 2010-2015, 2017-2018 + * Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -24,6 +25,7 @@ #include #include +#include #include #include #include @@ -42,6 +44,10 @@ #include "sudo_util.h" #include "sudo_plugin.h" +#ifndef HAVE_GETADDRINFO +# include "compat/getaddrinfo.h" +#endif + struct sudo_fatal_callback { SLIST_ENTRY(sudo_fatal_callback) entries; void (*func)(void); @@ -53,7 +59,7 @@ static sudo_conv_t sudo_warn_conversation; static bool (*sudo_warn_setlocale)(bool, int *); static bool (*sudo_warn_setlocale_prev)(bool, int *); -static void warning(int errnum, const char *fmt, va_list ap); +static void warning(const char *errstr, const char *fmt, va_list ap); static void do_cleanup(void) @@ -74,7 +80,7 @@ sudo_fatal_nodebug_v1(const char *fmt, ...) va_list ap; va_start(ap, fmt); - warning(errno, fmt, ap); + warning(strerror(errno), fmt, ap); va_end(ap); do_cleanup(); exit(EXIT_FAILURE); @@ -86,7 +92,7 @@ sudo_fatalx_nodebug_v1(const char *fmt, ...) va_list ap; va_start(ap, fmt); - warning(0, fmt, ap); + warning(NULL, fmt, ap); va_end(ap); do_cleanup(); exit(EXIT_FAILURE); @@ -95,7 +101,7 @@ sudo_fatalx_nodebug_v1(const char *fmt, ...) void sudo_vfatal_nodebug_v1(const char *fmt, va_list ap) { - warning(errno, fmt, ap); + warning(strerror(errno), fmt, ap); do_cleanup(); exit(EXIT_FAILURE); } @@ -103,7 +109,7 @@ sudo_vfatal_nodebug_v1(const char *fmt, va_list ap) void sudo_vfatalx_nodebug_v1(const char *fmt, va_list ap) { - warning(0, fmt, ap); + warning(NULL, fmt, ap); do_cleanup(); exit(EXIT_FAILURE); } @@ -114,7 +120,7 @@ sudo_warn_nodebug_v1(const char *fmt, ...) va_list ap; va_start(ap, fmt); - warning(errno, fmt, ap); + warning(strerror(errno), fmt, ap); va_end(ap); } @@ -123,24 +129,60 @@ sudo_warnx_nodebug_v1(const char *fmt, ...) { va_list ap; va_start(ap, fmt); - warning(0, fmt, ap); + warning(NULL, fmt, ap); va_end(ap); } void sudo_vwarn_nodebug_v1(const char *fmt, va_list ap) { - warning(errno, fmt, ap); + warning(strerror(errno), fmt, ap); } void sudo_vwarnx_nodebug_v1(const char *fmt, va_list ap) { - warning(0, fmt, ap); + warning(NULL, fmt, ap); +} + +void +sudo_gai_fatal_nodebug_v1(int errnum, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + warning(gai_strerror(errnum), fmt, ap); + va_end(ap); + do_cleanup(); + exit(EXIT_FAILURE); +} + +void +sudo_gai_vfatal_nodebug_v1(int errnum, const char *fmt, va_list ap) +{ + warning(gai_strerror(errnum), fmt, ap); + do_cleanup(); + exit(EXIT_FAILURE); +} + +void +sudo_gai_warn_nodebug_v1(int errnum, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + warning(gai_strerror(errnum), fmt, ap); + va_end(ap); +} + +void +sudo_gai_vwarn_nodebug_v1(int errnum, const char *fmt, va_list ap) +{ + warning(gai_strerror(errnum), fmt, ap); } static void -warning(int errnum, const char *fmt, va_list ap) +warning(const char *errstr, const char *fmt, va_list ap) { int cookie; @@ -176,11 +218,11 @@ warning(int errnum, const char *fmt, va_list ap) msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG; msgs[nmsgs++].msg = buf; } - if (errnum) { + if (errstr != NULL) { msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG; msgs[nmsgs++].msg = ": "; msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG; - msgs[nmsgs++].msg = strerror(errnum); + msgs[nmsgs++].msg = errstr; } msgs[nmsgs].msg_type = SUDO_CONV_ERROR_MSG; msgs[nmsgs++].msg = "\n"; @@ -194,9 +236,9 @@ warning(int errnum, const char *fmt, va_list ap) fputs(": ", stderr); vfprintf(stderr, fmt, ap); } - if (errnum) { + if (errstr != NULL) { fputs(": ", stderr); - fputs(strerror(errnum), stderr); + fputs(errstr, stderr); } putc('\n', stderr); } diff --git a/lib/util/util.exp.in b/lib/util/util.exp.in index e8fb862ee..510c34cec 100644 --- a/lib/util/util.exp.in +++ b/lib/util/util.exp.in @@ -70,6 +70,10 @@ sudo_fatal_callback_deregister_v1 sudo_fatal_callback_register_v1 sudo_fatal_nodebug_v1 sudo_fatalx_nodebug_v1 +sudo_gai_fatal_nodebug_v1 +sudo_gai_vfatal_nodebug_v1 +sudo_gai_vwarn_nodebug_v1 +sudo_gai_warn_nodebug_v1 sudo_get_ttysize_v1 sudo_getgrouplist2_v1 sudo_gethostname_v1 diff --git a/plugins/sudoers/Makefile.in b/plugins/sudoers/Makefile.in index 82d6c7ee2..e3f6bb5f6 100644 --- a/plugins/sudoers/Makefile.in +++ b/plugins/sudoers/Makefile.in @@ -1714,24 +1714,24 @@ locale.i: $(srcdir)/locale.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \ locale.plog: locale.i rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/locale.c --i-file $< --output-file $@ logging.lo: $(srcdir)/logging.c $(devdir)/def_data.h \ - $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ - $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \ - $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \ - $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \ - $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \ - $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \ - $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \ - $(top_builddir)/pathnames.h + $(incdir)/compat/getaddrinfo.h $(incdir)/compat/stdbool.h \ + $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \ + $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \ + $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \ + $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \ + $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \ + $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \ + $(top_builddir)/config.h $(top_builddir)/pathnames.h $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/logging.c logging.i: $(srcdir)/logging.c $(devdir)/def_data.h \ - $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ - $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \ - $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \ - $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \ - $(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \ - $(srcdir)/parse.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \ - $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \ - $(top_builddir)/pathnames.h + $(incdir)/compat/getaddrinfo.h $(incdir)/compat/stdbool.h \ + $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \ + $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \ + $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \ + $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \ + $(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \ + $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \ + $(top_builddir)/config.h $(top_builddir)/pathnames.h $(CC) -E -o $@ $(CPPFLAGS) $< logging.plog: logging.i rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/logging.c --i-file $< --output-file $@ diff --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c index 767b284a9..95626096a 100644 --- a/plugins/sudoers/logging.c +++ b/plugins/sudoers/logging.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994-1996, 1998-2017 Todd C. Miller + * Copyright (c) 1994-1996, 1998-2018 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -45,6 +45,7 @@ #ifdef HAVE_NL_LANGINFO # include #endif /* HAVE_NL_LANGINFO */ +#include #include #include #include @@ -56,6 +57,10 @@ #include "sudoers.h" +#ifndef HAVE_GETADDRINFO +# include "compat/getaddrinfo.h" +#endif + /* Special message for log_warning() so we know to use ngettext() */ #define INCORRECT_PASSWORD_ATTEMPT ((char *)0x01) @@ -64,7 +69,7 @@ static bool do_logfile(const char *); static bool send_mail(const char *fmt, ...); static bool should_mail(int); static void mysyslog(int, const char *, ...); -static char *new_logline(const char *, int); +static char *new_logline(const char *, const char *); #define MAXSYSLOGTRIES 16 /* num of retries for broken syslogs */ @@ -252,7 +257,7 @@ log_denial(int status, bool inform_user) else message = _("command not allowed"); - logline = new_logline(message, 0); + logline = new_logline(message, NULL); if (logline == NULL) debug_return_bool(false); @@ -396,7 +401,7 @@ log_allowed(int status) /* Log and mail messages should be in the sudoers locale. */ sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale); - if ((logline = new_logline(NULL, 0)) == NULL) + if ((logline = new_logline(NULL, NULL)) == NULL) debug_return_bool(false); /* Become root if we are not already. */ @@ -486,14 +491,15 @@ done: * Perform logging for log_warning()/log_warningx(). */ static bool -vlog_warning(int flags, const char *fmt, va_list ap) +vlog_warning(int flags, int errnum, const char *fmt, va_list ap) { - int oldlocale, serrno = errno; + int oldlocale; + const char *errstr = NULL; char *logline, *message; bool uid_changed, ret = true; va_list ap2; int len; - debug_decl(vlog_error, SUDOERS_DEBUG_LOGGING) + debug_decl(vlog_warning, SUDOERS_DEBUG_LOGGING) /* Need extra copy of ap for sudo_vwarn()/sudo_vwarnx() below. */ va_copy(ap2, ap); @@ -513,10 +519,15 @@ vlog_warning(int flags, const char *fmt, va_list ap) goto done; } + if (ISSET(flags, SLOG_USE_ERRNO)) + errstr = strerror(errnum); + else if (ISSET(flags, SLOG_GAI_ERRNO)) + errstr = gai_strerror(errnum); + /* Log to debug file. */ - if (SLOG_USE_ERRNO) { + if (errstr != NULL) { sudo_debug_printf2(NULL, NULL, 0, - SUDO_DEBUG_WARN|SUDO_DEBUG_ERRNO|sudo_debug_subsys, "%s", message); + SUDO_DEBUG_WARN|sudo_debug_subsys, "%s: %s", message, errstr); } else { sudo_debug_printf2(NULL, NULL, 0, SUDO_DEBUG_WARN|sudo_debug_subsys, "%s", message); @@ -525,7 +536,7 @@ vlog_warning(int flags, const char *fmt, va_list ap) if (ISSET(flags, SLOG_RAW_MSG)) { logline = message; } else { - logline = new_logline(message, ISSET(flags, SLOG_USE_ERRNO) ? serrno : 0); + logline = new_logline(message, errstr); free(message); if (logline == NULL) { ret = false; @@ -577,10 +588,12 @@ vlog_warning(int flags, const char *fmt, va_list ap) sudo_warnx_nodebug("%s", message); free(message); } else { - errno = serrno; - if (ISSET(flags, SLOG_USE_ERRNO)) + if (ISSET(flags, SLOG_USE_ERRNO)) { + errno = errnum; sudo_vwarn_nodebug(_(fmt), ap2); - else + } else if (ISSET(flags, SLOG_GAI_ERRNO)) { + sudo_gai_vwarn_nodebug(errnum, _(fmt), ap2); + } else sudo_vwarnx_nodebug(_(fmt), ap2); } } @@ -597,11 +610,11 @@ log_warning(int flags, const char *fmt, ...) { va_list ap; bool ret; - debug_decl(log_error, SUDOERS_DEBUG_LOGGING) + debug_decl(log_warning, SUDOERS_DEBUG_LOGGING) /* Log the error. */ va_start(ap, fmt); - ret = vlog_warning(flags|SLOG_USE_ERRNO, fmt, ap); + ret = vlog_warning(flags|SLOG_USE_ERRNO, errno, fmt, ap); va_end(ap); debug_return_bool(ret); @@ -612,16 +625,32 @@ log_warningx(int flags, const char *fmt, ...) { va_list ap; bool ret; - debug_decl(log_error, SUDOERS_DEBUG_LOGGING) + debug_decl(log_warningx, SUDOERS_DEBUG_LOGGING) + + /* Log the error. */ + va_start(ap, fmt); + ret = vlog_warning(flags, 0, fmt, ap); + va_end(ap); + + debug_return_bool(ret); +} + +bool +gai_log_warning(int flags, int errnum, const char *fmt, ...) +{ + va_list ap; + bool ret; + debug_decl(gai_log_warning, SUDOERS_DEBUG_LOGGING) /* Log the error. */ va_start(ap, fmt); - ret = vlog_warning(flags, fmt, ap); + ret = vlog_warning(flags|SLOG_GAI_ERRNO, errnum, fmt, ap); va_end(ap); debug_return_bool(ret); } + #define MAX_MAILFLAGS 63 /* @@ -868,9 +897,9 @@ should_mail(int status) * Allocate and fill in a new logline. */ static char * -new_logline(const char *message, int serrno) +new_logline(const char *message, const char *errstr) { - char *line = NULL, *errstr = NULL, *evstr = NULL; + char *line = NULL, *evstr = NULL; #ifndef SUDOERS_NO_SEQ char sessid[7]; #endif @@ -901,10 +930,8 @@ new_logline(const char *message, int serrno) */ if (message != NULL) len += strlen(message) + 3; - if (serrno) { - errstr = strerror(serrno); + if (errstr != NULL) len += strlen(errstr) + 3; - } len += sizeof(LL_TTY_STR) + 2 + strlen(user_tty); len += sizeof(LL_CWD_STR) + 2 + strlen(user_cwd); if (runas_pw != NULL) @@ -951,7 +978,7 @@ new_logline(const char *message, int serrno) strlcat(line, errstr ? " : " : " ; ", len) >= len) goto toobig; } - if (serrno) { + if (errstr != NULL) { if (strlcat(line, errstr, len) >= len || strlcat(line, " ; ", len) >= len) goto toobig; diff --git a/plugins/sudoers/logging.h b/plugins/sudoers/logging.h index 08202b333..c7e99aeed 100644 --- a/plugins/sudoers/logging.h +++ b/plugins/sudoers/logging.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2005, 2009-2017 + * Copyright (c) 1999-2005, 2009-2018 * Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any @@ -37,10 +37,11 @@ /* Flags for log_warning()/log_warningx() */ #define SLOG_USE_ERRNO 0x01 /* internal use only */ -#define SLOG_RAW_MSG 0x02 /* do not format msg before logging */ -#define SLOG_SEND_MAIL 0x04 /* log via mail */ -#define SLOG_NO_STDERR 0x08 /* do not log via stderr */ -#define SLOG_NO_LOG 0x10 /* do not log via file or syslog */ +#define SLOG_GAI_ERRNO 0x02 /* internal use only */ +#define SLOG_RAW_MSG 0x04 /* do not format msg before logging */ +#define SLOG_SEND_MAIL 0x08 /* log via mail */ +#define SLOG_NO_STDERR 0x10 /* do not log via stderr */ +#define SLOG_NO_LOG 0x20 /* do not log via file or syslog */ /* * Maximum number of characters to log per entry. The syslogger @@ -74,6 +75,7 @@ bool log_denial(int status, bool inform_user); bool log_failure(int status, int flags); bool log_warning(int flags, const char *fmt, ...) __printflike(2, 3); bool log_warningx(int flags, const char *fmt, ...) __printflike(2, 3); +bool gai_log_warning(int flags, int errnum, const char *fmt, ...) __printflike(3, 4); bool sudoers_initlocale(const char *ulocale, const char *slocale); bool sudoers_locale_callback(const union sudo_defs_val *); int writeln_wrap(FILE *fp, char *line, size_t len, size_t maxlen); diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index 55822afd8..ffc002cab 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -1010,29 +1010,30 @@ set_loginclass(struct passwd *pw) * Returns true on success, setting longp and shortp. * Returns false on failure, longp and shortp are unchanged. */ -static bool +static int resolve_host(const char *host, char **longp, char **shortp) { struct addrinfo *res0, hint; char *cp, *lname, *sname; + int ret; debug_decl(resolve_host, SUDOERS_DEBUG_PLUGIN) memset(&hint, 0, sizeof(hint)); hint.ai_family = PF_UNSPEC; hint.ai_flags = AI_FQDN; - if (getaddrinfo(host, NULL, &hint, &res0) != 0) - debug_return_bool(false); + if ((ret = getaddrinfo(host, NULL, &hint, &res0)) != 0) + debug_return_int(ret); if ((lname = strdup(res0->ai_canonname)) == NULL) { freeaddrinfo(res0); - debug_return_bool(false); + debug_return_int(EAI_MEMORY); } if ((cp = strchr(lname, '.')) != NULL) { sname = strndup(lname, (size_t)(cp - lname)); if (sname == NULL) { free(lname); freeaddrinfo(res0); - debug_return_bool(false); + debug_return_int(EAI_MEMORY); } } else { sname = lname; @@ -1041,7 +1042,7 @@ resolve_host(const char *host, char **longp, char **shortp) *longp = lname; *shortp = sname; - debug_return_bool(true); + debug_return_bool(0); } /* @@ -1063,9 +1064,10 @@ cb_fqdn(const union sudo_defs_val *sd_un) remote = strcmp(user_runhost, user_host) != 0; /* First resolve user_host, setting user_host and user_shost. */ - if (!resolve_host(user_host, &lhost, &shost)) { - if (!resolve_host(user_runhost, &lhost, &shost)) { - log_warning(SLOG_SEND_MAIL|SLOG_RAW_MSG, + if (resolve_host(user_host, &lhost, &shost) != 0) { + int rc = resolve_host(user_runhost, &lhost, &shost); + if (rc != 0) { + gai_log_warning(SLOG_SEND_MAIL|SLOG_RAW_MSG, rc, N_("unable to resolve host %s"), user_host); debug_return_bool(false); }