debug_return;
}
+/*
+ * Find the index of the specified Defaults name in sudo_defs_table[]
+ * On success, returns the matching index or -1 on failure.
+ */
+static int
+find_default(const char *name, const char *file, int lineno, bool quiet)
+{
+ int i;
+ debug_decl(find_default, SUDOERS_DEBUG_DEFAULTS)
+
+ for (i = 0; sudo_defs_table[i].name != NULL; i++) {
+ if (strcmp(name, sudo_defs_table[i].name) == 0)
+ debug_return_int(i);
+ }
+ if (!quiet) {
+ if (lineno > 0) {
+ sudo_warnx(U_("%s:%d unknown defaults entry \"%s\""),
+ file, lineno, name);
+ } else {
+ sudo_warnx(U_("%s: unknown defaults entry \"%s\""),
+ file, name);
+ }
+ }
+ debug_return_int(-1);
+}
+
+/*
+ * Parse a defaults entry, storing the parsed entry in sd_un.
+ * Returns true on success or false on failure.
+ */
static bool
parse_default_entry(struct sudo_defs_types *def, const char *val, int op,
union sudo_defs_val *sd_un, const char *file, int lineno, bool quiet)
}
struct early_default *
-is_early_default(int idx)
+is_early_default(const char *name)
{
struct early_default *early;
debug_decl(is_early_default, SUDOERS_DEBUG_DEFAULTS)
- for (early = early_defaults; early->idx != -1; early++) {
- if (idx == early->idx)
- debug_return_ptr(early);
- }
- debug_return_ptr(NULL);
-}
-
-struct early_default *
-is_early_default_byname(const char *name)
-{
- struct early_default *early;
- debug_decl(is_early_default_byname, SUDOERS_DEBUG_DEFAULTS)
-
for (early = early_defaults; early->idx != -1; early++) {
if (strcmp(name, sudo_defs_table[early->idx].name) == 0)
debug_return_ptr(early);
/*
* Sets/clears an entry in the defaults structure.
* Runs the callback if present on success.
- * XXX - deprecated, only used by ldap/sssd
*/
bool
set_default(const char *var, const char *val, int op, const char *file,
int lineno, bool quiet)
{
- union sudo_defs_val sd_un;
int idx;
debug_decl(set_default, SUDOERS_DEBUG_DEFAULTS)
- memset(&sd_un, 0, sizeof(sd_un));
- idx = parse_default(var, val, op, &sd_un, file, lineno, quiet);
+ idx = find_default(var, file, lineno, quiet);
if (idx != -1) {
/* Set parsed value in sudo_defs_table and run callback (if any). */
struct sudo_defs_types *def = &sudo_defs_table[idx];
- def->sd_un = sd_un;
- debug_return_bool(run_callback(def));
+ if (parse_default_entry(def, val, op, &def->sd_un, file, lineno, quiet))
+ debug_return_bool(run_callback(def));
}
debug_return_bool(false);
}
/*
* Like set_default() but stores the matching default value
* and does not run callbacks.
- * XXX - deprecated, only used by ldap/sssd
*/
bool
set_early_default(const char *var, const char *val, int op, const char *file,
int lineno, bool quiet, struct early_default *early)
{
- union sudo_defs_val sd_un;
int idx;
debug_decl(set_early_default, SUDOERS_DEBUG_DEFAULTS)
- memset(&sd_un, 0, sizeof(sd_un));
- idx = parse_default(var, val, op, &sd_un, file, lineno, quiet);
+ idx = find_default(var, file, lineno, quiet);
if (idx != -1) {
- /* Set parsed value in sudo_defs_table. */
+ /* Set parsed value in sudo_defs_table but defer callback (if any). */
struct sudo_defs_types *def = &sudo_defs_table[idx];
- def->sd_un = sd_un;
- /* Defer running callback until all early defaults are set. */
- early->run_callback = true;
- debug_return_bool(true);
+ if (parse_default_entry(def, val, op, &def->sd_un, file, lineno, quiet)) {
+ early->run_callback = true;
+ debug_return_bool(true);
+ }
}
debug_return_bool(false);
}
}
static void
-free_default(struct sudo_defs_types *def)
+free_default(int type, union sudo_defs_val *sd_un)
{
- switch (def->type & T_MASK) {
+ switch (type & T_MASK) {
case T_STR:
- free(def->sd_un.str);
+ free(sd_un->str);
break;
case T_LIST:
- (void)list_op(NULL, 0, &def->sd_un, freeall);
+ (void)list_op(NULL, 0, sd_un, freeall);
break;
}
- memset(&def->sd_un, 0, sizeof(def->sd_un));
+ memset(sd_un, 0, sizeof(*sd_un));
}
/*
/* Clear any old settings. */
if (!firsttime) {
for (def = sudo_defs_table; def->name != NULL; def++)
- free_default(def);
+ free_default(def->type, &def->sd_un);
}
/* First initialize the flags. */
* First apply Defaults values marked as early.
*/
TAILQ_FOREACH(d, &defaults, entries) {
- struct early_default *early = is_early_default(d->idx);
+ struct early_default *early = is_early_default(d->var);
if (early == NULL)
continue;
continue;
/* Copy the value to sudo_defs_table and mark as early. */
- sudo_defs_table[d->idx].sd_un = d->sd_un;
- early->run_callback = true;
+ if (!set_early_default(d->var, d->val, d->op, d->file, d->lineno,
+ quiet, early))
+ ret = false;
}
/* Run callbacks for early defaults (if any) */
if (!run_early_defaults())
*/
TAILQ_FOREACH(d, &defaults, entries) {
/* Skip Defaults marked as early, we already did them. */
- if (is_early_default(d->idx))
+ if (is_early_default(d->var))
continue;
/* Defaults type and binding must match. */
continue;
/* Copy the value to sudo_defs_table and run callback (if any) */
- sudo_defs_table[d->idx].sd_un = d->sd_un;
- if (!run_callback(&sudo_defs_table[d->idx]))
+ if (!set_default(d->var, d->val, d->op, d->file, d->lineno, quiet))
ret = false;
}
debug_return_bool(ret);
}
/*
- * Parse a defaults entry, storing the parsed entry in sd_un.
- * Returns the matching sudo_defs_table[] index on success or -1 on failure.
+ * Check all defaults entries without actually setting them.
*/
-int
-parse_default(const char *var, const char *val, int op,
- union sudo_defs_val *sd_un, const char *file, int lineno, bool quiet)
+bool
+check_defaults(bool quiet)
{
- int i;
- debug_decl(parse_default, SUDOERS_DEBUG_DEFAULTS)
+ struct defaults *d;
+ bool ret = true;
+ int idx;
+ debug_decl(check_defaults, SUDOERS_DEBUG_DEFAULTS)
- for (i = 0; sudo_defs_table[i].name != NULL; i++) {
- if (strcmp(var, sudo_defs_table[i].name) == 0) {
- if (parse_default_entry(&sudo_defs_table[i], val, op,
- sd_un, file, lineno, quiet))
- debug_return_int(i);
- debug_return_int(-1);
- }
- }
- if (!quiet) {
- if (lineno > 0) {
- sudo_warnx(U_("%s:%d unknown defaults entry \"%s\""),
- file, lineno, var);
- } else {
- sudo_warnx(U_("%s: unknown defaults entry \"%s\""),
- file, var);
+ TAILQ_FOREACH(d, &defaults, entries) {
+ idx = find_default(d->var, d->file, d->lineno, quiet);
+ if (idx != -1) {
+ struct sudo_defs_types *def = &sudo_defs_table[idx];
+ union sudo_defs_val sd_un;
+ memset(&sd_un, 0, sizeof(sd_un));
+ if (parse_default_entry(def, d->val, d->op, &sd_un, d->file,
+ d->lineno, quiet)) {
+ free_default(def->type, &sd_un);
+ continue;
+ }
}
+ /* There was an error in the entry, flag it. */
+ d->error = true;
+ ret = false;
}
- debug_return_int(-1);
+ debug_return_bool(ret);
}
static bool
*/
void dump_default(void);
bool init_defaults(void);
-struct early_default *is_early_default(int idx);
-struct early_default *is_early_default_byname(const char *name);
+struct early_default *is_early_default(const char *name);
bool run_early_defaults(void);
bool set_early_default(const char *var, const char *val, int op, const char *file, int lineno, bool quiet, struct early_default *early);
bool set_default(const char *var, const char *val, int op, const char *file, int lineno, bool quiet);
bool update_defaults(int what, bool quiet);
-int parse_default(const char *var, const char *val, int op, union sudo_defs_val *sd_un, const char *file, int lineno, bool quiet);
+bool check_defaults(bool quiet);
extern struct sudo_defs_types sudo_defs_table[];
* Globals
*/
bool sudoers_warnings = true;
-bool allow_unknown_defaults = true;
bool parse_error = false;
int errorlineno = -1;
char *errorfile = NULL;
*/
static bool add_defaults(int, struct member *, struct defaults *);
static bool add_userspec(struct member *, struct privilege *);
-static struct defaults *new_default(char *, char *, int);
+static struct defaults *new_default(char *, char *, short);
static struct member *new_member(char *, int);
static struct sudo_digest *new_digest(int, const char *);
-#line 74 "gram.y"
+#line 73 "gram.y"
#ifndef YYSTYPE_DEFINED
#define YYSTYPE_DEFINED
typedef union {
int tok;
} YYSTYPE;
#endif /* YYSTYPE_DEFINED */
-#line 128 "gram.c"
+#line 127 "gram.c"
#define COMMAND 257
#define ALIAS 258
#define DEFVAR 259
YYSTYPE *yyvs;
unsigned int yystacksize;
int yyparse(void);
-#line 850 "gram.y"
+#line 849 "gram.y"
void
sudoerserror(const char *s)
{
}
static struct defaults *
-new_default(char *var, char *val, int op)
+new_default(char *var, char *val, short op)
{
struct defaults *d;
debug_decl(new_default, SUDOERS_DEBUG_PARSER)
/* d->type = 0; */
d->op = op;
/* d->binding = NULL */
+ d->lineno = last_token == COMMENT ? sudolineno - 1 : sudolineno;
+ d->file = strdup(sudoers);
+ if (d->file == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ free(d);
+ debug_return_ptr(NULL);
+ }
HLTQ_INIT(d, entries);
debug_return_ptr(d);
{
struct defaults *d, *next;
struct member_list *binding;
- bool binding_used = false;
bool ret = true;
debug_decl(add_defaults, SUDOERS_DEBUG_PARSER)
/*
* Set type and binding (who it applies to) for new entries.
- * Then add to the global defaults list if it parses.
+ * Then add to the global defaults list.
*/
HLTQ_FOREACH_SAFE(d, defs, entries, next) {
- d->idx = parse_default(d->var, d->val, d->op, &d->sd_un,
- sudoers, sudolineno, !sudoers_warnings);
- if (d->idx != -1) {
- /* Append to defaults list */
- d->type = type;
- d->binding = binding;
- binding_used = true;
- TAILQ_INSERT_TAIL(&defaults, d, entries);
- } else {
- /* Did not parse */
- if (ret && !allow_unknown_defaults) {
- sudoerserror(NULL);
- ret = false;
- }
- free(d->var);
- free(d->val);
- free(d);
- }
- }
-
- if (!binding_used) {
- /* No valid Defaults entries, binding unused. */
- free_members(binding);
- free(binding);
+ d->type = type;
+ d->binding = binding;
+ TAILQ_INSERT_TAIL(&defaults, d, entries);
}
}
* the current sudoers file to path.
*/
bool
-init_parser(const char *path, bool quiet, bool strict_defaults)
+init_parser(const char *path, bool quiet)
{
struct member_list *binding;
struct defaults *d, *d_next;
/* no need to free sd_un */
free(d->var);
free(d->val);
+ free(d->file);
free(d);
}
TAILQ_INIT(&defaults);
free(errorfile);
errorfile = NULL;
sudoers_warnings = !quiet;
- allow_unknown_defaults = !strict_defaults;
debug_return_bool(ret);
}
-#line 980 "gram.c"
+#line 965 "gram.c"
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
#if defined(__cplusplus) || defined(__STDC__)
static int yygrowstack(void)
switch (yyn)
{
case 1:
-#line 168 "gram.y"
+#line 167 "gram.y"
{ ; }
break;
case 5:
-#line 176 "gram.y"
+#line 175 "gram.y"
{
;
}
break;
case 6:
-#line 179 "gram.y"
+#line 178 "gram.y"
{
yyerrok;
}
break;
case 7:
-#line 182 "gram.y"
+#line 181 "gram.y"
{
if (!add_userspec(yyvsp[-1].member, yyvsp[0].privilege)) {
sudoerserror(N_("unable to allocate memory"));
}
break;
case 8:
-#line 188 "gram.y"
+#line 187 "gram.y"
{
;
}
break;
case 9:
-#line 191 "gram.y"
+#line 190 "gram.y"
{
;
}
break;
case 10:
-#line 194 "gram.y"
+#line 193 "gram.y"
{
;
}
break;
case 11:
-#line 197 "gram.y"
+#line 196 "gram.y"
{
;
}
break;
case 12:
-#line 200 "gram.y"
+#line 199 "gram.y"
{
if (!add_defaults(DEFAULTS, NULL, yyvsp[0].defaults))
YYERROR;
}
break;
case 13:
-#line 204 "gram.y"
+#line 203 "gram.y"
{
if (!add_defaults(DEFAULTS_USER, yyvsp[-1].member, yyvsp[0].defaults))
YYERROR;
}
break;
case 14:
-#line 208 "gram.y"
+#line 207 "gram.y"
{
if (!add_defaults(DEFAULTS_RUNAS, yyvsp[-1].member, yyvsp[0].defaults))
YYERROR;
}
break;
case 15:
-#line 212 "gram.y"
+#line 211 "gram.y"
{
if (!add_defaults(DEFAULTS_HOST, yyvsp[-1].member, yyvsp[0].defaults))
YYERROR;
}
break;
case 16:
-#line 216 "gram.y"
+#line 215 "gram.y"
{
if (!add_defaults(DEFAULTS_CMND, yyvsp[-1].member, yyvsp[0].defaults))
YYERROR;
}
break;
case 18:
-#line 223 "gram.y"
+#line 222 "gram.y"
{
HLTQ_CONCAT(yyvsp[-2].defaults, yyvsp[0].defaults, entries);
yyval.defaults = yyvsp[-2].defaults;
}
break;
case 19:
-#line 229 "gram.y"
+#line 228 "gram.y"
{
yyval.defaults = new_default(yyvsp[0].string, NULL, true);
if (yyval.defaults == NULL) {
}
break;
case 20:
-#line 236 "gram.y"
+#line 235 "gram.y"
{
yyval.defaults = new_default(yyvsp[0].string, NULL, false);
if (yyval.defaults == NULL) {
}
break;
case 21:
-#line 243 "gram.y"
+#line 242 "gram.y"
{
yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, true);
if (yyval.defaults == NULL) {
}
break;
case 22:
-#line 250 "gram.y"
+#line 249 "gram.y"
{
yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '+');
if (yyval.defaults == NULL) {
}
break;
case 23:
-#line 257 "gram.y"
+#line 256 "gram.y"
{
yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '-');
if (yyval.defaults == NULL) {
}
break;
case 25:
-#line 267 "gram.y"
+#line 266 "gram.y"
{
HLTQ_CONCAT(yyvsp[-2].privilege, yyvsp[0].privilege, entries);
yyval.privilege = yyvsp[-2].privilege;
}
break;
case 26:
-#line 273 "gram.y"
+#line 272 "gram.y"
{
struct privilege *p = calloc(1, sizeof(*p));
if (p == NULL) {
}
break;
case 27:
-#line 286 "gram.y"
+#line 285 "gram.y"
{
yyval.member = yyvsp[0].member;
yyval.member->negated = false;
}
break;
case 28:
-#line 290 "gram.y"
+#line 289 "gram.y"
{
yyval.member = yyvsp[0].member;
yyval.member->negated = true;
}
break;
case 29:
-#line 296 "gram.y"
+#line 295 "gram.y"
{
yyval.member = new_member(yyvsp[0].string, ALIAS);
if (yyval.member == NULL) {
}
break;
case 30:
-#line 303 "gram.y"
+#line 302 "gram.y"
{
yyval.member = new_member(NULL, ALL);
if (yyval.member == NULL) {
}
break;
case 31:
-#line 310 "gram.y"
+#line 309 "gram.y"
{
yyval.member = new_member(yyvsp[0].string, NETGROUP);
if (yyval.member == NULL) {
}
break;
case 32:
-#line 317 "gram.y"
+#line 316 "gram.y"
{
yyval.member = new_member(yyvsp[0].string, NTWKADDR);
if (yyval.member == NULL) {
}
break;
case 33:
-#line 324 "gram.y"
+#line 323 "gram.y"
{
yyval.member = new_member(yyvsp[0].string, WORD);
if (yyval.member == NULL) {
}
break;
case 35:
-#line 334 "gram.y"
+#line 333 "gram.y"
{
struct cmndspec *prev;
prev = HLTQ_LAST(yyvsp[-2].cmndspec, cmndspec, entries);
}
break;
case 36:
-#line 379 "gram.y"
+#line 378 "gram.y"
{
struct cmndspec *cs = calloc(1, sizeof(*cs));
if (cs == NULL) {
}
break;
case 37:
-#line 427 "gram.y"
+#line 426 "gram.y"
{
yyval.digest = new_digest(SUDO_DIGEST_SHA224, yyvsp[0].string);
if (yyval.digest == NULL) {
}
break;
case 38:
-#line 434 "gram.y"
+#line 433 "gram.y"
{
yyval.digest = new_digest(SUDO_DIGEST_SHA256, yyvsp[0].string);
if (yyval.digest == NULL) {
}
break;
case 39:
-#line 441 "gram.y"
+#line 440 "gram.y"
{
yyval.digest = new_digest(SUDO_DIGEST_SHA384, yyvsp[0].string);
if (yyval.digest == NULL) {
}
break;
case 40:
-#line 448 "gram.y"
+#line 447 "gram.y"
{
yyval.digest = new_digest(SUDO_DIGEST_SHA512, yyvsp[0].string);
if (yyval.digest == NULL) {
}
break;
case 41:
-#line 457 "gram.y"
+#line 456 "gram.y"
{
yyval.member = yyvsp[0].member;
}
break;
case 42:
-#line 460 "gram.y"
+#line 459 "gram.y"
{
if (yyvsp[0].member->type != COMMAND) {
sudoerserror(N_("a digest requires a path name"));
}
break;
case 43:
-#line 471 "gram.y"
+#line 470 "gram.y"
{
yyval.member = yyvsp[0].member;
yyval.member->negated = false;
}
break;
case 44:
-#line 475 "gram.y"
+#line 474 "gram.y"
{
yyval.member = yyvsp[0].member;
yyval.member->negated = true;
}
break;
case 45:
-#line 481 "gram.y"
+#line 480 "gram.y"
{
yyval.string = yyvsp[0].string;
}
break;
case 46:
-#line 486 "gram.y"
+#line 485 "gram.y"
{
yyval.string = yyvsp[0].string;
}
break;
case 47:
-#line 491 "gram.y"
+#line 490 "gram.y"
{
yyval.seinfo.role = NULL;
yyval.seinfo.type = NULL;
}
break;
case 48:
-#line 495 "gram.y"
+#line 494 "gram.y"
{
yyval.seinfo.role = yyvsp[0].string;
yyval.seinfo.type = NULL;
}
break;
case 49:
-#line 499 "gram.y"
+#line 498 "gram.y"
{
yyval.seinfo.type = yyvsp[0].string;
yyval.seinfo.role = NULL;
}
break;
case 50:
-#line 503 "gram.y"
+#line 502 "gram.y"
{
yyval.seinfo.role = yyvsp[-1].string;
yyval.seinfo.type = yyvsp[0].string;
}
break;
case 51:
-#line 507 "gram.y"
+#line 506 "gram.y"
{
yyval.seinfo.type = yyvsp[-1].string;
yyval.seinfo.role = yyvsp[0].string;
}
break;
case 52:
-#line 513 "gram.y"
+#line 512 "gram.y"
{
yyval.string = yyvsp[0].string;
}
break;
case 53:
-#line 517 "gram.y"
+#line 516 "gram.y"
{
yyval.string = yyvsp[0].string;
}
break;
case 54:
-#line 522 "gram.y"
+#line 521 "gram.y"
{
yyval.privinfo.privs = NULL;
yyval.privinfo.limitprivs = NULL;
}
break;
case 55:
-#line 526 "gram.y"
+#line 525 "gram.y"
{
yyval.privinfo.privs = yyvsp[0].string;
yyval.privinfo.limitprivs = NULL;
}
break;
case 56:
-#line 530 "gram.y"
+#line 529 "gram.y"
{
yyval.privinfo.privs = NULL;
yyval.privinfo.limitprivs = yyvsp[0].string;
}
break;
case 57:
-#line 534 "gram.y"
+#line 533 "gram.y"
{
yyval.privinfo.privs = yyvsp[-1].string;
yyval.privinfo.limitprivs = yyvsp[0].string;
}
break;
case 58:
-#line 538 "gram.y"
+#line 537 "gram.y"
{
yyval.privinfo.limitprivs = yyvsp[-1].string;
yyval.privinfo.privs = yyvsp[0].string;
}
break;
case 59:
-#line 544 "gram.y"
+#line 543 "gram.y"
{
yyval.runas = NULL;
}
break;
case 60:
-#line 547 "gram.y"
+#line 546 "gram.y"
{
yyval.runas = yyvsp[-1].runas;
}
break;
case 61:
-#line 552 "gram.y"
+#line 551 "gram.y"
{
yyval.runas = calloc(1, sizeof(struct runascontainer));
if (yyval.runas != NULL) {
}
break;
case 62:
-#line 567 "gram.y"
+#line 566 "gram.y"
{
yyval.runas = calloc(1, sizeof(struct runascontainer));
if (yyval.runas == NULL) {
}
break;
case 63:
-#line 576 "gram.y"
+#line 575 "gram.y"
{
yyval.runas = calloc(1, sizeof(struct runascontainer));
if (yyval.runas == NULL) {
}
break;
case 64:
-#line 585 "gram.y"
+#line 584 "gram.y"
{
yyval.runas = calloc(1, sizeof(struct runascontainer));
if (yyval.runas == NULL) {
}
break;
case 65:
-#line 594 "gram.y"
+#line 593 "gram.y"
{
yyval.runas = calloc(1, sizeof(struct runascontainer));
if (yyval.runas != NULL) {
}
break;
case 66:
-#line 611 "gram.y"
+#line 610 "gram.y"
{
TAGS_INIT(yyval.tag);
}
break;
case 67:
-#line 614 "gram.y"
+#line 613 "gram.y"
{
yyval.tag.nopasswd = true;
}
break;
case 68:
-#line 617 "gram.y"
+#line 616 "gram.y"
{
yyval.tag.nopasswd = false;
}
break;
case 69:
-#line 620 "gram.y"
+#line 619 "gram.y"
{
yyval.tag.noexec = true;
}
break;
case 70:
-#line 623 "gram.y"
+#line 622 "gram.y"
{
yyval.tag.noexec = false;
}
break;
case 71:
-#line 626 "gram.y"
+#line 625 "gram.y"
{
yyval.tag.setenv = true;
}
break;
case 72:
-#line 629 "gram.y"
+#line 628 "gram.y"
{
yyval.tag.setenv = false;
}
break;
case 73:
-#line 632 "gram.y"
+#line 631 "gram.y"
{
yyval.tag.log_input = true;
}
break;
case 74:
-#line 635 "gram.y"
+#line 634 "gram.y"
{
yyval.tag.log_input = false;
}
break;
case 75:
-#line 638 "gram.y"
+#line 637 "gram.y"
{
yyval.tag.log_output = true;
}
break;
case 76:
-#line 641 "gram.y"
+#line 640 "gram.y"
{
yyval.tag.log_output = false;
}
break;
case 77:
-#line 644 "gram.y"
+#line 643 "gram.y"
{
yyval.tag.follow = true;
}
break;
case 78:
-#line 647 "gram.y"
+#line 646 "gram.y"
{
yyval.tag.follow = false;
}
break;
case 79:
-#line 650 "gram.y"
+#line 649 "gram.y"
{
yyval.tag.send_mail = true;
}
break;
case 80:
-#line 653 "gram.y"
+#line 652 "gram.y"
{
yyval.tag.send_mail = false;
}
break;
case 81:
-#line 658 "gram.y"
+#line 657 "gram.y"
{
yyval.member = new_member(NULL, ALL);
if (yyval.member == NULL) {
}
break;
case 82:
-#line 665 "gram.y"
+#line 664 "gram.y"
{
yyval.member = new_member(yyvsp[0].string, ALIAS);
if (yyval.member == NULL) {
}
break;
case 83:
-#line 672 "gram.y"
+#line 671 "gram.y"
{
struct sudo_command *c = calloc(1, sizeof(*c));
if (c == NULL) {
}
break;
case 86:
-#line 693 "gram.y"
+#line 692 "gram.y"
{
const char *s;
if ((s = alias_add(yyvsp[-2].string, HOSTALIAS, yyvsp[0].member)) != NULL) {
}
break;
case 88:
-#line 703 "gram.y"
+#line 702 "gram.y"
{
HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
yyval.member = yyvsp[-2].member;
}
break;
case 91:
-#line 713 "gram.y"
+#line 712 "gram.y"
{
const char *s;
if ((s = alias_add(yyvsp[-2].string, CMNDALIAS, yyvsp[0].member)) != NULL) {
}
break;
case 93:
-#line 723 "gram.y"
+#line 722 "gram.y"
{
HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
yyval.member = yyvsp[-2].member;
}
break;
case 96:
-#line 733 "gram.y"
+#line 732 "gram.y"
{
const char *s;
if ((s = alias_add(yyvsp[-2].string, RUNASALIAS, yyvsp[0].member)) != NULL) {
}
break;
case 99:
-#line 746 "gram.y"
+#line 745 "gram.y"
{
const char *s;
if ((s = alias_add(yyvsp[-2].string, USERALIAS, yyvsp[0].member)) != NULL) {
}
break;
case 101:
-#line 756 "gram.y"
+#line 755 "gram.y"
{
HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
yyval.member = yyvsp[-2].member;
}
break;
case 102:
-#line 762 "gram.y"
+#line 761 "gram.y"
{
yyval.member = yyvsp[0].member;
yyval.member->negated = false;
}
break;
case 103:
-#line 766 "gram.y"
+#line 765 "gram.y"
{
yyval.member = yyvsp[0].member;
yyval.member->negated = true;
}
break;
case 104:
-#line 772 "gram.y"
+#line 771 "gram.y"
{
yyval.member = new_member(yyvsp[0].string, ALIAS);
if (yyval.member == NULL) {
}
break;
case 105:
-#line 779 "gram.y"
+#line 778 "gram.y"
{
yyval.member = new_member(NULL, ALL);
if (yyval.member == NULL) {
}
break;
case 106:
-#line 786 "gram.y"
+#line 785 "gram.y"
{
yyval.member = new_member(yyvsp[0].string, NETGROUP);
if (yyval.member == NULL) {
}
break;
case 107:
-#line 793 "gram.y"
+#line 792 "gram.y"
{
yyval.member = new_member(yyvsp[0].string, USERGROUP);
if (yyval.member == NULL) {
}
break;
case 108:
-#line 800 "gram.y"
+#line 799 "gram.y"
{
yyval.member = new_member(yyvsp[0].string, WORD);
if (yyval.member == NULL) {
}
break;
case 110:
-#line 810 "gram.y"
+#line 809 "gram.y"
{
HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
yyval.member = yyvsp[-2].member;
}
break;
case 111:
-#line 816 "gram.y"
+#line 815 "gram.y"
{
yyval.member = yyvsp[0].member;
yyval.member->negated = false;
}
break;
case 112:
-#line 820 "gram.y"
+#line 819 "gram.y"
{
yyval.member = yyvsp[0].member;
yyval.member->negated = true;
}
break;
case 113:
-#line 826 "gram.y"
+#line 825 "gram.y"
{
yyval.member = new_member(yyvsp[0].string, ALIAS);
if (yyval.member == NULL) {
}
break;
case 114:
-#line 833 "gram.y"
+#line 832 "gram.y"
{
yyval.member = new_member(NULL, ALL);
if (yyval.member == NULL) {
}
break;
case 115:
-#line 840 "gram.y"
+#line 839 "gram.y"
{
yyval.member = new_member(yyvsp[0].string, WORD);
if (yyval.member == NULL) {
}
}
break;
-#line 2063 "gram.c"
+#line 2048 "gram.c"
}
yyssp -= yym;
yystate = *yyssp;
* Globals
*/
bool sudoers_warnings = true;
-bool allow_unknown_defaults = true;
bool parse_error = false;
int errorlineno = -1;
char *errorfile = NULL;
*/
static bool add_defaults(int, struct member *, struct defaults *);
static bool add_userspec(struct member *, struct privilege *);
-static struct defaults *new_default(char *, char *, int);
+static struct defaults *new_default(char *, char *, short);
static struct member *new_member(char *, int);
static struct sudo_digest *new_digest(int, const char *);
%}
}
static struct defaults *
-new_default(char *var, char *val, int op)
+new_default(char *var, char *val, short op)
{
struct defaults *d;
debug_decl(new_default, SUDOERS_DEBUG_PARSER)
/* d->type = 0; */
d->op = op;
/* d->binding = NULL */
+ d->lineno = last_token == COMMENT ? sudolineno - 1 : sudolineno;
+ d->file = strdup(sudoers);
+ if (d->file == NULL) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ free(d);
+ debug_return_ptr(NULL);
+ }
HLTQ_INIT(d, entries);
debug_return_ptr(d);
{
struct defaults *d, *next;
struct member_list *binding;
- bool binding_used = false;
bool ret = true;
debug_decl(add_defaults, SUDOERS_DEBUG_PARSER)
/*
* Set type and binding (who it applies to) for new entries.
- * Then add to the global defaults list if it parses.
+ * Then add to the global defaults list.
*/
HLTQ_FOREACH_SAFE(d, defs, entries, next) {
- d->idx = parse_default(d->var, d->val, d->op, &d->sd_un,
- sudoers, sudolineno, !sudoers_warnings);
- if (d->idx != -1) {
- /* Append to defaults list */
- d->type = type;
- d->binding = binding;
- binding_used = true;
- TAILQ_INSERT_TAIL(&defaults, d, entries);
- } else {
- /* Did not parse */
- if (ret && !allow_unknown_defaults) {
- sudoerserror(NULL);
- ret = false;
- }
- free(d->var);
- free(d->val);
- free(d);
- }
- }
-
- if (!binding_used) {
- /* No valid Defaults entries, binding unused. */
- free_members(binding);
- free(binding);
+ d->type = type;
+ d->binding = binding;
+ TAILQ_INSERT_TAIL(&defaults, d, entries);
}
}
* the current sudoers file to path.
*/
bool
-init_parser(const char *path, bool quiet, bool strict_defaults)
+init_parser(const char *path, bool quiet)
{
struct member_list *binding;
struct defaults *d, *d_next;
/* no need to free sd_un */
free(d->var);
free(d->val);
+ free(d->file);
free(d);
}
TAILQ_INIT(&defaults);
free(errorfile);
errorfile = NULL;
sudoers_warnings = !quiet;
- allow_unknown_defaults = !strict_defaults;
debug_return_bool(ret);
}
goto done;
}
op = sudo_ldap_parse_option(copy, &var, &val);
- early = is_early_default_byname(var);
+ early = is_early_default(var);
if (early != NULL) {
set_early_default(var, val, op,
source ? source : "sudoRole UNKNOWN", 0, false, early);
goto done;
}
op = sudo_ldap_parse_option(copy, &var, &val);
- if (is_early_default_byname(var) == NULL) {
+ if (is_early_default(var) == NULL) {
set_default(var, val, op,
source ? source : "sudoRole UNKNOWN", 0, false);
}
debug_decl(sudo_file_close, SUDOERS_DEBUG_NSS)
/* Free parser data structures and close sudoers file. */
- init_parser(NULL, false, false);
+ init_parser(NULL, false);
if (nss->handle != NULL) {
fclose(nss->handle);
nss->handle = NULL;
if (nss->handle == NULL)
debug_return_int(-1);
- init_parser(sudoers_file, false, false);
+ init_parser(sudoers_file, false);
sudoersin = nss->handle;
if (sudoersparse() != 0 || parse_error) {
if (errorlineno != -1) {
char *var; /* variable name */
char *val; /* variable value */
struct member_list *binding; /* user/host/runas binding */
- int type; /* DEFAULTS{,_USER,_RUNAS,_HOST} */
- int op; /* true, false, '+', '-' */
- int idx; /* index into sudo_defs_table */
- union sudo_defs_val sd_un; /* parsed value */
+ char *file; /* file Defaults entry was in */
+ short type; /* DEFAULTS{,_USER,_RUNAS,_HOST} */
+ char op; /* true, false, '+', '-' */
+ char error; /* parse error flag */
+ int lineno; /* line number of Defaults entry */
};
/*
bool init_aliases(void);
/* gram.c */
-bool init_parser(const char *path, bool quiet, bool strict_defaults);
+bool init_parser(const char *path, bool quiet);
void free_members(struct member_list *members);
/* match_addr.c */
#include "sudo_compat.h"
#include "sudo_queue.h"
-#include "defaults.h"
#include "parse.h"
#include "toke.h"
#include "sudo_plugin.h"
goto done;
}
op = sudo_sss_parse_option(copy, &var, &val);
- early = is_early_default_byname(var);
+ early = is_early_default(var);
if (early != NULL) {
set_early_default(var, val, op,
source ? source : "sudoRole UNKNOWN", 0, false, early);
goto done;
}
op = sudo_sss_parse_option(copy, &var, &val);
- if (is_early_default_byname(var) == NULL) {
+ if (is_early_default(var) == NULL) {
set_default(var, val, op,
source ? source : "sudoRole UNKNOWN", 0, false);
}
}
/* Allocate space for data structures in the parser. */
- init_parser("sudoers", false, true);
+ init_parser("sudoers", false);
/*
* Set runas passwd/group entries based on command line or sudoers.
*/
if ((sudoersin = open_sudoers(sudoers_file, true, NULL)) == NULL)
exit(1);
- init_parser(sudoers_file, quiet, true);
+ init_parser(sudoers_file, quiet);
sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
(void) sudoersparse();
(void) update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER, quiet);
debug_return_bool(ret);
}
+/*
+ * Check Defaults and Alias entries.
+ * Sets parse_error on error and errorfile/errorlineno if possible.
+ */
+static void
+check_defaults_and_aliases(bool strict, bool quiet)
+{
+ debug_decl(check_defaults_and_aliases, SUDOERS_DEBUG_UTIL)
+
+ if (!check_defaults(quiet)) {
+ struct defaults *d;
+ free(errorfile);
+ errorfile = NULL;
+ /* XXX - should edit all files with errors */
+ TAILQ_FOREACH(d, &defaults, entries) {
+ if (d->error) {
+ /* Defaults parse error, adopt the file name. */
+ errorfile = d->file;
+ errorlineno = d->lineno;
+ d->file = NULL;
+ d->error = false; /* paranoia */
+ break;
+ }
+ }
+ parse_error = true;
+ } else if (check_aliases(strict, quiet) != 0) {
+ free(errorfile);
+ errorfile = NULL; /* don't know which file */
+ parse_error = true;
+ }
+ debug_return;
+}
+
/*
* Parse sudoers after editing and re-edit any ones that caused a parse error.
*/
/* Clean slate for each parse */
if (!init_defaults())
sudo_fatalx(U_("unable to initialize sudoers default values"));
- init_parser(sp->path, quiet, true);
+ init_parser(sp->path, quiet);
/* Parse the sudoers temp file(s) */
sudoersrestart(fp);
fclose(sudoersin);
if (!parse_error) {
(void) update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER, true);
- if (check_aliases(strict, quiet) != 0) {
- parse_error = true;
- free(errorfile);
- errorfile = NULL; /* don't know which file */
- }
+ check_defaults_and_aliases(strict, quiet);
}
sudoers_setlocale(oldlocale, NULL);
}
if (!init_defaults())
sudo_fatalx(U_("unable to initialize sudoers default values"));
- init_parser(sudoers_file, quiet, true);
+ init_parser(sudoers_file, quiet);
sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
if (sudoersparse() && !parse_error) {
if (!quiet)
}
if (!parse_error) {
(void) update_defaults(SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER, true);
- if (check_aliases(strict, quiet) != 0) {
- parse_error = true;
- free(errorfile);
- errorfile = NULL; /* don't know which file */
- }
+ check_defaults_and_aliases(strict, quiet);
}
sudoers_setlocale(oldlocale, NULL);
ok = !parse_error;
goto done;
}
}
- init_parser(sudoers_path, quiet, true);
+ init_parser(sudoers_path, quiet);
if (sudoersparse() && !parse_error) {
if (!quiet)
sudo_warnx(U_("failed to parse %s file, unknown error"), sudoers_path);