From 1bfe03000d06c9fb8391d79a29a6d55d6209b7fa Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Sun, 15 Apr 2018 08:14:46 -0600 Subject: [PATCH] Prune alias contents when pruning and expanding aliases. This abuses the userlist_matches_filter() and hostlist_matches_filter() functions. A better approach would be to call the correct function from user_matches() and host_matches(). --- plugins/sudoers/cvtsudoers.c | 45 +++++++++++++++++++++++++++++++++++- plugins/sudoers/match.c | 2 ++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/plugins/sudoers/cvtsudoers.c b/plugins/sudoers/cvtsudoers.c index 1a6a07b10..0b9ec4e26 100644 --- a/plugins/sudoers/cvtsudoers.c +++ b/plugins/sudoers/cvtsudoers.c @@ -89,6 +89,7 @@ static int cvtsudoers_parse_suppression(char *expression); static void filter_userspecs(struct cvtsudoers_config *conf); static void filter_defaults(struct cvtsudoers_config *conf); static void alias_remove_unused(void); +static void alias_prune(struct cvtsudoers_config *conf); int main(int argc, char *argv[]) @@ -323,8 +324,11 @@ main(int argc, char *argv[]) /* Apply filters. */ filter_userspecs(conf); filter_defaults(conf); - if (filters != NULL) + if (filters != NULL) { alias_remove_unused(); + if (conf->prune_matches && conf->expand_aliases) + alias_prune(conf); + } switch (output_format) { case format_json: @@ -707,6 +711,7 @@ userlist_matches_filter(struct member_list *users, struct cvtsudoers_config *con struct passwd *pw = NULL; /* An upper case filter entry may be a User_Alias */ + /* XXX - doesn't handle nested aliases */ if (m->type == ALIAS && !conf->expand_aliases) { if (strcmp(m->name, s->str) == 0) { matched = true; @@ -790,6 +795,7 @@ hostlist_matches_filter(struct member_list *hostlist, struct cvtsudoers_config * shost = shosts[n++]; /* An upper case filter entry may be a Host_Alias */ + /* XXX - doesn't handle nested aliases */ if (m->type == ALIAS && !conf->expand_aliases) { if (strcmp(m->name, s->str) == 0) { matched = true; @@ -1187,6 +1193,43 @@ alias_remove_unused(void) debug_return; } +/* + * Prune out non-matching entries from user and host aliases. + */ +int +alias_prune_helper(void *v, void *cookie) +{ + struct alias *a = v; + struct cvtsudoers_config *conf = cookie; + + /* XXX - misue of these functions */ + switch (a->type) { + case USERALIAS: + userlist_matches_filter(&a->members, conf); + break; + case HOSTALIAS: + hostlist_matches_filter(&a->members, conf); + break; + default: + break; + } + + return 0; +} + +/* + * Prune out non-matching entries from within aliases. + */ +static void +alias_prune(struct cvtsudoers_config *conf) +{ + debug_decl(alias_prune, SUDOERS_DEBUG_ALIAS) + + alias_apply(alias_prune_helper, conf); + + debug_return; +} + /* * Convert back to sudoers. */ diff --git a/plugins/sudoers/match.c b/plugins/sudoers/match.c index 1ccbc1f0a..bf3eaa1cc 100644 --- a/plugins/sudoers/match.c +++ b/plugins/sudoers/match.c @@ -116,6 +116,7 @@ user_matches(const struct passwd *pw, const struct member *m) break; case ALIAS: if ((a = alias_get(m->name, USERALIAS)) != NULL) { + /* XXX */ int rc = userlist_matches(pw, &a->members); if (rc != UNSPEC) matched = m->negated ? !rc : rc; @@ -325,6 +326,7 @@ host_matches(const struct passwd *pw, const char *lhost, const char *shost, break; case ALIAS: if ((a = alias_get(m->name, HOSTALIAS)) != NULL) { + /* XXX */ int rc = hostlist_matches_int(pw, lhost, shost, &a->members); if (rc != UNSPEC) matched = m->negated ? !rc : rc; -- 2.40.0