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

