summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <Todd.Miller@sudo.ws>2023-03-03 13:57:27 -0700
committerTodd C. Miller <Todd.Miller@sudo.ws>2023-03-03 13:57:27 -0700
commit190394add122e06b00c95d2e022aabfd84107f35 (patch)
treebe032b5da2380b40c8d957330c4814bb8a9df2cf
parent63aa1cd20a5be07a1d948e3567583c367f4d22f2 (diff)
downloadsudo-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.c40
-rw-r--r--plugins/sudoers/parse.c36
-rw-r--r--plugins/sudoers/parse.h1
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);