Move alias checking code out of visudo.c and into check_aliases.c.
This commit is contained in:
1
MANIFEST
1
MANIFEST
@@ -499,6 +499,7 @@ plugins/sudoers/bsm_audit.c
|
||||
plugins/sudoers/bsm_audit.h
|
||||
plugins/sudoers/check.c
|
||||
plugins/sudoers/check.h
|
||||
plugins/sudoers/check_aliases.c
|
||||
plugins/sudoers/cvtsudoers.c
|
||||
plugins/sudoers/cvtsudoers.h
|
||||
plugins/sudoers/cvtsudoers_json.c
|
||||
|
@@ -186,8 +186,8 @@ SUDOERS_OBJS = $(AUTH_OBJS) audit.lo boottime.lo check.lo editor.lo env.lo \
|
||||
|
||||
SUDOERS_IOBJS = $(SUDOERS_OBJS:.lo=.i)
|
||||
|
||||
VISUDO_OBJS = editor.lo find_path.lo goodpath.lo locale.lo stubs.o \
|
||||
sudo_printf.o visudo.o
|
||||
VISUDO_OBJS = check_aliases.o editor.lo find_path.lo goodpath.lo locale.lo \
|
||||
stubs.o sudo_printf.o visudo.o
|
||||
|
||||
VISUDO_IOBJS = sudo_printf.i visudo.i
|
||||
|
||||
@@ -973,6 +973,30 @@ check_addr.i: $(srcdir)/regress/parser/check_addr.c $(devdir)/def_data.h \
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
check_addr.plog: check_addr.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/parser/check_addr.c --i-file $< --output-file $@
|
||||
check_aliases.o: $(srcdir)/check_aliases.c $(devdir)/def_data.h \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
|
||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
|
||||
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
|
||||
$(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
|
||||
$(top_builddir)/pathnames.h
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/check_aliases.c
|
||||
check_aliases.i: $(srcdir)/check_aliases.c $(devdir)/def_data.h \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
|
||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
|
||||
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
|
||||
$(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
|
||||
$(top_builddir)/pathnames.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
check_aliases.plog: check_aliases.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/check_aliases.c --i-file $< --output-file $@
|
||||
check_base64.o: $(srcdir)/regress/parser/check_base64.c \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
@@ -1551,10 +1575,10 @@ fuzz_sudoers.o: $(srcdir)/regress/fuzz/fuzz_sudoers.c $(devdir)/def_data.h \
|
||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
|
||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
|
||||
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
|
||||
$(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
|
||||
$(top_builddir)/pathnames.h
|
||||
$(srcdir)/defaults.h $(srcdir)/interfaces.h \
|
||||
$(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
|
||||
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
|
||||
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/fuzz/fuzz_sudoers.c
|
||||
fuzz_sudoers.i: $(srcdir)/regress/fuzz/fuzz_sudoers.c $(devdir)/def_data.h \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
@@ -1562,10 +1586,10 @@ fuzz_sudoers.i: $(srcdir)/regress/fuzz/fuzz_sudoers.c $(devdir)/def_data.h \
|
||||
$(incdir)/sudo_eventlog.h $(incdir)/sudo_fatal.h \
|
||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
|
||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||
$(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
|
||||
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
|
||||
$(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
|
||||
$(top_builddir)/pathnames.h
|
||||
$(srcdir)/defaults.h $(srcdir)/interfaces.h \
|
||||
$(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
|
||||
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
|
||||
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
fuzz_sudoers.plog: fuzz_sudoers.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/fuzz/fuzz_sudoers.c --i-file $< --output-file $@
|
||||
|
@@ -343,6 +343,9 @@ void alias_apply(struct sudoers_parse_tree *parse_tree, int (*func)(struct sudoe
|
||||
void alias_free(void *a);
|
||||
void alias_put(struct alias *a);
|
||||
|
||||
/* check_aliases.c */
|
||||
int check_aliases(struct sudoers_parse_tree *parse_tree, bool strict, bool quiet, int (*cb_unused)(struct sudoers_parse_tree *, struct alias *, void *));
|
||||
|
||||
/* gram.c */
|
||||
extern struct sudoers_parse_tree parsed_policy;
|
||||
bool init_parser(const char *path, bool quiet, bool strict);
|
||||
|
@@ -85,7 +85,6 @@ TAILQ_HEAD(sudoersfile_list, sudoersfile);
|
||||
*/
|
||||
static void quit(int);
|
||||
static int whatnow(void);
|
||||
static int check_aliases(bool strict, bool quiet);
|
||||
static char *get_editor(int *editor_argc, char ***editor_argv);
|
||||
static bool check_syntax(const char *, bool, bool, bool);
|
||||
static bool edit_sudoers(struct sudoersfile *, char *, int, char **, int);
|
||||
@@ -565,7 +564,7 @@ check_defaults_and_aliases(bool strict, bool quiet)
|
||||
}
|
||||
parse_error = true;
|
||||
}
|
||||
if (check_aliases(strict, quiet) != 0) {
|
||||
if (check_aliases(&parsed_policy, strict, quiet, print_unused) != 0) {
|
||||
parse_error = true;
|
||||
}
|
||||
debug_return;
|
||||
@@ -1058,128 +1057,17 @@ open_sudoers(const char *path, bool doedit, bool *keepopen)
|
||||
debug_return_ptr(fp);
|
||||
}
|
||||
|
||||
static int
|
||||
check_alias(char *name, int type, char *file, int line, int column,
|
||||
bool strict, bool quiet)
|
||||
{
|
||||
struct member *m;
|
||||
struct alias *a;
|
||||
int errors = 0;
|
||||
debug_decl(check_alias, SUDOERS_DEBUG_ALIAS);
|
||||
|
||||
if ((a = alias_get(&parsed_policy, name, type)) != NULL) {
|
||||
/* check alias contents */
|
||||
TAILQ_FOREACH(m, &a->members, entries) {
|
||||
if (m->type != ALIAS)
|
||||
continue;
|
||||
errors += check_alias(m->name, type, a->file, a->line, a->column,
|
||||
strict, quiet);
|
||||
}
|
||||
alias_put(a);
|
||||
} else {
|
||||
if (!quiet) {
|
||||
if (errno == ELOOP) {
|
||||
fprintf(stderr, strict ?
|
||||
U_("Error: %s:%d:%d: cycle in %s \"%s\"") :
|
||||
U_("Warning: %s:%d:%d: cycle in %s \"%s\""),
|
||||
file, line, column, alias_type_to_string(type), name);
|
||||
} else {
|
||||
fprintf(stderr, strict ?
|
||||
U_("Error: %s:%d:%d: %s \"%s\" referenced but not defined") :
|
||||
U_("Warning: %s:%d:%d: %s \"%s\" referenced but not defined"),
|
||||
file, line, column, alias_type_to_string(type), name);
|
||||
}
|
||||
fputc('\n', stderr);
|
||||
if (strict && errorfile == NULL) {
|
||||
errorfile = rcstr_addref(file);
|
||||
errorlineno = line;
|
||||
}
|
||||
}
|
||||
errors++;
|
||||
}
|
||||
|
||||
debug_return_int(errors);
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate through the sudoers datastructures looking for undefined
|
||||
* aliases or unused aliases.
|
||||
*/
|
||||
static int
|
||||
check_aliases(bool strict, bool quiet)
|
||||
{
|
||||
struct rbtree *used_aliases;
|
||||
struct cmndspec *cs;
|
||||
struct member *m;
|
||||
struct privilege *priv;
|
||||
struct userspec *us;
|
||||
int errors = 0;
|
||||
debug_decl(check_aliases, SUDOERS_DEBUG_ALIAS);
|
||||
|
||||
used_aliases = alloc_aliases();
|
||||
if (used_aliases == NULL) {
|
||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
debug_return_int(-1);
|
||||
}
|
||||
|
||||
/* Forward check. */
|
||||
TAILQ_FOREACH(us, &parsed_policy.userspecs, entries) {
|
||||
TAILQ_FOREACH(m, &us->users, entries) {
|
||||
if (m->type == ALIAS) {
|
||||
errors += check_alias(m->name, USERALIAS,
|
||||
us->file, us->line, us->column, strict, quiet);
|
||||
}
|
||||
}
|
||||
TAILQ_FOREACH(priv, &us->privileges, entries) {
|
||||
TAILQ_FOREACH(m, &priv->hostlist, entries) {
|
||||
if (m->type == ALIAS) {
|
||||
errors += check_alias(m->name, HOSTALIAS,
|
||||
us->file, us->line, us->column, strict, quiet);
|
||||
}
|
||||
}
|
||||
TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
|
||||
if (cs->runasuserlist != NULL) {
|
||||
TAILQ_FOREACH(m, cs->runasuserlist, entries) {
|
||||
if (m->type == ALIAS) {
|
||||
errors += check_alias(m->name, RUNASALIAS,
|
||||
us->file, us->line, us->column, strict, quiet);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cs->runasgrouplist != NULL) {
|
||||
TAILQ_FOREACH(m, cs->runasgrouplist, entries) {
|
||||
if (m->type == ALIAS) {
|
||||
errors += check_alias(m->name, RUNASALIAS,
|
||||
us->file, us->line, us->column, strict, quiet);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((m = cs->cmnd)->type == ALIAS) {
|
||||
errors += check_alias(m->name, CMNDALIAS,
|
||||
us->file, us->line, us->column, strict, quiet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Reverse check (destructive) */
|
||||
if (!alias_find_used(&parsed_policy, used_aliases))
|
||||
errors++;
|
||||
free_aliases(used_aliases);
|
||||
|
||||
/* If all aliases were referenced we will have an empty tree. */
|
||||
if (!no_aliases(&parsed_policy) && !quiet)
|
||||
alias_apply(&parsed_policy, print_unused, NULL);
|
||||
|
||||
debug_return_int(strict ? errors : 0);
|
||||
}
|
||||
|
||||
/* Display unused aliases from check_aliases(). */
|
||||
static int
|
||||
print_unused(struct sudoers_parse_tree *parse_tree, struct alias *a, void *v)
|
||||
{
|
||||
fprintf(stderr, U_("Warning: %s:%d:%d: unused %s \"%s\""),
|
||||
a->file, a->line, a->column, alias_type_to_string(a->type), a->name);
|
||||
const bool quiet = *((bool *)v);
|
||||
|
||||
if (!quiet) {
|
||||
fprintf(stderr, U_("Warning: %s:%d:%d: unused %s \"%s\""), a->file,
|
||||
a->line, a->column, alias_type_to_string(a->type), a->name);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user