Skip to content

Commit f2b94c9

Browse files
committed
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. --HG-- branch : 1.9
1 parent ef7cc6e commit f2b94c9

3 files changed

Lines changed: 65 additions & 12 deletions

File tree

plugins/sudoers/match.c

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* SPDX-License-Identifier: ISC
33
*
4-
* Copyright (c) 1996, 1998-2005, 2007-2019
4+
* Copyright (c) 1996, 1998-2005, 2007-2023
55
* Todd C. Miller <[email protected]>
66
*
77
* Permission to use, copy, modify, and distribute this software for any
@@ -418,6 +418,44 @@ cmnd_matches(struct sudoers_parse_tree *parse_tree, const struct member *m,
418418
debug_return_int(matched);
419419
}
420420

421+
/*
422+
* Like cmnd_matches() but only matches against the ALL command.
423+
* Returns ALLOW, DENY or UNSPEC.
424+
*/
425+
int
426+
cmnd_matches_all(struct sudoers_parse_tree *parse_tree, const struct member *m,
427+
const char *runchroot, struct cmnd_info *info)
428+
{
429+
const bool negated = m->negated;
430+
struct sudo_command *c;
431+
int matched = UNSPEC;
432+
struct alias *a;
433+
debug_decl(cmnd_matches_all, SUDOERS_DEBUG_MATCH);
434+
435+
switch (m->type) {
436+
case ALL:
437+
c = (struct sudo_command *)m->name;
438+
if (command_matches(c->cmnd, c->args, runchroot, info, &c->digests))
439+
matched = !negated;
440+
break;
441+
case ALIAS:
442+
a = alias_get(parse_tree, m->name, CMNDALIAS);
443+
if (a != NULL) {
444+
TAILQ_FOREACH_REVERSE(m, &a->members, member_list, entries) {
445+
matched = cmnd_matches_all(parse_tree, m, runchroot, info);
446+
if (matched != UNSPEC) {
447+
if (negated)
448+
matched = !matched;
449+
break;
450+
}
451+
}
452+
alias_put(a);
453+
}
454+
break;
455+
}
456+
debug_return_int(matched);
457+
}
458+
421459
/*
422460
* Returns true if the hostname matches the pattern, else false
423461
*/

plugins/sudoers/parse.c

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* SPDX-License-Identifier: ISC
33
*
4-
* Copyright (c) 2004-2005, 2007-2021 Todd C. Miller <[email protected]>
4+
* Copyright (c) 2004-2005, 2007-2023 Todd C. Miller <[email protected]>
55
*
66
* Permission to use, copy, modify, and distribute this software for any
77
* 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,
6767
struct privilege *priv;
6868
struct userspec *us;
6969
struct defaults *def;
70-
int nopass, match = DENY;
70+
int cmnd_match, nopass, match = DENY;
7171
enum def_tuple pwcheck;
7272
debug_decl(sudoers_lookup_pseudo, SUDOERS_DEBUG_PARSER);
7373

@@ -133,26 +133,40 @@ sudoers_lookup_pseudo(struct sudo_nss_list *snl, struct passwd *pw,
133133
*/
134134
switch (runas_matches_pw(nss->parse_tree, cs, list_pw)) {
135135
case DENY:
136-
continue;
136+
break;
137137
case ALLOW:
138+
/*
139+
* RunAs user matches list user.
140+
* Match on command "list" or ALL.
141+
*/
142+
cmnd_match = cmnd_matches(nss->parse_tree,
143+
cs->cmnd, cs->runchroot, NULL);
144+
if (cmnd_match != UNSPEC) {
145+
match = cmnd_match;
146+
goto done;
147+
}
138148
break;
139149
default:
150+
/*
151+
* RunAs user doesn't match list user. Only allow
152+
* listing if the user has "sudo ALL" for root.
153+
*/
140154
if (root_pw != NULL && runas_matches_pw(nss->parse_tree,
141155
cs, root_pw) == ALLOW) {
142-
break;
156+
cmnd_match = cmnd_matches_all(nss->parse_tree,
157+
cs->cmnd, cs->runchroot, NULL);
158+
if (cmnd_match != UNSPEC) {
159+
match = cmnd_match;
160+
goto done;
161+
}
143162
}
144-
continue;
145-
}
146-
147-
/* Match command: "list" or ALL. */
148-
if (cmnd_matches(nss->parse_tree, cs->cmnd, cs->runchroot,
149-
NULL) == ALLOW) {
150-
match = ALLOW;
163+
break;
151164
}
152165
}
153166
}
154167
}
155168
}
169+
done:
156170
if (root_pw != NULL)
157171
sudo_pw_delref(root_pw);
158172
if (match == ALLOW || user_uid == 0) {

plugins/sudoers/parse.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ bool netgr_matches(const char *netgr, const char *lhost, const char *shost, cons
405405
bool usergr_matches(const char *group, const char *user, const struct passwd *pw);
406406
bool userpw_matches(const char *sudoers_user, const char *user, const struct passwd *pw);
407407
int cmnd_matches(struct sudoers_parse_tree *parse_tree, const struct member *m, const char *runchroot, struct cmnd_info *info);
408+
int cmnd_matches_all(struct sudoers_parse_tree *parse_tree, const struct member *m, const char *runchroot, struct cmnd_info *info);
408409
int cmndlist_matches(struct sudoers_parse_tree *parse_tree, const struct member_list *list, const char *runchroot, struct cmnd_info *info);
409410
int host_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw, const char *host, const char *shost, const struct member *m);
410411
int hostlist_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw, const struct member_list *list);

0 commit comments

Comments
 (0)