fix CVE-2023-42465
Signed-off-by: qsW <wangqingsan@huawei.com>
This commit is contained in:
parent
bda97a71fc
commit
6bfa5229b5
424
backport-CVE-2023-42465.patch
Normal file
424
backport-CVE-2023-42465.patch
Normal file
@ -0,0 +1,424 @@
|
||||
From 7873f8334c8d31031f8cfa83bd97ac6029309e4f Mon Sep 17 00:00:00 2001
|
||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
||||
Date: Sat, 9 Sep 2023 14:07:04 -0600
|
||||
Subject: [PATCH] Try to make sudo less vulnerable to ROWHAMMER attacks.
|
||||
|
||||
We now use ROWHAMMER-resistent values for ALLOW, DENY, AUTH_SUCCESS,
|
||||
AUTH_FAILURE, AUTH_ERROR and AUTH_NONINTERACTIVE. In addition, we
|
||||
explicitly test for expected values instead of using a negated test
|
||||
against an error value. In the parser match functions this means
|
||||
explicitly checking for ALLOW or DENY instead of accepting anything
|
||||
that is not set to UNSPEC.
|
||||
|
||||
Thanks to Andrew J. Adiletta, M. Caner Tol, Yarkin Doroz, and Berk
|
||||
Sunar, all affiliated with the Vernam Applied Cryptography and
|
||||
Cybersecurity Lab at Worcester Polytechnic Institute, for the report.
|
||||
Paper preprint: https://arxiv.org/abs/2309.02545
|
||||
|
||||
Reference: https://github.com/sudo-project/sudo/commit/7873f8334c8d31031f8cfa83bd97ac6029309e4f
|
||||
Conflict: passwd.c sudo_auth.h match.c parse.c
|
||||
|
||||
---
|
||||
plugins/sudoers/auth/passwd.c | 18 ++++++-----
|
||||
plugins/sudoers/auth/sudo_auth.c | 51 ++++++++++++++++++++++----------
|
||||
plugins/sudoers/auth/sudo_auth.h | 10 +++----
|
||||
plugins/sudoers/match.c | 25 ++++++++--------
|
||||
plugins/sudoers/parse.c | 6 ++--
|
||||
plugins/sudoers/parse.h | 23 ++++++++++----
|
||||
6 files changed, 86 insertions(+), 47 deletions(-)
|
||||
|
||||
diff --git a/plugins/sudoers/auth/passwd.c b/plugins/sudoers/auth/passwd.c
|
||||
index 910a510..2a9766c 100644
|
||||
--- a/plugins/sudoers/auth/passwd.c
|
||||
+++ b/plugins/sudoers/auth/passwd.c
|
||||
@@ -61,7 +61,7 @@ sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_c
|
||||
char des_pass[9], *epass;
|
||||
char *pw_epasswd = auth->data;
|
||||
size_t pw_len;
|
||||
- int matched = 0;
|
||||
+ int ret;
|
||||
debug_decl(sudo_passwd_verify, SUDOERS_DEBUG_AUTH);
|
||||
|
||||
/* An empty plain-text password must match an empty encrypted password. */
|
||||
@@ -73,7 +73,7 @@ sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_c
|
||||
*/
|
||||
pw_len = strlen(pw_epasswd);
|
||||
if (pw_len == DESLEN || HAS_AGEINFO(pw_epasswd, pw_len)) {
|
||||
- strlcpy(des_pass, pass, sizeof(des_pass));
|
||||
+ (void)strlcpy(des_pass, pass, sizeof(des_pass));
|
||||
pass = des_pass;
|
||||
}
|
||||
|
||||
@@ -83,16 +83,20 @@ sudo_passwd_verify(struct passwd *pw, char *pass, sudo_auth *auth, struct sudo_c
|
||||
* only compare the first DESLEN characters in that case.
|
||||
*/
|
||||
epass = (char *) crypt(pass, pw_epasswd);
|
||||
+ ret = AUTH_FAILURE;
|
||||
if (epass != NULL) {
|
||||
- if (HAS_AGEINFO(pw_epasswd, pw_len) && strlen(epass) == DESLEN)
|
||||
- matched = !strncmp(pw_epasswd, epass, DESLEN);
|
||||
- else
|
||||
- matched = !strcmp(pw_epasswd, epass);
|
||||
+ if (HAS_AGEINFO(pw_epasswd, pw_len) && strlen(epass) == DESLEN){
|
||||
+ if(strncmp(pw_epasswd, epass, DESLEN) == 0)
|
||||
+ ret = AUTH_SUCCESS;
|
||||
+ }else{
|
||||
+ if(strcmp(pw_epasswd, epass) == 0)
|
||||
+ ret = AUTH_SUCCESS;
|
||||
+ }
|
||||
}
|
||||
|
||||
explicit_bzero(des_pass, sizeof(des_pass));
|
||||
|
||||
- debug_return_int(matched ? AUTH_SUCCESS : AUTH_FAILURE);
|
||||
+ debug_return_int(ret);
|
||||
}
|
||||
|
||||
int
|
||||
diff --git a/plugins/sudoers/auth/sudo_auth.c b/plugins/sudoers/auth/sudo_auth.c
|
||||
index 1bdacdb..767fe26 100644
|
||||
--- a/plugins/sudoers/auth/sudo_auth.c
|
||||
+++ b/plugins/sudoers/auth/sudo_auth.c
|
||||
@@ -112,10 +112,16 @@ sudo_auth_init(struct passwd *pw)
|
||||
if (auth->init && !IS_DISABLED(auth)) {
|
||||
/* Disable if it failed to init unless there was a fatal error. */
|
||||
status = (auth->init)(pw, auth);
|
||||
- if (status == AUTH_FAILURE)
|
||||
+ switch (status) {
|
||||
+ case AUTH_SUCCESS:
|
||||
+ break;
|
||||
+ case AUTH_FAILURE:
|
||||
SET(auth->flags, FLAG_DISABLED);
|
||||
- else if (status == AUTH_FATAL)
|
||||
- break; /* assume error msg already printed */
|
||||
+ break;
|
||||
+ default:
|
||||
+ /*Assume error msg already printed. */
|
||||
+ debug_return_int(-1);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +167,7 @@ sudo_auth_init(struct passwd *pw)
|
||||
}
|
||||
}
|
||||
|
||||
- debug_return_int(status == AUTH_FATAL ? -1 : 0);
|
||||
+ debug_return_int(0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -202,7 +208,7 @@ sudo_auth_cleanup(struct passwd *pw, bool force)
|
||||
for (auth = auth_switch; auth->name; auth++) {
|
||||
if (auth->cleanup && !IS_DISABLED(auth)) {
|
||||
int status = (auth->cleanup)(pw, auth, force);
|
||||
- if (status == AUTH_FATAL) {
|
||||
+ if (status != AUTH_SUCCESS) {
|
||||
/* Assume error msg already printed. */
|
||||
debug_return_int(-1);
|
||||
}
|
||||
@@ -297,7 +303,7 @@ verify_user(struct passwd *pw, char *prompt, int validated,
|
||||
status = (auth->setup)(pw, &prompt, auth);
|
||||
if (status == AUTH_FAILURE)
|
||||
SET(auth->flags, FLAG_DISABLED);
|
||||
- else if (status == AUTH_FATAL || user_interrupted())
|
||||
+ else if (status != AUTH_SUCCESS || user_interrupted())
|
||||
goto done; /* assume error msg already printed */
|
||||
}
|
||||
}
|
||||
@@ -350,7 +356,6 @@ done:
|
||||
log_auth_failure(validated, ntries);
|
||||
ret = false;
|
||||
break;
|
||||
- case AUTH_FATAL:
|
||||
default:
|
||||
log_auth_failure(validated, 0);
|
||||
ret = -1;
|
||||
@@ -362,24 +367,32 @@ done:
|
||||
|
||||
/*
|
||||
* Call authentication method begin session hooks.
|
||||
- * Returns 1 on success and -1 on error.
|
||||
+ * Returns true on success, false on failure and -1 on error.
|
||||
*/
|
||||
int
|
||||
sudo_auth_begin_session(struct passwd *pw, char **user_env[])
|
||||
{
|
||||
sudo_auth *auth;
|
||||
+ int ret = true;
|
||||
debug_decl(sudo_auth_begin_session, SUDOERS_DEBUG_AUTH);
|
||||
|
||||
for (auth = auth_switch; auth->name; auth++) {
|
||||
if (auth->begin_session && !IS_DISABLED(auth)) {
|
||||
int status = (auth->begin_session)(pw, user_env, auth);
|
||||
- if (status != AUTH_SUCCESS) {
|
||||
+ switch (status) {
|
||||
+ case AUTH_SUCCESS:
|
||||
+ break;
|
||||
+ case AUTH_FAILURE:
|
||||
+ ret = false;
|
||||
+ break;
|
||||
+ default:
|
||||
/* Assume error msg already printed. */
|
||||
- debug_return_int(-1);
|
||||
+ ret = -1;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
- debug_return_int(1);
|
||||
+ debug_return_int(ret);
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -400,25 +413,33 @@ sudo_auth_needs_end_session(void)
|
||||
|
||||
/*
|
||||
* Call authentication method end session hooks.
|
||||
- * Returns 1 on success and -1 on error.
|
||||
+ * Returns true on success,false on failure and -1 on error.
|
||||
*/
|
||||
int
|
||||
sudo_auth_end_session(struct passwd *pw)
|
||||
{
|
||||
sudo_auth *auth;
|
||||
+ int ret = true;
|
||||
int status;
|
||||
debug_decl(sudo_auth_end_session, SUDOERS_DEBUG_AUTH);
|
||||
|
||||
for (auth = auth_switch; auth->name; auth++) {
|
||||
if (auth->end_session && !IS_DISABLED(auth)) {
|
||||
status = (auth->end_session)(pw, auth);
|
||||
- if (status == AUTH_FATAL) {
|
||||
+ switch (status) {
|
||||
+ case AUTH_SUCCESS:
|
||||
+ break;
|
||||
+ case AUTH_FAILURE:
|
||||
+ ret = false;
|
||||
+ break;
|
||||
+ default:
|
||||
/* Assume error msg already printed. */
|
||||
- debug_return_int(-1);
|
||||
+ ret = -1;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
- debug_return_int(1);
|
||||
+ debug_return_int(ret);
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/plugins/sudoers/auth/sudo_auth.h b/plugins/sudoers/auth/sudo_auth.h
|
||||
index 9ee408d..585637c 100644
|
||||
--- a/plugins/sudoers/auth/sudo_auth.h
|
||||
+++ b/plugins/sudoers/auth/sudo_auth.h
|
||||
@@ -19,11 +19,11 @@
|
||||
#ifndef SUDO_AUTH_H
|
||||
#define SUDO_AUTH_H
|
||||
|
||||
-/* Auth function return values. */
|
||||
-#define AUTH_SUCCESS 0
|
||||
-#define AUTH_FAILURE 1
|
||||
-#define AUTH_INTR 2
|
||||
-#define AUTH_FATAL 3
|
||||
+/* Auth function return values(rowhammer resistent). */
|
||||
+#define AUTH_SUCCESS 0x52a2925 /* 0101001010100010100100100101 */
|
||||
+#define AUTH_FAILURE 0xad5d6da /* 1010110101011101011011011010 */
|
||||
+#define AUTH_INTR 0x69d61fc8 /* 1101001110101100001111111001000 */
|
||||
+#define AUTH_FATAL 0x1629e037 /* 0010110001010011110000000110111 */
|
||||
|
||||
typedef struct sudo_auth {
|
||||
int flags; /* various flags, see below */
|
||||
diff --git a/plugins/sudoers/match.c b/plugins/sudoers/match.c
|
||||
index 052e988..edf8fa1 100644
|
||||
--- a/plugins/sudoers/match.c
|
||||
+++ b/plugins/sudoers/match.c
|
||||
@@ -93,7 +93,7 @@ user_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
|
||||
if ((a = alias_get(parse_tree, m->name, USERALIAS)) != NULL) {
|
||||
/* XXX */
|
||||
const int rc = userlist_matches(parse_tree, pw, &a->members);
|
||||
- if (rc != UNSPEC) {
|
||||
+ if (SPECIFIED(rc)) {
|
||||
if(m->negated) {
|
||||
matched = rc == ALLOW ? DENY : ALLOW;
|
||||
} else {
|
||||
@@ -125,7 +125,8 @@ userlist_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
|
||||
debug_decl(userlist_matches, SUDOERS_DEBUG_MATCH);
|
||||
|
||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
||||
- if ((matched = user_matches(parse_tree, pw, m)) != UNSPEC)
|
||||
+ matched = user_matches(parse_tree, pw, m);
|
||||
+ if (SPECIFIED(matched))
|
||||
break;
|
||||
}
|
||||
debug_return_int(matched);
|
||||
@@ -195,7 +196,7 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
if (a != NULL) {
|
||||
rc = runaslist_matches(parse_tree, &a->members,
|
||||
&empty, matching_user, NULL);
|
||||
- if (rc != UNSPEC){
|
||||
+ if (SPECIFIED(rc)){
|
||||
if (m->negated) {
|
||||
user_matched = rc == ALLOW ? DENY : ALLOW;
|
||||
} else {
|
||||
@@ -216,7 +217,7 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
user_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
}
|
||||
- if (user_matched != UNSPEC) {
|
||||
+ if (SPECIFIED(user_matched)) {
|
||||
if (matching_user != NULL && m->type != ALIAS)
|
||||
*matching_user = m;
|
||||
break;
|
||||
@@ -229,7 +230,7 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
* Skip checking runas group if none was specified.
|
||||
*/
|
||||
if (ISSET(sudo_user.flags, RUNAS_GROUP_SPECIFIED)) {
|
||||
- if (user_matched == UNSPEC) {
|
||||
+ if (!SPECIFIED(user_matched)) {
|
||||
if (strcmp(user_name, runas_pw->pw_name) == 0)
|
||||
user_matched = ALLOW; /* only changing group */
|
||||
}
|
||||
@@ -244,7 +245,7 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
if (a != NULL) {
|
||||
rc = runaslist_matches(parse_tree, &empty,
|
||||
&a->members, NULL, matching_group);
|
||||
- if (rc != UNSPEC){
|
||||
+ if (SPECIFIED(rc)){
|
||||
if (m->negated) {
|
||||
group_matched = rc == ALLOW ? DENY : ALLOW;
|
||||
} else {
|
||||
@@ -260,14 +261,14 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
group_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
}
|
||||
- if (group_matched != UNSPEC) {
|
||||
+ if (SPECIFIED(group_matched)) {
|
||||
if (matching_group != NULL && m->type != ALIAS)
|
||||
*matching_group = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
- if (group_matched == UNSPEC) {
|
||||
+ if (!SPECIFIED(group_matched)) {
|
||||
struct gid_list *runas_groups;
|
||||
/*
|
||||
* The runas group was not explicitly allowed by sudoers.
|
||||
@@ -311,7 +312,7 @@ hostlist_matches_int(struct sudoers_parse_tree *parse_tree,
|
||||
|
||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
||||
matched = host_matches(parse_tree, pw, lhost, shost, m);
|
||||
- if (matched != UNSPEC)
|
||||
+ if (SPECIFIED(matched))
|
||||
break;
|
||||
}
|
||||
debug_return_int(matched);
|
||||
@@ -362,7 +363,7 @@ host_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
|
||||
/* XXX */
|
||||
const int rc = hostlist_matches_int(parse_tree, pw, lhost,
|
||||
shost,&a->members);
|
||||
- if (rc != UNSPEC){
|
||||
+ if (SPECIFIED(rc)){
|
||||
if(m->negated){
|
||||
matched = rc == ALLOW ? DENY : ALLOW;
|
||||
} else {
|
||||
@@ -395,7 +396,7 @@ cmndlist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
|
||||
TAILQ_FOREACH_REVERSE(m, list, member_list, entries) {
|
||||
matched = cmnd_matches(parse_tree, m);
|
||||
- if (matched != UNSPEC)
|
||||
+ if (SPECIFIED(matched))
|
||||
break;
|
||||
}
|
||||
debug_return_int(matched);
|
||||
@@ -429,7 +430,7 @@ cmnd_matches(struct sudoers_parse_tree *parse_tree, const struct member *m)
|
||||
a = alias_get(parse_tree, m->name, CMNDALIAS);
|
||||
if (a != NULL) {
|
||||
rc = cmndlist_matches(parse_tree, &a->members);
|
||||
- if (rc != UNSPEC){
|
||||
+ if (SPECIFIED(rc)){
|
||||
if (m->negated) {
|
||||
matched = rc == ALLOW ? DENY : ALLOW;
|
||||
} else {
|
||||
diff --git a/plugins/sudoers/parse.c b/plugins/sudoers/parse.c
|
||||
index 6f29e0b..b5d37fb 100644
|
||||
--- a/plugins/sudoers/parse.c
|
||||
+++ b/plugins/sudoers/parse.c
|
||||
@@ -147,7 +147,7 @@ sudoers_lookup_check(struct sudo_nss *nss, struct passwd *pw,
|
||||
NULL);
|
||||
if (runas_match == ALLOW) {
|
||||
cmnd_match = cmnd_matches(nss->parse_tree, cs->cmnd);
|
||||
- if (cmnd_match != UNSPEC) {
|
||||
+ if (SPECIFIED(cmnd_match)) {
|
||||
/*
|
||||
* If user is running command as himself,
|
||||
* set runas_pw = sudo_user.pw.
|
||||
@@ -301,7 +301,7 @@ sudoers_lookup(struct sudo_nss_list *snl, struct passwd *pw, int validated,
|
||||
}
|
||||
|
||||
m = sudoers_lookup_check(nss, pw, &validated, &cs, &defs, now);
|
||||
- if (m != UNSPEC) {
|
||||
+ if (SPECIFIED(m)) {
|
||||
match = m;
|
||||
parse_tree = nss->parse_tree;
|
||||
}
|
||||
@@ -309,7 +309,7 @@ sudoers_lookup(struct sudo_nss_list *snl, struct passwd *pw, int validated,
|
||||
if (!sudo_nss_can_continue(nss, m))
|
||||
break;
|
||||
}
|
||||
- if (match != UNSPEC) {
|
||||
+ if (SPECIFIED(match)) {
|
||||
if (defs != NULL)
|
||||
update_defaults(parse_tree, defs, SETDEF_GENERIC, false);
|
||||
if (!apply_cmndspec(cs))
|
||||
diff --git a/plugins/sudoers/parse.h b/plugins/sudoers/parse.h
|
||||
index ecc81b8..e1ba680 100644
|
||||
--- a/plugins/sudoers/parse.h
|
||||
+++ b/plugins/sudoers/parse.h
|
||||
@@ -28,15 +28,28 @@
|
||||
/* Returns true if string 's' contains meta characters. */
|
||||
#define has_meta(s) (strpbrk(s, "\\?*[]") != NULL)
|
||||
|
||||
+/* Allowed by policy (rowhammer resistent). */
|
||||
+#undef ALLOW
|
||||
+#define ALLOW 0x52a2925 /* 0101001010100010100100100101 */
|
||||
+
|
||||
+/* Denied by policy (rowhammer resistent) */
|
||||
+#undef DENY
|
||||
+#define DENY 0xad5d6da /* 1010110101011101011011011010 */
|
||||
+
|
||||
+/* Neither allowed, nor denied. */
|
||||
#undef UNSPEC
|
||||
#define UNSPEC -1
|
||||
-#undef DENY
|
||||
-#define DENY 0
|
||||
-#undef ALLOW
|
||||
-#define ALLOW 1
|
||||
+
|
||||
+/* Tag implied by root access (SETENV only). */
|
||||
#undef IMPLIED
|
||||
#define IMPLIED 2
|
||||
|
||||
+/*
|
||||
+ * We must explicitly check against ALLOW and DENY instead testing
|
||||
+ * that the value is not UNSPEC to avoid potential ROWHAMMER issues.
|
||||
+ */
|
||||
+#define SPECIFIED(_v) ((_v) == ALLOW || (_v) == DENY)
|
||||
+
|
||||
/*
|
||||
* Initialize all tags to UNSPEC.
|
||||
*/
|
||||
@@ -83,7 +96,7 @@
|
||||
* Returns true if the specified tag is not UNSPEC or IMPLIED, else false.
|
||||
*/
|
||||
#define TAG_SET(tt) \
|
||||
- ((tt) != UNSPEC && (tt) != IMPLIED)
|
||||
+ ((tt) == true || (tt) == false)
|
||||
|
||||
/*
|
||||
* Returns true if any tags set in nt differ between ot and nt, else false.
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,257 @@
|
||||
From cf00568d888c90a8c5d06a06283bc87a45992933 Mon Sep 17 00:00:00 2001
|
||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
||||
Date: Sat, 26 Aug 2023 10:32:37 -0600
|
||||
Subject: [PATCH] Do not rely on the definition of ALLOW/DENY being true/false.
|
||||
|
||||
We now explicitly check for ALLOW and DENY when checking return
|
||||
values and negating values.
|
||||
|
||||
Reference: https://github.com/sudo-project/sudo/commit/cf00568d888c90a8c5d06a06283bc87a45992933
|
||||
Conflict: cvtsudoers.c match.c
|
||||
---
|
||||
plugins/sudoers/cvtsudoers.c | 6 +--
|
||||
plugins/sudoers/match.c | 85 +++++++++++++++++++++++-------------
|
||||
2 files changed, 58 insertions(+), 33 deletions(-)
|
||||
|
||||
diff --git a/plugins/sudoers/cvtsudoers.c b/plugins/sudoers/cvtsudoers.c
|
||||
index 111b326..12fcfd4 100644
|
||||
--- a/plugins/sudoers/cvtsudoers.c
|
||||
+++ b/plugins/sudoers/cvtsudoers.c
|
||||
@@ -686,7 +686,7 @@ userlist_matches_filter(struct sudoers_parse_tree *parse_tree,
|
||||
pw.pw_uid = (uid_t)-1;
|
||||
pw.pw_gid = (gid_t)-1;
|
||||
|
||||
- if (user_matches(parse_tree, &pw, m) == true)
|
||||
+ if (user_matches(parse_tree, &pw, m) == ALLOW)
|
||||
matched = true;
|
||||
} else {
|
||||
STAILQ_FOREACH(s, &filters->users, entries) {
|
||||
@@ -712,7 +712,7 @@ userlist_matches_filter(struct sudoers_parse_tree *parse_tree,
|
||||
if (pw == NULL)
|
||||
continue;
|
||||
|
||||
- if (user_matches(parse_tree, pw, m) == true)
|
||||
+ if (user_matches(parse_tree, pw, m) == ALLOW)
|
||||
matched = true;
|
||||
sudo_pw_delref(pw);
|
||||
|
||||
@@ -788,7 +788,7 @@ hostlist_matches_filter(struct sudoers_parse_tree *parse_tree,
|
||||
|
||||
/* Only need one host in the filter to match. */
|
||||
/* XXX - can't use netgroup_tuple with NULL pw */
|
||||
- if (host_matches(parse_tree, NULL, lhost, shost, m) == true) {
|
||||
+ if (host_matches(parse_tree, NULL, lhost, shost, m) == ALLOW) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
diff --git a/plugins/sudoers/match.c b/plugins/sudoers/match.c
|
||||
index 9051545..052e988 100644
|
||||
--- a/plugins/sudoers/match.c
|
||||
+++ b/plugins/sudoers/match.c
|
||||
@@ -77,31 +77,36 @@ user_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
|
||||
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case NETGROUP:
|
||||
if (netgr_matches(m->name,
|
||||
def_netgroup_tuple ? lhost : NULL,
|
||||
def_netgroup_tuple ? shost : NULL, pw->pw_name))
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case USERGROUP:
|
||||
if (usergr_matches(m->name, pw->pw_name, pw))
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case ALIAS:
|
||||
if ((a = alias_get(parse_tree, m->name, USERALIAS)) != NULL) {
|
||||
/* XXX */
|
||||
- int rc = userlist_matches(parse_tree, pw, &a->members);
|
||||
- if (rc != UNSPEC)
|
||||
- matched = m->negated ? !rc : rc;
|
||||
+ const int rc = userlist_matches(parse_tree, pw, &a->members);
|
||||
+ if (rc != UNSPEC) {
|
||||
+ if(m->negated) {
|
||||
+ matched = rc == ALLOW ? DENY : ALLOW;
|
||||
+ } else {
|
||||
+ matched = rc;
|
||||
+ }
|
||||
+ }
|
||||
alias_put(a);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case WORD:
|
||||
if (userpw_matches(m->name, pw->pw_name, pw))
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
}
|
||||
debug_return_int(matched);
|
||||
@@ -172,38 +177,43 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
TAILQ_FOREACH_REVERSE(m, user_list, member_list, entries) {
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
- user_matched = !m->negated;
|
||||
+ user_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case NETGROUP:
|
||||
if (netgr_matches(m->name,
|
||||
def_netgroup_tuple ? lhost : NULL,
|
||||
def_netgroup_tuple ? shost : NULL,
|
||||
runas_pw->pw_name))
|
||||
- user_matched = !m->negated;
|
||||
+ user_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case USERGROUP:
|
||||
if (usergr_matches(m->name, runas_pw->pw_name, runas_pw))
|
||||
- user_matched = !m->negated;
|
||||
+ user_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case ALIAS:
|
||||
a = alias_get(parse_tree, m->name, RUNASALIAS);
|
||||
if (a != NULL) {
|
||||
rc = runaslist_matches(parse_tree, &a->members,
|
||||
&empty, matching_user, NULL);
|
||||
- if (rc != UNSPEC)
|
||||
- user_matched = m->negated ? !rc : rc;
|
||||
+ if (rc != UNSPEC){
|
||||
+ if (m->negated) {
|
||||
+ user_matched = rc == ALLOW ? DENY : ALLOW;
|
||||
+ } else {
|
||||
+ user_matched = rc;
|
||||
+ }
|
||||
+ }
|
||||
alias_put(a);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case WORD:
|
||||
if (userpw_matches(m->name, runas_pw->pw_name, runas_pw))
|
||||
- user_matched = !m->negated;
|
||||
+ user_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case MYSELF:
|
||||
if (!ISSET(sudo_user.flags, RUNAS_USER_SPECIFIED) ||
|
||||
strcmp(user_name, runas_pw->pw_name) == 0)
|
||||
- user_matched = !m->negated;
|
||||
+ user_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
}
|
||||
if (user_matched != UNSPEC) {
|
||||
@@ -227,22 +237,27 @@ runaslist_matches(struct sudoers_parse_tree *parse_tree,
|
||||
TAILQ_FOREACH_REVERSE(m, group_list, member_list, entries) {
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
- group_matched = !m->negated;
|
||||
+ group_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case ALIAS:
|
||||
a = alias_get(parse_tree, m->name, RUNASALIAS);
|
||||
if (a != NULL) {
|
||||
rc = runaslist_matches(parse_tree, &empty,
|
||||
&a->members, NULL, matching_group);
|
||||
- if (rc != UNSPEC)
|
||||
- group_matched = m->negated ? !rc : rc;
|
||||
+ if (rc != UNSPEC){
|
||||
+ if (m->negated) {
|
||||
+ group_matched = rc == ALLOW ? DENY : ALLOW;
|
||||
+ } else {
|
||||
+ group_matched = rc;
|
||||
+ }
|
||||
+ }
|
||||
alias_put(a);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case WORD:
|
||||
if (group_matches(m->name, runas_gr))
|
||||
- group_matched = !m->negated;
|
||||
+ group_matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
}
|
||||
if (group_matched != UNSPEC) {
|
||||
@@ -330,32 +345,37 @@ host_matches(struct sudoers_parse_tree *parse_tree, const struct passwd *pw,
|
||||
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case NETGROUP:
|
||||
if (netgr_matches(m->name, lhost, shost,
|
||||
def_netgroup_tuple ? pw->pw_name : NULL))
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case NTWKADDR:
|
||||
if (addr_matches(m->name))
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case ALIAS:
|
||||
a = alias_get(parse_tree, m->name, HOSTALIAS);
|
||||
if (a != NULL) {
|
||||
/* XXX */
|
||||
- int rc = hostlist_matches_int(parse_tree, pw, lhost, shost,
|
||||
- &a->members);
|
||||
- if (rc != UNSPEC)
|
||||
- matched = m->negated ? !rc : rc;
|
||||
+ const int rc = hostlist_matches_int(parse_tree, pw, lhost,
|
||||
+ shost,&a->members);
|
||||
+ if (rc != UNSPEC){
|
||||
+ if(m->negated){
|
||||
+ matched = rc == ALLOW ? DENY : ALLOW;
|
||||
+ } else {
|
||||
+ matched = rc;
|
||||
+ }
|
||||
+ }
|
||||
alias_put(a);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case WORD:
|
||||
if (hostname_matches(shost, lhost, m->name))
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
}
|
||||
debug_return_int(matched);
|
||||
@@ -396,21 +416,26 @@ cmnd_matches(struct sudoers_parse_tree *parse_tree, const struct member *m)
|
||||
switch (m->type) {
|
||||
case ALL:
|
||||
if (m->name == NULL) {
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case COMMAND:
|
||||
c = (struct sudo_command *)m->name;
|
||||
if (command_matches(c->cmnd, c->args, &c->digests))
|
||||
- matched = !m->negated;
|
||||
+ matched = m->negated ? DENY : ALLOW;
|
||||
break;
|
||||
case ALIAS:
|
||||
a = alias_get(parse_tree, m->name, CMNDALIAS);
|
||||
if (a != NULL) {
|
||||
rc = cmndlist_matches(parse_tree, &a->members);
|
||||
- if (rc != UNSPEC)
|
||||
- matched = m->negated ? !rc : rc;
|
||||
+ if (rc != UNSPEC){
|
||||
+ if (m->negated) {
|
||||
+ matched = rc == ALLOW ? DENY : ALLOW;
|
||||
+ } else {
|
||||
+ matched = rc;
|
||||
+ }
|
||||
+ }
|
||||
alias_put(a);
|
||||
}
|
||||
break;
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,989 @@
|
||||
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 | 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 <gram.h>
|
||||
|
||||
-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
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
Name: sudo
|
||||
Version: 1.9.2
|
||||
Release: 14
|
||||
Release: 15
|
||||
Summary: Allows restricted root access for specified users
|
||||
License: ISC
|
||||
URL: http://www.courtesan.com/sudo/
|
||||
@ -37,6 +37,9 @@ Patch23: backport-CVE-2023-22809.patch
|
||||
Patch24: backport-CVE-2023-28486_CVE-2023-28487.patch
|
||||
Patch25: Fix-compilation-error-on-sw64-arch.patch
|
||||
Patch26: backport-don-t-report-a-usage-error-for-sudo-V.patch
|
||||
Patch27: backport-Do-not-rely-on-the-definition-of-ALLOW-DENY-being-tr.patch
|
||||
Patch28: backport-CVE-2023-42465.patch
|
||||
Patch29: backport-Make-all-match-functions-return-ALLOW-DENY-not-true-.patch
|
||||
|
||||
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
Requires: pam
|
||||
@ -177,6 +180,9 @@ install -p -c -m 0644 %{SOURCE3} $RPM_BUILD_ROOT/etc/pam.d/sudo-i
|
||||
%exclude %{_pkgdocdir}/ChangeLog
|
||||
|
||||
%changelog
|
||||
* Mon Jan 8 2024 wangqingsan <wangqingsan@huawei.com> - 1.9.2-15
|
||||
- fix CVE-2023-42465.
|
||||
|
||||
* Mon Nov 27 2023 zhangruifang <zhangruifang1@h-partners.com> - 1.9.2-14
|
||||
- Don't report a usage error for "sudo -V".
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user