From: Todd C. Miller Date: Fri, 22 Jul 2016 16:41:56 +0000 (-0600) Subject: Update defaults in visudo after sudoers has been edited so we pick X-Git-Tag: SUDO_1_8_18^2~105 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=256ca993b9ada7c067f0bb9915ecfdc36581583b;p=sudo Update defaults in visudo after sudoers has been edited so we pick up locale changes. The init_defaults() function will now re-init the sudoers locale. --- diff --git a/plugins/sudoers/defaults.c b/plugins/sudoers/defaults.c index 139f3867f..044ad74dd 100644 --- a/plugins/sudoers/defaults.c +++ b/plugins/sudoers/defaults.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2005, 2007-2015 + * Copyright (c) 1999-2005, 2007-2016 * Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any @@ -205,7 +205,7 @@ dump_defaults(void) * This is only meaningful for variables that are *optional*. */ bool -set_default(const char *var, const char *val, int op) +set_default(const char *var, const char *val, int op, bool quiet) { struct sudo_defs_types *cur; int num; @@ -216,28 +216,33 @@ set_default(const char *var, const char *val, int op) break; } if (!cur->name) { - sudo_warnx(U_("unknown defaults entry `%s'"), var); + if (!quiet) + sudo_warnx(U_("unknown defaults entry `%s'"), var); debug_return_bool(false); } switch (cur->type & T_MASK) { case T_LOGFAC: if (!store_syslogfac(val, cur, op)) { - if (val) - sudo_warnx(U_("value `%s' is invalid for option `%s'"), - val, var); - else - sudo_warnx(U_("no value specified for `%s'"), var); + if (!quiet) { + if (val) + sudo_warnx(U_("value `%s' is invalid for option `%s'"), + val, var); + else + sudo_warnx(U_("no value specified for `%s'"), var); + } debug_return_bool(false); } break; case T_LOGPRI: if (!store_syslogpri(val, cur, op)) { - if (val) - sudo_warnx(U_("value `%s' is invalid for option `%s'"), - val, var); - else - sudo_warnx(U_("no value specified for `%s'"), var); + if (!quiet) { + if (val) + sudo_warnx(U_("value `%s' is invalid for option `%s'"), + val, var); + else + sudo_warnx(U_("no value specified for `%s'"), var); + } debug_return_bool(false); } break; @@ -245,12 +250,14 @@ set_default(const char *var, const char *val, int op) if (!val) { /* Check for bogus boolean usage or lack of a value. */ if (!ISSET(cur->type, T_BOOL) || op != false) { - sudo_warnx(U_("no value specified for `%s'"), var); + if (!quiet) + sudo_warnx(U_("no value specified for `%s'"), var); debug_return_bool(false); } } if (ISSET(cur->type, T_PATH) && val && *val != '/') { - sudo_warnx(U_("values for `%s' must start with a '/'"), var); + if (!quiet) + sudo_warnx(U_("values for `%s' must start with a '/'"), var); debug_return_bool(false); } switch (store_str(val, cur, op)) { @@ -258,7 +265,10 @@ set_default(const char *var, const char *val, int op) /* OK */ break; case false: - sudo_warnx(U_("value `%s' is invalid for option `%s'"), val, var); + if (!quiet) { + sudo_warnx(U_("value `%s' is invalid for option `%s'"), + val, var); + } /* FALLTHROUGH */ default: debug_return_bool(false); @@ -268,12 +278,16 @@ set_default(const char *var, const char *val, int op) if (!val) { /* Check for bogus boolean usage or lack of a value. */ if (!ISSET(cur->type, T_BOOL) || op != false) { - sudo_warnx(U_("no value specified for `%s'"), var); + if (!quiet) + sudo_warnx(U_("no value specified for `%s'"), var); debug_return_bool(false); } } if (!store_int(val, cur, op)) { - sudo_warnx(U_("value `%s' is invalid for option `%s'"), val, var); + if (!quiet) { + sudo_warnx(U_("value `%s' is invalid for option `%s'"), + val, var); + } debug_return_bool(false); } break; @@ -281,12 +295,16 @@ set_default(const char *var, const char *val, int op) if (!val) { /* Check for bogus boolean usage or lack of a value. */ if (!ISSET(cur->type, T_BOOL) || op != false) { - sudo_warnx(U_("no value specified for `%s'"), var); + if (!quiet) + sudo_warnx(U_("no value specified for `%s'"), var); debug_return_bool(false); } } if (!store_uint(val, cur, op)) { - sudo_warnx(U_("value `%s' is invalid for option `%s'"), val, var); + if (!quiet) { + sudo_warnx(U_("value `%s' is invalid for option `%s'"), + val, var); + } debug_return_bool(false); } break; @@ -294,12 +312,16 @@ set_default(const char *var, const char *val, int op) if (!val) { /* Check for bogus boolean usage or lack of a value. */ if (!ISSET(cur->type, T_BOOL) || op != false) { - sudo_warnx(U_("no value specified for `%s'"), var); + if (!quiet) + sudo_warnx(U_("no value specified for `%s'"), var); debug_return_bool(false); } } if (!store_float(val, cur, op)) { - sudo_warnx(U_("value `%s' is invalid for option `%s'"), val, var); + if (!quiet) { + sudo_warnx(U_("value `%s' is invalid for option `%s'"), + val, var); + } debug_return_bool(false); } break; @@ -307,18 +329,23 @@ set_default(const char *var, const char *val, int op) if (!val) { /* Check for bogus boolean usage or lack of a value. */ if (!ISSET(cur->type, T_BOOL) || op != false) { - sudo_warnx(U_("no value specified for `%s'"), var); + if (!quiet) + sudo_warnx(U_("no value specified for `%s'"), var); debug_return_bool(false); } } if (!store_mode(val, cur, op)) { - sudo_warnx(U_("value `%s' is invalid for option `%s'"), val, var); + if (!quiet) { + sudo_warnx(U_("value `%s' is invalid for option `%s'"), + val, var); + } debug_return_bool(false); } break; case T_FLAG: if (val) { - sudo_warnx(U_("option `%s' does not take a value"), var); + if (!quiet) + sudo_warnx(U_("option `%s' does not take a value"), var); debug_return_bool(false); } cur->sd_un.flag = op; @@ -329,22 +356,30 @@ set_default(const char *var, const char *val, int op) if (!val) { /* Check for bogus boolean usage or lack of a value. */ if (!ISSET(cur->type, T_BOOL) || op != false) { - sudo_warnx(U_("no value specified for `%s'"), var); + if (!quiet) + sudo_warnx(U_("no value specified for `%s'"), var); debug_return_bool(false); } } if (!store_list(val, cur, op)) { - sudo_warnx(U_("value `%s' is invalid for option `%s'"), val, var); + if (!quiet) { + sudo_warnx(U_("value `%s' is invalid for option `%s'"), + val, var); + } debug_return_bool(false); } break; case T_TUPLE: if (!val && !ISSET(cur->type, T_BOOL)) { - sudo_warnx(U_("no value specified for `%s'"), var); + if (!quiet) + sudo_warnx(U_("no value specified for `%s'"), var); debug_return_bool(false); } if (!store_tuple(val, cur, op)) { - sudo_warnx(U_("value `%s' is invalid for option `%s'"), val, var); + if (!quiet) { + sudo_warnx(U_("value `%s' is invalid for option `%s'"), + val, var); + } debug_return_bool(false); } break; @@ -526,6 +561,10 @@ init_defaults(void) def_set_utmp = true; def_pam_setcred = true; + /* Reset the locale. */ + if (!firsttime) + sudoers_initlocale(NULL, def_sudoers_locale); + /* Finally do the lists (currently just environment tables). */ if (!init_envtables()) goto oom; @@ -581,7 +620,7 @@ default_type_matches(struct defaults *def, int what) * Pass in an OR'd list of which default types to update. */ bool -update_defaults(int what) +update_defaults(int what, bool quiet) { struct early_default *early; struct defaults *def; @@ -609,7 +648,7 @@ update_defaults(int what) } for (early = early_defaults; early->var != NULL; early++) { if (early->val != NULL) { - if (!set_default(early->var, early->val, early->op)) + if (!set_default(early->var, early->val, early->op, quiet)) rc = false; early->val = NULL; /* clean state for next run */ } @@ -629,7 +668,7 @@ update_defaults(int what) if (!default_type_matches(def, what)) continue; - if (!set_default(def->var, def->val, def->op)) + if (!set_default(def->var, def->val, def->op, quiet)) rc = false; } debug_return_bool(rc); diff --git a/plugins/sudoers/defaults.h b/plugins/sudoers/defaults.h index 33c382e7c..06a5d607c 100644 --- a/plugins/sudoers/defaults.h +++ b/plugins/sudoers/defaults.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2005, 2008-2013 + * Copyright (c) 1999-2005, 2008-2016 * Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any @@ -113,8 +113,8 @@ struct sudo_defs_types { */ void dump_default(void); bool init_defaults(void); -bool set_default(const char *var, const char *val, int op); -bool update_defaults(int what); +bool set_default(const char *var, const char *val, int op, bool quiet); +bool update_defaults(int what, bool quiet); bool check_defaults(int what, bool quiet); extern struct sudo_defs_types sudo_defs_table[]; diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c index f745a9c79..400c1f421 100644 --- a/plugins/sudoers/ldap.c +++ b/plugins/sudoers/ldap.c @@ -1094,16 +1094,16 @@ sudo_ldap_parse_options(LDAP *ld, LDAPMessage *entry) ep[-1] = '\0'; } } - set_default(var, val, op); + set_default(var, val, op, false); } else if (*var == '!') { /* case !var Boolean False */ do { var++; } while (isblank((unsigned char)*var)); - set_default(var, NULL, false); + set_default(var, NULL, false, false); } else { /* case var Boolean True */ - set_default(var, NULL, true); + set_default(var, NULL, true, false); } free(copy); } diff --git a/plugins/sudoers/parse.c b/plugins/sudoers/parse.c index d79caac2f..d35188ecc 100644 --- a/plugins/sudoers/parse.c +++ b/plugins/sudoers/parse.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2005, 2007-2015 Todd C. Miller + * Copyright (c) 2004-2005, 2007-2016 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -132,7 +132,7 @@ sudo_file_setdefs(struct sudo_nss *nss) if (nss->handle == NULL) debug_return_int(-1); - if (!update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER)) + if (!update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER, false)) debug_return_int(-1); debug_return_int(0); } diff --git a/plugins/sudoers/sssd.c b/plugins/sudoers/sssd.c index 1f3096238..ff3c8f95d 100644 --- a/plugins/sudoers/sssd.c +++ b/plugins/sudoers/sssd.c @@ -1176,16 +1176,16 @@ sudo_sss_parse_options(struct sudo_sss_handle *handle, struct sss_sudo_rule *rul ep[-1] = '\0'; } } - set_default(v, val, op); + set_default(v, val, op, false); } else if (*v == '!') { /* case !var Boolean False */ do { v++; } while (isblank((unsigned char)*v)); - set_default(v, NULL, false); + set_default(v, NULL, false, false); } else { /* case var Boolean True */ - set_default(v, NULL, true); + set_default(v, NULL, true, false); } free(copy); } diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index 62bff2dae..da44135df 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -233,7 +233,7 @@ sudoers_policy_init(void *info, char * const envp[]) goto cleanup; } - if (!update_defaults(SETDEF_RUNAS)) { + if (!update_defaults(SETDEF_RUNAS, false)) { log_warningx(SLOG_SEND_MAIL|SLOG_NO_STDERR, N_("problem with defaults entries")); } @@ -862,7 +862,7 @@ set_cmnd(void) else user_base = user_cmnd; - if (!update_defaults(SETDEF_CMND)) { + if (!update_defaults(SETDEF_CMND, false)) { log_warningx(SLOG_SEND_MAIL|SLOG_NO_STDERR, N_("problem with defaults entries")); } diff --git a/plugins/sudoers/testsudoers.c b/plugins/sudoers/testsudoers.c index 6068bf4fc..ecaa59f9d 100644 --- a/plugins/sudoers/testsudoers.c +++ b/plugins/sudoers/testsudoers.c @@ -270,7 +270,7 @@ main(int argc, char *argv[]) (void) fputs("Parses OK", stdout); } - if (!update_defaults(SETDEF_ALL)) + if (!update_defaults(SETDEF_ALL, false)) (void) fputs(" (problem with defaults entries)", stdout); puts("."); diff --git a/plugins/sudoers/visudo.c b/plugins/sudoers/visudo.c index e8d090606..3ef2a0b5c 100644 --- a/plugins/sudoers/visudo.c +++ b/plugins/sudoers/visudo.c @@ -241,7 +241,7 @@ main(int argc, char *argv[]) init_parser(sudoers_file, false); sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale); (void) sudoersparse(); - (void) update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER); + (void) update_defaults(SETDEF_GENERIC|SETDEF_HOST, true); sudoers_setlocale(oldlocale, NULL); editor = get_editor(&editor_argc, &editor_argv); @@ -554,6 +554,7 @@ reparse_sudoers(char *editor, int editor_argc, char **editor_argv, struct sudoersfile *sp, *last; FILE *fp; int ch, oldlocale; + bool ok; debug_decl(reparse_sudoers, SUDOERS_DEBUG_UTIL) /* @@ -580,11 +581,13 @@ reparse_sudoers(char *editor, int editor_argc, char **editor_argv, parse_error = true; errorfile = sp->path; } + ok = update_defaults(SETDEF_GENERIC|SETDEF_HOST, quiet); + if (!check_defaults(SETDEF_ALL & ~(SETDEF_GENERIC|SETDEF_HOST), quiet)) + ok = false; sudoers_setlocale(oldlocale, NULL); fclose(sudoersin); if (!parse_error) { - if (!check_defaults(SETDEF_ALL, quiet) || - check_aliases(strict, quiet) != 0) { + if (!ok || check_aliases(strict, quiet) != 0) { parse_error = true; errorfile = NULL; } @@ -898,6 +901,7 @@ static bool check_syntax(const char *sudoers_file, bool quiet, bool strict, bool oldperms) { bool ok = false; + int oldlocale; debug_decl(check_syntax, SUDOERS_DEBUG_UTIL) if (strcmp(sudoers_file, "-") == 0) { @@ -908,7 +912,10 @@ check_syntax(const char *sudoers_file, bool quiet, bool strict, bool oldperms) sudo_warn(U_("unable to open %s"), sudoers_file); goto done; } + if (!init_defaults()) + sudo_fatalx(U_("unable to initialize sudoers default values")); init_parser(sudoers_file, quiet); + sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale); if (sudoersparse() && !parse_error) { if (!quiet) sudo_warnx(U_("failed to parse %s file, unknown error"), sudoers_file); @@ -916,12 +923,14 @@ check_syntax(const char *sudoers_file, bool quiet, bool strict, bool oldperms) errorfile = sudoers_file; } if (!parse_error) { - if (!check_defaults(SETDEF_ALL, quiet) || - check_aliases(strict, quiet) != 0) { + if (!update_defaults(SETDEF_GENERIC|SETDEF_HOST, quiet) || + !check_defaults(SETDEF_ALL & ~(SETDEF_GENERIC|SETDEF_HOST), quiet) + || check_aliases(strict, quiet) != 0) { parse_error = true; errorfile = NULL; } } + sudoers_setlocale(oldlocale, NULL); ok = !parse_error; if (parse_error) {