Accepting request 949359 from home:simotek:branches:Base:System
- Add support in the LDAP filter for negated users, patch taken from upstream (jsc#20068) * Adds sudo-feature-negated-LDAP-users.patch OBS-URL: https://build.opensuse.org/request/show/949359 OBS-URL: https://build.opensuse.org/package/show/Base:System/sudo?expand=0&rev=206
This commit is contained in:
parent
baf92a7f64
commit
bb99464edf
295
sudo-feature-negated-LDAP-users.patch
Normal file
295
sudo-feature-negated-LDAP-users.patch
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
From e88087721be391ec851b3cad8a88a5476f03d317 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
||||||
|
Date: Tue, 18 Jan 2022 11:20:22 -0700
|
||||||
|
Subject: [PATCH] Add support in the LDAP filter for negated users. Based on a
|
||||||
|
diff from Simon Lees
|
||||||
|
|
||||||
|
---
|
||||||
|
docs/sudoers.ldap.man.in | 31 ++++------
|
||||||
|
docs/sudoers.ldap.mdoc.in | 28 ++++-----
|
||||||
|
plugins/sudoers/ldap.c | 116 ++++++++++++++++++++++++++++----------
|
||||||
|
3 files changed, 109 insertions(+), 66 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c
|
||||||
|
index 4b768fdfb..e3c47b9bc 100644
|
||||||
|
--- a/plugins/sudoers/ldap.c
|
||||||
|
+++ b/plugins/sudoers/ldap.c
|
||||||
|
@@ -1,7 +1,7 @@
|
||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: ISC
|
||||||
|
*
|
||||||
|
- * Copyright (c) 2003-2020 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||||
|
+ * Copyright (c) 2003-2022 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed by Aaron Spangler.
|
||||||
|
*
|
||||||
|
@@ -315,18 +315,18 @@ sudo_ldap_get_values_len(LDAP *ld, LDAPMessage *entry, char *attr, int *rc)
|
||||||
|
/*
|
||||||
|
* Walk through search results and return true if we have a matching
|
||||||
|
* non-Unix group (including netgroups), else false.
|
||||||
|
+ * A matching entry that is negated will always return false.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
sudo_ldap_check_non_unix_group(LDAP *ld, LDAPMessage *entry, struct passwd *pw)
|
||||||
|
{
|
||||||
|
struct berval **bv, **p;
|
||||||
|
bool ret = false;
|
||||||
|
- char *val;
|
||||||
|
int rc;
|
||||||
|
debug_decl(sudo_ldap_check_non_unix_group, SUDOERS_DEBUG_LDAP);
|
||||||
|
|
||||||
|
if (!entry)
|
||||||
|
- debug_return_bool(ret);
|
||||||
|
+ debug_return_bool(false);
|
||||||
|
|
||||||
|
/* get the values from the entry */
|
||||||
|
bv = sudo_ldap_get_values_len(ld, entry, "sudoUser", &rc);
|
||||||
|
@@ -338,18 +338,29 @@ sudo_ldap_check_non_unix_group(LDAP *ld, LDAPMessage *entry, struct passwd *pw)
|
||||||
|
|
||||||
|
/* walk through values */
|
||||||
|
for (p = bv; *p != NULL && !ret; p++) {
|
||||||
|
- val = (*p)->bv_val;
|
||||||
|
+ bool negated = false;
|
||||||
|
+ char *val = (*p)->bv_val;
|
||||||
|
+
|
||||||
|
+ if (*val == '!') {
|
||||||
|
+ val++;
|
||||||
|
+ negated = true;
|
||||||
|
+ }
|
||||||
|
if (*val == '+') {
|
||||||
|
if (netgr_matches(val, def_netgroup_tuple ? user_runhost : NULL,
|
||||||
|
def_netgroup_tuple ? user_srunhost : NULL, pw->pw_name))
|
||||||
|
ret = true;
|
||||||
|
- DPRINTF2("ldap sudoUser netgroup '%s' ... %s", val,
|
||||||
|
- ret ? "MATCH!" : "not");
|
||||||
|
+ DPRINTF2("ldap sudoUser netgroup '%s%s' ... %s",
|
||||||
|
+ negated ? "!" : "", val, ret ? "MATCH!" : "not");
|
||||||
|
} else {
|
||||||
|
if (group_plugin_query(pw->pw_name, val + 2, pw))
|
||||||
|
ret = true;
|
||||||
|
- DPRINTF2("ldap sudoUser non-Unix group '%s' ... %s", val,
|
||||||
|
- ret ? "MATCH!" : "not");
|
||||||
|
+ DPRINTF2("ldap sudoUser non-Unix group '%s%s' ... %s",
|
||||||
|
+ negated ? "!" : "", val, ret ? "MATCH!" : "not");
|
||||||
|
+ }
|
||||||
|
+ /* A negated match overrides all other entries. */
|
||||||
|
+ if (ret && negated) {
|
||||||
|
+ ret = false;
|
||||||
|
+ break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -928,7 +939,8 @@ sudo_netgroup_lookup(LDAP *ld, struct passwd *pw,
|
||||||
|
static char *
|
||||||
|
sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||||
|
{
|
||||||
|
- char *buf, timebuffer[TIMEFILTER_LENGTH + 1], idbuf[MAX_UID_T_LEN + 1];
|
||||||
|
+ char timebuffer[TIMEFILTER_LENGTH + 1], idbuf[MAX_UID_T_LEN + 1];
|
||||||
|
+ char *buf, *notbuf;
|
||||||
|
struct ldap_netgroup_list netgroups;
|
||||||
|
struct ldap_netgroup *ng = NULL;
|
||||||
|
struct gid_list *gidlist;
|
||||||
|
@@ -940,34 +952,45 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||||
|
|
||||||
|
STAILQ_INIT(&netgroups);
|
||||||
|
|
||||||
|
- /* If there is a filter, allocate space for the global AND. */
|
||||||
|
- if (ldap_conf.timed || ldap_conf.search_filter)
|
||||||
|
+ if (ldap_conf.timed || ldap_conf.search_filter) {
|
||||||
|
+ /* Allocate space for the global AND. */
|
||||||
|
sz += 3;
|
||||||
|
|
||||||
|
- /* Add LDAP search filter if present. */
|
||||||
|
- if (ldap_conf.search_filter)
|
||||||
|
- sz += strlen(ldap_conf.search_filter);
|
||||||
|
+ /* Add LDAP search filter if present. */
|
||||||
|
+ if (ldap_conf.search_filter)
|
||||||
|
+ sz += strlen(ldap_conf.search_filter);
|
||||||
|
+
|
||||||
|
+ /* If timed, add space for time limits. */
|
||||||
|
+ if (ldap_conf.timed)
|
||||||
|
+ sz += TIMEFILTER_LENGTH;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Add space for the global OR clause + (sudoUser=ALL) + NOT + NUL. */
|
||||||
|
+ sz += sizeof("(|(sudoUser=ALL)(!(|)))");
|
||||||
|
|
||||||
|
- /* Then add (|(sudoUser=USERNAME)(sudoUser=#uid)(sudoUser=ALL)) + NUL */
|
||||||
|
- sz += 29 + (12 + MAX_UID_T_LEN) + sudo_ldap_value_len(pw->pw_name);
|
||||||
|
+ /* Add space for username and uid, including the negated versions. */
|
||||||
|
+ sz += ((sizeof("(sudoUser=)(sudoUser=#)") - 1 +
|
||||||
|
+ sudo_ldap_value_len(pw->pw_name) + MAX_UID_T_LEN) * 2) + 2;
|
||||||
|
|
||||||
|
/* Add space for primary and supplementary groups and gids */
|
||||||
|
if ((grp = sudo_getgrgid(pw->pw_gid)) != NULL) {
|
||||||
|
- sz += 12 + sudo_ldap_value_len(grp->gr_name);
|
||||||
|
+ sz += ((sizeof("(sudoUser=%)") - 1 +
|
||||||
|
+ sudo_ldap_value_len(grp->gr_name)) * 2) + 1;
|
||||||
|
}
|
||||||
|
- sz += 13 + MAX_UID_T_LEN;
|
||||||
|
+ sz += ((sizeof("(sudoUser=%#)") - 1 + MAX_UID_T_LEN) * 2) + 1;
|
||||||
|
if ((grlist = sudo_get_grlist(pw)) != NULL) {
|
||||||
|
for (i = 0; i < grlist->ngroups; i++) {
|
||||||
|
if (grp != NULL && strcasecmp(grlist->groups[i], grp->gr_name) == 0)
|
||||||
|
continue;
|
||||||
|
- sz += 12 + sudo_ldap_value_len(grlist->groups[i]);
|
||||||
|
+ sz += ((sizeof("(sudoUser=%)") - 1 +
|
||||||
|
+ sudo_ldap_value_len(grlist->groups[i])) * 2) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((gidlist = sudo_get_gidlist(pw, ENTRY_TYPE_ANY)) != NULL) {
|
||||||
|
for (i = 0; i < gidlist->ngids; i++) {
|
||||||
|
if (pw->pw_gid == gidlist->gids[i])
|
||||||
|
continue;
|
||||||
|
- sz += 13 + MAX_UID_T_LEN;
|
||||||
|
+ sz += ((sizeof("(sudoUser=%#)") - 1 + MAX_UID_T_LEN) * 2) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -976,7 +999,7 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||||
|
DPRINTF1("Looking up netgroups for %s", pw->pw_name);
|
||||||
|
if (sudo_netgroup_lookup(ld, pw, &netgroups)) {
|
||||||
|
STAILQ_FOREACH(ng, &netgroups, entries) {
|
||||||
|
- sz += 14 + strlen(ng->name);
|
||||||
|
+ sz += ((sizeof("(sudoUser=+)") - 1 + strlen(ng->name)) * 2) + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* sudo_netgroup_lookup() failed, clean up. */
|
||||||
|
@@ -988,12 +1011,12 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* If timed, add space for time limits. */
|
||||||
|
- if (ldap_conf.timed)
|
||||||
|
- sz += TIMEFILTER_LENGTH;
|
||||||
|
- if ((buf = malloc(sz)) == NULL)
|
||||||
|
+ buf = malloc(sz);
|
||||||
|
+ notbuf = malloc(sz);
|
||||||
|
+ if (buf == NULL || notbuf == NULL)
|
||||||
|
goto bad;
|
||||||
|
*buf = '\0';
|
||||||
|
+ *notbuf = '\0';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If timed or using a search filter, start a global AND clause to
|
||||||
|
@@ -1009,23 +1032,35 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||||
|
CHECK_STRLCAT(buf, "(|(sudoUser=", sz);
|
||||||
|
CHECK_LDAP_VCAT(buf, pw->pw_name, sz);
|
||||||
|
CHECK_STRLCAT(buf, ")", sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, "(sudoUser=!", sz);
|
||||||
|
+ CHECK_LDAP_VCAT(notbuf, pw->pw_name, sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, ")", sz);
|
||||||
|
|
||||||
|
/* Append user-ID */
|
||||||
|
(void) snprintf(idbuf, sizeof(idbuf), "%u", (unsigned int)pw->pw_uid);
|
||||||
|
CHECK_STRLCAT(buf, "(sudoUser=#", sz);
|
||||||
|
CHECK_STRLCAT(buf, idbuf, sz);
|
||||||
|
CHECK_STRLCAT(buf, ")", sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, "(sudoUser=!#", sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, idbuf, sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, ")", sz);
|
||||||
|
|
||||||
|
/* Append primary group and group-ID */
|
||||||
|
if (grp != NULL) {
|
||||||
|
CHECK_STRLCAT(buf, "(sudoUser=%", sz);
|
||||||
|
CHECK_LDAP_VCAT(buf, grp->gr_name, sz);
|
||||||
|
CHECK_STRLCAT(buf, ")", sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, "(sudoUser=!%", sz);
|
||||||
|
+ CHECK_LDAP_VCAT(notbuf, grp->gr_name, sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, ")", sz);
|
||||||
|
}
|
||||||
|
(void) snprintf(idbuf, sizeof(idbuf), "%u", (unsigned int)pw->pw_gid);
|
||||||
|
CHECK_STRLCAT(buf, "(sudoUser=%#", sz);
|
||||||
|
CHECK_STRLCAT(buf, idbuf, sz);
|
||||||
|
CHECK_STRLCAT(buf, ")", sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, "(sudoUser=!%#", sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, idbuf, sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, ")", sz);
|
||||||
|
|
||||||
|
/* Append supplementary groups and group-IDs */
|
||||||
|
if (grlist != NULL) {
|
||||||
|
@@ -1035,6 +1070,9 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||||
|
CHECK_STRLCAT(buf, "(sudoUser=%", sz);
|
||||||
|
CHECK_LDAP_VCAT(buf, grlist->groups[i], sz);
|
||||||
|
CHECK_STRLCAT(buf, ")", sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, "(sudoUser=!%", sz);
|
||||||
|
+ CHECK_LDAP_VCAT(notbuf, grlist->groups[i], sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, ")", sz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (gidlist != NULL) {
|
||||||
|
@@ -1046,6 +1084,9 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||||
|
CHECK_STRLCAT(buf, "(sudoUser=%#", sz);
|
||||||
|
CHECK_STRLCAT(buf, idbuf, sz);
|
||||||
|
CHECK_STRLCAT(buf, ")", sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, "(sudoUser=!%#", sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, idbuf, sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, ")", sz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1063,12 +1104,20 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||||
|
CHECK_STRLCAT(buf, "(sudoUser=+", sz);
|
||||||
|
CHECK_LDAP_VCAT(buf, ng->name, sz);
|
||||||
|
CHECK_STRLCAT(buf, ")", sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, "(sudoUser=!+", sz);
|
||||||
|
+ CHECK_LDAP_VCAT(notbuf, ng->name, sz);
|
||||||
|
+ CHECK_STRLCAT(notbuf, ")", sz);
|
||||||
|
free(ng->name);
|
||||||
|
free(ng);
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Add ALL to list and end the global OR. */
|
||||||
|
- CHECK_STRLCAT(buf, "(sudoUser=ALL)", sz);
|
||||||
|
+ /* Add ALL to list. */
|
||||||
|
+ CHECK_STRLCAT(buf, "(sudoUser=ALL))", sz);
|
||||||
|
+
|
||||||
|
+ /* Add filter for negated entries. */
|
||||||
|
+ CHECK_STRLCAT(buf, "(!(|", sz);
|
||||||
|
+ CHECK_STRLCAT(buf, notbuf, sz);
|
||||||
|
+ CHECK_STRLCAT(buf, ")", sz);
|
||||||
|
|
||||||
|
/* Add the time restriction, or simply end the global OR. */
|
||||||
|
if (ldap_conf.timed) {
|
||||||
|
@@ -1079,8 +1128,10 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||||
|
} else if (ldap_conf.search_filter) {
|
||||||
|
CHECK_STRLCAT(buf, ")", sz); /* closes the global OR */
|
||||||
|
}
|
||||||
|
+
|
||||||
|
CHECK_STRLCAT(buf, ")", sz); /* closes the global OR or the global AND */
|
||||||
|
|
||||||
|
+ free(notbuf);
|
||||||
|
debug_return_str(buf);
|
||||||
|
overflow:
|
||||||
|
sudo_warnx(U_("internal error, %s overflow"), __func__);
|
||||||
|
@@ -1097,6 +1148,7 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||||
|
free(ng);
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
+ free(notbuf);
|
||||||
|
debug_return_str(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1133,16 +1185,18 @@ sudo_ldap_build_pass2(void)
|
||||||
|
* those get ANDed in to the expression.
|
||||||
|
*/
|
||||||
|
if (query_netgroups && def_group_plugin) {
|
||||||
|
- len = asprintf(&filt, "%s%s(|(sudoUser=+*)(sudoUser=%%:*))%s%s",
|
||||||
|
+ len = asprintf(&filt, "%s%s(|(sudoUser=+*)(sudoUser=!+*)(sudoUser=%%:*)(sudoUser=!%%:*))%s%s",
|
||||||
|
(ldap_conf.timed || ldap_conf.search_filter) ? "(&" : "",
|
||||||
|
ldap_conf.search_filter ? ldap_conf.search_filter : "",
|
||||||
|
ldap_conf.timed ? timebuffer : "",
|
||||||
|
(ldap_conf.timed || ldap_conf.search_filter) ? ")" : "");
|
||||||
|
} else {
|
||||||
|
- len = asprintf(&filt, "(&%s(sudoUser=*)(sudoUser=%s*)%s)",
|
||||||
|
+ len = asprintf(&filt, "%s%s(|(sudoUser=%s*)(sudoUser=!%s*))%s%s",
|
||||||
|
+ (ldap_conf.timed || ldap_conf.search_filter) ? "(&" : "",
|
||||||
|
ldap_conf.search_filter ? ldap_conf.search_filter : "",
|
||||||
|
- query_netgroups ? "+" : "%:",
|
||||||
|
- ldap_conf.timed ? timebuffer : "");
|
||||||
|
+ query_netgroups ? "+" : "%:", query_netgroups ? "+" : "%:",
|
||||||
|
+ ldap_conf.timed ? timebuffer : "",
|
||||||
|
+ (ldap_conf.timed || ldap_conf.search_filter) ? ")" : "");
|
||||||
|
}
|
||||||
|
if (len == -1)
|
||||||
|
filt = NULL;
|
@ -1,3 +1,10 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Jan 27 03:00:26 UTC 2022 - Simon Lees <sflees@suse.de>
|
||||||
|
|
||||||
|
- Add support in the LDAP filter for negated users, patch taken
|
||||||
|
from upstream (jsc#20068)
|
||||||
|
* Adds sudo-feature-negated-LDAP-users.patch
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Wed Sep 22 12:27:51 UTC 2021 - Kristyna Streitova <kstreitova@suse.com>
|
Wed Sep 22 12:27:51 UTC 2021 - Kristyna Streitova <kstreitova@suse.com>
|
||||||
|
|
||||||
|
@ -38,6 +38,8 @@ Source6: fate_313276_test.sh
|
|||||||
Source7: README_313276.test
|
Source7: README_313276.test
|
||||||
# PATCH-OPENSUSE: the "SUSE" branding of the default sudo config
|
# PATCH-OPENSUSE: the "SUSE" branding of the default sudo config
|
||||||
Patch0: sudo-sudoers.patch
|
Patch0: sudo-sudoers.patch
|
||||||
|
# PATCH-Upstream fixes jira SLE-20068 - sflees@suse.de
|
||||||
|
Patch1: sudo-feature-negated-LDAP-users.patch
|
||||||
BuildRequires: audit-devel
|
BuildRequires: audit-devel
|
||||||
BuildRequires: cyrus-sasl-devel
|
BuildRequires: cyrus-sasl-devel
|
||||||
BuildRequires: groff
|
BuildRequires: groff
|
||||||
|
Loading…
x
Reference in New Issue
Block a user