sudo/backport-Make-all-match-functions-return-ALLOW-DENY-.patch
2024-01-10 10:21:39 +08:00

1118 lines
37 KiB
Diff

From 2ef90231a132547fa4236ff05fc0fafcd3f3d7a4 Mon Sep 17 00:00:00 2001
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
Date: Sat, 9 Sep 2023 14:07:06 -0600
Subject: [PATCH] Make all match functions return ALLOW/DENY not true/false.
Reference: https://github.com/sudo-project/sudo/commit/2ef90231a132547fa4236ff05fc0fafcd3f3d7a4
Conflict: match.c match_command.c lookup.c
---
plugins/sudoers/ldap.c | 2 +-
plugins/sudoers/match.c | 147 +++++++++++---------
plugins/sudoers/match_addr.c | 45 +++---
plugins/sudoers/match_command.c | 131 ++++++++---------
plugins/sudoers/match_digest.c | 12 +-
plugins/sudoers/parse.h | 16 +--
plugins/sudoers/regress/parser/check_addr.c | 2 +-
plugins/sudoers/sssd.c | 6 +-
8 files changed, 187 insertions(+), 174 deletions(-)
diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c
index 60ffeb9..44e4693 100644
--- a/plugins/sudoers/ldap.c
+++ b/plugins/sudoers/ldap.c
@@ -341,7 +341,7 @@ sudo_ldap_check_non_unix_group(LDAP *ld, LDAPMessage *entry, struct passwd *pw)
val = (*p)->bv_val;
if (*val == '+') {
if (netgr_matches(val, def_netgroup_tuple ? user_runhost : NULL,
- def_netgroup_tuple ? user_srunhost : NULL, pw->pw_name))
+ def_netgroup_tuple ? user_srunhost : NULL, pw->pw_name) == ALLOW)
ret = true;
DPRINTF2("ldap sudoUser netgroup '%s' ... %s", val,
ret ? "MATCH!" : "not");
diff --git a/plugins/sudoers/match.c b/plugins/sudoers/match.c
index 0891d63..efb596e 100644
--- a/plugins/sudoers/match.c
+++ b/plugins/sudoers/match.c
@@ -81,11 +81,11 @@ user_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
case NETGROUP:
if (netgr_matches(m->name,
def_netgroup_tuple ? lhost : NULL,
- def_netgroup_tuple ? shost : NULL, pw->pw_name))
+ def_netgroup_tuple ? shost : NULL, pw->pw_name) == ALLOW)
matched = m->negated ? DENY : ALLOW;
break;
case USERGROUP:
- if (usergr_matches(m->name, pw->pw_name, pw))
+ if (usergr_matches(m->name, pw->pw_name, pw) == ALLOW)
matched = m->negated ? DENY : ALLOW;
break;
case ALIAS:
@@ -104,7 +104,7 @@ user_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
}
FALLTHROUGH;
case WORD:
- if (userpw_matches(m->name, pw->pw_name, pw))
+ if (userpw_matches(m->name, pw->pw_name, pw) == ALLOW)
matched = m->negated ? DENY : ALLOW;
break;
}
@@ -183,11 +183,11 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
if (netgr_matches(m->name,
def_netgroup_tuple ? lhost : NULL,
def_netgroup_tuple ? shost : NULL,
- runas_pw->pw_name))
+ runas_pw->pw_name) == ALLOW)
user_matched = m->negated ? DENY : ALLOW;
break;
case USERGROUP:
- if (usergr_matches(m->name, runas_pw->pw_name, runas_pw))
+ if (usergr_matches(m->name, runas_pw->pw_name, runas_pw) == ALLOW)
user_matched = m->negated ? DENY : ALLOW;
break;
case ALIAS:
@@ -207,7 +207,7 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
}
FALLTHROUGH;
case WORD:
- if (userpw_matches(m->name, runas_pw->pw_name, runas_pw))
+ if (userpw_matches(m->name, runas_pw->pw_name, runas_pw) == ALLOW)
user_matched = m->negated ? DENY : ALLOW;
break;
case MYSELF:
@@ -256,7 +256,7 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
}
FALLTHROUGH;
case WORD:
- if (group_matches(m->name, runas_gr))
+ if (group_matches(m->name, runas_gr) == ALLOW)
group_matched = m->negated ? DENY : ALLOW;
break;
}
@@ -340,21 +340,21 @@ host_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
const char *lhost, const char *shost, const struct member *m)
{
struct alias *a;
- int matched = UNSPEC;
+ int ret = UNSPEC;
debug_decl(host_matches, SUDOERS_DEBUG_MATCH);
switch (m->type) {
case ALL:
- matched = m->negated ? DENY : ALLOW;
+ ret = m->negated ? DENY : ALLOW;
break;
case NETGROUP:
if (netgr_matches(m->name, lhost, shost,
- def_netgroup_tuple ? pw->pw_name : NULL))
- matched = m->negated ? DENY : ALLOW;
+ def_netgroup_tuple ? pw->pw_name : NULL) == ALLOW)
+ ret = m->negated ? DENY : ALLOW;
break;
case NTWKADDR:
- if (addr_matches(m->name))
- matched = m->negated ? DENY : ALLOW;
+ if (addr_matches(m->name) == ALLOW)
+ ret = m->negated ? DENY : ALLOW;
break;
case ALIAS:
a = alias_get(parse_tree, m->name, HOSTALIAS);
@@ -364,9 +364,9 @@ host_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
shost, &a->members);
if (SPECIFIED(rc)) {
if (m->negated) {
- matched = rc == ALLOW ? DENY : ALLOW;
+ ret = rc == ALLOW ? DENY : ALLOW;
} else {
- matched = rc;
+ ret = rc;
}
}
alias_put(a);
@@ -374,11 +374,11 @@ host_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
}
FALLTHROUGH;
case WORD:
- if (hostname_matches(shost, lhost, m->name))
- matched = m->negated ? DENY : ALLOW;
+ if (hostname_matches(shost, lhost, m->name) == ALLOW)
+ ret = m->negated ? DENY : ALLOW;
break;
}
- debug_return_int(matched);
+ debug_return_int(ret);
}
/*
@@ -391,15 +391,15 @@ cmndlist_matches(struct sudoers_parse_tree *parse_tree,
struct cmnd_info *info)
{
struct member *m;
- int matched = UNSPEC;
+ int matched;
debug_decl(cmndlist_matches, SUDOERS_DEBUG_MATCH);
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
matched = cmnd_matches(parse_tree, m, runchroot, info);
if (SPECIFIED(matched))
- break;
+ debug_return_int(matched);
}
- debug_return_int(matched);
+ debug_return_int(UNSPEC);
}
/*
@@ -419,7 +419,8 @@ cmnd_matches(struct sudoers_parse_tree *parse_tree, const struct member *m,
case ALL:
case COMMAND:
c = (struct sudo_command *)m->name;
- if (command_matches(c->cmnd, c->args, runchroot, info, &c->digests))
+ if (command_matches(c->cmnd, c->args, runchroot,
+ info, &c->digests) == ALLOW)
matched = m->negated ? DENY : ALLOW;
break;
case ALIAS:
@@ -441,96 +442,105 @@ cmnd_matches(struct sudoers_parse_tree *parse_tree, const struct member *m,
}
/*
- * Returns true if the hostname matches the pattern, else false
+ * Returns ALLOW if the hostname matches the pattern, else DENY
*/
-bool
+int
hostname_matches(const char *shost, const char *lhost, const char *pattern)
{
const char *host;
- bool rc;
+ int ret;
debug_decl(hostname_matches, SUDOERS_DEBUG_MATCH);
host = strchr(pattern, '.') != NULL ? lhost : shost;
+ ret = DENY;
if (has_meta(pattern)) {
- rc = !fnmatch(pattern, host, FNM_CASEFOLD);
+ if (fnmatch(pattern, host, FNM_CASEFOLD) == 0)
+ ret = ALLOW;
} else {
- rc = !strcasecmp(host, pattern);
+ if (strcasecmp(host, pattern) == 0)
+ ret = ALLOW;
}
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
"host %s matches sudoers pattern %s: %s",
- host, pattern, rc ? "true" : "false");
- debug_return_bool(rc);
+ host, pattern, ret == ALLOW ? "ALLOW" : "DENY");
+ debug_return_int(ret);
}
/*
- * Returns true if the user/uid from sudoers matches the specified user/uid,
- * else returns false.
+ * Returns ALLOW if the user/uid from sudoers matches the specified user/uid,
+ * else returns DENY.
*/
-bool
+int
userpw_matches(const char *sudoers_user, const char *user, const struct passwd *pw)
{
const char *errstr;
+ int ret = DENY;
uid_t uid;
- bool rc;
debug_decl(userpw_matches, SUDOERS_DEBUG_MATCH);
if (pw != NULL && *sudoers_user == '#') {
uid = (uid_t) sudo_strtoid(sudoers_user + 1, &errstr);
if (errstr == NULL && uid == pw->pw_uid) {
- rc = true;
+ ret = ALLOW;
goto done;
}
}
- if (def_case_insensitive_user)
- rc = strcasecmp(sudoers_user, user) == 0;
- else
- rc = strcmp(sudoers_user, user) == 0;
+ if (def_case_insensitive_user) {
+ if (strcasecmp(sudoers_user, user) == 0)
+ ret = ALLOW;
+ } else {
+ if (strcmp(sudoers_user, user) == 0)
+ ret = ALLOW;
+ }
done:
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
"user %s matches sudoers user %s: %s",
- user, sudoers_user, rc ? "true" : "false");
- debug_return_bool(rc);
+ user, sudoers_user, ret == ALLOW ? "ALLOW" : "DENY");
+ debug_return_int(ret);
}
/*
- * Returns true if the group/gid from sudoers matches the specified group/gid,
- * else returns false.
+ * Returns ALLOW if the group/gid from sudoers matches the specified group/gid,
+ * else returns DENY.
*/
-bool
+int
group_matches(const char *sudoers_group, const struct group *gr)
{
const char *errstr;
+ int ret = DENY;
gid_t gid;
- bool rc;
debug_decl(group_matches, SUDOERS_DEBUG_MATCH);
if (*sudoers_group == '#') {
gid = (gid_t) sudo_strtoid(sudoers_group + 1, &errstr);
if (errstr == NULL && gid == gr->gr_gid) {
- rc = true;
+ ret = ALLOW;
goto done;
}
}
- if (def_case_insensitive_group)
- rc = strcasecmp(sudoers_group, gr->gr_name) == 0;
- else
- rc = strcmp(sudoers_group, gr->gr_name) == 0;
+ if (def_case_insensitive_group) {
+ if (strcasecmp(sudoers_group, gr->gr_name) == 0)
+ ret = ALLOW;
+ } else {
+ if (strcmp(sudoers_group, gr->gr_name) == 0)
+ ret = ALLOW;
+ }
done:
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
"group %s matches sudoers group %s: %s",
- gr->gr_name, sudoers_group, rc ? "true" : "false");
- debug_return_bool(rc);
+ gr->gr_name, sudoers_group, ret == ALLOW ? "ALLOW" : "DENY");
+ debug_return_int(ret);
}
/*
* Returns true if the given user belongs to the named group,
* else returns false.
*/
-bool
+int
usergr_matches(const char *group, const char *user, const struct passwd *pw)
{
- bool matched = false;
struct passwd *pw0 = NULL;
+ int ret = DENY;
debug_decl(usergr_matches, SUDOERS_DEBUG_MATCH);
/* Make sure we have a valid usergroup, sudo style */
@@ -543,7 +553,7 @@ usergr_matches(const char *group, const char *user, const struct passwd *pw)
/* Query group plugin for %:name groups. */
if (*group == ':' && def_group_plugin) {
if (group_plugin_query(user, group + 1, pw) == true)
- matched = true;
+ ret = ALLOW;
goto done;
}
@@ -558,14 +568,14 @@ usergr_matches(const char *group, const char *user, const struct passwd *pw)
}
if (user_in_group(pw, group)) {
- matched = true;
+ ret = ALLOW;
goto done;
}
/* Query the group plugin for Unix groups too? */
if (def_group_plugin && def_always_query_group_plugin) {
if (group_plugin_query(user, group, pw) == true) {
- matched = true;
+ ret = ALLOW;
goto done;
}
}
@@ -575,8 +585,9 @@ done:
sudo_pw_delref(pw0);
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
- "user %s matches group %s: %s", user, group, matched ? "true" : "false");
- debug_return_bool(matched);
+ "user %s matches group %s: %s", user, group,
+ ret == ALLOW ? "ALLOW" : "DENY");
+ debug_return_int(ret);
}
#if defined(HAVE_GETDOMAINNAME) || defined(SI_SRPC_DOMAIN)
@@ -652,22 +663,22 @@ sudo_getdomainname(void)
#endif /* HAVE_GETDOMAINNAME || SI_SRPC_DOMAIN */
/*
- * Returns true if "host" and "user" belong to the netgroup "netgr",
- * else return false. Either of "lhost", "shost" or "user" may be NULL
+ * Returns ALLOW if "host" and "user" belong to the netgroup "netgr",
+ * else return DENY. Either of "lhost", "shost" or "user" may be NULL
* in which case that argument is not checked...
*/
-bool
+int
netgr_matches(const char *netgr, const char *lhost, const char *shost, const char *user)
{
#ifdef HAVE_INNETGR
const char *domain;
#endif
- bool rc = false;
+ int ret = DENY;
debug_decl(netgr_matches, SUDOERS_DEBUG_MATCH);
if (!def_use_netgroups) {
sudo_debug_printf(SUDO_DEBUG_INFO, "netgroups are disabled");
- debug_return_bool(false);
+ debug_return_int(DENY);
}
#ifdef HAVE_INNETGR
@@ -675,22 +686,22 @@ netgr_matches(const char *netgr, const char *lhost, const char *shost, const cha
if (*netgr++ != '+') {
sudo_debug_printf(SUDO_DEBUG_DIAG, "netgroup %s has no leading '+'",
netgr);
- debug_return_bool(false);
+ debug_return_int(DENY);
}
/* get the domain name (if any) */
domain = sudo_getdomainname();
if (innetgr(netgr, lhost, user, domain))
- rc = true;
+ ret = ALLOW;
else if (lhost != shost && innetgr(netgr, shost, user, domain))
- rc = true;
+ ret = ALLOW;
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
"netgroup %s matches (%s|%s, %s, %s): %s", netgr, lhost ? lhost : "",
shost ? shost : "", user ? user : "", domain ? domain : "",
- rc ? "true" : "false");
+ ret == ALLOW ? "ALLOW" : "DENY");
#endif /* HAVE_INNETGR */
- debug_return_bool(rc);
+ debug_return_int(ret);
}
diff --git a/plugins/sudoers/match_addr.c b/plugins/sudoers/match_addr.c
index 714c41c..3b701c9 100644
--- a/plugins/sudoers/match_addr.c
+++ b/plugins/sudoers/match_addr.c
@@ -44,7 +44,7 @@
#include "sudoers.h"
#include "interfaces.h"
-static bool
+static int
addr_matches_if(const char *n)
{
union sudo_in_addr_un addr;
@@ -63,7 +63,7 @@ addr_matches_if(const char *n)
if (inet_pton(AF_INET, n, &addr.ip4) == 1) {
family = AF_INET;
} else {
- debug_return_bool(false);
+ debug_return_int(DENY);
}
SLIST_FOREACH(ifp, get_interfaces(), entries) {
@@ -74,28 +74,28 @@ addr_matches_if(const char *n)
if (ifp->addr.ip4.s_addr == addr.ip4.s_addr ||
(ifp->addr.ip4.s_addr & ifp->netmask.ip4.s_addr)
== addr.ip4.s_addr)
- debug_return_bool(true);
+ debug_return_int(ALLOW);
break;
#ifdef HAVE_STRUCT_IN6_ADDR
case AF_INET6:
if (memcmp(ifp->addr.ip6.s6_addr, addr.ip6.s6_addr,
sizeof(addr.ip6.s6_addr)) == 0)
- debug_return_bool(true);
+ debug_return_int(ALLOW);
for (j = 0; j < sizeof(addr.ip6.s6_addr); j++) {
if ((ifp->addr.ip6.s6_addr[j] & ifp->netmask.ip6.s6_addr[j]) != addr.ip6.s6_addr[j])
break;
}
if (j == sizeof(addr.ip6.s6_addr))
- debug_return_bool(true);
+ debug_return_int(ALLOW);
break;
#endif /* HAVE_STRUCT_IN6_ADDR */
}
}
- debug_return_bool(false);
+ debug_return_int(DENY);
}
-static bool
+static int
addr_matches_if_netmask(const char *n, const char *m)
{
unsigned int i;
@@ -116,7 +116,7 @@ addr_matches_if_netmask(const char *n, const char *m)
if (inet_pton(AF_INET, n, &addr.ip4) == 1) {
family = AF_INET;
} else {
- debug_return_bool(false);
+ debug_return_int(DENY);
}
if (family == AF_INET) {
@@ -124,14 +124,14 @@ addr_matches_if_netmask(const char *n, const char *m)
if (inet_pton(AF_INET, m, &mask.ip4) != 1) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"IPv4 netmask %s: %s", m, "invalid value");
- debug_return_bool(false);
+ debug_return_int(DENY);
}
} else {
i = sudo_strtonum(m, 1, 32, &errstr);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"IPv4 netmask %s: %s", m, errstr);
- debug_return_bool(false);
+ debug_return_int(DENY);
}
mask.ip4.s_addr = htonl(0xffffffffU << (32 - i));
}
@@ -144,7 +144,7 @@ addr_matches_if_netmask(const char *n, const char *m)
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"IPv6 netmask %s: %s", m, errstr);
- debug_return_bool(false);
+ debug_return_int(DENY);
}
for (i = 0; i < sizeof(addr.ip6.s6_addr); i++) {
if (j < i * 8)
@@ -165,7 +165,7 @@ addr_matches_if_netmask(const char *n, const char *m)
switch (family) {
case AF_INET:
if ((ifp->addr.ip4.s_addr & mask.ip4.s_addr) == addr.ip4.s_addr)
- debug_return_bool(true);
+ debug_return_int(ALLOW);
break;
#ifdef HAVE_STRUCT_IN6_ADDR
case AF_INET6:
@@ -174,35 +174,36 @@ addr_matches_if_netmask(const char *n, const char *m)
break;
}
if (j == sizeof(addr.ip6.s6_addr))
- debug_return_bool(true);
+ debug_return_int(ALLOW);
break;
#endif /* HAVE_STRUCT_IN6_ADDR */
}
}
- debug_return_bool(false);
+ debug_return_int(DENY);
}
/*
- * Returns true if "n" is one of our ip addresses or if
- * "n" is a network that we are on, else returns false.
+ * Returns ALLOW if "n" is one of our ip addresses or if
+ * "n" is a network that we are on, else returns DENY.
*/
-bool
+int
addr_matches(char *n)
{
char *m;
- bool rc;
+ int ret;
debug_decl(addr_matches, SUDOERS_DEBUG_MATCH);
/* If there's an explicit netmask, use it. */
if ((m = strchr(n, '/'))) {
*m++ = '\0';
- rc = addr_matches_if_netmask(n, m);
+ ret = addr_matches_if_netmask(n, m);
*(m - 1) = '/';
} else
- rc = addr_matches_if(n);
+ ret = addr_matches_if(n);
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
- "IP address %s matches local host: %s", n, rc ? "true" : "false");
- debug_return_bool(rc);
+ "IP address %s matches local host: %s", n,
+ ret == ALLOW ? "ALLOW" : "DENY");
+ debug_return_int(ret);
}
diff --git a/plugins/sudoers/match_command.c b/plugins/sudoers/match_command.c
index f1c09bd..ee89741 100644
--- a/plugins/sudoers/match_command.c
+++ b/plugins/sudoers/match_command.c
@@ -56,7 +56,7 @@
# define O_EXEC O_PATH
#endif
-static bool
+static int
command_args_match(const char *sudoers_cmnd, const char *sudoers_args)
{
int flags = 0;
@@ -67,7 +67,7 @@ command_args_match(const char *sudoers_cmnd, const char *sudoers_args)
* If the empty string is specified in sudoers, no user args are allowed.
*/
if (!sudoers_args || (!user_args && !strcmp("\"\"", sudoers_args)))
- debug_return_bool(true);
+ debug_return_int(ALLOW);
/*
* If args are specified in sudoers, they must match the user args.
@@ -76,9 +76,9 @@ command_args_match(const char *sudoers_cmnd, const char *sudoers_args)
if (strcmp(sudoers_cmnd, "sudoedit") == 0)
flags = FNM_PATHNAME;
if (fnmatch(sudoers_args, user_args ? user_args : "", flags) == 0)
- debug_return_bool(true);
+ debug_return_int(ALLOW);
- debug_return_bool(false);
+ debug_return_int(DENY);
}
#ifndef SUDOERS_NAME_MATCH
@@ -229,7 +229,7 @@ set_cmnd_fd(int fd)
/*
* Return true if user_cmnd names one of the inodes in dir, else false.
*/
-static bool
+static int
command_matches_dir(const char *sudoers_dir, size_t dlen, const char *runchroot,
bool intercepted, const struct command_digest_list *digests)
{
@@ -247,7 +247,7 @@ command_matches_dir(const char *sudoers_dir, size_t dlen, const char *runchroot,
snprintf(sdbuf, sizeof(sdbuf), "%s%s", runchroot, sudoers_dir);
if (len >= ssizeof(sdbuf)) {
errno = ENAMETOOLONG;
- debug_return_bool(false);
+ debug_return_int(DENY);
}
sudoers_dir = sdbuf;
chrootlen = strlen(runchroot);
@@ -258,11 +258,11 @@ command_matches_dir(const char *sudoers_dir, size_t dlen, const char *runchroot,
*/
dirp = opendir(sudoers_dir);
if (dirp == NULL)
- debug_return_bool(false);
+ debug_return_int(DENY);
if (strlcpy(buf, sudoers_dir, sizeof(buf)) >= sizeof(buf)) {
closedir(dirp);
- debug_return_bool(false);
+ debug_return_int(DENY);
}
while ((dent = readdir(dirp)) != NULL) {
if (fd != -1) {
@@ -289,7 +289,7 @@ command_matches_dir(const char *sudoers_dir, size_t dlen, const char *runchroot,
(user_stat->st_dev == sudoers_stat.st_dev &&
user_stat->st_ino == sudoers_stat.st_ino)) {
/* buf is already relative to runchroot */
- if (!digest_matches(fd, buf, NULL, digests))
+ if (digest_matches(fd, buf, NULL, digests) != ALLOW)
continue;
free(safe_cmnd);
if ((safe_cmnd = strdup(buf + chrootlen)) == NULL) {
@@ -304,17 +304,17 @@ command_matches_dir(const char *sudoers_dir, size_t dlen, const char *runchroot,
if (dent != NULL) {
set_cmnd_fd(fd);
- debug_return_bool(true);
+ debug_return_int(ALLOW);
}
if (fd != -1)
close(fd);
- debug_return_bool(false);
+ debug_return_int(DENY);
}
#else /* SUDOERS_NAME_MATCH */
/*
* Return true if user_cmnd names one of the inodes in dir, else false.
*/
-static bool
+static int
command_matches_dir(const char *sudoers_dir, size_t dlen, const char *runchroot,
bool intercepted, const struct command_digest_list *digests)
{
@@ -332,19 +332,19 @@ command_matches_dir(const char *sudoers_dir, size_t dlen, const char *runchroot,
/* Open the file for fdexec or for digest matching. */
if (!open_cmnd(user_cmnd, runchroot, digests, &fd))
goto bad;
- if (!digest_matches(fd, user_cmnd, runchroot, digests))
+ if (digest_matches(fd, user_cmnd, runchroot, digests) != ALLOW)
goto bad;
set_cmnd_fd(fd);
- debug_return_bool(true);
+ debug_return_int(ALLOW);
bad:
if (fd != -1)
close(fd);
- debug_return_bool(false);
+ debug_return_int(DENY);
}
#endif /* SUDOERS_NAME_MATCH */
-static bool
+static int
command_matches_all(const char *runchroot,
bool intercepted, const struct command_digest_list *digests)
{
@@ -366,19 +366,19 @@ command_matches_all(const char *runchroot,
}
/* Check digest of user_cmnd since we have no sudoers_cmnd for ALL. */
- if (!digest_matches(fd, user_cmnd, runchroot, digests))
+ if (digest_matches(fd, user_cmnd, runchroot, digests) != ALLOW)
goto bad;
set_cmnd_fd(fd);
/* No need to set safe_cmnd for ALL. */
- debug_return_bool(true);
+ debug_return_int(ALLOW);
bad:
if (fd != -1)
close(fd);
- debug_return_bool(false);
+ debug_return_int(DENY);
}
-static bool
+static int
command_matches_fnmatch(const char *sudoers_cmnd, const char *sudoers_args,
const char *runchroot, bool intercepted,
const struct command_digest_list *digests)
@@ -396,8 +396,8 @@ command_matches_fnmatch(const char *sudoers_cmnd, const char *sudoers_args,
* Neither sudoers_cmnd nor user_cmnd are relative to runchroot.
*/
if (fnmatch(sudoers_cmnd, user_cmnd, FNM_PATHNAME) != 0)
- debug_return_bool(false);
- if (command_args_match(sudoers_cmnd, sudoers_args)) {
+ debug_return_int(DENY);
+ if (command_args_match(sudoers_cmnd, sudoers_args) == ALLOW) {
/* Open the file for fdexec or for digest matching. */
if (!open_cmnd(user_cmnd, runchroot, digests, &fd))
goto bad;
@@ -406,22 +406,22 @@ command_matches_fnmatch(const char *sudoers_cmnd, const char *sudoers_args,
goto bad;
#endif
/* Check digest of user_cmnd since sudoers_cmnd is a pattern. */
- if (!digest_matches(fd, user_cmnd, runchroot, digests))
+ if (digest_matches(fd, user_cmnd, runchroot, digests) != ALLOW)
goto bad;
set_cmnd_fd(fd);
/* No need to set safe_cmnd since user_cmnd matches sudoers_cmnd */
- debug_return_bool(true);
+ debug_return_int(ALLOW);
bad:
if (fd != -1)
close(fd);
- debug_return_bool(false);
+ debug_return_int(DENY);
}
- debug_return_bool(false);
+ debug_return_int(DENY);
}
#ifndef SUDOERS_NAME_MATCH
-static bool
+static int
command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args,
const char *runchroot, bool intercepted,
const struct command_digest_list *digests)
@@ -444,7 +444,7 @@ command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args,
if (sudoers_cmnd[dlen - 1] != '/') {
base = sudo_basename(sudoers_cmnd);
if (!has_meta(base) && strcmp(user_base, base) != 0)
- debug_return_bool(false);
+ debug_return_int(DENY);
}
/* Make sudoers_cmnd relative to the new root, if any. */
@@ -453,22 +453,22 @@ command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args,
snprintf(pathbuf, sizeof(pathbuf), "%s%s", runchroot, sudoers_cmnd);
if (len >= ssizeof(pathbuf)) {
errno = ENAMETOOLONG;
- debug_return_bool(false);
+ debug_return_int(DENY);
}
sudoers_cmnd = pathbuf;
chrootlen = strlen(runchroot);
}
/*
- * Return true if we find a match in the glob(3) results AND
+ * Return ALLOW if we find a match in the glob(3) results AND
* a) there are no args in sudoers OR
* b) there are no args on command line and none required by sudoers OR
* c) there are args in sudoers and on command line and they match
- * else return false.
+ * else return DENY.
*/
if (glob(sudoers_cmnd, GLOB_NOSORT, NULL, &gl) != 0 || gl.gl_pathc == 0) {
globfree(&gl);
- debug_return_bool(false);
+ debug_return_int(DENY);
}
/* If user_cmnd is fully-qualified, check for an exact match. */
if (user_cmnd[0] == '/') {
@@ -491,7 +491,7 @@ command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args,
(user_stat->st_dev == sudoers_stat.st_dev &&
user_stat->st_ino == sudoers_stat.st_ino)) {
/* There could be multiple matches, check digest early. */
- if (!digest_matches(fd, cp, runchroot, digests)) {
+ if (digest_matches(fd, cp, runchroot, digests) != ALLOW) {
bad_digest = true;
continue;
}
@@ -522,9 +522,9 @@ command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args,
/* If it ends in '/' it is a directory spec. */
dlen = strlen(cp);
if (cp[dlen - 1] == '/') {
- if (command_matches_dir(cp, dlen, runchroot, intercepted, digests)) {
+ if (command_matches_dir(cp, dlen, runchroot, intercepted, digests) == ALLOW) {
globfree(&gl);
- debug_return_bool(true);
+ debug_return_int(ALLOW);
}
continue;
}
@@ -542,7 +542,7 @@ command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args,
if (user_stat == NULL ||
(user_stat->st_dev == sudoers_stat.st_dev &&
user_stat->st_ino == sudoers_stat.st_ino)) {
- if (!digest_matches(fd, cp, runchroot, digests))
+ if (digest_matches(fd, cp, runchroot, digests) != ALLOW)
continue;
free(safe_cmnd);
if ((safe_cmnd = strdup(cp)) == NULL) {
@@ -557,18 +557,18 @@ command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args,
done:
globfree(&gl);
if (cp != NULL) {
- if (command_args_match(sudoers_cmnd, sudoers_args)) {
+ if (command_args_match(sudoers_cmnd, sudoers_args) == ALLOW) {
/* safe_cmnd was set above. */
set_cmnd_fd(fd);
- debug_return_bool(true);
+ debug_return_int(ALLOW);
}
}
if (fd != -1)
close(fd);
- debug_return_bool(false);
+ debug_return_int(DENY);
}
-static bool
+static int
command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args,
const char *runchroot, bool intercepted,
const struct command_digest_list *digests)
@@ -582,14 +582,14 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args,
/* If it ends in '/' it is a directory spec. */
dlen = strlen(sudoers_cmnd);
if (sudoers_cmnd[dlen - 1] == '/') {
- debug_return_bool(command_matches_dir(sudoers_cmnd, dlen, runchroot,
+ debug_return_int(command_matches_dir(sudoers_cmnd, dlen, runchroot,
intercepted, digests));
}
/* Only proceed if user_base and basename(sudoers_cmnd) match */
base = sudo_basename(sudoers_cmnd);
if (strcmp(user_base, base) != 0)
- debug_return_bool(false);
+ debug_return_int(DENY);
/* Open the file for fdexec or for digest matching. */
if (!open_cmnd(sudoers_cmnd, runchroot, digests, &fd))
@@ -611,9 +611,9 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args,
if (strcmp(user_cmnd, sudoers_cmnd) != 0)
goto bad;
}
- if (!command_args_match(sudoers_cmnd, sudoers_args))
+ if (command_args_match(sudoers_cmnd, sudoers_args) != ALLOW)
goto bad;
- if (!digest_matches(fd, sudoers_cmnd, runchroot, digests)) {
+ if (digest_matches(fd, sudoers_cmnd, runchroot, digests) != ALLOW) {
/* XXX - log functions not available but we should log very loudly */
goto bad;
}
@@ -623,14 +623,14 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args,
goto bad;
}
set_cmnd_fd(fd);
- debug_return_bool(true);
+ debug_return_int(ALLOW);
bad:
if (fd != -1)
close(fd);
- debug_return_bool(false);
+ debug_return_int(DENY);
}
#else /* SUDOERS_NAME_MATCH */
-static bool
+static int
command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args,
const char *runchroot, bool intercepted,
const struct command_digest_list *digests)
@@ -639,7 +639,7 @@ command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args,
intercepted, digests);
}
-static bool
+static int
command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args,
const char *runchroot, bool intercepted,
const struct command_digest_list *digests)
@@ -651,16 +651,16 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args,
/* If it ends in '/' it is a directory spec. */
dlen = strlen(sudoers_cmnd);
if (sudoers_cmnd[dlen - 1] == '/') {
- debug_return_bool(command_matches_dir(sudoers_cmnd, dlen, runchroot,
+ debug_return_int(command_matches_dir(sudoers_cmnd, dlen, runchroot,
intercepted, digests));
}
if (strcmp(user_cmnd, sudoers_cmnd) == 0) {
- if (command_args_match(sudoers_cmnd, sudoers_args)) {
+ if (command_args_match(sudoers_cmnd, sudoers_args) == ALLOW) {
/* Open the file for fdexec or for digest matching. */
if (!open_cmnd(user_cmnd, runchroot, digests, &fd))
goto bad;
- if (!digest_matches(fd, user_cmnd, runchroot, digests))
+ if (digest_matches(fd, user_cmnd, runchroot, digests) != ALLOW)
goto bad;
/* Successful match. */
@@ -671,21 +671,22 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args,
goto bad;
}
set_cmnd_fd(fd);
- debug_return_bool(true);
+ debug_return_int(ALLOW);
}
}
bad:
if (fd != -1)
close(fd);
- debug_return_bool(false);
+ debug_return_int(DENY);
}
#endif /* SUDOERS_NAME_MATCH */
/*
- * If path doesn't end in /, return true iff cmnd & path name the same inode;
- * otherwise, return true if user_cmnd names one of the inodes in path.
+ * If path doesn't end in /, return ALLOW iff cmnd & path name the same inode;
+ * otherwise, return ALLOW if ctx->user.cmnd names one of the inodes in path.
+ * Returns DENY on failure.
*/
-bool
+int
command_matches(const char *sudoers_cmnd, const char *sudoers_args,
const char *runchroot, struct cmnd_info *info,
const struct command_digest_list *digests)
@@ -693,7 +694,7 @@ command_matches(const char *sudoers_cmnd, const char *sudoers_args,
const bool intercepted = info ? info->intercepted : false;
char *saved_user_cmnd = NULL;
struct stat saved_user_stat;
- bool rc = false;
+ int ret = DENY;
debug_decl(command_matches, SUDOERS_DEBUG_MATCH);
if (user_runchroot != NULL) {
@@ -728,7 +729,7 @@ command_matches(const char *sudoers_cmnd, const char *sudoers_args,
if (sudoers_cmnd == NULL) {
sudoers_cmnd = "ALL";
- rc = command_matches_all(runchroot, intercepted, digests);
+ ret = command_matches_all(runchroot, intercepted, digests);
goto done;
}
@@ -742,9 +743,9 @@ command_matches(const char *sudoers_cmnd, const char *sudoers_args,
*/
if (strcmp(sudoers_cmnd, "sudoedit") == 0 &&
strcmp(user_cmnd, "sudoedit") == 0 &&
- command_args_match(sudoers_cmnd, sudoers_args)) {
+ command_args_match(sudoers_cmnd, sudoers_args) == ALLOW) {
/* No need to set safe_cmnd since user_cmnd matches sudoers_cmnd */
- rc = true;
+ ret = ALLOW;
}
goto done;
}
@@ -755,14 +756,14 @@ command_matches(const char *sudoers_cmnd, const char *sudoers_args,
* use glob(3) and/or fnmatch(3) to do the matching.
*/
if (def_fast_glob) {
- rc = command_matches_fnmatch(sudoers_cmnd, sudoers_args, runchroot,
+ ret = command_matches_fnmatch(sudoers_cmnd, sudoers_args, runchroot,
intercepted, digests);
} else {
- rc = command_matches_glob(sudoers_cmnd, sudoers_args, runchroot,
+ ret = command_matches_glob(sudoers_cmnd, sudoers_args, runchroot,
intercepted, digests);
}
} else {
- rc = command_matches_normal(sudoers_cmnd, sudoers_args, runchroot,
+ ret = command_matches_normal(sudoers_cmnd, sudoers_args, runchroot,
intercepted, digests);
}
done:
@@ -783,6 +784,6 @@ done:
user_cmnd, user_args ? " " : "", user_args ? user_args : "",
sudoers_cmnd, sudoers_args ? " " : "", sudoers_args ? sudoers_args : "",
runchroot ? ", chroot " : "", runchroot ? runchroot : "",
- rc ? "true" : "false");
- debug_return_bool(rc);
+ ret == ALLOW ? "ALLOW" : "DENY");
+ debug_return_int(ret);
}
diff --git a/plugins/sudoers/match_digest.c b/plugins/sudoers/match_digest.c
index 5c39f52..78cfe0d 100644
--- a/plugins/sudoers/match_digest.c
+++ b/plugins/sudoers/match_digest.c
@@ -38,7 +38,7 @@
#include "sudo_digest.h"
#include <gram.h>
-bool
+int
digest_matches(int fd, const char *path, const char *runchroot,
const struct command_digest_list *digests)
{
@@ -48,12 +48,12 @@ digest_matches(int fd, const char *path, const char *runchroot,
struct command_digest *digest;
size_t digest_len = (size_t)-1;
char pathbuf[PATH_MAX];
- bool matched = false;
+ int matched = DENY;
debug_decl(digest_matches, SUDOERS_DEBUG_MATCH);
if (TAILQ_EMPTY(digests)) {
/* No digest, no problem. */
- debug_return_bool(true);
+ debug_return_int(ALLOW);
}
if (fd == -1) {
@@ -66,7 +66,7 @@ digest_matches(int fd, const char *path, const char *runchroot,
snprintf(pathbuf, sizeof(pathbuf), "%s%s", runchroot, path);
if (len >= ssizeof(pathbuf)) {
errno = ENAMETOOLONG;
- debug_return_bool(false);
+ debug_return_int(DENY);
}
path = pathbuf;
}
@@ -113,7 +113,7 @@ digest_matches(int fd, const char *path, const char *runchroot,
}
}
if (memcmp(file_digest, sudoers_digest, digest_len) == 0) {
- matched = true;
+ matched = ALLOW;
break;
}
@@ -131,5 +131,5 @@ bad_format:
done:
free(sudoers_digest);
free(file_digest);
- debug_return_bool(matched);
+ debug_return_int(matched);
}
diff --git a/plugins/sudoers/parse.h b/plugins/sudoers/parse.h
index 8559849..bfc5bc8 100644
--- a/plugins/sudoers/parse.h
+++ b/plugins/sudoers/parse.h
@@ -384,22 +384,22 @@ bool parser_leak_remove(enum parser_leak_types type, void *v);
void parser_leak_init(void);
/* match_addr.c */
-bool addr_matches(char *n);
+int addr_matches(char *n);
/* match_command.c */
-bool command_matches(const char *sudoers_cmnd, const char *sudoers_args, const char *runchroot, struct cmnd_info *info, const struct command_digest_list *digests);
+int command_matches(const char *sudoers_cmnd, const char *sudoers_args, const char *runchroot, struct cmnd_info *info, const struct command_digest_list *digests);
/* match_digest.c */
-bool digest_matches(int fd, const char *path, const char *runchroot, const struct command_digest_list *digests);
+int digest_matches(int fd, const char *path, const char *runchroot, const struct command_digest_list *digests);
/* match.c */
struct group;
struct passwd;
-bool group_matches(const char *sudoers_group, const struct group *gr);
-bool hostname_matches(const char *shost, const char *lhost, const char *pattern);
-bool netgr_matches(const char *netgr, const char *lhost, const char *shost, const char *user);
-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 group_matches(const char *sudoers_group, const struct group *gr);
+int hostname_matches(const char *shost, const char *lhost, const char *pattern);
+int netgr_matches(const char *netgr, const char *lhost, const char *shost, const char *user);
+int usergr_matches(const char *group, const char *user, const struct passwd *pw);
+int 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 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);
diff --git a/plugins/sudoers/regress/parser/check_addr.c b/plugins/sudoers/regress/parser/check_addr.c
index cf50226..a465d14 100644
--- a/plugins/sudoers/regress/parser/check_addr.c
+++ b/plugins/sudoers/regress/parser/check_addr.c
@@ -57,7 +57,7 @@ check_addr(char *input)
sudo_fatalx("expecting 0 or 1, got %s", cp);
input[len] = '\0';
- matched = addr_matches(input);
+ matched = addr_matches(input) == ALLOW;
if (matched != expected) {
sudo_warnx("%s %smatched: FAIL", input, matched ? "" : "not ");
return 1;
diff --git a/plugins/sudoers/sssd.c b/plugins/sudoers/sssd.c
index e396d84..8760e4c 100644
--- a/plugins/sudoers/sssd.c
+++ b/plugins/sudoers/sssd.c
@@ -195,20 +195,20 @@ sudo_sss_check_user(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
case '+':
/* Netgroup spec found, check membership. */
if (netgr_matches(val, def_netgroup_tuple ? host : NULL,
- def_netgroup_tuple ? shost : NULL, handle->pw->pw_name)) {
+ def_netgroup_tuple ? shost : NULL, handle->pw->pw_name) == ALLOW) {
ret = true;
}
break;
case '%':
/* User group found, check membership. */
- if (usergr_matches(val, handle->pw->pw_name, handle->pw)) {
+ if (usergr_matches(val, handle->pw->pw_name, handle->pw) == ALLOW) {
ret = true;
}
break;
default:
/* Not a netgroup or user group. */
if (strcmp(val, "ALL") == 0 ||
- userpw_matches(val, handle->pw->pw_name, handle->pw)) {
+ userpw_matches(val, handle->pw->pw_name, handle->pw) == ALLOW) {
ret = true;
}
break;
--
2.42.0.windows.2