From: Todd C. Miller Date: Mon, 18 Jul 2016 17:37:32 +0000 (-0600) Subject: When updating defaults, process certain values fist since they can X-Git-Tag: SUDO_1_8_18^2~121 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6ddc95a47c9668236b37c8722189613b7ddc2d48;p=sudo When updating defaults, process certain values fist since they can influence how other defaults are parsed. Currently, runas_default and sudoers_locale are processed early. --- diff --git a/plugins/sudoers/defaults.c b/plugins/sudoers/defaults.c index 16ee782b1..b1916f0ae 100644 --- a/plugins/sudoers/defaults.c +++ b/plugins/sudoers/defaults.c @@ -76,6 +76,15 @@ static struct strmap priorities[] = { { NULL, -1 } }; +/* + * Defaults values to apply before others. + */ +static const char *early_defaults[] = { + "runas_default", + "sudoers_locale", + NULL +}; + /* * Local prototypes. */ @@ -528,39 +537,53 @@ update_defaults(int what) { struct defaults *def; bool rc = true; + int pass; debug_decl(update_defaults, SUDOERS_DEBUG_DEFAULTS) - TAILQ_FOREACH(def, &defaults, entries) { - switch (def->type) { + /* + * Run through the Defaulsts list twice. + * First, set early defaults, then set the rest. + */ + for (pass = 0; pass < 2; pass++) { + TAILQ_FOREACH(def, &defaults, entries) { + const char **early; + + /* Only do early defaults in pass 0, skip them in pass 1. */ + for (early = early_defaults; *early != NULL; early++) { + if (strcmp(def->var, *early) == 0) + break; + } + if (!!*early == pass) + continue; + + switch (def->type) { case DEFAULTS: - if (ISSET(what, SETDEF_GENERIC) && - !set_default(def->var, def->val, def->op)) - rc = false; + if (!ISSET(what, SETDEF_GENERIC)) + continue; break; case DEFAULTS_USER: - if (ISSET(what, SETDEF_USER) && - userlist_matches(sudo_user.pw, def->binding) == ALLOW && - !set_default(def->var, def->val, def->op)) - rc = false; + if (!ISSET(what, SETDEF_USER) || + userlist_matches(sudo_user.pw, def->binding) != ALLOW) + continue; break; case DEFAULTS_RUNAS: - if (ISSET(what, SETDEF_RUNAS) && - runaslist_matches(def->binding, NULL, NULL, NULL) == ALLOW && - !set_default(def->var, def->val, def->op)) - rc = false; + if (!ISSET(what, SETDEF_RUNAS) || + runaslist_matches(def->binding, NULL, NULL, NULL) != ALLOW) + continue; break; case DEFAULTS_HOST: - if (ISSET(what, SETDEF_HOST) && - hostlist_matches(sudo_user.pw, def->binding) == ALLOW && - !set_default(def->var, def->val, def->op)) - rc = false; + if (!ISSET(what, SETDEF_HOST) || + hostlist_matches(sudo_user.pw, def->binding) != ALLOW) + continue; break; case DEFAULTS_CMND: - if (ISSET(what, SETDEF_CMND) && - cmndlist_matches(def->binding) == ALLOW && - !set_default(def->var, def->val, def->op)) - rc = false; + if (!ISSET(what, SETDEF_CMND) || + cmndlist_matches(def->binding) != ALLOW) + continue; break; + } + if (!set_default(def->var, def->val, def->op)) + rc = false; } } debug_return_bool(rc);