diff options
author | Todd C. Miller <Todd.Miller@sudo.ws> | 2023-03-03 13:57:27 -0700 |
---|---|---|
committer | Todd C. Miller <Todd.Miller@sudo.ws> | 2023-03-03 13:57:27 -0700 |
commit | 190394add122e06b00c95d2e022aabfd84107f35 (patch) | |
tree | be032b5da2380b40c8d957330c4814bb8a9df2cf | |
parent | 63aa1cd20a5be07a1d948e3567583c367f4d22f2 (diff) | |
download | sudo-190394add122e06b00c95d2e022aabfd84107f35.tar.gz |
A user with "list" privs for root may not list all users.
A user with "sudo ALL" for root _is_ allowed to list any user.
-rw-r--r-- | plugins/sudoers/match.c | 40 | ||||
-rw-r--r-- | plugins/sudoers/parse.c | 36 | ||||
-rw-r--r-- | plugins/sudoers/parse.h | 1 |
3 files changed, 65 insertions, 12 deletions
diff --git a/plugins/sudoers/match.c b/plugins/sudoers/match.c index e5634c4da..445bdb248 100644 --- a/plugins/sudoers/match.c +++ b/plugins/sudoers/match.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: ISC * - * Copyright (c) 1996, 1998-2005, 2007-2019 + * Copyright (c) 1996, 1998-2005, 2007-2023 * Todd C. Miller <Todd.Miller@sudo.ws> * * Permission to use, copy, modify, and distribute this software for any @@ -419,6 +419,44 @@ cmnd_matches(struct sudoers_parse_tree *parse_tree, const struct member *m, } /* + * Like cmnd_matches() but only matches against the ALL command. + * Returns ALLOW, DENY or UNSPEC. + */ +int +cmnd_matches_all(struct sudoers_parse_tree *parse_tree, const struct member *m, + const char *runchroot, struct cmnd_info *info) +{ + const bool negated = m->negated; + struct sudo_command *c; + int matched = UNSPEC; + struct alias *a; + debug_decl(cmnd_matches_all, SUDOERS_DEBUG_MATCH); + + switch (m->type) { + case ALL: + c = (struct sudo_command *)m->name; + if (command_matches(c->cmnd, c->args, runchroot, info, &c->digests)) + matched = !negated; + break; + case ALIAS: + a = alias_get(parse_tree, m->name, CMNDALIAS); + if (a != NULL) { + TAILQ_FOREACH_REVERSE(m, &a->members, member_list, entries) { + matched = cmnd_matches_all(parse_tree, m, runchroot, info); + if (matched != UNSPEC) { + if (negated) + matched = !matched; + break; + } + } + alias_put(a); + } + break; + } + debug_return_int(matched); +} + +/* * Returns true if the hostname matches the pattern, else false */ bool diff --git a/plugins/sudoers/parse.c b/plugins/sudoers/parse.c index ec1e2a09a..820fae2ef 100644 --- a/plugins/sudoers/parse.c +++ b/plugins/sudoers/parse.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: ISC * - * Copyright (c) 2004-2005, 2007-2021 Todd C. Miller <Todd.Miller@sudo.ws> + * Copyright (c) 2004-2005, 2007-2023 Todd C. Miller <Todd.Miller@sudo.ws> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -67,7 +67,7 @@ sudoers_lookup_pseudo(struct sudo_nss_list *snl, struct passwd *pw, struct privilege *priv; struct userspec *us; struct defaults *def; - int nopass, match = DENY; + int cmnd_match, nopass, match = DENY; enum def_tuple pwcheck; debug_decl(sudoers_lookup_pseudo, SUDOERS_DEBUG_PARSER); @@ -133,26 +133,40 @@ sudoers_lookup_pseudo(struct sudo_nss_list *snl, struct passwd *pw, */ switch (runas_matches_pw(nss->parse_tree, cs, list_pw)) { case DENY: - continue; + break; case ALLOW: + /* + * RunAs user matches list user. + * Match on command "list" or ALL. + */ + cmnd_match = cmnd_matches(nss->parse_tree, + cs->cmnd, cs->runchroot, NULL); + if (cmnd_match != UNSPEC) { + match = cmnd_match; + goto done; + } break; default: + /* + * RunAs user doesn't match list user. Only allow + * listing if the user has "sudo ALL" for root. + */ if (root_pw != NULL && runas_matches_pw(nss->parse_tree, cs, root_pw) == ALLOW) { - break; + cmnd_match = cmnd_matches_all(nss->parse_tree, + cs->cmnd, cs->runchroot, NULL); + if (cmnd_match != UNSPEC) { + match = cmnd_match; + goto done; + } } - continue; - } - - /* Match command: "list" or ALL. */ - if (cmnd_matches(nss->parse_tree, cs->cmnd, cs->runchroot, - NULL) == ALLOW) { - match = ALLOW; + break; } } } } } +done: if (root_pw != NULL) sudo_pw_delref(root_pw); if (match == ALLOW || user_uid == 0) { diff --git a/plugins/sudoers/parse.h b/plugins/sudoers/parse.h index d9f4872d9..cda2a3f2e 100644 --- a/plugins/sudoers/parse.h +++ b/plugins/sudoers/parse.h @@ -405,6 +405,7 @@ bool netgr_matches(const char *netgr, const char *lhost, const char *shost, cons bool usergr_matches(const char *group, const char *user, const struct passwd *pw); bool userpw_matches(const char *sudoers_user, const char *user, const struct passwd *pw); int cmnd_matches(struct sudoers_parse_tree *parse_tree, const struct member *m, const char *runchroot, struct cmnd_info *info); +int cmnd_matches_all(struct sudoers_parse_tree *parse_tree, const struct member *m, const char *runchroot, struct cmnd_info *info); int cmndlist_matches(struct sudoers_parse_tree *parse_tree, const struct member_list *list, const char *runchroot, struct cmnd_info *info); int host_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw, const char *host, const char *shost, const struct member *m); int hostlist_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw, const struct member_list *list); |