sssd/backport-ipa-correctly-remove-missing-attributes-on-netgroup-.patch
fly_fzc bcf7f22f07 backport upstream patches
(cherry picked from commit dfd154fc1eab69ccf7205c936abb022bbd1fb80a)
2023-09-22 17:05:18 +08:00

251 lines
8.7 KiB
Diff

From b033b0dda972e885f63234aa81dca317c8234c2c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 23 May 2023 12:21:44 +0200
Subject: [PATCH] ipa: correctly remove missing attributes on netgroup update
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When a netgroup is updated, previously it did not remove the missing
attributes. This caused an issue especially when a member was removed.
Resolves: https://github.com/SSSD/sssd/issues/6652
Reviewed-by: Alejandro López <allopez@redhat.com>
Reviewed-by: Iker Pedrosa <ipedrosa@redhat.com>
Reference: https://github.com/SSSD/sssd/commit/b033b0dda972e885f63234aa81dca317c8234c2c
Conflict: NA
---
src/db/sysdb.c | 9 ++
src/db/sysdb.h | 1 +
src/providers/ipa/ipa_netgroups.c | 35 +++++++-
src/tests/system/tests/test_netgroups.py | 108 +++++++++++++++++++++++
4 files changed, 151 insertions(+), 2 deletions(-)
create mode 100644 src/tests/system/tests/test_netgroups.py
diff --git a/src/db/sysdb.c b/src/db/sysdb.c
index 649e79fca..1faa11b16 100644
--- a/src/db/sysdb.c
+++ b/src/db/sysdb.c
@@ -523,6 +523,15 @@ static int sysdb_attrs_add_val_int(struct sysdb_attrs *attrs,
return EOK;
}
+
+int sysdb_attrs_add_empty(struct sysdb_attrs *attrs, const char *name)
+{
+ struct ldb_message_element *el;
+
+ /* Calling this will create the element if it does not exist. */
+ return sysdb_attrs_get_el_ext(attrs, name, true, &el);
+}
+
int sysdb_attrs_add_val(struct sysdb_attrs *attrs,
const char *name, const struct ldb_val *val)
{
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 2f20692cc..887a9630e 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -398,6 +398,7 @@ enum sysdb_obj_type {
extern const char *sysdb_ts_cache_attrs[];
/* values are copied in the structure, allocated on "attrs" */
+int sysdb_attrs_add_empty(struct sysdb_attrs *attrs, const char *name);
int sysdb_attrs_add_val(struct sysdb_attrs *attrs,
const char *name, const struct ldb_val *val);
int sysdb_attrs_add_val_safe(struct sysdb_attrs *attrs,
diff --git a/src/providers/ipa/ipa_netgroups.c b/src/providers/ipa/ipa_netgroups.c
index 52d90af4f..57f11a507 100644
--- a/src/providers/ipa/ipa_netgroups.c
+++ b/src/providers/ipa/ipa_netgroups.c
@@ -70,7 +70,10 @@ static errno_t ipa_save_netgroup(TALLOC_CTX *mem_ctx,
struct ldb_message_element *el;
struct sysdb_attrs *netgroup_attrs;
const char *name = NULL;
+ char **missing;
+ int missing_index;
int ret;
+ int i;
size_t c;
ret = sysdb_attrs_get_el(attrs,
@@ -90,6 +93,23 @@ static errno_t ipa_save_netgroup(TALLOC_CTX *mem_ctx,
goto fail;
}
+ missing = talloc_zero_array(netgroup_attrs, char *, attrs->num + 1);
+ if (missing == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ for (i = 0, missing_index = 0; i < attrs->num; i++) {
+ if (attrs->a[i].num_values == 0) {
+ missing[missing_index] = talloc_strdup(missing, attrs->a[i].name);
+ if (missing[missing_index] == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ missing_index++;
+ }
+ }
+
ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
if (ret) {
goto fail;
@@ -138,7 +158,6 @@ static errno_t ipa_save_netgroup(TALLOC_CTX *mem_ctx,
if (el->num_values == 0) {
DEBUG(SSSDBG_TRACE_LIBS,
"No original members for netgroup [%s]\n", name);
-
} else {
DEBUG(SSSDBG_TRACE_LIBS,
"Adding original members to netgroup [%s]\n", name);
@@ -173,7 +192,7 @@ static errno_t ipa_save_netgroup(TALLOC_CTX *mem_ctx,
DEBUG(SSSDBG_TRACE_FUNC, "Storing info for netgroup %s\n", name);
- ret = sysdb_add_netgroup(dom, name, NULL, netgroup_attrs, NULL,
+ ret = sysdb_add_netgroup(dom, name, NULL, netgroup_attrs, missing,
dom->netgroup_timeout, 0);
if (ret) goto fail;
@@ -866,6 +885,18 @@ static int ipa_netgr_process_all(struct ipa_get_netgroups_state *state)
hash_iterate(state->new_netgroups, extract_netgroups, state);
for (i = 0; i < state->netgroups_count; i++) {
+ /* Make sure these attributes always exist, so we can remove them if
+ * there are no members. */
+ ret = sysdb_attrs_add_empty(state->netgroups[i], SYSDB_NETGROUP_MEMBER);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = sysdb_attrs_add_empty(state->netgroups[i], SYSDB_NETGROUP_TRIPLE);
+ if (ret != EOK) {
+ goto done;
+ }
+
/* load all its member netgroups, translate */
DEBUG(SSSDBG_TRACE_INTERNAL, "Extracting netgroup members of netgroup %d\n", i);
ret = sysdb_attrs_get_string_array(state->netgroups[i],
diff --git a/src/tests/system/tests/test_netgroups.py b/src/tests/system/tests/test_netgroups.py
new file mode 100644
index 000000000..6b6bc8e8b
--- /dev/null
+++ b/src/tests/system/tests/test_netgroups.py
@@ -0,0 +1,108 @@
+"""
+Netgroup tests.
+
+:requirement: netgroup
+"""
+
+from __future__ import annotations
+
+import pytest
+from sssd_test_framework.roles.client import Client
+from sssd_test_framework.roles.generic import GenericProvider
+from sssd_test_framework.topology import KnownTopologyGroup
+
+
+@pytest.mark.tier(1)
+@pytest.mark.ticket(gh=6652, bz=2162552)
+@pytest.mark.topology(KnownTopologyGroup.AnyProvider)
+def test_netgroups__add_remove_netgroup_triple(client: Client, provider: GenericProvider):
+ """
+ :title: Netgroup triple is correctly removed from cached record
+ :setup:
+ 1. Create local user "user-1"
+ 2. Create netgroup "ng-1"
+ 3. Add "(-,user-1,)" triple to the netgroup
+ 4. Start SSSD
+ :steps:
+ 1. Run "getent netgroup ng-1"
+ 2. Remove "(-,user-1,)" triple from "ng-1"
+ 3. Invalidate netgroup in cache "sssctl cache-expire -n ng-1"
+ 4. Run "getent netgroup ng-1"
+ :expectedresults:
+ 1. "(-,user-1,)" is present in the netgroup
+ 2. Triple was removed from the netgroup
+ 3. Cached record was invalidated
+ 4. "(-,user-1,)" is not present in the netgroup
+ :customerscenario: True
+ """
+ user = provider.user("user-1").add()
+ ng = provider.netgroup("ng-1").add().add_member(user=user)
+
+ client.sssd.start()
+
+ result = client.tools.getent.netgroup("ng-1")
+ assert result is not None
+ assert result.name == "ng-1"
+ assert len(result.members) == 1
+ assert "(-, user-1)" in result.members
+
+ ng.remove_member(user=user)
+ client.sssctl.cache_expire(netgroups=True)
+
+ result = client.tools.getent.netgroup("ng-1")
+ assert result is not None
+ assert result.name == "ng-1"
+ assert len(result.members) == 0
+
+
+@pytest.mark.tier(1)
+@pytest.mark.ticket(gh=6652, bz=2162552)
+@pytest.mark.topology(KnownTopologyGroup.AnyProvider)
+def test_netgroups__add_remove_netgroup_member(client: Client, provider: GenericProvider):
+ """
+ :title: Netgroup member is correctly removed from cached record
+ :setup:
+ 1. Create local user "user-1"
+ 2. Create local user "user-2"
+ 3. Create netgroup "ng-1"
+ 4. Create netgroup "ng-2"
+ 5. Add "(-,user-1,)" triple to the netgroup "ng-1"
+ 6. Add "(-,user-2,)" triple to the netgroup "ng-2"
+ 7. Add "ng-1" as a member to "ng-2"
+ 8. Start SSSD
+ :steps:
+ 1. Run "getent netgroup ng-2"
+ 2. Remove "ng-1" from "ng-2"
+ 3. Invalidate netgroup "ng-2" in cache "sssctl cache-expire -n ng-2"
+ 4. Run "getent netgroup ng-2"
+ :expectedresults:
+ 1. "(-,user-1,)", "(-,user-2,)" is present in the netgroup
+ 2. Netgroup member was removed from the netgroup
+ 3. Cached record was invalidated
+ 4. "(-,user-1,)" is not present in the netgroup, only "(-,user-2,)"
+ :customerscenario: True
+ """
+ u1 = provider.user("user-1").add()
+ u2 = provider.user("user-2").add()
+
+ ng1 = provider.netgroup("ng-1").add().add_member(user=u1)
+ ng2 = provider.netgroup("ng-2").add().add_member(user=u2, ng=ng1)
+
+ client.sssd.start()
+
+ result = client.tools.getent.netgroup("ng-2")
+ assert result is not None
+ assert result.name == "ng-2"
+ assert len(result.members) == 2
+ assert "(-, user-1)" in result.members
+ assert "(-, user-2)" in result.members
+
+ ng2.remove_member(ng=ng1)
+ client.sssctl.cache_expire(netgroups=True)
+
+ result = client.tools.getent.netgroup("ng-2")
+ assert result is not None
+ assert result.name == "ng-2"
+ assert len(result.members) == 1
+ assert "(-, user-1)" not in result.members
+ assert "(-, user-2)" in result.members
--
2.27.0