mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-22 01:49:11 +00:00
Add simple locale switching to make it easy to switch from the
user's locale to the sudoers locale without making excessive setlocale() calls when we don't need to.
This commit is contained in:
parent
f8660f9988
commit
4207589fe2
1
MANIFEST
1
MANIFEST
@ -184,6 +184,7 @@ plugins/sudoers/iolog_path.c
|
|||||||
plugins/sudoers/ldap.c
|
plugins/sudoers/ldap.c
|
||||||
plugins/sudoers/linux_audit.c
|
plugins/sudoers/linux_audit.c
|
||||||
plugins/sudoers/linux_audit.h
|
plugins/sudoers/linux_audit.h
|
||||||
|
plugins/sudoers/locale.c
|
||||||
plugins/sudoers/logging.c
|
plugins/sudoers/logging.c
|
||||||
plugins/sudoers/logging.h
|
plugins/sudoers/logging.h
|
||||||
plugins/sudoers/logwrap.c
|
plugins/sudoers/logwrap.c
|
||||||
|
@ -129,8 +129,8 @@ LIBPARSESUDOERS_OBJS = alias.lo audit.lo defaults.lo gram.lo match.lo \
|
|||||||
|
|
||||||
SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo env.lo find_path.lo \
|
SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo env.lo find_path.lo \
|
||||||
goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
|
goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
|
||||||
iolog_path.lo logging.lo logwrap.lo parse.lo policy.lo \
|
iolog_path.lo locale.lo logging.lo logwrap.lo parse.lo \
|
||||||
prompt.lo set_perms.lo sudo_nss.lo sudoers.lo \
|
policy.lo prompt.lo set_perms.lo sudo_nss.lo sudoers.lo \
|
||||||
timestamp.lo @SUDOERS_OBJS@
|
timestamp.lo @SUDOERS_OBJS@
|
||||||
|
|
||||||
VISUDO_OBJS = visudo.o goodpath.o find_path.o error.o
|
VISUDO_OBJS = visudo.o goodpath.o find_path.o error.o
|
||||||
@ -613,6 +613,13 @@ linux_audit.lo: $(srcdir)/linux_audit.c $(top_builddir)/config.h \
|
|||||||
$(incdir)/gettext.h $(incdir)/sudo_debug.h \
|
$(incdir)/gettext.h $(incdir)/sudo_debug.h \
|
||||||
$(srcdir)/linux_audit.h
|
$(srcdir)/linux_audit.h
|
||||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(srcdir)/linux_audit.c
|
$(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 \
|
logging.lo: $(srcdir)/logging.c $(top_builddir)/config.h $(srcdir)/sudoers.h \
|
||||||
$(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
|
$(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
|
||||||
$(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
|
$(incdir)/missing.h $(incdir)/error.h $(incdir)/alloc.h \
|
||||||
|
@ -1113,7 +1113,21 @@ sudoers_hook_getenv(const char *name, char **value, void *closure)
|
|||||||
return SUDO_HOOK_RET_NEXT;
|
return SUDO_HOOK_RET_NEXT;
|
||||||
|
|
||||||
in_progress = true;
|
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);
|
*value = sudo_getenv_nodebug(name);
|
||||||
|
done:
|
||||||
in_progress = false;
|
in_progress = false;
|
||||||
return SUDO_HOOK_RET_STOP;
|
return SUDO_HOOK_RET_STOP;
|
||||||
}
|
}
|
||||||
|
83
plugins/sudoers/locale.c
Normal file
83
plugins/sudoers/locale.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* 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 */
|
@ -30,6 +30,12 @@
|
|||||||
#define SLOG_FILE 0x02
|
#define SLOG_FILE 0x02
|
||||||
#define SLOG_BOTH 0x03
|
#define SLOG_BOTH 0x03
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values for sudoers_setlocale()
|
||||||
|
*/
|
||||||
|
#define SUDOERS_LOCALE_USER 0
|
||||||
|
#define SUDOERS_LOCALE_SUDOERS 1
|
||||||
|
|
||||||
/* Flags for log_error()/log_fatal() */
|
/* Flags for log_error()/log_fatal() */
|
||||||
#define MSG_ONLY 0x01
|
#define MSG_ONLY 0x01
|
||||||
#define USE_ERRNO 0x02
|
#define USE_ERRNO 0x02
|
||||||
@ -61,5 +67,6 @@ void log_failure(int status, int flags);
|
|||||||
void log_error(int flags, const char *fmt, ...) __printflike(2, 3);
|
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 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);
|
void writeln_wrap(FILE *fp, char *line, size_t len, size_t maxlen);
|
||||||
|
int sudoers_setlocale(int newlocale, int *prevlocale);
|
||||||
|
|
||||||
#endif /* _LOGGING_H */
|
#endif /* _LOGGING_H */
|
||||||
|
@ -563,6 +563,10 @@ init_vars(char * const envp[])
|
|||||||
(void) tzset(); /* set the timezone if applicable */
|
(void) tzset(); /* set the timezone if applicable */
|
||||||
#endif /* HAVE_TZSET */
|
#endif /* HAVE_TZSET */
|
||||||
|
|
||||||
|
#ifdef HAVE_SETLOCALE
|
||||||
|
user_locale = estrdup(setlocale(LC_ALL, NULL));
|
||||||
|
#endif
|
||||||
|
|
||||||
for (ep = envp; *ep; ep++) {
|
for (ep = envp; *ep; ep++) {
|
||||||
/* XXX - don't fill in if empty string */
|
/* XXX - don't fill in if empty string */
|
||||||
switch (**ep) {
|
switch (**ep) {
|
||||||
|
@ -87,6 +87,7 @@ struct sudo_user {
|
|||||||
#endif
|
#endif
|
||||||
const char *cwd;
|
const char *cwd;
|
||||||
char *iolog_file;
|
char *iolog_file;
|
||||||
|
char *locale;
|
||||||
GETGROUPS_T *gids;
|
GETGROUPS_T *gids;
|
||||||
int ngids;
|
int ngids;
|
||||||
int closefrom;
|
int closefrom;
|
||||||
@ -180,6 +181,7 @@ struct sudo_user {
|
|||||||
#define user_tty (sudo_user.tty)
|
#define user_tty (sudo_user.tty)
|
||||||
#define user_ttypath (sudo_user.ttypath)
|
#define user_ttypath (sudo_user.ttypath)
|
||||||
#define user_cwd (sudo_user.cwd)
|
#define user_cwd (sudo_user.cwd)
|
||||||
|
#define user_locale (sudo_user.locale)
|
||||||
#define user_cmnd (sudo_user.cmnd)
|
#define user_cmnd (sudo_user.cmnd)
|
||||||
#define user_args (sudo_user.cmnd_args)
|
#define user_args (sudo_user.cmnd_args)
|
||||||
#define user_base (sudo_user.cmnd_base)
|
#define user_base (sudo_user.cmnd_base)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user