]> granicus.if.org Git - sudo/commitdiff
Call gettext inside log_error et al instead of having the caller do it. This way...
authorTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 8 Nov 2012 20:37:44 +0000 (15:37 -0500)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 8 Nov 2012 20:37:44 +0000 (15:37 -0500)
15 files changed:
plugins/sudoers/auth/bsdauth.c
plugins/sudoers/auth/kerb5.c
plugins/sudoers/auth/pam.c
plugins/sudoers/auth/sia.c
plugins/sudoers/auth/sudo_auth.c
plugins/sudoers/check.c
plugins/sudoers/env.c
plugins/sudoers/iolog.c
plugins/sudoers/locale.c
plugins/sudoers/logging.c
plugins/sudoers/logging.h
plugins/sudoers/parse.c
plugins/sudoers/set_perms.c
plugins/sudoers/sudoers.c
plugins/sudoers/timestamp.c

index 3597e56eeecb286cd0b2e0975adbcebcfca8da65..e2cbb05819953a7348badcafb71576f4141df200 100644 (file)
@@ -75,13 +75,13 @@ bsdauth_init(struct passwd *pw, sudo_auth *auth)
        state.lc = login_getclass(pw->pw_uid ? LOGIN_DEFCLASS : LOGIN_DEFROOTCLASS);
     if (state.lc == NULL) {
        log_error(USE_ERRNO|NO_MAIL,
-           _("unable to get login class for user %s"), pw->pw_name);
+           N_("unable to get login class for user %s"), pw->pw_name);
        debug_return_int(AUTH_FATAL);
     }
 
     if ((state.as = auth_open()) == NULL) {
        log_error(USE_ERRNO|NO_MAIL,
-           _("unable to begin bsd authentication"));
+           N_("unable to begin bsd authentication"));
        login_close(state.lc);
        debug_return_int(AUTH_FATAL);
     }
@@ -89,7 +89,7 @@ bsdauth_init(struct passwd *pw, sudo_auth *auth)
     /* XXX - maybe sanity check the auth style earlier? */
     login_style = login_getstyle(state.lc, login_style, "auth-sudo");
     if (login_style == NULL) {
-       log_error(NO_MAIL, _("invalid authentication type"));
+       log_error(NO_MAIL, N_("invalid authentication type"));
        auth_close(state.as);
        login_close(state.lc);
        debug_return_int(AUTH_FATAL);
@@ -98,7 +98,7 @@ bsdauth_init(struct passwd *pw, sudo_auth *auth)
      if (auth_setitem(state.as, AUTHV_STYLE, login_style) < 0 ||
        auth_setitem(state.as, AUTHV_NAME, pw->pw_name) < 0 ||
        auth_setitem(state.as, AUTHV_CLASS, login_class) < 0) {
-       log_error(NO_MAIL, _("unable to setup authentication"));
+       log_error(NO_MAIL, N_("unable to setup authentication"));
        auth_close(state.as);
        login_close(state.lc);
        debug_return_int(AUTH_FATAL);
index ab47c190c83304105177e10b5b34bab46efe3e51..0ccdb0e75d627a21f8fc005aebeb68b836af8a92 100644 (file)
@@ -114,7 +114,7 @@ sudo_krb5_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
         */
        if ((error = krb5_unparse_name(sudo_context, princ, &pname))) {
            log_error(NO_MAIL,
-                     _("%s: unable to unparse princ ('%s'): %s"), auth->name,
+                     N_("%s: unable to unparse princ ('%s'): %s"), auth->name,
                      pw->pw_name, error_message(error));
            debug_return_int(AUTH_FAILURE);
        }
@@ -157,7 +157,7 @@ sudo_krb5_init(struct passwd *pw, sudo_auth *auth)
     error = krb5_parse_name(sudo_context, pname, &(sudo_krb5_data.princ));
     if (error) {
        log_error(NO_MAIL,
-                 _("%s: unable to parse '%s': %s"), auth->name, pname,
+                 N_("%s: unable to parse '%s': %s"), auth->name, pname,
                  error_message(error));
        goto done;
     }
@@ -167,7 +167,7 @@ sudo_krb5_init(struct passwd *pw, sudo_auth *auth)
     if ((error = krb5_cc_resolve(sudo_context, cache_name,
        &(sudo_krb5_data.ccache)))) {
        log_error(NO_MAIL,
-                 _("%s: unable to resolve ccache: %s"), auth->name,
+                 N_("%s: unable to resolve ccache: %s"), auth->name,
                  error_message(error));
        goto done;
     }
@@ -215,7 +215,7 @@ sudo_krb5_verify(struct passwd *pw, char *pass, sudo_auth *auth)
     error = krb5_get_init_creds_opt_alloc(sudo_context, &opts);
     if (error) {
        log_error(NO_MAIL,
-                 _("%s: unable to allocate options: %s"), auth->name,
+                 N_("%s: unable to allocate options: %s"), auth->name,
                  error_message(error));
        goto done;
     }
@@ -231,7 +231,7 @@ sudo_krb5_verify(struct passwd *pw, char *pass, sudo_auth *auth)
        /* Don't print error if just a bad password */
        if (error != KRB5KRB_AP_ERR_BAD_INTEGRITY)
            log_error(NO_MAIL,
-                     _("%s: unable to get credentials: %s"), auth->name,
+                     N_("%s: unable to get credentials: %s"), auth->name,
                      error_message(error));
        goto done;
     }
@@ -244,11 +244,11 @@ sudo_krb5_verify(struct passwd *pw, char *pass, sudo_auth *auth)
     /* Store cred in cred cache. */
     if ((error = krb5_cc_initialize(sudo_context, ccache, princ))) {
        log_error(NO_MAIL,
-                 _("%s: unable to initialize ccache: %s"), auth->name,
+                 N_("%s: unable to initialize ccache: %s"), auth->name,
                  error_message(error));
     } else if ((error = krb5_cc_store_cred(sudo_context, ccache, creds))) {
        log_error(NO_MAIL,
-                 _("%s: unable to store cred in ccache: %s"), auth->name,
+                 N_("%s: unable to store cred in ccache: %s"), auth->name,
                  error_message(error));
     }
 
@@ -313,7 +313,7 @@ verify_krb_v5_tgt(krb5_context sudo_context, krb5_creds *cred, char *auth_name)
     if ((error = krb5_sname_to_principal(sudo_context, NULL, NULL,
                                        KRB5_NT_SRV_HST, &server))) {
        log_error(NO_MAIL,
-                 _("%s: unable to get host principal: %s"), auth_name,
+                 N_("%s: unable to get host principal: %s"), auth_name,
                  error_message(error));
        debug_return_int(-1);
     }
@@ -328,7 +328,7 @@ verify_krb_v5_tgt(krb5_context sudo_context, krb5_creds *cred, char *auth_name)
     krb5_free_principal(sudo_context, server);
     if (error)
        log_error(NO_MAIL,
-                 _("%s: Cannot verify TGT! Possible attack!: %s"),
+                 N_("%s: Cannot verify TGT! Possible attack!: %s"),
                  auth_name, error_message(error));
     debug_return_int(error);
 }
index 0ede540880dfe909dcaf1d858fc5b6c049255907..6ec97c6cec4c478b83ebc8ff88cecb638fed2466 100644 (file)
@@ -97,7 +97,7 @@ sudo_pam_init(struct passwd *pw, sudo_auth *auth)
 #endif
        pam_status = pam_start("sudo", pw->pw_name, &pam_conv, &pamh);
     if (pam_status != PAM_SUCCESS) {
-       log_error(USE_ERRNO|NO_MAIL, _("unable to initialize PAM"));
+       log_error(USE_ERRNO|NO_MAIL, N_("unable to initialize PAM"));
        debug_return_int(AUTH_FATAL);
     }
 
@@ -141,26 +141,26 @@ sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
                case PAM_SUCCESS:
                    debug_return_int(AUTH_SUCCESS);
                case PAM_AUTH_ERR:
-                   log_error(NO_MAIL, _("account validation failure, "
+                   log_error(NO_MAIL, N_("account validation failure, "
                        "is your account locked?"));
                    debug_return_int(AUTH_FATAL);
                case PAM_NEW_AUTHTOK_REQD:
-                   log_error(NO_MAIL, _("Account or password is "
+                   log_error(NO_MAIL, N_("Account or password is "
                        "expired, reset your password and try again"));
                    *pam_status = pam_chauthtok(pamh,
                        PAM_CHANGE_EXPIRED_AUTHTOK);
                    if (*pam_status == PAM_SUCCESS)
                        debug_return_int(AUTH_SUCCESS);
                    if ((s = pam_strerror(pamh, *pam_status)))
-                       log_error(NO_MAIL, _("pam_chauthtok: %s"), s);
+                       log_error(NO_MAIL, N_("pam_chauthtok: %s"), s);
                    debug_return_int(AUTH_FAILURE);
                case PAM_AUTHTOK_EXPIRED:
                    log_error(NO_MAIL,
-                       _("Password expired, contact your system administrator"));
+                       N_("Password expired, contact your system administrator"));
                    debug_return_int(AUTH_FATAL);
                case PAM_ACCT_EXPIRED:
                    log_error(NO_MAIL,
-                       _("Account expired or PAM config lacks an \"account\" "
+                       N_("Account expired or PAM config lacks an \"account\" "
                        "section for sudo, contact your system administrator"));
                    debug_return_int(AUTH_FATAL);
            }
@@ -177,7 +177,7 @@ sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth)
            debug_return_int(AUTH_FAILURE);
        default:
            if ((s = pam_strerror(pamh, *pam_status)))
-               log_error(NO_MAIL, _("pam_authenticate: %s"), s);
+               log_error(NO_MAIL, N_("pam_authenticate: %s"), s);
            debug_return_int(AUTH_FATAL);
     }
 }
index d9f685e17e7b8e0502498ac87470c644e636f338..a9f847edaa6023f76fe239574ad3d078254da5f2 100644 (file)
@@ -106,7 +106,7 @@ sudo_sia_setup(struct passwd *pw, char **promptp, sudo_auth *auth)
     if (sia_ses_init(&siah, sudo_argc, sudo_argv, NULL, pw->pw_name, user_ttypath, 1, NULL) != SIASUCCESS) {
 
        log_error(USE_ERRNO|NO_MAIL,
-           _("unable to initialize SIA session"));
+           N_("unable to initialize SIA session"));
        debug_return_int(AUTH_FATAL);
     }
 
index 79bb12543330966b11fdfe3d8bb5af2bc0f1dba0..e23954221b0cd0b4ce108c8dca62576a4708b6c4 100644 (file)
@@ -118,7 +118,7 @@ sudo_auth_init(struct passwd *pw)
     standalone = IS_STANDALONE(&auth_switch[0]);
     if (standalone && auth_switch[1].name != NULL) {
        audit_failure(NewArgv, N_("invalid authentication methods"));
-       log_fatal(0, _("Invalid authentication methods compiled into sudo!  "
+       log_fatal(0, N_("Invalid authentication methods compiled into sudo!  "
            "You may mix standalone and non-standalone authentication."));
        debug_return_int(-1);
     }
@@ -203,7 +203,7 @@ verify_user(struct passwd *pw, char *prompt, int validated)
     if (auth_switch[0].name == NULL) {
        audit_failure(NewArgv, N_("no authentication methods"));
        log_error(0,
-           _("There are no authentication methods compiled into sudo!  "
+           N_("There are no authentication methods compiled into sudo!  "
            "If you want to turn off authentication, use the "
            "--disable-authentication configure option."));
        debug_return_int(-1);
index 978dad2c01d6fd8d1e3cd6017e28a9aac452dc8b..cb2e35679e8e16c73a9403798fa0dca5e732a302 100644 (file)
@@ -208,13 +208,13 @@ get_authpw(void)
 
     if (def_rootpw) {
        if ((pw = sudo_getpwuid(ROOT_UID)) == NULL)
-           log_fatal(0, _("unknown uid: %u"), ROOT_UID);
+           log_fatal(0, N_("unknown uid: %u"), ROOT_UID);
     } else if (def_runaspw) {
        if ((pw = sudo_getpwnam(def_runas_default)) == NULL)
-           log_fatal(0, _("unknown user: %s"), def_runas_default);
+           log_fatal(0, N_("unknown user: %s"), def_runas_default);
     } else if (def_targetpw) {
        if (runas_pw->pw_name == NULL)
-           log_fatal(NO_MAIL|MSG_ONLY, _("unknown uid: %u"),
+           log_fatal(NO_MAIL|MSG_ONLY, N_("unknown uid: %u"),
                (unsigned int) runas_pw->pw_uid);
        sudo_pw_addref(runas_pw);
        pw = runas_pw;
index 3307366e24fb5a2e0a8800a722b395ab4b0f5045..ca0b0f4223d4f89f87f16888cef7994648dc812b 100644 (file)
@@ -1010,7 +1010,7 @@ validate_env_vars(char * const env_vars[])
     if (bad != NULL) {
        bad[blen - 2] = '\0';           /* remove trailing ", " */
        log_fatal(NO_MAIL,
-           _("sorry, you are not allowed to set the following environment variables: %s"), bad);
+           N_("sorry, you are not allowed to set the following environment variables: %s"), bad);
        /* NOTREACHED */
        efree(bad);
     }
index 4332d035bc1c47053a3ba7944ce6834f7f24e258..bd526caa554b0a30f277cd816784a45f6d946188 100644 (file)
@@ -119,9 +119,9 @@ mkdir_parents(char *path)
        *slash = '\0';
        if (stat(path, &sb) != 0) {
            if (mkdir(path, S_IRWXU) != 0)
-               log_fatal(USE_ERRNO, _("unable to mkdir %s"), path);
+               log_fatal(USE_ERRNO, N_("unable to mkdir %s"), path);
        } else if (!S_ISDIR(sb.st_mode)) {
-           log_fatal(0, _("%s: %s"), path, strerror(ENOTDIR));
+           log_fatal(0, N_("%s: %s"), path, strerror(ENOTDIR));
        }
        *slash = '/';
     }
@@ -152,9 +152,9 @@ io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7])
     mkdir_parents(iolog_dir);
     if (stat(iolog_dir, &sb) != 0) {
        if (mkdir(iolog_dir, S_IRWXU) != 0)
-           log_fatal(USE_ERRNO, _("unable to mkdir %s"), iolog_dir);
+           log_fatal(USE_ERRNO, N_("unable to mkdir %s"), iolog_dir);
     } else if (!S_ISDIR(sb.st_mode)) {
-       log_fatal(0, _("%s exists but is not a directory (0%o)"),
+       log_fatal(0, N_("%s exists but is not a directory (0%o)"),
            iolog_dir, (unsigned int) sb.st_mode);
     }
 
@@ -168,7 +168,7 @@ io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7])
     }
     fd = open(pathbuf, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
     if (fd == -1)
-       log_fatal(USE_ERRNO, _("unable to open %s"), pathbuf);
+       log_fatal(USE_ERRNO, N_("unable to open %s"), pathbuf);
     lock_file(fd, SUDO_LOCK);
 
     /*
@@ -201,10 +201,10 @@ io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7])
        nread = read(fd, buf, sizeof(buf));
        if (nread != 0) {
            if (nread == -1)
-               log_fatal(USE_ERRNO, _("unable to read %s"), pathbuf);
+               log_fatal(USE_ERRNO, N_("unable to read %s"), pathbuf);
            id = strtoul(buf, &ep, 36);
            if (buf == ep || id >= SESSID_MAX)
-               log_fatal(0, _("invalid sequence number %s"), pathbuf);
+               log_fatal(0, N_("invalid sequence number %s"), pathbuf);
        }
     }
     id++;
@@ -225,7 +225,7 @@ io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7])
 
     /* Rewind and overwrite old seq file. */
     if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1 || write(fd, buf, 7) != 7)
-       log_fatal(USE_ERRNO, _("unable to write to %s"), pathbuf);
+       log_fatal(USE_ERRNO, N_("unable to write to %s"), pathbuf);
     close(fd);
 
     debug_return;
@@ -254,10 +254,10 @@ mkdir_iopath(const char *iolog_path, char *pathbuf, size_t pathsize)
     mkdir_parents(pathbuf);
     if (len >= 6 && strcmp(&pathbuf[len - 6], "XXXXXX") == 0) {
        if (mkdtemp(pathbuf) == NULL)
-           log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
+           log_fatal(USE_ERRNO, N_("unable to create %s"), pathbuf);
     } else {
        if (mkdir(pathbuf, S_IRWXU) != 0)
-           log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
+           log_fatal(USE_ERRNO, N_("unable to create %s"), pathbuf);
     }
 
     debug_return_size_t(len);
@@ -522,18 +522,18 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
      */
     io_logfile = open_io_fd(pathbuf, len, "/log", false);
     if (io_logfile == NULL)
-       log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
+       log_fatal(USE_ERRNO, N_("unable to create %s"), pathbuf);
 
     io_fds[IOFD_TIMING].v = open_io_fd(pathbuf, len, "/timing",
        iolog_compress);
     if (io_fds[IOFD_TIMING].v == NULL)
-       log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
+       log_fatal(USE_ERRNO, N_("unable to create %s"), pathbuf);
 
     if (details.iolog_ttyin) {
        io_fds[IOFD_TTYIN].v = open_io_fd(pathbuf, len, "/ttyin",
            iolog_compress);
        if (io_fds[IOFD_TTYIN].v == NULL)
-           log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
+           log_fatal(USE_ERRNO, N_("unable to create %s"), pathbuf);
     } else {
        sudoers_io.log_ttyin = NULL;
     }
@@ -541,7 +541,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
        io_fds[IOFD_STDIN].v = open_io_fd(pathbuf, len, "/stdin",
            iolog_compress);
        if (io_fds[IOFD_STDIN].v == NULL)
-           log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
+           log_fatal(USE_ERRNO, N_("unable to create %s"), pathbuf);
     } else {
        sudoers_io.log_stdin = NULL;
     }
@@ -549,7 +549,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
        io_fds[IOFD_TTYOUT].v = open_io_fd(pathbuf, len, "/ttyout",
            iolog_compress);
        if (io_fds[IOFD_TTYOUT].v == NULL)
-           log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
+           log_fatal(USE_ERRNO, N_("unable to create %s"), pathbuf);
     } else {
        sudoers_io.log_ttyout = NULL;
     }
@@ -557,7 +557,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
        io_fds[IOFD_STDOUT].v = open_io_fd(pathbuf, len, "/stdout",
            iolog_compress);
        if (io_fds[IOFD_STDOUT].v == NULL)
-           log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
+           log_fatal(USE_ERRNO, N_("unable to create %s"), pathbuf);
     } else {
        sudoers_io.log_stdout = NULL;
     }
@@ -565,7 +565,7 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
        io_fds[IOFD_STDERR].v = open_io_fd(pathbuf, len, "/stderr",
            iolog_compress);
        if (io_fds[IOFD_STDERR].v == NULL)
-           log_fatal(USE_ERRNO, _("unable to create %s"), pathbuf);
+           log_fatal(USE_ERRNO, N_("unable to create %s"), pathbuf);
     } else {
        sudoers_io.log_stderr = NULL;
     }
index 771b963c73485cd1f25aff9345dd9ebb6d5720dd..e82bb3ece5eeb1d57205b8aa0055ca09df3266e3 100644 (file)
 
 static int current_locale = SUDOERS_LOCALE_USER;
 
+int
+sudoers_getlocale(void)
+{
+    return current_locale;
+}
+
 int
 sudoers_setlocale(int newlocale, int *prevlocale)
 {
index b6b265dcb8dafd3e0936d0f839959cef9f251e83..7e5288323fc00632534c42947aba79d0f582a86e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994-1996, 1998-2011 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1994-1996, 1998-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
 
 #include "sudoers.h"
 
+#ifndef va_copy
+# define va_copy(d, s) memcpy(&(d), &(s), sizeof(d));
+#endif
+
+/* Special message for log_error() so we know to use ngettext() */
+#define INCORRECT_PASSWORD_ATTEMPT     ((char *)0x01)
+
 static void do_syslog(int, char *);
 static void do_logfile(char *);
 static void send_mail(const char *fmt, ...);
@@ -235,15 +242,20 @@ do_logfile(char *msg)
 void
 log_denial(int status, bool inform_user)
 {
-    char *logline, *message;
+    const char *message;
+    char *logline;
+    int oldlocale;
     debug_decl(log_denial, SUDO_DEBUG_LOGGING)
 
-    /* Handle auditing first. */
+    /* Handle auditing first (audit_failure() handles the locale itself). */
     if (ISSET(status, FLAG_NO_USER | FLAG_NO_HOST))
        audit_failure(NewArgv, N_("No user or host"));
     else
        audit_failure(NewArgv, N_("validation failure"));
 
+    /* Log and mail messages should be in the sudoers locale. */
+    sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
+
     /* Set error message. */
     if (ISSET(status, FLAG_NO_USER))
        message = _("user NOT in sudoers");
@@ -257,8 +269,23 @@ log_denial(int status, bool inform_user)
     if (should_mail(status))
        send_mail("%s", logline);       /* send mail based on status */
 
-    /* Inform the user if they failed to authenticate.  */
+    /*
+     * Log via syslog and/or a file.
+     */
+    if (def_syslog)
+       do_syslog(def_syslog_badpri, logline);
+    if (def_logfile)
+       do_logfile(logline);
+
+    efree(logline);
+
+    /* Restore locale. */
+    sudoers_setlocale(oldlocale, NULL);
+
+    /* Inform the user if they failed to authenticate (in their locale).  */
     if (inform_user) {
+       sudoers_setlocale(SUDOERS_LOCALE_USER, &oldlocale);
+
        if (ISSET(status, FLAG_NO_USER)) {
            sudo_printf(SUDO_CONV_ERROR_MSG, _("%s is not in the sudoers "
                "file.  This incident will be reported.\n"), user_name);
@@ -278,17 +305,8 @@ log_denial(int status, bool inform_user)
                runas_pw->pw_name : user_name, runas_gr ? ":" : "",
                runas_gr ? runas_gr->gr_name : "", user_host);
        }
+       sudoers_setlocale(oldlocale, NULL);
     }
-
-    /*
-     * Log via syslog and/or a file.
-     */
-    if (def_syslog)
-       do_syslog(def_syslog_badpri, logline);
-    if (def_logfile)
-       do_logfile(logline);
-
-    efree(logline);
     debug_return;
 }
 
@@ -357,12 +375,10 @@ log_auth_failure(int status, int tries)
     /*
      * If sudoers denied the command we'll log that separately.
      */
-    if (ISSET(status, FLAG_BAD_PASSWORD)) {
-       log_error(flags, ngettext("%d incorrect password attempt",
-           "%d incorrect password attempts", tries), tries);
-    } else if (ISSET(status, FLAG_NON_INTERACTIVE)) {
-       log_error(flags, _("a password is required"));
-    }
+    if (ISSET(status, FLAG_BAD_PASSWORD))
+       log_error(flags, INCORRECT_PASSWORD_ATTEMPT, tries);
+    else if (ISSET(status, FLAG_NON_INTERACTIVE))
+       log_error(flags, N_("a password is required"));
 
     debug_return;
 }
@@ -399,32 +415,36 @@ log_allowed(int status)
 static void
 vlog_error(int flags, const char *fmt, va_list ap)
 {
-    int serrno = errno;
+    int oldlocale, serrno = errno;
     char *logline, *message;
+    va_list ap2;
     debug_decl(vlog_error, SUDO_DEBUG_LOGGING)
 
-    /* Expand printf-style format + args. */
-    evasprintf(&message, fmt, ap);
-
     /* Become root if we are not already to avoid user interference */
     set_perms(PERM_ROOT|PERM_NOEXIT);
 
-    if (ISSET(flags, MSG_ONLY))
-       logline = message;
-    else
-       logline = new_logline(message, ISSET(flags, USE_ERRNO) ? serrno : 0);
+    /* Need extra copy of ap for warning() below. */
+    if (!ISSET(flags, NO_STDERR))
+       va_copy(ap2, ap);
 
-    /*
-     * Tell the user.
-     */
-    if (!ISSET(flags, NO_STDERR)) {
-       if (ISSET(flags, USE_ERRNO))
-           warning("%s", message);
-       else
-           warningx("%s", message);
+    /* Log messages should be in the sudoers locale. */
+    sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
+
+    /* Expand printf-style format + args (with a special case). */
+    if (fmt == INCORRECT_PASSWORD_ATTEMPT) {
+       int tries = va_arg(ap, int);
+       easprintf(&message, ngettext("%d incorrect password attempt",
+           "%d incorrect password attempts", tries), tries);
+    } else {
+       evasprintf(&message, _(fmt), ap);
     }
-    if (logline != message)
+
+    if (ISSET(flags, MSG_ONLY)) {
+       logline = message;
+    } else {
+       logline = new_logline(message, ISSET(flags, USE_ERRNO) ? serrno : 0);
         efree(message);
+    }
 
     /*
      * Send a copy of the error via mail.
@@ -444,8 +464,27 @@ vlog_error(int flags, const char *fmt, va_list ap)
 
     efree(logline);
 
+    sudoers_setlocale(oldlocale, NULL);
+
     restore_perms();
 
+    /*
+     * Tell the user (in their locale).
+     */
+    if (!ISSET(flags, NO_STDERR)) {
+       if (fmt == INCORRECT_PASSWORD_ATTEMPT) {
+           int tries = va_arg(ap2, int);
+           warningx(ngettext("%d incorrect password attempt",
+               "%d incorrect password attempts", tries), tries);
+       } else {
+           if (ISSET(flags, USE_ERRNO))
+               vwarning(fmt, ap2);
+           else
+               vwarningx(fmt, ap2);
+       }
+       va_end(ap2);
+    }
+
     debug_return;
 }
 
index bed13f252bab133c24ff0c82a2088cb8f2c77614..290839a10098a4841ebf7396d41f99aa44b0fa37 100644 (file)
@@ -68,5 +68,6 @@ 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);
+int sudoers_getlocale(void);
 
 #endif /* _LOGGING_H */
index 7172ea9a378dcf105021e533d99b87d758e8cb92..f5addf0a649e5322d25e7404c0caf301f84c361e 100644 (file)
@@ -120,10 +120,10 @@ sudo_file_parse(struct sudo_nss *nss)
     sudoersin = nss->handle;
     if (sudoersparse() != 0 || parse_error) {
        if (errorlineno != -1) {
-           log_error(0, _("parse error in %s near line %d"),
+           log_error(0, N_("parse error in %s near line %d"),
                errorfile, errorlineno);
        } else {
-           log_error(0, _("parse error in %s"), errorfile);
+           log_error(0, N_("parse error in %s"), errorfile);
        }
        debug_return_int(-1);
     }
index be665dae326791cafc4aa45858d1b07caa49ea17..d91640ab40eae3f871217310b867ce4d2a71470f 100644 (file)
@@ -1539,7 +1539,7 @@ runas_setgroups(void)
     aix_restoreauthdb();
 #endif
     if (sudo_setgroups(grlist->ngids, grlist->gids) < 0)
-       log_fatal(USE_ERRNO|MSG_ONLY, _("unable to set runas group vector"));
+       log_fatal(USE_ERRNO|MSG_ONLY, N_("unable to set runas group vector"));
     debug_return_ptr(grlist);
 }
 #endif /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
index d37863f47ce115e09a90231e669870ca65e695b0..a76f12055327cb983ca5a2ca68f25e825b13817d 100644 (file)
@@ -162,7 +162,7 @@ sudoers_policy_init(void *info, char * const envp[])
         if (nss->open(nss) == 0 && nss->parse(nss) == 0) {
             sources++;
             if (nss->setdefs(nss) != 0)
-                log_error(NO_STDERR, _("problem with defaults entries"));
+                log_error(NO_STDERR, N_("problem with defaults entries"));
         } else {
             tq_remove(snl, nss);
         }
@@ -196,7 +196,7 @@ sudoers_policy_init(void *info, char * const envp[])
        set_runaspw(runas_user ? runas_user : def_runas_default);
 
     if (!update_defaults(SETDEF_RUNAS))
-       log_error(NO_STDERR, _("problem with defaults entries"));
+       log_error(NO_STDERR, N_("problem with defaults entries"));
 
     if (def_fqdn)
        set_fqdn();     /* deferred until after sudoers is parsed */
@@ -333,7 +333,7 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
            timestamp_uid = pw->pw_uid;
            sudo_pw_delref(pw);
        } else {
-           log_error(0, _("timestamp owner (%s): No such user"),
+           log_error(0, N_("timestamp owner (%s): No such user"),
                def_timestampowner);
            timestamp_uid = ROOT_UID;
        }
@@ -595,7 +595,7 @@ init_vars(char * const envp[])
 
            /* Need to make a fake struct passwd for the call to log_fatal(). */
            sudo_user.pw = sudo_fakepwnamid(user_name, user_uid, user_gid);
-           log_fatal(0, _("unknown uid: %u"), (unsigned int) user_uid);
+           log_fatal(0, N_("unknown uid: %u"), (unsigned int) user_uid);
            /* NOTREACHED */
        }
     }
@@ -694,7 +694,7 @@ set_cmnd(void)
        user_base = user_cmnd;
 
     if (!update_defaults(SETDEF_CMND))
-       log_error(NO_STDERR, _("problem with defaults entries"));
+       log_error(NO_STDERR, N_("problem with defaults entries"));
 
     debug_return_int(rval);
 }
@@ -729,10 +729,10 @@ open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
             * the user with a reasonable error message (unlike the lexer).
             */
            if ((fp = fopen(sudoers, "r")) == NULL) {
-               log_error(USE_ERRNO, _("unable to open %s"), sudoers);
+               log_error(USE_ERRNO, N_("unable to open %s"), sudoers);
            } else {
                if (sb.st_size != 0 && fgetc(fp) == EOF) {
-                   log_error(USE_ERRNO, _("unable to read %s"),
+                   log_error(USE_ERRNO, N_("unable to read %s"),
                        sudoers);
                    fclose(fp);
                    fp = NULL;
@@ -744,20 +744,20 @@ open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
            }
            break;
        case SUDO_PATH_MISSING:
-           log_error(USE_ERRNO, _("unable to stat %s"), sudoers);
+           log_error(USE_ERRNO, N_("unable to stat %s"), sudoers);
            break;
        case SUDO_PATH_BAD_TYPE:
-           log_error(0, _("%s is not a regular file"), sudoers);
+           log_error(0, N_("%s is not a regular file"), sudoers);
            break;
        case SUDO_PATH_WRONG_OWNER:
-           log_error(0, _("%s is owned by uid %u, should be %u"),
+           log_error(0, N_("%s is owned by uid %u, should be %u"),
                sudoers, (unsigned int) sb.st_uid, (unsigned int) sudoers_uid);
            break;
        case SUDO_PATH_WORLD_WRITABLE:
-           log_error(0, _("%s is world writable"), sudoers);
+           log_error(0, N_("%s is world writable"), sudoers);
            break;
        case SUDO_PATH_GROUP_WRITABLE:
-           log_error(0, _("%s is owned by gid %u, should be %u"),
+           log_error(0, N_("%s is owned by gid %u, should be %u"),
                sudoers, (unsigned int) sb.st_gid, (unsigned int) sudoers_gid);
            break;
        default:
@@ -801,9 +801,9 @@ set_loginclass(struct passwd *pw)
         * corrupted we want the admin to be able to use sudo to fix it.
         */
        if (login_class)
-           log_fatal(errflags, _("unknown login class: %s"), login_class);
+           log_fatal(errflags, N_("unknown login class: %s"), login_class);
        else
-           log_error(errflags, _("unknown login class: %s"), login_class);
+           log_error(errflags, N_("unknown login class: %s"), login_class);
        def_use_loginclass = false;
     }
     login_close(lc);
@@ -835,7 +835,7 @@ set_fqdn(void)
     hint.ai_family = PF_UNSPEC;
     hint.ai_flags = AI_FQDN;
     if (getaddrinfo(user_host, NULL, &hint, &res0) != 0) {
-       log_error(MSG_ONLY, _("unable to resolve host %s"), user_host);
+       log_error(MSG_ONLY, N_("unable to resolve host %s"), user_host);
     } else {
        if (user_shost != user_host)
            efree(user_shost);
@@ -866,7 +866,7 @@ set_runaspw(const char *user)
            runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0);
     } else {
        if ((runas_pw = sudo_getpwnam(user)) == NULL)
-           log_fatal(NO_MAIL|MSG_ONLY, _("unknown user: %s"), user);
+           log_fatal(NO_MAIL|MSG_ONLY, N_("unknown user: %s"), user);
     }
     debug_return;
 }
@@ -887,7 +887,7 @@ set_runasgr(const char *group)
            runas_gr = sudo_fakegrnam(group);
     } else {
        if ((runas_gr = sudo_getgrnam(group)) == NULL)
-           log_fatal(NO_MAIL|MSG_ONLY, _("unknown group: %s"), group);
+           log_fatal(NO_MAIL|MSG_ONLY, N_("unknown group: %s"), group);
     }
     debug_return;
 }
index b4fc4bc2146865891e4c549d7a9d2f40df4a5af5..84f1f2cef8835882ac7f61f925f157cb5228ba5a 100644 (file)
@@ -125,7 +125,7 @@ build_timestamp(void)
 
     debug_return_int(len);
 bad:
-    log_fatal(0, _("timestamp path too long: %s"),
+    log_fatal(0, N_("timestamp path too long: %s"),
        *timestampfile ? timestampfile : timestampdir);
     /* NOTREACHED */
     debug_return_int(-1);
@@ -151,17 +151,17 @@ update_timestamp(void)
         */
        int fd = open(timestampfile, O_WRONLY|O_CREAT, 0600);
        if (fd == -1)
-           log_error(USE_ERRNO, _("unable to open %s"), timestampfile);
+           log_error(USE_ERRNO, N_("unable to open %s"), timestampfile);
        else {
            lock_file(fd, SUDO_LOCK);
            if (write(fd, &tty_info, sizeof(tty_info)) != sizeof(tty_info))
-               log_error(USE_ERRNO, _("unable to write to %s"), timestampfile);
+               log_error(USE_ERRNO, N_("unable to write to %s"), timestampfile);
            close(fd);
        }
     } else {
        if (touch(-1, timestampdir, NULL) == -1) {
            if (mkdir(timestampdir, 0700) == -1) {
-               log_error(USE_ERRNO, _("unable to mkdir %s"),
+               log_error(USE_ERRNO, N_("unable to mkdir %s"),
                    timestampdir);
            }
        }
@@ -196,15 +196,15 @@ timestamp_status_internal(bool removing)
      */
     if (lstat(dirparent, &sb) == 0) {
        if (!S_ISDIR(sb.st_mode))
-           log_error(0, _("%s exists but is not a directory (0%o)"),
+           log_error(0, N_("%s exists but is not a directory (0%o)"),
                dirparent, (unsigned int) sb.st_mode);
        else if (sb.st_uid != timestamp_uid)
-           log_error(0, _("%s owned by uid %u, should be uid %u"),
+           log_error(0, N_("%s owned by uid %u, should be uid %u"),
                dirparent, (unsigned int) sb.st_uid,
                (unsigned int) timestamp_uid);
        else if ((sb.st_mode & 0000022))
            log_error(0,
-               _("%s writable by non-owner (0%o), should be mode 0700"),
+               N_("%s writable by non-owner (0%o), should be mode 0700"),
                dirparent, (unsigned int) sb.st_mode);
        else {
            if ((sb.st_mode & 0000777) != 0700)
@@ -212,12 +212,12 @@ timestamp_status_internal(bool removing)
            status = TS_MISSING;
        }
     } else if (errno != ENOENT) {
-       log_error(USE_ERRNO, _("unable to stat %s"), dirparent);
+       log_error(USE_ERRNO, N_("unable to stat %s"), dirparent);
     } else {
        /* No dirparent, try to make one. */
        if (!removing) {
            if (mkdir(dirparent, S_IRWXU))
-               log_error(USE_ERRNO, _("unable to mkdir %s"),
+               log_error(USE_ERRNO, N_("unable to mkdir %s"),
                    dirparent);
            else
                status = TS_MISSING;
@@ -240,15 +240,15 @@ timestamp_status_internal(bool removing)
                if (unlink(timestampdir) == 0)
                    status = TS_MISSING;
            } else
-               log_error(0, _("%s exists but is not a directory (0%o)"),
+               log_error(0, N_("%s exists but is not a directory (0%o)"),
                    timestampdir, (unsigned int) sb.st_mode);
        } else if (sb.st_uid != timestamp_uid)
-           log_error(0, _("%s owned by uid %u, should be uid %u"),
+           log_error(0, N_("%s owned by uid %u, should be uid %u"),
                timestampdir, (unsigned int) sb.st_uid,
                (unsigned int) timestamp_uid);
        else if ((sb.st_mode & 0000022))
            log_error(0,
-               _("%s writable by non-owner (0%o), should be mode 0700"),
+               N_("%s writable by non-owner (0%o), should be mode 0700"),
                timestampdir, (unsigned int) sb.st_mode);
        else {
            if ((sb.st_mode & 0000777) != 0700)
@@ -256,7 +256,7 @@ timestamp_status_internal(bool removing)
            status = TS_OLD;            /* do date check later */
        }
     } else if (errno != ENOENT) {
-       log_error(USE_ERRNO, _("unable to stat %s"), timestampdir);
+       log_error(USE_ERRNO, N_("unable to stat %s"), timestampdir);
     } else
        status = TS_MISSING;
 
@@ -267,7 +267,7 @@ timestamp_status_internal(bool removing)
     if (status == TS_MISSING && *timestampfile && !removing) {
        if (mkdir(timestampdir, S_IRWXU) == -1) {
            status = TS_ERROR;
-           log_error(USE_ERRNO, _("unable to mkdir %s"), timestampdir);
+           log_error(USE_ERRNO, N_("unable to mkdir %s"), timestampdir);
        }
     }
 
@@ -282,19 +282,19 @@ timestamp_status_internal(bool removing)
        if (lstat(timestampfile, &sb) == 0) {
            if (!S_ISREG(sb.st_mode)) {
                status = TS_ERROR;
-               log_error(0, _("%s exists but is not a regular file (0%o)"),
+               log_error(0, N_("%s exists but is not a regular file (0%o)"),
                    timestampfile, (unsigned int) sb.st_mode);
            } else {
                /* If bad uid or file mode, complain and kill the bogus file. */
                if (sb.st_uid != timestamp_uid) {
                    log_error(0,
-                       _("%s owned by uid %u, should be uid %u"),
+                       N_("%s owned by uid %u, should be uid %u"),
                        timestampfile, (unsigned int) sb.st_uid,
                        (unsigned int) timestamp_uid);
                    (void) unlink(timestampfile);
                } else if ((sb.st_mode & 0000022)) {
                    log_error(0,
-                       _("%s writable by non-owner (0%o), should be mode 0600"),
+                       N_("%s writable by non-owner (0%o), should be mode 0600"),
                        timestampfile, (unsigned int) sb.st_mode);
                    (void) unlink(timestampfile);
                } else {
@@ -324,7 +324,7 @@ timestamp_status_internal(bool removing)
                }
            }
        } else if (errno != ENOENT) {
-           log_error(USE_ERRNO, _("unable to stat %s"), timestampfile);
+           log_error(USE_ERRNO, N_("unable to stat %s"), timestampfile);
            status = TS_ERROR;
        }
     }
@@ -348,7 +348,7 @@ timestamp_status_internal(bool removing)
                if (mtime.tv_sec > now + 60 * def_timestamp_timeout * 2) {
                    time_t tv_sec = (time_t)mtime.tv_sec;
                    log_error(0,
-                       _("timestamp too far in the future: %20.20s"),
+                       N_("timestamp too far in the future: %20.20s"),
                        4 + ctime(&tv_sec));
                    if (*timestampfile)
                        (void) unlink(timestampfile);
@@ -400,7 +400,7 @@ remove_timestamp(bool remove)
                status = rmdir(timestampdir);
            if (status == -1 && errno != ENOENT) {
                log_error(0,
-                   _("unable to remove %s (%s), will reset to the epoch"),
+                   N_("unable to remove %s (%s), will reset to the epoch"),
                    path, strerror(errno));
                remove = false;
            }