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/bsm_audit.h
|
||||||
plugins/sudoers/check.c
|
plugins/sudoers/check.c
|
||||||
plugins/sudoers/check.h
|
plugins/sudoers/check.h
|
||||||
|
plugins/sudoers/check_aliases.c
|
||||||
plugins/sudoers/cvtsudoers.c
|
plugins/sudoers/cvtsudoers.c
|
||||||
plugins/sudoers/cvtsudoers.h
|
plugins/sudoers/cvtsudoers.h
|
||||||
plugins/sudoers/cvtsudoers_json.c
|
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)
|
SUDOERS_IOBJS = $(SUDOERS_OBJS:.lo=.i)
|
||||||
|
|
||||||
VISUDO_OBJS = editor.lo find_path.lo goodpath.lo locale.lo stubs.o \
|
VISUDO_OBJS = check_aliases.o editor.lo find_path.lo goodpath.lo locale.lo \
|
||||||
sudo_printf.o visudo.o
|
stubs.o sudo_printf.o visudo.o
|
||||||
|
|
||||||
VISUDO_IOBJS = sudo_printf.i visudo.i
|
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) $<
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
check_addr.plog: check_addr.i
|
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 $@
|
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 \
|
check_base64.o: $(srcdir)/regress/parser/check_base64.c \
|
||||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||||
$(incdir)/sudo_util.h $(top_builddir)/config.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_eventlog.h $(incdir)/sudo_fatal.h \
|
||||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
|
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
|
||||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||||
$(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
|
$(srcdir)/defaults.h $(srcdir)/interfaces.h \
|
||||||
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
|
$(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
|
||||||
$(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
|
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
|
||||||
$(top_builddir)/pathnames.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
|
$(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 \
|
fuzz_sudoers.i: $(srcdir)/regress/fuzz/fuzz_sudoers.c $(devdir)/def_data.h \
|
||||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.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_eventlog.h $(incdir)/sudo_fatal.h \
|
||||||
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
|
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
|
||||||
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
|
||||||
$(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
|
$(srcdir)/defaults.h $(srcdir)/interfaces.h \
|
||||||
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
|
$(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/sudo_nss.h \
|
||||||
$(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
|
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
|
||||||
$(top_builddir)/pathnames.h
|
$(top_builddir)/config.h $(top_builddir)/pathnames.h
|
||||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||||
fuzz_sudoers.plog: fuzz_sudoers.i
|
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 $@
|
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_free(void *a);
|
||||||
void alias_put(struct alias *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 */
|
/* gram.c */
|
||||||
extern struct sudoers_parse_tree parsed_policy;
|
extern struct sudoers_parse_tree parsed_policy;
|
||||||
bool init_parser(const char *path, bool quiet, bool strict);
|
bool init_parser(const char *path, bool quiet, bool strict);
|
||||||
|
@@ -85,7 +85,6 @@ TAILQ_HEAD(sudoersfile_list, sudoersfile);
|
|||||||
*/
|
*/
|
||||||
static void quit(int);
|
static void quit(int);
|
||||||
static int whatnow(void);
|
static int whatnow(void);
|
||||||
static int check_aliases(bool strict, bool quiet);
|
|
||||||
static char *get_editor(int *editor_argc, char ***editor_argv);
|
static char *get_editor(int *editor_argc, char ***editor_argv);
|
||||||
static bool check_syntax(const char *, bool, bool, bool);
|
static bool check_syntax(const char *, bool, bool, bool);
|
||||||
static bool edit_sudoers(struct sudoersfile *, char *, int, char **, int);
|
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;
|
parse_error = true;
|
||||||
}
|
}
|
||||||
if (check_aliases(strict, quiet) != 0) {
|
if (check_aliases(&parsed_policy, strict, quiet, print_unused) != 0) {
|
||||||
parse_error = true;
|
parse_error = true;
|
||||||
}
|
}
|
||||||
debug_return;
|
debug_return;
|
||||||
@@ -1058,128 +1057,17 @@ open_sudoers(const char *path, bool doedit, bool *keepopen)
|
|||||||
debug_return_ptr(fp);
|
debug_return_ptr(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
/* Display unused aliases from check_aliases(). */
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
print_unused(struct sudoers_parse_tree *parse_tree, struct alias *a, void *v)
|
print_unused(struct sudoers_parse_tree *parse_tree, struct alias *a, void *v)
|
||||||
{
|
{
|
||||||
fprintf(stderr, U_("Warning: %s:%d:%d: unused %s \"%s\""),
|
const bool quiet = *((bool *)v);
|
||||||
a->file, a->line, a->column, alias_type_to_string(a->type), a->name);
|
|
||||||
|
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);
|
fputc('\n', stderr);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user