From 6ddc95a47c9668236b37c8722189613b7ddc2d48 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Mon, 18 Jul 2016 11:37:32 -0600 Subject: [PATCH] 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. --- plugins/sudoers/defaults.c | 65 ++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 21 deletions(-) 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); -- 2.40.0