]> granicus.if.org Git - sudo/commitdiff
Allow sudoers programs (visudo, sudoreplay, visudo) to use
authorTodd C. Miller <Todd.Miller@courtesan.com>
Sun, 25 Nov 2012 14:33:52 +0000 (09:33 -0500)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Sun, 25 Nov 2012 14:33:52 +0000 (09:33 -0500)
plugin_error.c instead of the error.c from the front-end.  This
means sudoers_setlocale() needs to be independent of the sudo_user
struct and the defaults table.  The sudoers locale is now updated
via a callback.

plugins/sudoers/Makefile.in
plugins/sudoers/locale.c
plugins/sudoers/logging.h
plugins/sudoers/sudoers.c
plugins/sudoers/sudoers.h
plugins/sudoers/sudoreplay.c
plugins/sudoers/testsudoers.c
plugins/sudoers/visudo.c

index 9999d8da49918c38e5de186f69f7dda7a2828e62..3157b9e8ca5f9b6a7ae417238e49d7b88371e197 100644 (file)
@@ -133,23 +133,23 @@ 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 = visudo.o goodpath.o find_path.o error.o
+VISUDO_OBJS = find_path.o goodpath.o locale.o plugin_error.o visudo.o
 
-REPLAY_OBJS = getdate.o sudoreplay.o error.o
+REPLAY_OBJS = getdate.o locale.o plugin_error.o sudoreplay.o
 
-TEST_OBJS = interfaces.o testsudoers.o tsgetgrpw.o error.o group_plugin.o \
-           net_ifs.o
+TEST_OBJS = group_plugin.o interfaces.o locale.o net_ifs.o plugin_error.o \
+           testsudoers.o tsgetgrpw.o
 
-CHECK_ADDR_OBJS = check_addr.o match_addr.o interfaces.o error.o
+CHECK_ADDR_OBJS = check_addr.o interfaces.o locale.o match_addr.o plugin_error.o
 
-CHECK_FILL_OBJS = check_fill.o toke_util.o error.o
+CHECK_FILL_OBJS = check_fill.o locale.o plugin_error.o toke_util.o
 
-CHECK_IOLOG_PATH_OBJS = check_iolog_path.o error.o iolog_path.o pwutil.o \
-                       pwutil_impl.o redblack.o
+CHECK_IOLOG_PATH_OBJS = check_iolog_path.o iolog_path.o locale.o \
+                       plugin_error.o pwutil.o pwutil_impl.o redblack.o
 
-CHECK_SYMBOLS_OBJS = check_symbols.o error.o
+CHECK_SYMBOLS_OBJS = check_symbols.o locale.o plugin_error.o
 
-CHECK_WRAP_OBJS = check_wrap.o logwrap.o error.o
+CHECK_WRAP_OBJS = check_wrap.o locale.o logwrap.o plugin_error.o
 
 LIBOBJDIR = $(top_builddir)/@ac_config_libobj_dir@/
 
@@ -508,10 +508,6 @@ env.lo: $(srcdir)/env.c $(top_builddir)/config.h $(srcdir)/sudoers.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)/env.c
-error.o: $(top_srcdir)/src/error.c $(top_builddir)/config.h \
-         $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \
-         $(incdir)/gettext.h
-       $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(top_srcdir)/src/error.c
 find_path.lo: $(srcdir)/find_path.c $(top_builddir)/config.h \
               $(srcdir)/sudoers.h $(top_srcdir)/compat/stdbool.h \
               $(top_builddir)/pathnames.h $(incdir)/missing.h \
@@ -684,6 +680,7 @@ plugin_error.lo: $(srcdir)/plugin_error.c $(top_builddir)/config.h \
                  $(incdir)/alloc.h $(incdir)/error.h $(srcdir)/logging.h \
                  $(incdir)/sudo_plugin.h $(incdir)/gettext.h
        $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(DEFS) $(srcdir)/plugin_error.c
+plugin_error.o: plugin_error.lo
 policy.lo: $(srcdir)/policy.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 \
index d0b72dcb94b057cb0f51cb3fb163aa1c63f7e999..4244b2f5247efc8582221591eb8f3bbbef1422fa 100644 (file)
@@ -36,6 +36,8 @@
 #include "sudoers.h"
 
 static int current_locale = SUDOERS_LOCALE_USER;
+static char *user_locale;
+static char *sudoers_locale;
 
 int
 sudoers_getlocale(void)
@@ -43,6 +45,19 @@ sudoers_getlocale(void)
     return current_locale;
 }
 
+void
+sudoers_initlocale(const char *ulocale, const char *slocale)
+{
+    if (ulocale != NULL) {
+       efree(user_locale);
+       user_locale = estrdup(ulocale);
+    }
+    if (slocale != NULL) {
+       efree(sudoers_locale);
+       sudoers_locale = estrdup(slocale);
+    }
+}
+
 /*
  * Set locale to user or sudoers value.
  * Returns true on success and false on failure,
@@ -61,6 +76,8 @@ sudoers_setlocale(int newlocale, int *prevlocale)
            if (current_locale != SUDOERS_LOCALE_USER) {
                current_locale = SUDOERS_LOCALE_USER;
                res = setlocale(LC_ALL, user_locale ? user_locale : "");
+               if (res != NULL && user_locale == NULL)
+                   user_locale = estrdup(setlocale(LC_ALL, NULL));
            }
            break;
        case SUDOERS_LOCALE_SUDOERS:
@@ -68,11 +85,11 @@ sudoers_setlocale(int newlocale, int *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, sudoers_locale ? sudoers_locale : "C");
+               if (res == NULL && sudoers_locale != NULL) {
+                   if (strcmp(sudoers_locale, "C") != 0) {
+                       efree(sudoers_locale);
+                       sudoers_locale = estrdup("C");
                        res = setlocale(LC_ALL, "C");
                    }
                }
index f89a1ed269cd82603be552879c992c7b001f523c..e3f4efd8bb53d3a88cb289148d3a3fd4cb0c7686 100644 (file)
@@ -68,6 +68,7 @@ void log_denial(int status, bool inform_user);
 void log_failure(int status, int flags);
 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 sudoers_initlocale(const char *ulocale, const char *slocale);
 void writeln_wrap(FILE *fp, char *line, size_t len, size_t maxlen);
 
 #endif /* _LOGGING_H */
index 314fc05eb3ae5dd8fbc67e363608c9f2fe84c2f6..7184a3b13c41c9ba6080d9500f08e729ea0052d2 100644 (file)
@@ -85,6 +85,7 @@
  */
 static char *find_editor(int nfiles, char **files, char ***argv_out);
 static int cb_runas_default(const char *);
+static int cb_sudoers_locale(const char *);
 static int set_cmnd(void);
 static void create_admin_success_flag(void);
 static void init_vars(char * const *);
@@ -548,7 +549,7 @@ init_vars(char * const envp[])
     (void) tzset();            /* set the timezone if applicable */
 #endif /* HAVE_TZSET */
 
-    user_locale = estrdup(setlocale(LC_ALL, NULL));
+    sudoers_initlocale(setlocale(LC_ALL, NULL), def_sudoers_locale);
 
     for (ep = envp; *ep; ep++) {
        /* XXX - don't fill in if empty string */
@@ -600,6 +601,9 @@ init_vars(char * const envp[])
     /* Set runas callback. */
     sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default;
 
+    /* Set locale callback. */
+    sudo_defs_table[I_SUDOERS_LOCALE].callback = cb_sudoers_locale;
+
     /* It is now safe to use log_fatal() and set_perms() */
     debug_return;
 }
@@ -897,6 +901,17 @@ cb_runas_default(const char *user)
     return true;
 }
 
+/*
+/*
+ * Callback for sudoers_locale sudoers setting.
+ */
+static int
+cb_sudoers_locale(const char *locale)
+{
+    sudoers_initlocale(NULL, locale);
+    return true;
+}
+
 /*
  * Cleanup hook for error()/errorx()
  */
index a6572d57333c742d034e1ddb8c1dcb5df3ab5712..8f230021030bbc9ec3815a6c85c45739e0e5145d 100644 (file)
@@ -88,7 +88,6 @@ struct sudo_user {
 #endif
     const char *cwd;
     char *iolog_file;
-    char *locale;
     GETGROUPS_T *gids;
     int   ngids;
     int   closefrom;
@@ -182,7 +181,6 @@ struct sudo_user {
 #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)
index 81c2c2c7bf5ae32e1423a503772ba525e049a34d..4f715cdc853e2d33cc5ed415cc6b53ea51fb5b65 100644 (file)
@@ -95,6 +95,7 @@
 #include "alloc.h"
 #include "error.h"
 #include "gettext.h"
+#include "logging.h"
 #include "sudo_plugin.h"
 #include "sudo_conf.h"
 #include "sudo_debug.h"
@@ -201,7 +202,7 @@ extern char *get_timestr(time_t, int);
 extern int term_raw(int, int);
 extern int term_restore(int, int);
 extern void get_ttysize(int *rowp, int *colp);
-void cleanup(int);
+void sudoers_cleanup(int);
 
 static int list_sessions(int, char **, const char *, const char *, const char *);
 static int parse_expr(struct search_node **, char **);
@@ -263,7 +264,7 @@ main(int argc, char *argv[])
     setprogname(argc > 0 ? argv[0] : "sudoreplay");
 #endif
 
-    setlocale(LC_ALL, "");
+    sudoers_setlocale(SUDOERS_LOCALE_USER, NULL);
     decimal = localeconv()->decimal_point;
     bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have sudoreplay domain */
     textdomain("sudoers");
@@ -377,7 +378,7 @@ main(int argc, char *argv[])
     memset(&sa, 0, sizeof(sa));
     sigemptyset(&sa.sa_mask);
     sa.sa_flags = SA_RESETHAND;
-    sa.sa_handler = cleanup;
+    sa.sa_handler = sudoers_cleanup;
     (void) sigaction(SIGINT, &sa, NULL);
     (void) sigaction(SIGKILL, &sa, NULL);
     (void) sigaction(SIGTERM, &sa, NULL);
@@ -1207,7 +1208,7 @@ help(void)
  * Cleanup hook for error()/errorx()
   */
 void
-cleanup(int signo)
+sudoers_cleanup(int signo)
 {
     term_restore(STDIN_FILENO, 0);
     if (signo)
index 81498b011d5f9c7894052043617efea16fa5787c..ba503925c05ddfed1f72a7c4748bfc6d36d916cf 100644 (file)
@@ -78,7 +78,7 @@ void print_defaults(void);
 void print_privilege(struct privilege *);
 void print_userspecs(void);
 void usage(void) __attribute__((__noreturn__));
-void cleanup(int);
+void sudoers_cleanup(int);
 static void set_runaspw(const char *);
 static void set_runasgr(const char *);
 static int cb_runas_default(const char *);
@@ -148,7 +148,7 @@ main(int argc, char *argv[])
     setprogname(argc > 0 ? argv[0] : "testsudoers");
 #endif
 
-    setlocale(LC_ALL, "");
+    sudoers_setlocale(SUDOERS_LOCALE_USER, NULL);
     bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have own domain */
     textdomain("sudoers");
 
@@ -469,7 +469,7 @@ restore_perms(void)
 }
 
 void
-cleanup(int gotsignal)
+sudoers_cleanup(int gotsignal)
 {
     if (!gotsignal) {
        sudo_endpwent();
index f7893c031aead54856f04d30421e9da336214026..45015050eaa1933d3388a6ed8acf9aee7f2c16af 100644 (file)
@@ -112,7 +112,7 @@ static void setup_signals(void);
 static void help(void) __attribute__((__noreturn__));
 static void usage(int);
 
-void cleanup(int);
+void sudoers_cleanup(int);
 
 extern void sudoerserror(const char *);
 extern void sudoersrestart(FILE *);
@@ -161,7 +161,7 @@ main(int argc, char *argv[])
     setprogname(argc > 0 ? argv[0] : "visudo");
 #endif
 
-    setlocale(LC_ALL, "");
+    sudoers_setlocale(SUDOERS_LOCALE_USER, NULL);
     bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have visudo domain */
     textdomain("sudoers");
 
@@ -510,7 +510,7 @@ reparse_sudoers(char *editor, char *args, bool strict, bool quiet)
                case 'Q' :      parse_error = false;    /* ignore parse error */
                                break;
                case 'x' :      /* XXX - should return instead of exiting */
-                               cleanup(0);
+                               sudoers_cleanup(0);
                                sudo_debug_exit_int(__func__, __FILE__,
                                    __LINE__, sudo_debug_subsys, 0);
                                exit(0);
@@ -1254,7 +1254,7 @@ print_unused(void *v1, void *v2)
  * Unlink any sudoers temp files that remain.
  */
 void
-cleanup(int gotsignal)
+sudoers_cleanup(int gotsignal)
 {
     struct sudoersfile *sp;
 
@@ -1276,7 +1276,7 @@ quit(int signo)
 {
     const char *signame, *myname;
 
-    cleanup(signo);
+    sudoers_cleanup(signo);
 #define        emsg     " exiting due to signal: "
     myname = getprogname();
     signame = strsignal(signo);