Call gettext inside log_error et al instead of having the caller do it. This way we can display any messages to the user in their own locale but log in the sudoers local.
This commit is contained in:
@@ -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);
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -42,6 +42,12 @@
|
||||
|
||||
static int current_locale = SUDOERS_LOCALE_USER;
|
||||
|
||||
int
|
||||
sudoers_getlocale(void)
|
||||
{
|
||||
return current_locale;
|
||||
}
|
||||
|
||||
int
|
||||
sudoers_setlocale(int newlocale, int *prevlocale)
|
||||
{
|
||||
|
@@ -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
|
||||
@@ -61,6 +61,13 @@
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
@@ -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 */
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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 */
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user