debug_return_bool(false);
}
+bool
+is_early_default(const char *var)
+{
+ struct early_default *early;
+ debug_decl(is_early_default, SUDOERS_DEBUG_DEFAULTS)
+
+ for (early = early_defaults; early->var != NULL; early++) {
+ if (strcmp(var, early->var) == 0)
+ debug_return_bool(true);
+ }
+ debug_return_bool(false);
+}
+
+bool
+store_early_default(struct defaults *def, int what)
+{
+ struct early_default *early;
+ debug_decl(store_early_default, SUDOERS_DEBUG_DEFAULTS)
+
+ for (early = early_defaults; early->var != NULL; early++) {
+ if (strcmp(def->var, early->var) == 0) {
+ if (default_type_matches(def, what) &&
+ default_binding_matches(def, what)) {
+ early->val = def->val;
+ early->op = def->op;
+ }
+ debug_return_bool(true);
+ }
+ }
+ debug_return_bool(false);
+}
+
+bool
+apply_early_defaults(bool quiet)
+{
+ struct early_default *early;
+ bool rc = true;
+ debug_decl(apply_early_defaults, SUDOERS_DEBUG_DEFAULTS)
+
+ for (early = early_defaults; early->var != NULL; early++) {
+ if (early->val != NULL) {
+ if (!set_default(early->var, early->val, early->op, quiet))
+ rc = false;
+ early->val = NULL; /* clean state for next run */
+ }
+ }
+ debug_return_bool(rc);
+}
+
/*
* Update the defaults based on what was set by sudoers.
* Pass in an OR'd list of which default types to update.
bool
update_defaults(int what, bool quiet)
{
- struct early_default *early;
struct defaults *def;
bool rc = true;
debug_decl(update_defaults, SUDOERS_DEBUG_DEFAULTS)
"what: 0x%02x", what);
/*
- * First set Defaults values marked as early.
+ * First apply Defaults values marked as early.
* We only set early Defaults once (the last instance).
*/
- TAILQ_FOREACH(def, &defaults, entries) {
- /* Skip any Defaults not marked as early. */
- for (early = early_defaults; early->var != NULL; early++) {
- if (strcmp(def->var, early->var) == 0) {
- if (default_type_matches(def, what) &&
- default_binding_matches(def, what)) {
- early->val = def->val;
- early->op = def->op;
- }
- break;
- }
- }
- }
- for (early = early_defaults; early->var != NULL; early++) {
- if (early->val != NULL) {
- if (!set_default(early->var, early->val, early->op, quiet))
- rc = false;
- early->val = NULL; /* clean state for next run */
- }
- }
+ TAILQ_FOREACH(def, &defaults, entries)
+ store_early_default(def, what);
+ apply_early_defaults(quiet);
/*
* 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->var != NULL)
+ if (is_early_default(def->var))
continue;
if (!default_type_matches(def, what) ||
/*
* Prototypes
*/
+struct defaults;
void dump_default(void);
+bool apply_early_defaults(bool quiet);
+bool check_defaults(int what, bool quiet);
bool init_defaults(void);
+bool is_early_default(const char *var);
bool set_default(const char *var, const char *val, int op, bool quiet);
+bool store_early_default(struct defaults *def, int what);
bool update_defaults(int what, bool quiet);
-bool check_defaults(int what, bool quiet);
extern struct sudo_defs_types sudo_defs_table[];
#include "sudoers.h"
#include "parse.h"
+#include "gram.h" /* for DEFAULTS */
#include "sudo_lbuf.h"
#include "sudo_dso.h"
debug_return_int(ret);
}
+/*
+ * Parse an option string into a defaults structure.
+ * The members of def are pointers into optstr (which is modified).
+ */
+static void
+sudo_ldap_parse_option(char *optstr, struct defaults *def)
+{
+ char *cp, *val = NULL;
+ char *var = optstr;
+ int op;
+ debug_decl(sudo_ldap_parse_option, SUDOERS_DEBUG_LDAP)
+
+ DPRINTF2("ldap sudoOption: '%s'", optstr);
+
+ /* check for equals sign past first char */
+ cp = strchr(var, '=');
+ if (cp > var) {
+ val = cp + 1;
+ op = cp[-1]; /* peek for += or -= cases */
+ if (op == '+' || op == '-') {
+ /* case var+=val or var-=val */
+ cp--;
+ } else {
+ /* case var=val */
+ op = true;
+ }
+ /* Trim whitespace between var and operator. */
+ while (cp > var && isblank((unsigned char)cp[-1]))
+ cp--;
+ /* Truncate variable name. */
+ *cp = '\0';
+ /* Trim leading whitespace from val. */
+ while (isblank((unsigned char)*val))
+ val++;
+ /* Strip double quotes if present. */
+ if (*val == '"') {
+ char *ep = val + strlen(val);
+ if (ep != val && ep[-1] == '"') {
+ val++;
+ ep[-1] = '\0';
+ }
+ }
+ } else {
+ /* Boolean value, either true or false. */
+ op = true;
+ while (*var == '!') {
+ op = !op;
+ do {
+ var++;
+ } while (isblank((unsigned char)*var));
+ }
+ }
+ def->var = var;
+ def->val = val;
+ def->op = op;
+ def->type = DEFAULTS;
+ def->binding = NULL;
+
+ debug_return;
+}
+
/*
* Read sudoOption and modify the defaults as we go. This is used once
* from the cn=defaults entry and also once when a final sudoRole is matched.
sudo_ldap_parse_options(LDAP *ld, LDAPMessage *entry)
{
struct berval **bv, **p;
- char *copy, *cp, *var;
- int op;
- bool rc = false;
+ struct defaults def;
+ char *copy;
+ bool ret = false;
debug_decl(sudo_ldap_parse_options, SUDOERS_DEBUG_LDAP)
bv = ldap_get_values_len(ld, entry, "sudoOption");
if (bv == NULL)
debug_return_bool(true);
- /* walk through options */
+ /* walk through options, early ones first */
for (p = bv; *p != NULL; p++) {
- if ((copy = var = strdup((*p)->bv_val)) == NULL) {
+ if ((copy = strdup((*p)->bv_val)) == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto done;
}
- DPRINTF2("ldap sudoOption: '%s'", var);
+ sudo_ldap_parse_option(copy, &def);
+ store_early_default(&def, SETDEF_GENERIC);
+ free(copy);
+ }
+ apply_early_defaults(false);
- /* check for equals sign past first char */
- cp = strchr(var, '=');
- if (cp > var) {
- char *val = cp + 1;
- op = cp[-1]; /* peek for += or -= cases */
- if (op == '+' || op == '-') {
- /* case var+=val or var-=val */
- cp--;
- } else {
- /* case var=val */
- op = true;
- }
- /* Trim whitespace between var and operator. */
- while (cp > var && isblank((unsigned char)cp[-1]))
- cp--;
- /* Truncate variable name. */
- *cp = '\0';
- /* Trim leading whitespace from val. */
- while (isblank((unsigned char)*val))
- val++;
- /* Strip double quotes if present. */
- if (*val == '"') {
- char *ep = val + strlen(val);
- if (ep != val && ep[-1] == '"') {
- val++;
- ep[-1] = '\0';
- }
- }
- 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, false);
- } else {
- /* case var Boolean True */
- set_default(var, NULL, true, false);
+ /* walk through options again, skipping early ones */
+ for (p = bv; *p != NULL; p++) {
+ if ((copy = strdup((*p)->bv_val)) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
}
+ sudo_ldap_parse_option(copy, &def);
+ if (!is_early_default(def.var))
+ set_default(def.var, def.val, def.op, false);
free(copy);
}
- rc = true;
+ ret = true;
done:
ldap_value_free_len(bv);
- debug_return_bool(rc);
+ debug_return_bool(ret);
}
/*
#include "sudoers.h"
#include "parse.h"
+#include "gram.h" /* for DEFAULTS */
#include "sudo_lbuf.h"
#include "sudo_dso.h"
debug_return_int(ret);
}
+/*
+ * Parse an option string into a defaults structure.
+ * The members of def are pointers into optstr (which is modified).
+ */
+static void
+sudo_sss_parse_option(char *optstr, struct defaults *def)
+{
+ char *cp, *val = NULL;
+ char *var = optstr;
+ int op;
+ debug_decl(sudo_sss_parse_option, SUDOERS_DEBUG_SSSD)
+
+ sudo_debug_printf(SUDO_DEBUG_INFO, "sssd/ldap sudoOption: '%s'", optstr);
+
+ /* check for equals sign past first char */
+ cp = strchr(var, '=');
+ if (cp > var) {
+ val = cp + 1;
+ op = cp[-1]; /* peek for += or -= cases */
+ if (op == '+' || op == '-') {
+ /* case var+=val or var-=val */
+ cp--;
+ } else {
+ /* case var=val */
+ op = true;
+ }
+ /* Trim whitespace between var and operator. */
+ while (cp > var && isblank((unsigned char)cp[-1]))
+ cp--;
+ /* Truncate variable name. */
+ *cp = '\0';
+ /* Trim leading whitespace from val. */
+ while (isblank((unsigned char)*val))
+ val++;
+ /* Strip double quotes if present. */
+ if (*val == '"') {
+ char *ep = val + strlen(val);
+ if (ep != val && ep[-1] == '"') {
+ val++;
+ ep[-1] = '\0';
+ }
+ }
+ } else {
+ /* Boolean value, either true or false. */
+ op = true;
+ while (*var == '!') {
+ op = !op;
+ do {
+ var++;
+ } while (isblank((unsigned char)*var));
+ }
+ }
+ def->var = var;
+ def->val = val;
+ def->op = op;
+ def->type = DEFAULTS;
+ def->binding = NULL;
+
+ debug_return;
+}
+
static bool
sudo_sss_parse_options(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
{
- int i, op;
+ int i;
+ char *copy;
bool ret = false;
- char *copy, *cp, *v;
+ struct defaults def;
char **val_array = NULL;
debug_decl(sudo_sss_parse_options, SUDOERS_DEBUG_SSSD);
debug_return_bool(false);
}
- /* walk through options */
+ /* walk through options, early ones first */
for (i = 0; val_array[i] != NULL; i++) {
- sudo_debug_printf(SUDO_DEBUG_INFO, "sssd/ldap sudoOption: '%s'",
- val_array[i]);
- if ((v = copy = strdup(val_array[i])) == NULL) {
+ if ((copy = strdup(val_array[i])) == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto done;
}
+ sudo_sss_parse_option(copy, &def);
+ store_early_default(&def, SETDEF_GENERIC);
+ free(copy);
+ }
- /* check for equals sign past first char */
- cp = strchr(v, '=');
- if (cp > v) {
- char *val = cp + 1;
- op = cp[-1]; /* peek for += or -= cases */
- if (op == '+' || op == '-') {
- /* case var+=val or var-=val */
- cp--;
- } else {
- /* case var=val */
- op = true;
- }
- /* Trim whitespace between var and operator. */
- while (cp > v && isblank((unsigned char)cp[-1]))
- cp--;
- /* Truncate variable name. */
- *cp = '\0';
- /* Trim leading whitespace from val. */
- while (isblank((unsigned char)*val))
- val++;
- /* Strip double quotes if present. */
- if (*val == '"') {
- char *ep = val + strlen(val);
- if (ep != val && ep[-1] == '"') {
- val++;
- ep[-1] = '\0';
- }
- }
- 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, false);
- } else {
- /* case var Boolean True */
- set_default(v, NULL, true, false);
+ /* walk through options again, skipping early ones */
+ for (i = 0; val_array[i] != NULL; i++) {
+ if ((copy = strdup(val_array[i])) == NULL) {
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
+ goto done;
}
+ sudo_sss_parse_option(copy, &def);
+ if (!is_early_default(def.var))
+ set_default(def.var, def.val, def.op, false);
free(copy);
}
ret = true;