diff --git a/NEWS b/NEWS index fe3c02032..0e1396946 100644 --- a/NEWS +++ b/NEWS @@ -71,6 +71,10 @@ What's new in Sudo 1.7.5? after validating the command so the sudoers entries do not need to include the backslashes. + * Logging and email sending are now done in the locale specified + by the "sudoers_locale" setting ("C" by default). Email send by + sudo now includes MIME headers when "sudoers_locale" is not "C". + What's new in Sudo 1.7.4p6? * A bug has been fixed in the I/O logging support that could cause diff --git a/config.h.in b/config.h.in index d2ea6c43b..a6b115615 100644 --- a/config.h.in +++ b/config.h.in @@ -352,6 +352,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NETGROUP_H +/* Define to 1 if you have the `nl_langinfo' function. */ +#undef HAVE_NL_LANGINFO + /* Define to 1 if you have the `openpty' function. */ #undef HAVE_OPENPTY diff --git a/configure b/configure index 5e0b3a3e9..6ce85ae14 100755 --- a/configure +++ b/configure @@ -15003,7 +15003,8 @@ fi LIBS=$ac_save_LIBS for ac_func in strrchr sysconf tzset strftime initgroups getgroups fstat \ - regcomp setlocale getaddrinfo mbr_check_membership setrlimit64 + regcomp setlocale nl_langinfo getaddrinfo mbr_check_membership \ + setrlimit64 do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" diff --git a/configure.in b/configure.in index d0409c44f..59c9bad07 100644 --- a/configure.in +++ b/configure.in @@ -1943,7 +1943,8 @@ dnl Function checks dnl AC_FUNC_GETGROUPS AC_CHECK_FUNCS(strrchr sysconf tzset strftime initgroups getgroups fstat \ - regcomp setlocale getaddrinfo mbr_check_membership setrlimit64) + regcomp setlocale nl_langinfo getaddrinfo mbr_check_membership \ + setrlimit64) AC_CHECK_FUNCS(getline, [], [ AC_LIBOBJ(getline) AC_CHECK_FUNCS(fgetln) diff --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c index d550d5030..b93f4e56b 100644 --- a/plugins/sudoers/logging.c +++ b/plugins/sudoers/logging.c @@ -47,6 +47,12 @@ #ifdef HAVE_UNISTD_H # include #endif /* HAVE_UNISTD_H */ +#ifdef HAVE_SETLOCALE +# include +#endif /* HAVE_SETLOCALE */ +#ifdef HAVE_NL_LANGINFO +# include +#endif /* HAVE_NL_LANGINFO */ #include #include #include @@ -122,6 +128,12 @@ do_syslog(int pri, char *msg) char *p, *tmp, save; const char *fmt; +#ifdef HAVE_SETLOCALE + const char *old_locale = estrdup(setlocale(LC_ALL, NULL)); + if (!setlocale(LC_ALL, def_sudoers_locale)) + setlocale(LC_ALL, "C"); +#endif /* HAVE_SETLOCALE */ + /* * Log the full line, breaking into multiple syslog(3) calls if necessary */ @@ -156,6 +168,11 @@ do_syslog(int pri, char *msg) fmt = FMT_CONTD; maxlen = MAXSYSLOGLEN - (sizeof(FMT_CONTD) - 6 + strlen(user_name)); } + +#ifdef HAVE_SETLOCALE + setlocale(LC_ALL, old_locale); + efree((void *)old_locale); +#endif /* HAVE_SETLOCALE */ } static void @@ -178,6 +195,12 @@ do_logfile(char *msg) } else { time_t now; +#ifdef HAVE_SETLOCALE + const char *old_locale = estrdup(setlocale(LC_ALL, NULL)); + if (!setlocale(LC_ALL, def_sudoers_locale)) + setlocale(LC_ALL, "C"); +#endif /* HAVE_SETLOCALE */ + now = time(NULL); if (def_loglinelen == 0) { /* Don't pretty-print long log file lines (hard to grep) */ @@ -247,6 +270,11 @@ do_logfile(char *msg) (void) fflush(fp); (void) lock_file(fileno(fp), SUDO_UNLOCK); (void) fclose(fp); + +#ifdef HAVE_SETLOCALE + setlocale(LC_ALL, old_locale); + efree((void *)old_locale); +#endif /* HAVE_SETLOCALE */ } } @@ -410,7 +438,7 @@ send_mail(const char *fmt, ...) "USER=root", NULL }; -#endif +#endif /* NO_ROOT_MAILER */ /* Just return if mailer is disabled. */ if (!def_mailerpath || !def_mailto) @@ -456,6 +484,14 @@ send_mail(const char *fmt, ...) (void) dup2(fd, STDERR_FILENO); } +#ifdef HAVE_SETLOCALE + if (!setlocale(LC_ALL, def_sudoers_locale)) { + setlocale(LC_ALL, "C"); + efree(def_sudoers_locale); + def_sudoers_locale = estrdup("C"); + } +#endif /* HAVE_SETLOCALE */ + /* Close password, group and other fds so we don't leak. */ sudo_endpwent(); sudo_endgrent(); @@ -552,6 +588,11 @@ send_mail(const char *fmt, ...) (void) fputc(*p, mail); } +#ifdef HAVE_NL_LANGINFO + if (strcmp(def_sudoers_locale, "C") != 0) + (void) fprintf(mail, "\nContent-Type: text/plain; charset=\"%s\"\nContent-Transfer-Encoding: 8bit", nl_langinfo(CODESET)); +#endif /* HAVE_NL_LANGINFO */ + (void) fprintf(mail, "\n\n%s : %s : %s : ", user_host, get_timestr(time(NULL), def_log_year), user_name); va_start(ap, fmt);