mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-28 12:57:50 +00:00
runaslist_matches: split out user_list and group_list matching.
This makes it possible to call the appropriate runas user or group list match function when resolving aliases instead of calling runaslist_matches() itself. Fixes a bug that prevented the group specified via "sudo -g" from matching when a Runas_Alias was used in the user or group portion of a Runas_Spec.
This commit is contained in:
parent
4710283516
commit
78e65e14ea
@ -58,8 +58,6 @@
|
|||||||
#include "sudoers.h"
|
#include "sudoers.h"
|
||||||
#include <gram.h>
|
#include <gram.h>
|
||||||
|
|
||||||
static struct member_list empty = TAILQ_HEAD_INITIALIZER(empty);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether user described by pw matches member.
|
* Check whether user described by pw matches member.
|
||||||
* Returns ALLOW, DENY or UNSPEC.
|
* Returns ALLOW, DENY or UNSPEC.
|
||||||
@ -142,37 +140,22 @@ runas_getgroups(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for user described by pw in a list of members.
|
* Check whether the requested runas user matches user_list, the
|
||||||
* If both lists are empty compare against def_runas_default.
|
* user portion of a sudoers runaslist. If user_list is NULL, a
|
||||||
|
* list containing runas_default is used.
|
||||||
* Returns ALLOW, DENY or UNSPEC.
|
* Returns ALLOW, DENY or UNSPEC.
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
runaslist_matches(const struct sudoers_parse_tree *parse_tree,
|
runas_userlist_matches(const struct sudoers_parse_tree *parse_tree,
|
||||||
const struct member_list *user_list, const struct member_list *group_list,
|
const struct member_list *user_list, struct member **matching_user)
|
||||||
struct member **matching_user, struct member **matching_group)
|
|
||||||
{
|
{
|
||||||
const char *lhost = parse_tree->lhost ? parse_tree->lhost : user_runhost;
|
const char *lhost = parse_tree->lhost ? parse_tree->lhost : user_runhost;
|
||||||
const char *shost = parse_tree->shost ? parse_tree->shost : user_srunhost;
|
const char *shost = parse_tree->shost ? parse_tree->shost : user_srunhost;
|
||||||
struct member_list _user_list = TAILQ_HEAD_INITIALIZER(_user_list);
|
|
||||||
struct member m_user;
|
|
||||||
int user_matched = UNSPEC;
|
int user_matched = UNSPEC;
|
||||||
int group_matched = UNSPEC;
|
|
||||||
struct member *m;
|
struct member *m;
|
||||||
struct alias *a;
|
struct alias *a;
|
||||||
int rc;
|
debug_decl(runas_userlist_matches, SUDOERS_DEBUG_MATCH);
|
||||||
debug_decl(runaslist_matches, SUDOERS_DEBUG_MATCH);
|
|
||||||
|
|
||||||
/* If no runas user listed in sudoers, use a default value. */
|
|
||||||
if (user_list == NULL) {
|
|
||||||
m_user.name = def_runas_default;
|
|
||||||
m_user.type = WORD;
|
|
||||||
m_user.negated = false;
|
|
||||||
TAILQ_INSERT_HEAD(&_user_list, &m_user, entries);
|
|
||||||
user_list = &_user_list;
|
|
||||||
matching_user = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check runas user. */
|
|
||||||
TAILQ_FOREACH_REVERSE(m, user_list, member_list, entries) {
|
TAILQ_FOREACH_REVERSE(m, user_list, member_list, entries) {
|
||||||
switch (m->type) {
|
switch (m->type) {
|
||||||
case ALL:
|
case ALL:
|
||||||
@ -192,8 +175,8 @@ runaslist_matches(const struct sudoers_parse_tree *parse_tree,
|
|||||||
case ALIAS:
|
case ALIAS:
|
||||||
a = alias_get(parse_tree, m->name, RUNASALIAS);
|
a = alias_get(parse_tree, m->name, RUNASALIAS);
|
||||||
if (a != NULL) {
|
if (a != NULL) {
|
||||||
rc = runaslist_matches(parse_tree, &a->members,
|
const int rc = runas_userlist_matches(parse_tree,
|
||||||
&empty, matching_user, NULL);
|
&a->members, matching_user);
|
||||||
if (rc != UNSPEC)
|
if (rc != UNSPEC)
|
||||||
user_matched = m->negated ? !rc : rc;
|
user_matched = m->negated ? !rc : rc;
|
||||||
alias_put(a);
|
alias_put(a);
|
||||||
@ -216,9 +199,23 @@ runaslist_matches(const struct sudoers_parse_tree *parse_tree,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
debug_return_int(user_matched);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether the requested runas group matches group_list, the
|
||||||
|
* group portion of a sudoers runaslist, or the runas user's groups.
|
||||||
|
* Returns ALLOW, DENY or UNSPEC.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
runas_grouplist_matches(const struct sudoers_parse_tree *parse_tree,
|
||||||
|
const struct member_list *group_list, struct member **matching_group)
|
||||||
|
{
|
||||||
|
int group_matched = UNSPEC;
|
||||||
|
struct member *m;
|
||||||
|
struct alias *a;
|
||||||
|
debug_decl(runas_grouplist_matches, SUDOERS_DEBUG_MATCH);
|
||||||
|
|
||||||
/* Check runas group, if one was specified. */
|
|
||||||
if (ISSET(sudo_user.flags, RUNAS_GROUP_SPECIFIED)) {
|
|
||||||
if (group_list != NULL) {
|
if (group_list != NULL) {
|
||||||
TAILQ_FOREACH_REVERSE(m, group_list, member_list, entries) {
|
TAILQ_FOREACH_REVERSE(m, group_list, member_list, entries) {
|
||||||
switch (m->type) {
|
switch (m->type) {
|
||||||
@ -228,8 +225,8 @@ runaslist_matches(const struct sudoers_parse_tree *parse_tree,
|
|||||||
case ALIAS:
|
case ALIAS:
|
||||||
a = alias_get(parse_tree, m->name, RUNASALIAS);
|
a = alias_get(parse_tree, m->name, RUNASALIAS);
|
||||||
if (a != NULL) {
|
if (a != NULL) {
|
||||||
rc = runaslist_matches(parse_tree, &empty,
|
const int rc = runas_grouplist_matches(parse_tree,
|
||||||
&a->members, NULL, matching_group);
|
&a->members, matching_group);
|
||||||
if (rc != UNSPEC)
|
if (rc != UNSPEC)
|
||||||
group_matched = m->negated ? !rc : rc;
|
group_matched = m->negated ? !rc : rc;
|
||||||
alias_put(a);
|
alias_put(a);
|
||||||
@ -268,6 +265,41 @@ runaslist_matches(const struct sudoers_parse_tree *parse_tree,
|
|||||||
sudo_gidlist_delref(runas_groups);
|
sudo_gidlist_delref(runas_groups);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug_return_int(group_matched);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check whether the sudoers runaslist, composed of user_list and
|
||||||
|
* group_list, matches the runas user/group requested by the user.
|
||||||
|
* Either (or both) user_list and group_list may be NULL.
|
||||||
|
* If user_list is NULL, a list containing runas_default is used.
|
||||||
|
* Returns ALLOW, DENY or UNSPEC.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
runaslist_matches(const struct sudoers_parse_tree *parse_tree,
|
||||||
|
const struct member_list *user_list, const struct member_list *group_list,
|
||||||
|
struct member **matching_user, struct member **matching_group)
|
||||||
|
{
|
||||||
|
struct member_list _user_list = TAILQ_HEAD_INITIALIZER(_user_list);
|
||||||
|
int user_matched, group_matched = UNSPEC;
|
||||||
|
struct member m_user;
|
||||||
|
debug_decl(runaslist_matches, SUDOERS_DEBUG_MATCH);
|
||||||
|
|
||||||
|
/* If no runas user listed in sudoers, use the default value. */
|
||||||
|
if (user_list == NULL) {
|
||||||
|
m_user.name = def_runas_default;
|
||||||
|
m_user.type = WORD;
|
||||||
|
m_user.negated = false;
|
||||||
|
TAILQ_INSERT_HEAD(&_user_list, &m_user, entries);
|
||||||
|
user_list = &_user_list;
|
||||||
|
matching_user = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
user_matched = runas_userlist_matches(parse_tree, user_list, matching_user);
|
||||||
|
if (ISSET(sudo_user.flags, RUNAS_GROUP_SPECIFIED)) {
|
||||||
|
group_matched = runas_grouplist_matches(parse_tree, group_list,
|
||||||
|
matching_group);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user_matched == DENY || group_matched == DENY)
|
if (user_matched == DENY || group_matched == DENY)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user