From 2ef90231a132547fa4236ff05fc0fafcd3f3d7a4 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" 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 | 146 +++++++++++--------- plugins/sudoers/match_addr.c | 45 +++--- plugins/sudoers/match_command.c | 103 +++++++------- plugins/sudoers/match_digest.c | 10 +- plugins/sudoers/parse.h | 16 +-- plugins/sudoers/regress/parser/check_addr.c | 2 +- plugins/sudoers/sssd.c | 6 +- 8 files changed, 171 insertions(+), 159 deletions(-) diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c index 5bdd488..b64a5a8 100644 --- a/plugins/sudoers/ldap.c +++ b/plugins/sudoers/ldap.c @@ -340,7 +340,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 edf8fa1..6fb7a2c 100644 --- a/plugins/sudoers/match.c +++ b/plugins/sudoers/match.c @@ -82,11 +82,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: @@ -105,7 +105,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; } @@ -184,11 +184,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: @@ -208,7 +208,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: @@ -257,7 +257,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; } @@ -341,21 +341,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); @@ -365,9 +365,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); @@ -375,11 +375,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, const struct member_list *list) { 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); if (SPECIFIED(matched)) - break; + debug_return_int(matched); } - debug_return_int(matched); + debug_return_int(UNSPEC); } /* @@ -423,7 +423,7 @@ cmnd_matches(struct sudoers_parse_tree *parse_tree, const struct member *m) /* FALLTHROUGH */ case COMMAND: c = (struct sudo_command *)m->name; - if (command_matches(c->cmnd, c->args, &c->digests)) + if (command_matches(c->cmnd, c->args, &c->digests) == ALLOW) matched = m->negated ? DENY : ALLOW; break; case ALIAS: @@ -445,96 +445,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 */ @@ -547,7 +556,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; } @@ -562,14 +571,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; } } @@ -579,8 +588,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) @@ -656,22 +666,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 @@ -679,22 +689,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 ac942f4..d06634a 100644 --- a/plugins/sudoers/match_command.c +++ b/plugins/sudoers/match_command.c @@ -55,7 +55,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; @@ -66,7 +66,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. @@ -75,9 +75,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); } /* @@ -189,7 +189,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 struct command_digest_list *digests) { @@ -205,11 +205,11 @@ command_matches_dir(const char *sudoers_dir, size_t dlen, */ 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) { @@ -250,14 +250,14 @@ command_matches_dir(const char *sudoers_dir, size_t dlen, 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); } -static bool +static int command_matches_all(const struct command_digest_list *digests) { struct stat sb; /* XXX - unused */ @@ -273,21 +273,21 @@ command_matches_all(const struct command_digest_list *digests) } /* Check digest of user_cmnd since we have no sudoers_cmnd for ALL. */ - if (!digest_matches(fd, user_cmnd, digests)) + if (digest_matches(fd, user_cmnd, 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); fd = -1; } - debug_return_bool(false); + debug_return_int(DENY); } -static bool +static int command_matches_fnmatch(const char *sudoers_cmnd, const char *sudoers_args, const struct command_digest_list *digests) { @@ -303,31 +303,31 @@ command_matches_fnmatch(const char *sudoers_cmnd, const char *sudoers_args, * else return false. */ 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, digests, &fd)) goto bad; if (!do_stat(fd, user_cmnd, &sb)) goto bad; /* Check digest of user_cmnd since sudoers_cmnd is a pattern. */ - if (!digest_matches(fd, user_cmnd, digests)) + if (digest_matches(fd, user_cmnd, 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); fd = -1; } - debug_return_bool(false); + debug_return_int(DENY); } - debug_return_bool(false); + debug_return_int(DENY); } -static bool +static int command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args, const struct command_digest_list *digests) { @@ -349,19 +349,19 @@ command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args, if ((base = strrchr(sudoers_cmnd, '/')) != NULL) { base++; if (!has_meta(base) && strcmp(user_base, base) != 0) - debug_return_bool(false); + debug_return_int(DENY); } } /* - * 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] == '/') { @@ -381,7 +381,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, digests)) { + if (digest_matches(fd, cp, digests) != ALLOW) { bad_digest = true; continue; } @@ -409,8 +409,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, digests)) - debug_return_bool(true); + if (command_matches_dir(cp, dlen, + digests) == ALLOW) + debug_return_int(ALLOW); continue; } @@ -430,7 +431,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, digests)) + if (digest_matches(fd, cp, digests) != ALLOW) continue; free(safe_cmnd); if ((safe_cmnd = strdup(cp)) == NULL) { @@ -445,18 +446,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 struct command_digest_list *digests) { struct stat sudoers_stat; @@ -468,7 +469,7 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args, const /* 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, digests)); + debug_return_int(command_matches_dir(sudoers_cmnd, dlen, digests)); /* Only proceed if user_base and basename(sudoers_cmnd) match */ if ((base = strrchr(sudoers_cmnd, '/')) == NULL) @@ -476,7 +477,7 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args, const else base++; 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, digests, &fd)) @@ -498,9 +499,9 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args, const 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, digests)) { + if (digest_matches(fd, sudoers_cmnd, digests) != ALLOW) { /* XXX - log functions not available but we should log very loudly */ goto bad; } @@ -510,25 +511,25 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args, const 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); } /* - * 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 user_cmnd names one of the inodes in path. */ -bool +int command_matches(const char *sudoers_cmnd, const char *sudoers_args, const struct command_digest_list *digests) { - bool rc = false; + int ret = DENY; debug_decl(command_matches, SUDOERS_DEBUG_MATCH); if (sudoers_cmnd == NULL) { - rc = command_matches_all(digests); + ret = command_matches_all(digests); goto done; } @@ -542,9 +543,9 @@ command_matches(const char *sudoers_cmnd, const char *sudoers_args, const struct */ 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; } @@ -555,17 +556,17 @@ command_matches(const char *sudoers_cmnd, const char *sudoers_args, const struct * use glob(3) and/or fnmatch(3) to do the matching. */ if (def_fast_glob) - rc = command_matches_fnmatch(sudoers_cmnd, sudoers_args, digests); + ret = command_matches_fnmatch(sudoers_cmnd, sudoers_args, digests); else - rc = command_matches_glob(sudoers_cmnd, sudoers_args, digests); + ret = command_matches_glob(sudoers_cmnd, sudoers_args, digests); } else { - rc = command_matches_normal(sudoers_cmnd, sudoers_args, digests); + ret = command_matches_normal(sudoers_cmnd, sudoers_args, digests); } done: sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO, "user command \"%s%s%s\" matches sudoers command \"%s%s%s\": %s", user_cmnd, user_args ? " " : "", user_args ? user_args : "", sudoers_cmnd, sudoers_args ? " " : "", sudoers_args ? sudoers_args : "", - 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 b08ba58..aa47462 100644 --- a/plugins/sudoers/match_digest.c +++ b/plugins/sudoers/match_digest.c @@ -37,7 +37,7 @@ #include "sudo_digest.h" #include -bool +int digest_matches(int fd, const char *file, const struct command_digest_list *digests) { unsigned int digest_type = SUDO_DIGEST_INVALID; @@ -45,12 +45,12 @@ digest_matches(int fd, const char *file, const struct command_digest_list *diges unsigned char *sudoers_digest = NULL; struct command_digest *digest; size_t digest_len = (size_t)-1; - 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) { @@ -100,7 +100,7 @@ digest_matches(int fd, const char *file, const struct command_digest_list *diges } } if (memcmp(file_digest, sudoers_digest, digest_len) == 0) { - matched = true; + matched = ALLOW; break; } @@ -118,5 +118,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 e1ba680..6734eb6 100644 --- a/plugins/sudoers/parse.h +++ b/plugins/sudoers/parse.h @@ -318,22 +318,22 @@ void free_parse_tree(struct sudoers_parse_tree *parse_tree); void reparent_parse_tree(struct sudoers_parse_tree *new_tree); /* 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 struct command_digest_list *digests); +int command_matches(const char *sudoers_cmnd, const char *sudoers_args, const struct command_digest_list *digests); /* match_digest.c */ -bool digest_matches(int fd, const char *file, const struct command_digest_list *digests); +int digest_matches(int fd, const char *file, 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); int cmndlist_matches(struct sudoers_parse_tree *parse_tree, const struct member_list *list); 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 fd0515f..135235d 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 6fe8337..e993099 100644 --- a/plugins/sudoers/sssd.c +++ b/plugins/sudoers/sssd.c @@ -196,20 +196,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.33.0