]> granicus.if.org Git - sudo/commitdiff
Update defaults in visudo after sudoers has been edited so we pick
authorTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 22 Jul 2016 16:41:56 +0000 (10:41 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Fri, 22 Jul 2016 16:41:56 +0000 (10:41 -0600)
up locale changes.  The init_defaults() function will now re-init
the sudoers locale.

plugins/sudoers/defaults.c
plugins/sudoers/defaults.h
plugins/sudoers/ldap.c
plugins/sudoers/parse.c
plugins/sudoers/sssd.c
plugins/sudoers/sudoers.c
plugins/sudoers/testsudoers.c
plugins/sudoers/visudo.c

index 139f3867f3b45fe25e9146cd7709d756b514e04e..044ad74ddd5dd66876cdf0f6d8eec165fd604ade 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2005, 2007-2015
+ * Copyright (c) 1999-2005, 2007-2016
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * 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);
index 33c382e7c2072ee2cb623c1ea291345ce140f750..06a5d607c163fabd4a53970286fa7d5cb58b815a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2005, 2008-2013
+ * Copyright (c) 1999-2005, 2008-2016
  *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * 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[];
index f745a9c796486ed6787cf6c3fee57e225486e7f8..400c1f421b94f830581bfae0562482db2c0778aa 100644 (file)
@@ -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);
     }
index d79caac2f88aa6246c39107986c6b6455dc2c191..d35188ecc520d31d2e418462616b833b61d83b60 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2005, 2007-2015 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2004-2005, 2007-2016 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
@@ -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);
 }
index 1f3096238ba5a5a708fc43e863dadaa23332df32..ff3c8f95d7ffabdbee30d4b7ef9040ffba3a68ab 100644 (file)
@@ -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);
     }
index 62bff2dae3b66d00fad295ef1d61b27be868ec75..da44135df857b8a104470823a97a26096c2b417c 100644 (file)
@@ -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"));
     }
index 6068bf4fcb14e94bd7c433edcb13ea344351cd8a..ecaa59f9d48b9d466a28e4c26f586cf413111223 100644 (file)
@@ -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(".");
 
index e8d090606283d182bc1d1a8bf8b8046eea3b99bc..3ef2a0b5c8787d5cce4be752073eb3e458ffc43f 100644 (file)
@@ -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) {