plugins/sudoers/ldap.c
plugins/sudoers/linux_audit.c
plugins/sudoers/linux_audit.h
+plugins/sudoers/locale.c
plugins/sudoers/logging.c
plugins/sudoers/logging.h
plugins/sudoers/logwrap.c
SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo env.lo find_path.lo \
goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
- iolog_path.lo logging.lo logwrap.lo parse.lo policy.lo \
- prompt.lo set_perms.lo sudo_nss.lo sudoers.lo \
+ iolog_path.lo locale.lo logging.lo logwrap.lo parse.lo \
+ policy.lo prompt.lo set_perms.lo sudo_nss.lo sudoers.lo \
timestamp.lo @SUDOERS_OBJS@
VISUDO_OBJS = visudo.o goodpath.o find_path.o error.o
$(incdir)/gettext.h $(incdir)/sudo_debug.h \
$(srcdir)/linux_audit.h
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(srcdir)/linux_audit.c
+locale.lo: $(srcdir)/locale.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
+ $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+ $(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
+ $(incdir)/list.h $(incdir)/fileops.h $(srcdir)/defaults.h \
+ $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+ $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
+ $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(srcdir)/locale.c
logging.lo: $(srcdir)/logging.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
$(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
$(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
return SUDO_HOOK_RET_NEXT;
in_progress = true;
+
+ /* Hack to make GNU gettext() find the sudoers locale when needed. */
+ if (*name == 'L' && sudoers_getlocale() == SUDOERS_LOCALE_SUDOERS) {
+ if (strcmp(name, "LANGUAGE") == 0 || strcmp(name, "LANG") == 0) {
+ *value = NULL;
+ goto done;
+ }
+ if (strcmp(name, "LC_ALL") == 0 || strcmp(name, "LC_MESSAGES") == 0) {
+ *value = def_sudoers_locale;
+ goto done;
+ }
+ }
+
*value = sudo_getenv_nodebug(name);
+done:
in_progress = false;
return SUDO_HOOK_RET_STOP;
}
--- /dev/null
+/*
+ * Copyright (c) 2012 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_SETLOCALE
+# include <locale.h>
+#endif
+
+#include "sudoers.h"
+
+#ifdef HAVE_SETLOCALE
+
+static int current_locale = SUDOERS_LOCALE_USER;
+
+int
+sudoers_setlocale(int newlocale, int *prevlocale)
+{
+ char *res = NULL;
+
+ switch (newlocale) {
+ case SUDOERS_LOCALE_USER:
+ if (prevlocale)
+ *prevlocale = current_locale;
+ if (current_locale != SUDOERS_LOCALE_USER) {
+ current_locale = SUDOERS_LOCALE_USER;
+ res = setlocale(LC_ALL, user_locale ? user_locale : "");
+ }
+ break;
+ case SUDOERS_LOCALE_SUDOERS:
+ if (prevlocale)
+ *prevlocale = current_locale;
+ if (current_locale != SUDOERS_LOCALE_SUDOERS) {
+ current_locale = SUDOERS_LOCALE_SUDOERS;
+ res = setlocale(LC_ALL, def_sudoers_locale);
+ if (res == NULL) {
+ if (strcmp(def_sudoers_locale, "C") != 0) {
+ efree(def_sudoers_locale);
+ def_sudoers_locale = estrdup("C");
+ res = setlocale(LC_ALL, "C");
+ }
+ }
+ }
+ break;
+ }
+ return res ? 1 : 0;
+}
+#else
+int
+sudoers_setlocale(int newlocale, int *prevlocale)
+{
+ return 1;
+}
+#endif /* HAVE_SETLOCALE */
#define SLOG_FILE 0x02
#define SLOG_BOTH 0x03
+/*
+ * Values for sudoers_setlocale()
+ */
+#define SUDOERS_LOCALE_USER 0
+#define SUDOERS_LOCALE_SUDOERS 1
+
/* Flags for log_error()/log_fatal() */
#define MSG_ONLY 0x01
#define USE_ERRNO 0x02
void log_error(int flags, const char *fmt, ...) __printflike(2, 3);
void log_fatal(int flags, const char *fmt, ...) __printflike(2, 3) __attribute__((__noreturn__));
void writeln_wrap(FILE *fp, char *line, size_t len, size_t maxlen);
+int sudoers_setlocale(int newlocale, int *prevlocale);
#endif /* _LOGGING_H */
(void) tzset(); /* set the timezone if applicable */
#endif /* HAVE_TZSET */
+#ifdef HAVE_SETLOCALE
+ user_locale = estrdup(setlocale(LC_ALL, NULL));
+#endif
+
for (ep = envp; *ep; ep++) {
/* XXX - don't fill in if empty string */
switch (**ep) {
#endif
const char *cwd;
char *iolog_file;
+ char *locale;
GETGROUPS_T *gids;
int ngids;
int closefrom;
#define user_tty (sudo_user.tty)
#define user_ttypath (sudo_user.ttypath)
#define user_cwd (sudo_user.cwd)
+#define user_locale (sudo_user.locale)
#define user_cmnd (sudo_user.cmnd)
#define user_args (sudo_user.cmnd_args)
#define user_base (sudo_user.cmnd_base)