From 6daf3c5ce12ad4b8c0f3d6daa2ad6987fd2e5c88 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Tue, 19 Jul 2016 14:58:06 -0600 Subject: [PATCH] Only set early defaults once, regardless of how many times the variable is set in sudoers. This avoids running an early callback more than once. For example, we don't want to call cb_fqdn() if sudo is compiled with FQDN set but sudoers has "Defaults !fqdn". --- plugins/sudoers/defaults.c | 118 ++++++++++++++++++++++--------------- plugins/sudoers/sudoers.c | 4 -- 2 files changed, 70 insertions(+), 52 deletions(-) diff --git a/plugins/sudoers/defaults.c b/plugins/sudoers/defaults.c index 499d45792..054687dc6 100644 --- a/plugins/sudoers/defaults.c +++ b/plugins/sudoers/defaults.c @@ -79,11 +79,21 @@ static struct strmap priorities[] = { /* * Defaults values to apply before others. */ -static const char *early_defaults[] = { - "fqdn", - "runas_default", - "sudoers_locale", - NULL +struct early_default { + const char *var; + const char *val; + int op; +}; + +static struct early_default early_defaults[] = { +#ifdef FQDN + { "fqdn", "true", true }, +#else + { "fqdn" }, +#endif + { "runas_default" }, + { "sudoers_locale" }, + { NULL } }; /* @@ -413,9 +423,6 @@ init_defaults(void) #ifndef DONT_LEAK_PATH_INFO def_path_info = true; #endif -#ifdef FQDN - def_fqdn = true; -#endif #ifdef USE_INSULTS def_insults = true; #endif @@ -538,57 +545,72 @@ oom: bool update_defaults(int what) { + struct early_default *early; struct defaults *def; bool rc = true; - int pass; debug_decl(update_defaults, SUDOERS_DEBUG_DEFAULTS) /* - * Run through the Defaulsts list twice. - * First, set early defaults, then set the rest. + * First set Defaults values marked as early. + * We only set early Defaults once (the last instance). */ - 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)) - continue; - break; - case DEFAULTS_USER: - 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) - continue; - break; - case DEFAULTS_HOST: - 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) - continue; + TAILQ_FOREACH(def, &defaults, entries) { + for (early = early_defaults; early->var != NULL; early++) { + if (strcmp(def->var, early->var) == 0) { + early->val = def->val; + early->op = def->op; break; } - if (!set_default(def->var, def->val, def->op)) + } + } + for (early = early_defaults; early->var != NULL; early++) { + if (early->val != NULL) { + if (!set_default(early->var, early->val, early->op)) rc = false; } } + + /* + * Then set the rest of the defaults. + */ + TAILQ_FOREACH(def, &defaults, entries) { + /* Skip Defaults marked as early, we already did them. */ + for (early = early_defaults; early->var != NULL; early++) { + if (strcmp(def->var, early->var) == 0) + break; + } + if (early->val != NULL) + continue; + + switch (def->type) { + case DEFAULTS: + if (!ISSET(what, SETDEF_GENERIC)) + continue; + break; + case DEFAULTS_USER: + 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) + continue; + break; + case DEFAULTS_HOST: + 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) + continue; + break; + } + if (!set_default(def->var, def->val, def->op)) + rc = false; + } debug_return_bool(rc); } diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index 216eeafb7..d71401b0c 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -762,10 +762,6 @@ init_vars(char * const envp[]) debug_return_bool(false); } - /* Set fully-qualified domain name if specified. */ - if (def_fqdn) - cb_fqdn(NULL); - debug_return_bool(true); } -- 2.40.0